fs/minix: bugfix, number of indirect block ptrs per block depends on block size

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Linux Kernel Mailing List
Date: Friday, May 28, 2010 - 11:59 am

Gitweb:     http://git.kernel.org/linus/0ab7620a0cefe6982b914a830a41f65ecccd74bd
Commit:     0ab7620a0cefe6982b914a830a41f65ecccd74bd
Parent:     1b061d9247f71cd15edc4c4c4600191a903642c0
Author:     Erik van der Kouwe <vdkouwe@cs.vu.nl>
AuthorDate: Wed May 26 12:03:23 2010 +0200
Committer:  Al Viro <viro@zeniv.linux.org.uk>
CommitDate: Thu May 27 22:06:22 2010 -0400

    fs/minix: bugfix, number of indirect block ptrs per block depends on block size
    
    The MINIX filesystem driver used a constant number of indirect block
    pointers in an indirect block. This worked only for filesystems with 1kb
    block, while the MINIX default block size is now 4kb. As a consequence,
    large files were read incorrectly on such filesystems and writing a
    large file would cause the filesystem to become corrupted. This patch
    computes the number of indirect block pointers based on the block size,
    making the driver work for each block size.
    
    I would like to thank Feiran Zheng ('Fam') for pointing out the cause
    of the corruption.
    
    Signed-off-by: Erik van der Kouwe <vdkouwe@cs.vu.nl>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/minix/itree_v2.c |   27 +++++++++++++++------------
 1 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/fs/minix/itree_v2.c b/fs/minix/itree_v2.c
index f230109..13487ad 100644
--- a/fs/minix/itree_v2.c
+++ b/fs/minix/itree_v2.c
@@ -20,6 +20,9 @@ static inline block_t *i_data(struct inode *inode)
 	return (block_t *)minix_i(inode)->u.i2_data;
 }
 
+#define DIRCOUNT 7
+#define INDIRCOUNT(sb) (1 << ((sb)->s_blocksize_bits - 2))
+
 static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
 {
 	int n = 0;
@@ -34,21 +37,21 @@ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
 			printk("MINIX-fs: block_to_path: "
 			       "block %ld too big on dev %s\n",
 				block, bdevname(sb->s_bdev, b));
-	} else if (block < 7) {
+	} else if (block < DIRCOUNT) {
 		offsets[n++] = block;
-	} else if ((block -= 7) < 256) {
-		offsets[n++] = 7;
+	} else if ((block -= DIRCOUNT) < INDIRCOUNT(sb)) {
+		offsets[n++] = DIRCOUNT;
 		offsets[n++] = block;
-	} else if ((block -= 256) < 256*256) {
-		offsets[n++] = 8;
-		offsets[n++] = block>>8;
-		offsets[n++] = block & 255;
+	} else if ((block -= INDIRCOUNT(sb)) < INDIRCOUNT(sb) * INDIRCOUNT(sb)) {
+		offsets[n++] = DIRCOUNT + 1;
+		offsets[n++] = block / INDIRCOUNT(sb);
+		offsets[n++] = block % INDIRCOUNT(sb);
 	} else {
-		block -= 256*256;
-		offsets[n++] = 9;
-		offsets[n++] = block>>16;
-		offsets[n++] = (block>>8) & 255;
-		offsets[n++] = block & 255;
+		block -= INDIRCOUNT(sb) * INDIRCOUNT(sb);
+		offsets[n++] = DIRCOUNT + 2;
+		offsets[n++] = (block / INDIRCOUNT(sb)) / INDIRCOUNT(sb);
+		offsets[n++] = (block / INDIRCOUNT(sb)) % INDIRCOUNT(sb);
+		offsets[n++] = block % INDIRCOUNT(sb);
 	}
 	return n;
 }
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
fs/minix: bugfix, number of indirect block ptrs per block ..., Linux Kernel Mailing ..., (Fri May 28, 11:59 am)