Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] Minix V3 support

This morning I needed to read a Minix V3 filesystem, but unfortunately my
2.6.19 did not support that, and neither did the downloaded 2.6.20rc4.

Fortunately, google told me that Daniel Aragones had already done the work,
patch found at http://www.terra.es/personal2/danarag/

Unfortunaly, looking at the patch was painful to my eyes, so I polished it
a bit before applying. The resulting kernel boots, and reads the
filesystem it needed to read.

Signed-off-by: Daniel Aragones <danarag@gmail.com>
Signed-off-by: Andries Brouwer <aeb@cwi.nl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Andries Brouwer and committed by
Linus Torvalds
939b00df b587b13a

+233 -112
+40 -29
fs/minix/bitmap.c
··· 26 26 for (i=0; i<numblocks-1; i++) { 27 27 if (!(bh=map[i])) 28 28 return(0); 29 - for (j=0; j<BLOCK_SIZE; j++) 29 + for (j=0; j<bh->b_size; j++) 30 30 sum += nibblemap[bh->b_data[j] & 0xf] 31 31 + nibblemap[(bh->b_data[j]>>4) & 0xf]; 32 32 } 33 33 34 34 if (numblocks==0 || !(bh=map[numblocks-1])) 35 35 return(0); 36 - i = ((numbits-(numblocks-1)*BLOCK_SIZE*8)/16)*2; 36 + i = ((numbits - (numblocks-1) * bh->b_size * 8) / 16) * 2; 37 37 for (j=0; j<i; j++) { 38 38 sum += nibblemap[bh->b_data[j] & 0xf] 39 39 + nibblemap[(bh->b_data[j]>>4) & 0xf]; ··· 48 48 return(sum); 49 49 } 50 50 51 - void minix_free_block(struct inode * inode, int block) 51 + void minix_free_block(struct inode *inode, unsigned long block) 52 52 { 53 - struct super_block * sb = inode->i_sb; 54 - struct minix_sb_info * sbi = minix_sb(sb); 55 - struct buffer_head * bh; 56 - unsigned int bit,zone; 53 + struct super_block *sb = inode->i_sb; 54 + struct minix_sb_info *sbi = minix_sb(sb); 55 + struct buffer_head *bh; 56 + int k = sb->s_blocksize_bits + 3; 57 + unsigned long bit, zone; 57 58 58 59 if (block < sbi->s_firstdatazone || block >= sbi->s_nzones) { 59 60 printk("Trying to free block not in datazone\n"); 60 61 return; 61 62 } 62 63 zone = block - sbi->s_firstdatazone + 1; 63 - bit = zone & 8191; 64 - zone >>= 13; 64 + bit = zone & ((1<<k) - 1); 65 + zone >>= k; 65 66 if (zone >= sbi->s_zmap_blocks) { 66 67 printk("minix_free_block: nonexistent bitmap buffer\n"); 67 68 return; 68 69 } 69 70 bh = sbi->s_zmap[zone]; 70 71 lock_kernel(); 71 - if (!minix_test_and_clear_bit(bit,bh->b_data)) 72 - printk("free_block (%s:%d): bit already cleared\n", 72 + if (!minix_test_and_clear_bit(bit, bh->b_data)) 73 + printk("minix_free_block (%s:%lu): bit already cleared\n", 73 74 sb->s_id, block); 74 75 unlock_kernel(); 75 76 mark_buffer_dirty(bh); ··· 80 79 int minix_new_block(struct inode * inode) 81 80 { 82 81 struct minix_sb_info *sbi = minix_sb(inode->i_sb); 82 + int bits_per_zone = 8 * inode->i_sb->s_blocksize; 83 83 int i; 84 84 85 85 for (i = 0; i < sbi->s_zmap_blocks; i++) { ··· 88 86 int j; 89 87 90 88 lock_kernel(); 91 - if ((j = minix_find_first_zero_bit(bh->b_data, 8192)) < 8192) { 92 - minix_set_bit(j,bh->b_data); 89 + j = minix_find_first_zero_bit(bh->b_data, bits_per_zone); 90 + if (j < bits_per_zone) { 91 + minix_set_bit(j, bh->b_data); 93 92 unlock_kernel(); 94 93 mark_buffer_dirty(bh); 95 - j += i*8192 + sbi->s_firstdatazone-1; 94 + j += i * bits_per_zone + sbi->s_firstdatazone-1; 96 95 if (j < sbi->s_firstdatazone || j >= sbi->s_nzones) 97 96 break; 98 97 return j; ··· 140 137 int block; 141 138 struct minix_sb_info *sbi = minix_sb(sb); 142 139 struct minix2_inode *p; 140 + int minix2_inodes_per_block = sb->s_blocksize / sizeof(struct minix2_inode); 143 141 144 142 *bh = NULL; 145 143 if (!ino || ino > sbi->s_ninodes) { ··· 150 146 } 151 147 ino--; 152 148 block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks + 153 - ino / MINIX2_INODES_PER_BLOCK; 149 + ino / minix2_inodes_per_block; 154 150 *bh = sb_bread(sb, block); 155 151 if (!*bh) { 156 152 printk("Unable to read inode block\n"); 157 153 return NULL; 158 154 } 159 155 p = (void *)(*bh)->b_data; 160 - return p + ino % MINIX2_INODES_PER_BLOCK; 156 + return p + ino % minix2_inodes_per_block; 161 157 } 162 158 163 159 /* Clear the link count and mode of a deleted inode on disk. */ ··· 189 185 190 186 void minix_free_inode(struct inode * inode) 191 187 { 188 + struct super_block *sb = inode->i_sb; 192 189 struct minix_sb_info *sbi = minix_sb(inode->i_sb); 193 - struct buffer_head * bh; 194 - unsigned long ino; 190 + struct buffer_head *bh; 191 + int k = sb->s_blocksize_bits + 3; 192 + unsigned long ino, bit; 195 193 196 194 ino = inode->i_ino; 197 195 if (ino < 1 || ino > sbi->s_ninodes) { 198 196 printk("minix_free_inode: inode 0 or nonexistent inode\n"); 199 197 goto out; 200 198 } 201 - if ((ino >> 13) >= sbi->s_imap_blocks) { 199 + bit = ino & ((1<<k) - 1); 200 + ino >>= k; 201 + if (ino >= sbi->s_imap_blocks) { 202 202 printk("minix_free_inode: nonexistent imap in superblock\n"); 203 203 goto out; 204 204 } 205 205 206 206 minix_clear_inode(inode); /* clear on-disk copy */ 207 207 208 - bh = sbi->s_imap[ino >> 13]; 208 + bh = sbi->s_imap[ino]; 209 209 lock_kernel(); 210 - if (!minix_test_and_clear_bit(ino & 8191, bh->b_data)) 211 - printk("minix_free_inode: bit %lu already cleared\n", ino); 210 + if (!minix_test_and_clear_bit(bit, bh->b_data)) 211 + printk("minix_free_inode: bit %lu already cleared\n", bit); 212 212 unlock_kernel(); 213 213 mark_buffer_dirty(bh); 214 214 out: ··· 225 217 struct minix_sb_info *sbi = minix_sb(sb); 226 218 struct inode *inode = new_inode(sb); 227 219 struct buffer_head * bh; 228 - int i,j; 220 + int bits_per_zone = 8 * sb->s_blocksize; 221 + unsigned long j; 222 + int i; 229 223 230 224 if (!inode) { 231 225 *error = -ENOMEM; 232 226 return NULL; 233 227 } 234 - j = 8192; 228 + j = bits_per_zone; 235 229 bh = NULL; 236 230 *error = -ENOSPC; 237 231 lock_kernel(); 238 232 for (i = 0; i < sbi->s_imap_blocks; i++) { 239 233 bh = sbi->s_imap[i]; 240 - if ((j = minix_find_first_zero_bit(bh->b_data, 8192)) < 8192) 234 + j = minix_find_first_zero_bit(bh->b_data, bits_per_zone); 235 + if (j < bits_per_zone) 241 236 break; 242 237 } 243 - if (!bh || j >= 8192) { 238 + if (!bh || j >= bits_per_zone) { 244 239 unlock_kernel(); 245 240 iput(inode); 246 241 return NULL; 247 242 } 248 - if (minix_test_and_set_bit(j,bh->b_data)) { /* shouldn't happen */ 249 - printk("new_inode: bit already set\n"); 243 + if (minix_test_and_set_bit(j, bh->b_data)) { /* shouldn't happen */ 250 244 unlock_kernel(); 245 + printk("minix_new_inode: bit already set\n"); 251 246 iput(inode); 252 247 return NULL; 253 248 } 254 249 unlock_kernel(); 255 250 mark_buffer_dirty(bh); 256 - j += i*8192; 251 + j += i * bits_per_zone; 257 252 if (!j || j > sbi->s_ninodes) { 258 253 iput(inode); 259 254 return NULL;
+111 -51
fs/minix/dir.c
··· 4 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 5 * 6 6 * minix directory handling functions 7 + * 8 + * Updated to filesystem version 3 by Daniel Aragones 7 9 */ 8 10 9 11 #include "minix.h" ··· 13 11 #include <linux/smp_lock.h> 14 12 15 13 typedef struct minix_dir_entry minix_dirent; 14 + typedef struct minix3_dir_entry minix3_dirent; 16 15 17 16 static int minix_readdir(struct file *, void *, filldir_t); 18 17 ··· 92 89 unsigned long npages = dir_pages(inode); 93 90 struct minix_sb_info *sbi = minix_sb(sb); 94 91 unsigned chunk_size = sbi->s_dirsize; 92 + char *name; 93 + __u32 inumber; 95 94 96 95 lock_kernel(); 97 96 ··· 110 105 kaddr = (char *)page_address(page); 111 106 p = kaddr+offset; 112 107 limit = kaddr + minix_last_byte(inode, n) - chunk_size; 113 - for ( ; p <= limit ; p = minix_next_entry(p, sbi)) { 114 - minix_dirent *de = (minix_dirent *)p; 115 - if (de->inode) { 108 + for ( ; p <= limit; p = minix_next_entry(p, sbi)) { 109 + if (sbi->s_version == MINIX_V3) { 110 + minix3_dirent *de3 = (minix3_dirent *)p; 111 + name = de3->name; 112 + inumber = de3->inode; 113 + } else { 114 + minix_dirent *de = (minix_dirent *)p; 115 + name = de->name; 116 + inumber = de->inode; 117 + } 118 + if (inumber) { 116 119 int over; 117 - unsigned l = strnlen(de->name,sbi->s_namelen); 118 120 121 + unsigned l = strnlen(name, sbi->s_namelen); 119 122 offset = p - kaddr; 120 - over = filldir(dirent, de->name, l, 121 - (n<<PAGE_CACHE_SHIFT) | offset, 122 - de->inode, DT_UNKNOWN); 123 + over = filldir(dirent, name, l, 124 + (n << PAGE_CACHE_SHIFT) | offset, 125 + inumber, DT_UNKNOWN); 123 126 if (over) { 124 127 dir_put_page(page); 125 128 goto done; ··· 169 156 unsigned long n; 170 157 unsigned long npages = dir_pages(dir); 171 158 struct page *page = NULL; 172 - struct minix_dir_entry *de; 159 + char *p; 173 160 161 + char *namx; 162 + __u32 inumber; 174 163 *res_page = NULL; 175 164 176 165 for (n = 0; n < npages; n++) { 177 - char *kaddr; 166 + char *kaddr, *limit; 167 + 178 168 page = dir_get_page(dir, n); 179 169 if (IS_ERR(page)) 180 170 continue; 181 171 182 172 kaddr = (char*)page_address(page); 183 - de = (struct minix_dir_entry *) kaddr; 184 - kaddr += minix_last_byte(dir, n) - sbi->s_dirsize; 185 - for ( ; (char *) de <= kaddr ; de = minix_next_entry(de,sbi)) { 186 - if (!de->inode) 173 + limit = kaddr + minix_last_byte(dir, n) - sbi->s_dirsize; 174 + for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) { 175 + if (sbi->s_version == MINIX_V3) { 176 + minix3_dirent *de3 = (minix3_dirent *)p; 177 + namx = de3->name; 178 + inumber = de3->inode; 179 + } else { 180 + minix_dirent *de = (minix_dirent *)p; 181 + namx = de->name; 182 + inumber = de->inode; 183 + } 184 + if (!inumber) 187 185 continue; 188 - if (namecompare(namelen,sbi->s_namelen,name,de->name)) 186 + if (namecompare(namelen, sbi->s_namelen, name, namx)) 189 187 goto found; 190 188 } 191 189 dir_put_page(page); ··· 205 181 206 182 found: 207 183 *res_page = page; 208 - return de; 184 + return (minix_dirent *)p; 209 185 } 210 186 211 187 int minix_add_link(struct dentry *dentry, struct inode *inode) ··· 216 192 struct super_block * sb = dir->i_sb; 217 193 struct minix_sb_info * sbi = minix_sb(sb); 218 194 struct page *page = NULL; 219 - struct minix_dir_entry * de; 220 195 unsigned long npages = dir_pages(dir); 221 196 unsigned long n; 222 - char *kaddr; 197 + char *kaddr, *p; 198 + minix_dirent *de; 199 + minix3_dirent *de3; 223 200 unsigned from, to; 224 201 int err; 202 + char *namx = NULL; 203 + __u32 inumber; 225 204 226 205 /* 227 206 * We take care of directory expansion in the same loop ··· 232 205 * to protect that region. 233 206 */ 234 207 for (n = 0; n <= npages; n++) { 235 - char *dir_end; 208 + char *limit, *dir_end; 236 209 237 210 page = dir_get_page(dir, n); 238 211 err = PTR_ERR(page); ··· 241 214 lock_page(page); 242 215 kaddr = (char*)page_address(page); 243 216 dir_end = kaddr + minix_last_byte(dir, n); 244 - de = (minix_dirent *)kaddr; 245 - kaddr += PAGE_CACHE_SIZE - sbi->s_dirsize; 246 - while ((char *)de <= kaddr) { 247 - if ((char *)de == dir_end) { 217 + limit = kaddr + PAGE_CACHE_SIZE - sbi->s_dirsize; 218 + for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) { 219 + de = (minix_dirent *)p; 220 + de3 = (minix3_dirent *)p; 221 + if (sbi->s_version == MINIX_V3) { 222 + namx = de3->name; 223 + inumber = de3->inode; 224 + } else { 225 + namx = de->name; 226 + inumber = de->inode; 227 + } 228 + if (p == dir_end) { 248 229 /* We hit i_size */ 249 - de->inode = 0; 230 + if (sbi->s_version == MINIX_V3) 231 + de3->inode = 0; 232 + else 233 + de->inode = 0; 250 234 goto got_it; 251 235 } 252 - if (!de->inode) 236 + if (!inumber) 253 237 goto got_it; 254 238 err = -EEXIST; 255 - if (namecompare(namelen,sbi->s_namelen,name,de->name)) 239 + if (namecompare(namelen, sbi->s_namelen, name, namx)) 256 240 goto out_unlock; 257 - de = minix_next_entry(de, sbi); 258 241 } 259 242 unlock_page(page); 260 243 dir_put_page(page); ··· 273 236 return -EINVAL; 274 237 275 238 got_it: 276 - from = (char*)de - (char*)page_address(page); 239 + from = p - (char*)page_address(page); 277 240 to = from + sbi->s_dirsize; 278 241 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 279 242 if (err) 280 243 goto out_unlock; 281 - memcpy (de->name, name, namelen); 282 - memset (de->name + namelen, 0, sbi->s_dirsize - namelen - 2); 283 - de->inode = inode->i_ino; 244 + memcpy (namx, name, namelen); 245 + if (sbi->s_version == MINIX_V3) { 246 + memset (namx + namelen, 0, sbi->s_dirsize - namelen - 4); 247 + de3->inode = inode->i_ino; 248 + } else { 249 + memset (namx + namelen, 0, sbi->s_dirsize - namelen - 2); 250 + de->inode = inode->i_ino; 251 + } 284 252 err = dir_commit_chunk(page, from, to); 285 253 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 286 254 mark_inode_dirty(dir); ··· 325 283 { 326 284 struct address_space *mapping = inode->i_mapping; 327 285 struct page *page = grab_cache_page(mapping, 0); 328 - struct minix_sb_info * sbi = minix_sb(inode->i_sb); 329 - struct minix_dir_entry * de; 286 + struct minix_sb_info *sbi = minix_sb(inode->i_sb); 330 287 char *kaddr; 331 288 int err; 332 289 ··· 340 299 kaddr = kmap_atomic(page, KM_USER0); 341 300 memset(kaddr, 0, PAGE_CACHE_SIZE); 342 301 343 - de = (struct minix_dir_entry *)kaddr; 344 - de->inode = inode->i_ino; 345 - strcpy(de->name,"."); 346 - de = minix_next_entry(de, sbi); 347 - de->inode = dir->i_ino; 348 - strcpy(de->name,".."); 302 + if (sbi->s_version == MINIX_V3) { 303 + minix3_dirent *de3 = (minix3_dirent *)kaddr; 304 + 305 + de3->inode = inode->i_ino; 306 + strcpy(de3->name, "."); 307 + de3 = minix_next_entry(de3, sbi); 308 + de3->inode = dir->i_ino; 309 + strcpy(de3->name, ".."); 310 + } else { 311 + minix_dirent *de = (minix_dirent *)kaddr; 312 + 313 + de->inode = inode->i_ino; 314 + strcpy(de->name, "."); 315 + de = minix_next_entry(de, sbi); 316 + de->inode = dir->i_ino; 317 + strcpy(de->name, ".."); 318 + } 349 319 kunmap_atomic(kaddr, KM_USER0); 350 320 351 321 err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize); ··· 373 321 struct page *page = NULL; 374 322 unsigned long i, npages = dir_pages(inode); 375 323 struct minix_sb_info *sbi = minix_sb(inode->i_sb); 324 + char *name; 325 + __u32 inumber; 376 326 377 327 for (i = 0; i < npages; i++) { 378 - char *kaddr; 379 - minix_dirent * de; 380 - page = dir_get_page(inode, i); 328 + char *p, *kaddr, *limit; 381 329 330 + page = dir_get_page(inode, i); 382 331 if (IS_ERR(page)) 383 332 continue; 384 333 385 334 kaddr = (char *)page_address(page); 386 - de = (minix_dirent *)kaddr; 387 - kaddr += minix_last_byte(inode, i) - sbi->s_dirsize; 335 + limit = kaddr + minix_last_byte(inode, i) - sbi->s_dirsize; 336 + for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) { 337 + if (sbi->s_version == MINIX_V3) { 338 + minix3_dirent *de3 = (minix3_dirent *)p; 339 + name = de3->name; 340 + inumber = de3->inode; 341 + } else { 342 + minix_dirent *de = (minix_dirent *)p; 343 + name = de->name; 344 + inumber = de->inode; 345 + } 388 346 389 - while ((char *)de <= kaddr) { 390 - if (de->inode != 0) { 347 + if (inumber != 0) { 391 348 /* check for . and .. */ 392 - if (de->name[0] != '.') 349 + if (name[0] != '.') 393 350 goto not_empty; 394 - if (!de->name[1]) { 395 - if (de->inode != inode->i_ino) 351 + if (!name[1]) { 352 + if (inumber != inode->i_ino) 396 353 goto not_empty; 397 - } else if (de->name[1] != '.') 354 + } else if (name[1] != '.') 398 355 goto not_empty; 399 - else if (de->name[2]) 356 + else if (name[2]) 400 357 goto not_empty; 401 358 } 402 - de = minix_next_entry(de, sbi); 403 359 } 404 360 dir_put_page(page); 405 361 }
+38 -11
fs/minix/inode.c
··· 7 7 * Minix V2 fs support. 8 8 * 9 9 * Modified for 680x0 by Andreas Schwab 10 + * Updated to filesystem version 3 by Daniel Aragones 10 11 */ 11 12 12 13 #include <linux/module.h> ··· 37 36 struct minix_sb_info *sbi = minix_sb(sb); 38 37 39 38 if (!(sb->s_flags & MS_RDONLY)) { 40 - sbi->s_ms->s_state = sbi->s_mount_state; 39 + if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ 40 + sbi->s_ms->s_state = sbi->s_mount_state; 41 41 mark_buffer_dirty(sbi->s_sbh); 42 42 } 43 43 for (i = 0; i < sbi->s_imap_blocks; i++) ··· 119 117 !(sbi->s_mount_state & MINIX_VALID_FS)) 120 118 return 0; 121 119 /* Mounting a rw partition read-only. */ 122 - ms->s_state = sbi->s_mount_state; 120 + if (sbi->s_version != MINIX_V3) 121 + ms->s_state = sbi->s_mount_state; 123 122 mark_buffer_dirty(sbi->s_sbh); 124 123 } else { 125 124 /* Mount a partition which is read-only, read-write. */ 126 - sbi->s_mount_state = ms->s_state; 127 - ms->s_state &= ~MINIX_VALID_FS; 125 + if (sbi->s_version != MINIX_V3) { 126 + sbi->s_mount_state = ms->s_state; 127 + ms->s_state &= ~MINIX_VALID_FS; 128 + } else { 129 + sbi->s_mount_state = MINIX_VALID_FS; 130 + } 128 131 mark_buffer_dirty(sbi->s_sbh); 129 132 130 133 if (!(sbi->s_mount_state & MINIX_VALID_FS)) ··· 147 140 struct buffer_head *bh; 148 141 struct buffer_head **map; 149 142 struct minix_super_block *ms; 150 - int i, block; 143 + struct minix3_super_block *m3s = NULL; 144 + unsigned long i, block; 151 145 struct inode *root_inode; 152 146 struct minix_sb_info *sbi; 153 147 ··· 200 192 sbi->s_dirsize = 32; 201 193 sbi->s_namelen = 30; 202 194 sbi->s_link_max = MINIX2_LINK_MAX; 195 + } else if ( *(__u16 *)(bh->b_data + 24) == MINIX3_SUPER_MAGIC) { 196 + m3s = (struct minix3_super_block *) bh->b_data; 197 + s->s_magic = m3s->s_magic; 198 + sbi->s_imap_blocks = m3s->s_imap_blocks; 199 + sbi->s_zmap_blocks = m3s->s_zmap_blocks; 200 + sbi->s_firstdatazone = m3s->s_firstdatazone; 201 + sbi->s_log_zone_size = m3s->s_log_zone_size; 202 + sbi->s_max_size = m3s->s_max_size; 203 + sbi->s_ninodes = m3s->s_ninodes; 204 + sbi->s_nzones = m3s->s_zones; 205 + sbi->s_dirsize = 64; 206 + sbi->s_namelen = 60; 207 + sbi->s_version = MINIX_V3; 208 + sbi->s_link_max = MINIX2_LINK_MAX; 209 + sbi->s_mount_state = MINIX_VALID_FS; 210 + sb_set_blocksize(s, m3s->s_blocksize); 203 211 } else 204 212 goto out_no_fs; 205 213 ··· 260 236 s->s_root->d_op = &minix_dentry_operations; 261 237 262 238 if (!(s->s_flags & MS_RDONLY)) { 263 - ms->s_state &= ~MINIX_VALID_FS; 239 + if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ 240 + ms->s_state &= ~MINIX_VALID_FS; 264 241 mark_buffer_dirty(bh); 265 242 } 266 243 if (!(sbi->s_mount_state & MINIX_VALID_FS)) ··· 303 278 304 279 out_no_fs: 305 280 if (!silent) 306 - printk("VFS: Can't find a Minix or Minix V2 filesystem " 307 - "on device %s\n", s->s_id); 281 + printk("VFS: Can't find a Minix filesystem V1 | V2 | V3 " 282 + "on device %s.\n", s->s_id); 308 283 out_release: 309 284 brelse(bh); 310 285 goto out; ··· 562 537 563 538 int minix_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 564 539 { 540 + struct inode *dir = dentry->d_parent->d_inode; 541 + struct super_block *sb = dir->i_sb; 565 542 generic_fillattr(dentry->d_inode, stat); 566 543 if (INODE_VERSION(dentry->d_inode) == MINIX_V1) 567 - stat->blocks = (BLOCK_SIZE / 512) * V1_minix_blocks(stat->size); 544 + stat->blocks = (BLOCK_SIZE / 512) * V1_minix_blocks(stat->size, sb); 568 545 else 569 - stat->blocks = (BLOCK_SIZE / 512) * V2_minix_blocks(stat->size); 570 - stat->blksize = BLOCK_SIZE; 546 + stat->blocks = (sb->s_blocksize / 512) * V2_minix_blocks(stat->size, sb); 547 + stat->blksize = sb->s_blocksize; 571 548 return 0; 572 549 } 573 550
+9 -7
fs/minix/itree_common.c
··· 23 23 24 24 static inline block_t *block_end(struct buffer_head *bh) 25 25 { 26 - return (block_t *)((char*)bh->b_data + BLOCK_SIZE); 26 + return (block_t *)((char*)bh->b_data + bh->b_size); 27 27 } 28 28 29 29 static inline Indirect *get_branch(struct inode *inode, ··· 85 85 branch[n].key = cpu_to_block(nr); 86 86 bh = sb_getblk(inode->i_sb, parent); 87 87 lock_buffer(bh); 88 - memset(bh->b_data, 0, BLOCK_SIZE); 88 + memset(bh->b_data, 0, bh->b_size); 89 89 branch[n].bh = bh; 90 90 branch[n].p = (block_t*) bh->b_data + offsets[n]; 91 91 *branch[n].p = branch[n].key; ··· 292 292 293 293 static inline void truncate (struct inode * inode) 294 294 { 295 + struct super_block *sb = inode->i_sb; 295 296 block_t *idata = i_data(inode); 296 297 int offsets[DEPTH]; 297 298 Indirect chain[DEPTH]; ··· 302 301 int first_whole; 303 302 long iblock; 304 303 305 - iblock = (inode->i_size + BLOCK_SIZE-1) >> 10; 304 + iblock = (inode->i_size + sb->s_blocksize -1) >> sb->s_blocksize_bits; 306 305 block_truncate_page(inode->i_mapping, inode->i_size, get_block); 307 306 308 307 n = block_to_path(inode, iblock, offsets); ··· 347 346 mark_inode_dirty(inode); 348 347 } 349 348 350 - static inline unsigned nblocks(loff_t size) 349 + static inline unsigned nblocks(loff_t size, struct super_block *sb) 351 350 { 351 + int k = sb->s_blocksize_bits - 10; 352 352 unsigned blocks, res, direct = DIRECT, i = DEPTH; 353 - blocks = (size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS; 353 + blocks = (size + sb->s_blocksize - 1) >> (BLOCK_SIZE_BITS + k); 354 354 res = blocks; 355 355 while (--i && blocks > direct) { 356 356 blocks -= direct; 357 - blocks += BLOCK_SIZE/sizeof(block_t) - 1; 358 - blocks /= BLOCK_SIZE/sizeof(block_t); 357 + blocks += sb->s_blocksize/sizeof(block_t) - 1; 358 + blocks /= sb->s_blocksize/sizeof(block_t); 359 359 res += blocks; 360 360 direct = 1; 361 361 }
+2 -2
fs/minix/itree_v1.c
··· 55 55 truncate(inode); 56 56 } 57 57 58 - unsigned V1_minix_blocks(loff_t size) 58 + unsigned V1_minix_blocks(loff_t size, struct super_block *sb) 59 59 { 60 - return nblocks(size); 60 + return nblocks(size, sb); 61 61 }
+4 -3
fs/minix/itree_v2.c
··· 23 23 static int block_to_path(struct inode * inode, long block, int offsets[DEPTH]) 24 24 { 25 25 int n = 0; 26 + struct super_block *sb = inode->i_sb; 26 27 27 28 if (block < 0) { 28 29 printk("minix_bmap: block<0\n"); 29 - } else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) { 30 + } else if (block >= (minix_sb(inode->i_sb)->s_max_size/sb->s_blocksize)) { 30 31 printk("minix_bmap: block>big\n"); 31 32 } else if (block < 7) { 32 33 offsets[n++] = block; ··· 61 60 truncate(inode); 62 61 } 63 62 64 - unsigned V2_minix_blocks(loff_t size) 63 + unsigned V2_minix_blocks(loff_t size, struct super_block *sb) 65 64 { 66 - return nblocks(size); 65 + return nblocks(size, sb); 67 66 }
+4 -8
fs/minix/minix.h
··· 7 7 * truncated. Else they will be disallowed (ENAMETOOLONG). 8 8 */ 9 9 #define NO_TRUNCATE 1 10 - 11 10 #define INODE_VERSION(inode) minix_sb(inode->i_sb)->s_version 12 - 13 11 #define MINIX_V1 0x0001 /* original minix fs */ 14 12 #define MINIX_V2 0x0002 /* minix V2 fs */ 13 + #define MINIX_V3 0x0003 /* minix V3 fs */ 15 14 16 15 /* 17 16 * minix fs inode data in memory ··· 51 52 extern void minix_free_inode(struct inode * inode); 52 53 extern unsigned long minix_count_free_inodes(struct minix_sb_info *sbi); 53 54 extern int minix_new_block(struct inode * inode); 54 - extern void minix_free_block(struct inode * inode, int block); 55 + extern void minix_free_block(struct inode *inode, unsigned long block); 55 56 extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi); 56 - 57 57 extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *); 58 58 59 - extern void V2_minix_truncate(struct inode *); 60 59 extern void V1_minix_truncate(struct inode *); 61 60 extern void V2_minix_truncate(struct inode *); 62 61 extern void minix_truncate(struct inode *); ··· 62 65 extern void minix_set_inode(struct inode *, dev_t); 63 66 extern int V1_minix_get_block(struct inode *, long, struct buffer_head *, int); 64 67 extern int V2_minix_get_block(struct inode *, long, struct buffer_head *, int); 65 - extern unsigned V1_minix_blocks(loff_t); 66 - extern unsigned V2_minix_blocks(loff_t); 68 + extern unsigned V1_minix_blocks(loff_t, struct super_block *); 69 + extern unsigned V2_minix_blocks(loff_t, struct super_block *); 67 70 68 71 extern struct minix_dir_entry *minix_find_entry(struct dentry*, struct page**); 69 72 extern int minix_add_link(struct dentry*, struct inode*); ··· 73 76 extern void minix_set_link(struct minix_dir_entry*, struct page*, struct inode*); 74 77 extern struct minix_dir_entry *minix_dotdot(struct inode*, struct page**); 75 78 extern ino_t minix_inode_by_name(struct dentry*); 76 - 77 79 extern int minix_sync_file(struct file *, struct dentry *, int); 78 80 79 81 extern struct inode_operations minix_file_inode_operations;
+1
include/linux/magic.h
··· 18 18 #define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */ 19 19 #define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */ 20 20 #define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */ 21 + #define MINIX3_SUPER_MAGIC 0x4d5a /* minix V3 fs */ 21 22 22 23 #define MSDOS_SUPER_MAGIC 0x4d44 /* MD */ 23 24 #define NCP_SUPER_MAGIC 0x564c /* Guess, what 0x564c is :-) */
+24 -1
include/linux/minix_fs.h
··· 25 25 #define MINIX_ERROR_FS 0x0002 /* fs has errors. */ 26 26 27 27 #define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode))) 28 - #define MINIX2_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix2_inode))) 29 28 30 29 /* 31 30 * This is the original minix inode layout on disk. ··· 74 75 __u32 s_zones; 75 76 }; 76 77 78 + /* 79 + * V3 minix super-block data on disk 80 + */ 81 + struct minix3_super_block { 82 + __u16 s_ninodes; 83 + __u16 s_nzones; 84 + __u16 s_pad0; 85 + __u16 s_imap_blocks; 86 + __u16 s_zmap_blocks; 87 + __u16 s_firstdatazone; 88 + __u16 s_log_zone_size; 89 + __u16 s_pad1; 90 + __u32 s_max_size; 91 + __u32 s_zones; 92 + __u16 s_magic; 93 + __u16 s_pad2; 94 + __u16 s_blocksize; 95 + __u8 s_disk_version; 96 + }; 97 + 77 98 struct minix_dir_entry { 78 99 __u16 inode; 79 100 char name[0]; 80 101 }; 81 102 103 + struct minix3_dir_entry { 104 + __u32 inode; 105 + char name[0]; 106 + }; 82 107 #endif