aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-10 14:47:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-10 14:47:36 -0400
commit8196867c74890ccdf40a2b5e3e173597fbc4f9ac (patch)
tree3bb2df18233327ed9fd3bdd3da2f84cefe7d5611
parent8c8946f509a494769a8c602b5ed189df01917d39 (diff)
parentffc18879903e55487bc5ac3c774b99a07de06029 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bcopeland/omfs
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bcopeland/omfs: omfs: fix uninitialized variable warning omfs: sanity check cluster size omfs: refuse to mount if bitmap pointer is obviously wrong omfs: check bounds on block numbers before passing to sb_bread omfs: fix memory leak
-rw-r--r--fs/omfs/dir.c22
-rw-r--r--fs/omfs/file.c10
-rw-r--r--fs/omfs/inode.c44
-rw-r--r--fs/omfs/omfs.h1
-rw-r--r--fs/omfs/omfs_fs.h1
5 files changed, 48 insertions, 30 deletions
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c
index b42d6241903..393f3f659da 100644
--- a/fs/omfs/dir.c
+++ b/fs/omfs/dir.c
@@ -25,11 +25,10 @@ static struct buffer_head *omfs_get_bucket(struct inode *dir,
25 const char *name, int namelen, int *ofs) 25 const char *name, int namelen, int *ofs)
26{ 26{
27 int nbuckets = (dir->i_size - OMFS_DIR_START)/8; 27 int nbuckets = (dir->i_size - OMFS_DIR_START)/8;
28 int block = clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino);
29 int bucket = omfs_hash(name, namelen, nbuckets); 28 int bucket = omfs_hash(name, namelen, nbuckets);
30 29
31 *ofs = OMFS_DIR_START + bucket * 8; 30 *ofs = OMFS_DIR_START + bucket * 8;
32 return sb_bread(dir->i_sb, block); 31 return omfs_bread(dir->i_sb, dir->i_ino);
33} 32}
34 33
35static struct buffer_head *omfs_scan_list(struct inode *dir, u64 block, 34static struct buffer_head *omfs_scan_list(struct inode *dir, u64 block,
@@ -42,8 +41,7 @@ static struct buffer_head *omfs_scan_list(struct inode *dir, u64 block,
42 *prev_block = ~0; 41 *prev_block = ~0;
43 42
44 while (block != ~0) { 43 while (block != ~0) {
45 bh = sb_bread(dir->i_sb, 44 bh = omfs_bread(dir->i_sb, block);
46 clus_to_blk(OMFS_SB(dir->i_sb), block));
47 if (!bh) { 45 if (!bh) {
48 err = -EIO; 46 err = -EIO;
49 goto err; 47 goto err;
@@ -86,11 +84,10 @@ static struct buffer_head *omfs_find_entry(struct inode *dir,
86int omfs_make_empty(struct inode *inode, struct super_block *sb) 84int omfs_make_empty(struct inode *inode, struct super_block *sb)
87{ 85{
88 struct omfs_sb_info *sbi = OMFS_SB(sb); 86 struct omfs_sb_info *sbi = OMFS_SB(sb);
89 int block = clus_to_blk(sbi, inode->i_ino);
90 struct buffer_head *bh; 87 struct buffer_head *bh;
91 struct omfs_inode *oi; 88 struct omfs_inode *oi;
92 89
93 bh = sb_bread(sb, block); 90 bh = omfs_bread(sb, inode->i_ino);
94 if (!bh) 91 if (!bh)
95 return -ENOMEM; 92 return -ENOMEM;
96 93
@@ -134,7 +131,7 @@ static int omfs_add_link(struct dentry *dentry, struct inode *inode)
134 brelse(bh); 131 brelse(bh);
135 132
136 /* now set the sibling and parent pointers on the new inode */ 133 /* now set the sibling and parent pointers on the new inode */
137 bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), inode->i_ino)); 134 bh = omfs_bread(dir->i_sb, inode->i_ino);
138 if (!bh) 135 if (!bh)
139 goto out; 136 goto out;
140 137
@@ -190,8 +187,7 @@ static int omfs_delete_entry(struct dentry *dentry)
190 if (prev != ~0) { 187 if (prev != ~0) {
191 /* found in middle of list, get list ptr */ 188 /* found in middle of list, get list ptr */
192 brelse(bh); 189 brelse(bh);
193 bh = sb_bread(dir->i_sb, 190 bh = omfs_bread(dir->i_sb, prev);
194 clus_to_blk(OMFS_SB(dir->i_sb), prev));
195 if (!bh) 191 if (!bh)
196 goto out; 192 goto out;
197 193
@@ -224,8 +220,7 @@ static int omfs_dir_is_empty(struct inode *inode)
224 u64 *ptr; 220 u64 *ptr;
225 int i; 221 int i;
226 222
227 bh = sb_bread(inode->i_sb, clus_to_blk(OMFS_SB(inode->i_sb), 223 bh = omfs_bread(inode->i_sb, inode->i_ino);
228 inode->i_ino));
229 224
230 if (!bh) 225 if (!bh)
231 return 0; 226 return 0;
@@ -353,8 +348,7 @@ static int omfs_fill_chain(struct file *filp, void *dirent, filldir_t filldir,
353 348
354 /* follow chain in this bucket */ 349 /* follow chain in this bucket */
355 while (fsblock != ~0) { 350 while (fsblock != ~0) {
356 bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), 351 bh = omfs_bread(dir->i_sb, fsblock);
357 fsblock));
358 if (!bh) 352 if (!bh)
359 goto out; 353 goto out;
360 354
@@ -466,7 +460,7 @@ static int omfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
466 hchain = (filp->f_pos >> 20) - 1; 460 hchain = (filp->f_pos >> 20) - 1;
467 hindex = filp->f_pos & 0xfffff; 461 hindex = filp->f_pos & 0xfffff;
468 462
469 bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino)); 463 bh = omfs_bread(dir->i_sb, dir->i_ino);
470 if (!bh) 464 if (!bh)
471 goto out; 465 goto out;
472 466
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index 5542c284dc1..8a6d34fa668 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -50,7 +50,7 @@ int omfs_shrink_inode(struct inode *inode)
50 if (inode->i_size != 0) 50 if (inode->i_size != 0)
51 goto out; 51 goto out;
52 52
53 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); 53 bh = omfs_bread(inode->i_sb, next);
54 if (!bh) 54 if (!bh)
55 goto out; 55 goto out;
56 56
@@ -90,7 +90,7 @@ int omfs_shrink_inode(struct inode *inode)
90 if (next == ~0) 90 if (next == ~0)
91 break; 91 break;
92 92
93 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); 93 bh = omfs_bread(inode->i_sb, next);
94 if (!bh) 94 if (!bh)
95 goto out; 95 goto out;
96 oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); 96 oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]);
@@ -222,7 +222,7 @@ static int omfs_get_block(struct inode *inode, sector_t block,
222 struct buffer_head *bh; 222 struct buffer_head *bh;
223 sector_t next, offset; 223 sector_t next, offset;
224 int ret; 224 int ret;
225 u64 new_block; 225 u64 uninitialized_var(new_block);
226 u32 max_extents; 226 u32 max_extents;
227 int extent_count; 227 int extent_count;
228 struct omfs_extent *oe; 228 struct omfs_extent *oe;
@@ -232,7 +232,7 @@ static int omfs_get_block(struct inode *inode, sector_t block,
232 int remain; 232 int remain;
233 233
234 ret = -EIO; 234 ret = -EIO;
235 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, inode->i_ino)); 235 bh = omfs_bread(inode->i_sb, inode->i_ino);
236 if (!bh) 236 if (!bh)
237 goto out; 237 goto out;
238 238
@@ -265,7 +265,7 @@ static int omfs_get_block(struct inode *inode, sector_t block,
265 break; 265 break;
266 266
267 brelse(bh); 267 brelse(bh);
268 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); 268 bh = omfs_bread(inode->i_sb, next);
269 if (!bh) 269 if (!bh)
270 goto out; 270 goto out;
271 oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); 271 oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]);
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c
index 56121debc22..14a22863291 100644
--- a/fs/omfs/inode.c
+++ b/fs/omfs/inode.c
@@ -19,6 +19,15 @@ MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>");
19MODULE_DESCRIPTION("OMFS (ReplayTV/Karma) Filesystem for Linux"); 19MODULE_DESCRIPTION("OMFS (ReplayTV/Karma) Filesystem for Linux");
20MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
21 21
22struct buffer_head *omfs_bread(struct super_block *sb, sector_t block)
23{
24 struct omfs_sb_info *sbi = OMFS_SB(sb);
25 if (block >= sbi->s_num_blocks)
26 return NULL;
27
28 return sb_bread(sb, clus_to_blk(sbi, block));
29}
30
22struct inode *omfs_new_inode(struct inode *dir, int mode) 31struct inode *omfs_new_inode(struct inode *dir, int mode)
23{ 32{
24 struct inode *inode; 33 struct inode *inode;
@@ -93,15 +102,13 @@ static int __omfs_write_inode(struct inode *inode, int wait)
93 struct omfs_inode *oi; 102 struct omfs_inode *oi;
94 struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); 103 struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb);
95 struct buffer_head *bh, *bh2; 104 struct buffer_head *bh, *bh2;
96 unsigned int block;
97 u64 ctime; 105 u64 ctime;
98 int i; 106 int i;
99 int ret = -EIO; 107 int ret = -EIO;
100 int sync_failed = 0; 108 int sync_failed = 0;
101 109
102 /* get current inode since we may have written sibling ptrs etc. */ 110 /* get current inode since we may have written sibling ptrs etc. */
103 block = clus_to_blk(sbi, inode->i_ino); 111 bh = omfs_bread(inode->i_sb, inode->i_ino);
104 bh = sb_bread(inode->i_sb, block);
105 if (!bh) 112 if (!bh)
106 goto out; 113 goto out;
107 114
@@ -140,8 +147,7 @@ static int __omfs_write_inode(struct inode *inode, int wait)
140 147
141 /* if mirroring writes, copy to next fsblock */ 148 /* if mirroring writes, copy to next fsblock */
142 for (i = 1; i < sbi->s_mirrors; i++) { 149 for (i = 1; i < sbi->s_mirrors; i++) {
143 bh2 = sb_bread(inode->i_sb, block + i * 150 bh2 = omfs_bread(inode->i_sb, inode->i_ino + i);
144 (sbi->s_blocksize / sbi->s_sys_blocksize));
145 if (!bh2) 151 if (!bh2)
146 goto out_brelse; 152 goto out_brelse;
147 153
@@ -196,7 +202,6 @@ struct inode *omfs_iget(struct super_block *sb, ino_t ino)
196 struct omfs_sb_info *sbi = OMFS_SB(sb); 202 struct omfs_sb_info *sbi = OMFS_SB(sb);
197 struct omfs_inode *oi; 203 struct omfs_inode *oi;
198 struct buffer_head *bh; 204 struct buffer_head *bh;
199 unsigned int block;
200 u64 ctime; 205 u64 ctime;
201 unsigned long nsecs; 206 unsigned long nsecs;
202 struct inode *inode; 207 struct inode *inode;
@@ -207,8 +212,7 @@ struct inode *omfs_iget(struct super_block *sb, ino_t ino)
207 if (!(inode->i_state & I_NEW)) 212 if (!(inode->i_state & I_NEW))
208 return inode; 213 return inode;
209 214
210 block = clus_to_blk(sbi, ino); 215 bh = omfs_bread(inode->i_sb, ino);
211 bh = sb_bread(inode->i_sb, block);
212 if (!bh) 216 if (!bh)
213 goto iget_failed; 217 goto iget_failed;
214 218
@@ -322,6 +326,9 @@ static int omfs_get_imap(struct super_block *sb)
322 goto nomem; 326 goto nomem;
323 327
324 block = clus_to_blk(sbi, sbi->s_bitmap_ino); 328 block = clus_to_blk(sbi, sbi->s_bitmap_ino);
329 if (block >= sbi->s_num_blocks)
330 goto nomem;
331
325 ptr = sbi->s_imap; 332 ptr = sbi->s_imap;
326 for (count = bitmap_size; count > 0; count -= sb->s_blocksize) { 333 for (count = bitmap_size; count > 0; count -= sb->s_blocksize) {
327 bh = sb_bread(sb, block++); 334 bh = sb_bread(sb, block++);
@@ -420,7 +427,6 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent)
420 struct omfs_root_block *omfs_rb; 427 struct omfs_root_block *omfs_rb;
421 struct omfs_sb_info *sbi; 428 struct omfs_sb_info *sbi;
422 struct inode *root; 429 struct inode *root;
423 sector_t start;
424 int ret = -EINVAL; 430 int ret = -EINVAL;
425 431
426 save_mount_options(sb, (char *) data); 432 save_mount_options(sb, (char *) data);
@@ -489,8 +495,7 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent)
489 sbi->s_block_shift = get_bitmask_order(sbi->s_blocksize) - 495 sbi->s_block_shift = get_bitmask_order(sbi->s_blocksize) -
490 get_bitmask_order(sbi->s_sys_blocksize); 496 get_bitmask_order(sbi->s_sys_blocksize);
491 497
492 start = clus_to_blk(sbi, be64_to_cpu(omfs_sb->s_root_block)); 498 bh2 = omfs_bread(sb, be64_to_cpu(omfs_sb->s_root_block));
493 bh2 = sb_bread(sb, start);
494 if (!bh2) 499 if (!bh2)
495 goto out_brelse_bh; 500 goto out_brelse_bh;
496 501
@@ -507,6 +512,21 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent)
507 goto out_brelse_bh2; 512 goto out_brelse_bh2;
508 } 513 }
509 514
515 if (sbi->s_bitmap_ino != ~0ULL &&
516 sbi->s_bitmap_ino > sbi->s_num_blocks) {
517 printk(KERN_ERR "omfs: free space bitmap location is corrupt "
518 "(%llx, total blocks %llx)\n",
519 (unsigned long long) sbi->s_bitmap_ino,
520 (unsigned long long) sbi->s_num_blocks);
521 goto out_brelse_bh2;
522 }
523 if (sbi->s_clustersize < 1 ||
524 sbi->s_clustersize > OMFS_MAX_CLUSTER_SIZE) {
525 printk(KERN_ERR "omfs: cluster size out of range (%d)",
526 sbi->s_clustersize);
527 goto out_brelse_bh2;
528 }
529
510 ret = omfs_get_imap(sb); 530 ret = omfs_get_imap(sb);
511 if (ret) 531 if (ret)
512 goto out_brelse_bh2; 532 goto out_brelse_bh2;
@@ -532,6 +552,8 @@ out_brelse_bh2:
532out_brelse_bh: 552out_brelse_bh:
533 brelse(bh); 553 brelse(bh);
534end: 554end:
555 if (ret)
556 kfree(sbi);
535 return ret; 557 return ret;
536} 558}
537 559
diff --git a/fs/omfs/omfs.h b/fs/omfs/omfs.h
index ebe2fdbe535..7d414fef501 100644
--- a/fs/omfs/omfs.h
+++ b/fs/omfs/omfs.h
@@ -58,6 +58,7 @@ extern void omfs_make_empty_table(struct buffer_head *bh, int offset);
58extern int omfs_shrink_inode(struct inode *inode); 58extern int omfs_shrink_inode(struct inode *inode);
59 59
60/* inode.c */ 60/* inode.c */
61extern struct buffer_head *omfs_bread(struct super_block *sb, sector_t block);
61extern struct inode *omfs_iget(struct super_block *sb, ino_t inode); 62extern struct inode *omfs_iget(struct super_block *sb, ino_t inode);
62extern struct inode *omfs_new_inode(struct inode *dir, int mode); 63extern struct inode *omfs_new_inode(struct inode *dir, int mode);
63extern int omfs_reserve_block(struct super_block *sb, sector_t block); 64extern int omfs_reserve_block(struct super_block *sb, sector_t block);
diff --git a/fs/omfs/omfs_fs.h b/fs/omfs/omfs_fs.h
index 12cca245d6e..ee5e4327de9 100644
--- a/fs/omfs/omfs_fs.h
+++ b/fs/omfs/omfs_fs.h
@@ -17,6 +17,7 @@
17#define OMFS_EXTENT_CONT 0x40 17#define OMFS_EXTENT_CONT 0x40
18#define OMFS_XOR_COUNT 19 18#define OMFS_XOR_COUNT 19
19#define OMFS_MAX_BLOCK_SIZE 8192 19#define OMFS_MAX_BLOCK_SIZE 8192
20#define OMFS_MAX_CLUSTER_SIZE 8
20 21
21struct omfs_super_block { 22struct omfs_super_block {
22 char s_fill1[256]; 23 char s_fill1[256];