Skip to content

Commit 0ab7620

Browse files
Erik van der KouweAl Viro
authored andcommitted
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 <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent 1b061d9 commit 0ab7620

File tree

1 file changed

+15
-12
lines changed

1 file changed

+15
-12
lines changed

fs/minix/itree_v2.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ static inline block_t *i_data(struct inode *inode)
2020
return (block_t *)minix_i(inode)->u.i2_data;
2121
}
2222

23+
#define DIRCOUNT 7
24+
#define INDIRCOUNT(sb) (1 << ((sb)->s_blocksize_bits - 2))
25+
2326
static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
2427
{
2528
int n = 0;
@@ -34,21 +37,21 @@ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
3437
printk("MINIX-fs: block_to_path: "
3538
"block %ld too big on dev %s\n",
3639
block, bdevname(sb->s_bdev, b));
37-
} else if (block < 7) {
40+
} else if (block < DIRCOUNT) {
3841
offsets[n++] = block;
39-
} else if ((block -= 7) < 256) {
40-
offsets[n++] = 7;
42+
} else if ((block -= DIRCOUNT) < INDIRCOUNT(sb)) {
43+
offsets[n++] = DIRCOUNT;
4144
offsets[n++] = block;
42-
} else if ((block -= 256) < 256*256) {
43-
offsets[n++] = 8;
44-
offsets[n++] = block>>8;
45-
offsets[n++] = block & 255;
45+
} else if ((block -= INDIRCOUNT(sb)) < INDIRCOUNT(sb) * INDIRCOUNT(sb)) {
46+
offsets[n++] = DIRCOUNT + 1;
47+
offsets[n++] = block / INDIRCOUNT(sb);
48+
offsets[n++] = block % INDIRCOUNT(sb);
4649
} else {
47-
block -= 256*256;
48-
offsets[n++] = 9;
49-
offsets[n++] = block>>16;
50-
offsets[n++] = (block>>8) & 255;
51-
offsets[n++] = block & 255;
50+
block -= INDIRCOUNT(sb) * INDIRCOUNT(sb);
51+
offsets[n++] = DIRCOUNT + 2;
52+
offsets[n++] = (block / INDIRCOUNT(sb)) / INDIRCOUNT(sb);
53+
offsets[n++] = (block / INDIRCOUNT(sb)) % INDIRCOUNT(sb);
54+
offsets[n++] = block % INDIRCOUNT(sb);
5255
}
5356
return n;
5457
}

0 commit comments

Comments
 (0)