[Tux3] Patch: Use negative seg count to indicate read hole

Daniel Phillips phillips at phunq.net
Tue Dec 16 13:13:21 PST 2008


Hi,

This is a small change that just makes me feel better about the
get_segs interface, it allows physical address zero as a block
address.  Even though we will never use physical block zero, it
makes me feel the interface is cleaner.  And it makes sure that
any caller will notice and handle the read hole.

Not applied yet.

Daniel

diff -r 3193c496333d user/kernel/filemap.c
--- a/user/kernel/filemap.c	Mon Dec 15 22:35:29 2008 -0800
+++ b/user/kernel/filemap.c	Tue Dec 16 13:07:13 2008 -0800
@@ -9,7 +9,7 @@
 #define trace trace_on
 #endif
 
-struct seg { block_t block; unsigned count; };
+struct seg { block_t block; int count; };
 
 int get_segs(struct inode *inode, block_t start, unsigned limit, struct seg seg[], unsigned max_segs, int write)
 {
@@ -55,7 +55,6 @@
 			trace("emit %Lx/%x", (L)extent_block(*next_extent), extent_count(*next_extent));
 			seg[segs++] = (struct seg){ extent_block(*next_extent), extent_count(*next_extent) };
 
-
 			unsigned count = extent_count(*next_extent);
 			if (start > dwalk_index(walk))
 				count -= start - dwalk_index(walk);
@@ -85,7 +84,7 @@
 
 			/* there is gap, so stop */
 			if (!write) {
-				seg[segs++] = (struct seg){ 0, gap };
+				seg[segs++] = (struct seg){ .count = -gap };
 				break;
 			}
 
@@ -214,7 +213,9 @@
 
 	int err = 0;
 	for (int i = 0, index = start; !err && index < limit; i++) {
-		unsigned count = seg[i].count;
+		int count = seg[i].count, hole = count < 0;
+		if (hole)
+			count = -count;
 		trace_on("extent 0x%Lx/%x => %Lx", (L)index, count, (L)seg[i].block);
 		for (int j = 0; !err && j < count; j++) {
 			block_t block = seg[i].block + j;
@@ -223,7 +224,7 @@
 			if (write) {
 				err = diskwrite(dev->fd, bufdata(buffer), sb->blocksize, block << dev->bits);
 			} else {
-				if (!block) { /* block zero is never allocated */
+				if (hole) {
 					trace("zero fill buffer");
 					memset(bufdata(buffer), 0, sb->blocksize);
 					continue;
@@ -259,19 +260,20 @@
 		return -EIO;
 	}
 	block_t block = seg[0].block;
-	size_t count = seg[0].count;
+	int count = seg[0].count;
 	for (i = 1; i < segs; i++) {
 		if (block + count != seg[i].block)
 			break;
 		count += seg[i].count;
 	}
-	if (block) {
+	if (count < 0)
+		set_buffer_uptodate(bh_result);
+	else {
 		unsigned blocks = min(max_blocks, count);
 		map_bh(bh_result, inode->i_sb, block);
 		bh_result->b_size = blocks << sbi->blockbits;
 		inode->i_blocks += blocks << (sbi->blockbits - 9);
-	} else
-		set_buffer_new(bh_result);
+	}
 	trace("<== inum %Lu, mapped %d, block %Lu, size %zu",
 	      (L)tux_inode(inode)->inum, buffer_mapped(bh_result),
 	      (L)bh_result->b_blocknr, bh_result->b_size);

_______________________________________________
Tux3 mailing list
Tux3 at tux3.org
http://mailman.tux3.org/cgi-bin/mailman/listinfo/tux3



More information about the Tux3 mailing list