diff options
Diffstat (limited to 'fs/affs')
-rw-r--r-- | fs/affs/affs.h | 3 | ||||
-rw-r--r-- | fs/affs/amigaffs.c | 6 | ||||
-rw-r--r-- | fs/affs/inode.c | 20 | ||||
-rw-r--r-- | fs/affs/namei.c | 12 | ||||
-rw-r--r-- | fs/affs/super.c | 26 |
5 files changed, 45 insertions, 22 deletions
diff --git a/fs/affs/affs.h b/fs/affs/affs.h index 232c69493683..d5bd497ab9cb 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h | |||
@@ -174,7 +174,8 @@ extern void affs_put_inode(struct inode *inode); | |||
174 | extern void affs_drop_inode(struct inode *inode); | 174 | extern void affs_drop_inode(struct inode *inode); |
175 | extern void affs_delete_inode(struct inode *inode); | 175 | extern void affs_delete_inode(struct inode *inode); |
176 | extern void affs_clear_inode(struct inode *inode); | 176 | extern void affs_clear_inode(struct inode *inode); |
177 | extern void affs_read_inode(struct inode *inode); | 177 | extern struct inode *affs_iget(struct super_block *sb, |
178 | unsigned long ino); | ||
178 | extern int affs_write_inode(struct inode *inode, int); | 179 | extern int affs_write_inode(struct inode *inode, int); |
179 | extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type); | 180 | extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type); |
180 | 181 | ||
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c index f4de4b98004f..805573005de6 100644 --- a/fs/affs/amigaffs.c +++ b/fs/affs/amigaffs.c | |||
@@ -170,9 +170,11 @@ affs_remove_link(struct dentry *dentry) | |||
170 | if (!link_bh) | 170 | if (!link_bh) |
171 | goto done; | 171 | goto done; |
172 | 172 | ||
173 | dir = iget(sb, be32_to_cpu(AFFS_TAIL(sb, link_bh)->parent)); | 173 | dir = affs_iget(sb, be32_to_cpu(AFFS_TAIL(sb, link_bh)->parent)); |
174 | if (!dir) | 174 | if (IS_ERR(dir)) { |
175 | retval = PTR_ERR(dir); | ||
175 | goto done; | 176 | goto done; |
177 | } | ||
176 | 178 | ||
177 | affs_lock_dir(dir); | 179 | affs_lock_dir(dir); |
178 | affs_fix_dcache(dentry, link_ino); | 180 | affs_fix_dcache(dentry, link_ino); |
diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 4609a6c13fe9..27fe6cbe43ae 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c | |||
@@ -15,20 +15,25 @@ | |||
15 | extern const struct inode_operations affs_symlink_inode_operations; | 15 | extern const struct inode_operations affs_symlink_inode_operations; |
16 | extern struct timezone sys_tz; | 16 | extern struct timezone sys_tz; |
17 | 17 | ||
18 | void | 18 | struct inode *affs_iget(struct super_block *sb, unsigned long ino) |
19 | affs_read_inode(struct inode *inode) | ||
20 | { | 19 | { |
21 | struct super_block *sb = inode->i_sb; | ||
22 | struct affs_sb_info *sbi = AFFS_SB(sb); | 20 | struct affs_sb_info *sbi = AFFS_SB(sb); |
23 | struct buffer_head *bh; | 21 | struct buffer_head *bh; |
24 | struct affs_head *head; | 22 | struct affs_head *head; |
25 | struct affs_tail *tail; | 23 | struct affs_tail *tail; |
24 | struct inode *inode; | ||
26 | u32 block; | 25 | u32 block; |
27 | u32 size; | 26 | u32 size; |
28 | u32 prot; | 27 | u32 prot; |
29 | u16 id; | 28 | u16 id; |
30 | 29 | ||
31 | pr_debug("AFFS: read_inode(%lu)\n",inode->i_ino); | 30 | inode = iget_locked(sb, ino); |
31 | if (!inode) | ||
32 | return ERR_PTR(-ENOMEM); | ||
33 | if (!(inode->i_state & I_NEW)) | ||
34 | return inode; | ||
35 | |||
36 | pr_debug("AFFS: affs_iget(%lu)\n", inode->i_ino); | ||
32 | 37 | ||
33 | block = inode->i_ino; | 38 | block = inode->i_ino; |
34 | bh = affs_bread(sb, block); | 39 | bh = affs_bread(sb, block); |
@@ -154,12 +159,13 @@ affs_read_inode(struct inode *inode) | |||
154 | sys_tz.tz_minuteswest * 60; | 159 | sys_tz.tz_minuteswest * 60; |
155 | inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0; | 160 | inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0; |
156 | affs_brelse(bh); | 161 | affs_brelse(bh); |
157 | return; | 162 | unlock_new_inode(inode); |
163 | return inode; | ||
158 | 164 | ||
159 | bad_inode: | 165 | bad_inode: |
160 | make_bad_inode(inode); | ||
161 | affs_brelse(bh); | 166 | affs_brelse(bh); |
162 | return; | 167 | iget_failed(inode); |
168 | return ERR_PTR(-EIO); | ||
163 | } | 169 | } |
164 | 170 | ||
165 | int | 171 | int |
diff --git a/fs/affs/namei.c b/fs/affs/namei.c index a42143ca0169..2218f1ee71ce 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c | |||
@@ -208,9 +208,8 @@ affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
208 | affs_lock_dir(dir); | 208 | affs_lock_dir(dir); |
209 | bh = affs_find_entry(dir, dentry); | 209 | bh = affs_find_entry(dir, dentry); |
210 | affs_unlock_dir(dir); | 210 | affs_unlock_dir(dir); |
211 | if (IS_ERR(bh)) { | 211 | if (IS_ERR(bh)) |
212 | return ERR_PTR(PTR_ERR(bh)); | 212 | return ERR_CAST(bh); |
213 | } | ||
214 | if (bh) { | 213 | if (bh) { |
215 | u32 ino = bh->b_blocknr; | 214 | u32 ino = bh->b_blocknr; |
216 | 215 | ||
@@ -223,10 +222,9 @@ affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
223 | ino = be32_to_cpu(AFFS_TAIL(sb, bh)->original); | 222 | ino = be32_to_cpu(AFFS_TAIL(sb, bh)->original); |
224 | } | 223 | } |
225 | affs_brelse(bh); | 224 | affs_brelse(bh); |
226 | inode = iget(sb, ino); | 225 | inode = affs_iget(sb, ino); |
227 | if (!inode) { | 226 | if (IS_ERR(inode)) |
228 | return ERR_PTR(-EACCES); | 227 | return ERR_PTR(PTR_ERR(inode)); |
229 | } | ||
230 | } | 228 | } |
231 | dentry->d_op = AFFS_SB(sb)->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations; | 229 | dentry->d_op = AFFS_SB(sb)->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations; |
232 | d_add(dentry, inode); | 230 | d_add(dentry, inode); |
diff --git a/fs/affs/super.c b/fs/affs/super.c index b53e5d0ec65c..d2dc047cb479 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -113,7 +113,6 @@ static void destroy_inodecache(void) | |||
113 | static const struct super_operations affs_sops = { | 113 | static const struct super_operations affs_sops = { |
114 | .alloc_inode = affs_alloc_inode, | 114 | .alloc_inode = affs_alloc_inode, |
115 | .destroy_inode = affs_destroy_inode, | 115 | .destroy_inode = affs_destroy_inode, |
116 | .read_inode = affs_read_inode, | ||
117 | .write_inode = affs_write_inode, | 116 | .write_inode = affs_write_inode, |
118 | .put_inode = affs_put_inode, | 117 | .put_inode = affs_put_inode, |
119 | .drop_inode = affs_drop_inode, | 118 | .drop_inode = affs_drop_inode, |
@@ -123,6 +122,7 @@ static const struct super_operations affs_sops = { | |||
123 | .write_super = affs_write_super, | 122 | .write_super = affs_write_super, |
124 | .statfs = affs_statfs, | 123 | .statfs = affs_statfs, |
125 | .remount_fs = affs_remount, | 124 | .remount_fs = affs_remount, |
125 | .show_options = generic_show_options, | ||
126 | }; | 126 | }; |
127 | 127 | ||
128 | enum { | 128 | enum { |
@@ -271,6 +271,9 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) | |||
271 | unsigned long mount_flags; | 271 | unsigned long mount_flags; |
272 | int tmp_flags; /* fix remount prototype... */ | 272 | int tmp_flags; /* fix remount prototype... */ |
273 | u8 sig[4]; | 273 | u8 sig[4]; |
274 | int ret = -EINVAL; | ||
275 | |||
276 | save_mount_options(sb, data); | ||
274 | 277 | ||
275 | pr_debug("AFFS: read_super(%s)\n",data ? (const char *)data : "no options"); | 278 | pr_debug("AFFS: read_super(%s)\n",data ? (const char *)data : "no options"); |
276 | 279 | ||
@@ -444,7 +447,12 @@ got_root: | |||
444 | 447 | ||
445 | /* set up enough so that it can read an inode */ | 448 | /* set up enough so that it can read an inode */ |
446 | 449 | ||
447 | root_inode = iget(sb, root_block); | 450 | root_inode = affs_iget(sb, root_block); |
451 | if (IS_ERR(root_inode)) { | ||
452 | ret = PTR_ERR(root_inode); | ||
453 | goto out_error_noinode; | ||
454 | } | ||
455 | |||
448 | sb->s_root = d_alloc_root(root_inode); | 456 | sb->s_root = d_alloc_root(root_inode); |
449 | if (!sb->s_root) { | 457 | if (!sb->s_root) { |
450 | printk(KERN_ERR "AFFS: Get root inode failed\n"); | 458 | printk(KERN_ERR "AFFS: Get root inode failed\n"); |
@@ -461,12 +469,13 @@ got_root: | |||
461 | out_error: | 469 | out_error: |
462 | if (root_inode) | 470 | if (root_inode) |
463 | iput(root_inode); | 471 | iput(root_inode); |
472 | out_error_noinode: | ||
464 | kfree(sbi->s_bitmap); | 473 | kfree(sbi->s_bitmap); |
465 | affs_brelse(root_bh); | 474 | affs_brelse(root_bh); |
466 | kfree(sbi->s_prefix); | 475 | kfree(sbi->s_prefix); |
467 | kfree(sbi); | 476 | kfree(sbi); |
468 | sb->s_fs_info = NULL; | 477 | sb->s_fs_info = NULL; |
469 | return -EINVAL; | 478 | return ret; |
470 | } | 479 | } |
471 | 480 | ||
472 | static int | 481 | static int |
@@ -481,14 +490,21 @@ affs_remount(struct super_block *sb, int *flags, char *data) | |||
481 | int root_block; | 490 | int root_block; |
482 | unsigned long mount_flags; | 491 | unsigned long mount_flags; |
483 | int res = 0; | 492 | int res = 0; |
493 | char *new_opts = kstrdup(data, GFP_KERNEL); | ||
484 | 494 | ||
485 | pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data); | 495 | pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data); |
486 | 496 | ||
487 | *flags |= MS_NODIRATIME; | 497 | *flags |= MS_NODIRATIME; |
488 | 498 | ||
489 | if (!parse_options(data,&uid,&gid,&mode,&reserved,&root_block, | 499 | if (!parse_options(data, &uid, &gid, &mode, &reserved, &root_block, |
490 | &blocksize,&sbi->s_prefix,sbi->s_volume,&mount_flags)) | 500 | &blocksize, &sbi->s_prefix, sbi->s_volume, |
501 | &mount_flags)) { | ||
502 | kfree(new_opts); | ||
491 | return -EINVAL; | 503 | return -EINVAL; |
504 | } | ||
505 | kfree(sb->s_options); | ||
506 | sb->s_options = new_opts; | ||
507 | |||
492 | sbi->s_flags = mount_flags; | 508 | sbi->s_flags = mount_flags; |
493 | sbi->s_mode = mode; | 509 | sbi->s_mode = mode; |
494 | sbi->s_uid = uid; | 510 | sbi->s_uid = uid; |