Commit 3d23985d6cfa7908e46fd0c62a2ee84faffe4d8b
1 parent
6cc9c1d2c1
Exists in
master
and in
4 other branches
switch fat to ->s_d_op, close exportfs races there
don't bother with lock_super() in fat_fill_super() callers, while we are at it - there won't be any concurrency anyway. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 4 changed files with 25 additions and 45 deletions Side-by-side Diff
fs/fat/fat.h
... | ... | @@ -319,7 +319,8 @@ |
319 | 319 | struct msdos_dir_entry *de, loff_t i_pos); |
320 | 320 | extern int fat_sync_inode(struct inode *inode); |
321 | 321 | extern int fat_fill_super(struct super_block *sb, void *data, int silent, |
322 | - const struct inode_operations *fs_dir_inode_ops, int isvfat); | |
322 | + const struct inode_operations *fs_dir_inode_ops, | |
323 | + int isvfat, void (*setup)(struct super_block *)); | |
323 | 324 | |
324 | 325 | extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, |
325 | 326 | struct inode *i2); |
fs/fat/inode.c
... | ... | @@ -703,7 +703,6 @@ |
703 | 703 | struct fid *fid, int fh_len, int fh_type) |
704 | 704 | { |
705 | 705 | struct inode *inode = NULL; |
706 | - struct dentry *result; | |
707 | 706 | u32 *fh = fid->raw; |
708 | 707 | |
709 | 708 | if (fh_len < 5 || fh_type != 3) |
... | ... | @@ -748,10 +747,7 @@ |
748 | 747 | * the fat_iget lookup again. If that fails, then we are totally out |
749 | 748 | * of luck. But all that is for another day |
750 | 749 | */ |
751 | - result = d_obtain_alias(inode); | |
752 | - if (!IS_ERR(result)) | |
753 | - d_set_d_op(result, sb->s_root->d_op); | |
754 | - return result; | |
750 | + return d_obtain_alias(inode); | |
755 | 751 | } |
756 | 752 | |
757 | 753 | static int |
... | ... | @@ -799,8 +795,6 @@ |
799 | 795 | brelse(bh); |
800 | 796 | |
801 | 797 | parent = d_obtain_alias(inode); |
802 | - if (!IS_ERR(parent)) | |
803 | - d_set_d_op(parent, sb->s_root->d_op); | |
804 | 798 | out: |
805 | 799 | unlock_super(sb); |
806 | 800 | |
... | ... | @@ -1244,7 +1238,8 @@ |
1244 | 1238 | * Read the super block of an MS-DOS FS. |
1245 | 1239 | */ |
1246 | 1240 | int fat_fill_super(struct super_block *sb, void *data, int silent, |
1247 | - const struct inode_operations *fs_dir_inode_ops, int isvfat) | |
1241 | + const struct inode_operations *fs_dir_inode_ops, int isvfat, | |
1242 | + void (*setup)(struct super_block *)) | |
1248 | 1243 | { |
1249 | 1244 | struct inode *root_inode = NULL, *fat_inode = NULL; |
1250 | 1245 | struct buffer_head *bh; |
... | ... | @@ -1279,6 +1274,8 @@ |
1279 | 1274 | error = parse_options(data, isvfat, silent, &debug, &sbi->options); |
1280 | 1275 | if (error) |
1281 | 1276 | goto out_fail; |
1277 | + | |
1278 | + setup(sb); /* flavour-specific stuff that needs options */ | |
1282 | 1279 | |
1283 | 1280 | error = -EIO; |
1284 | 1281 | sb_min_blocksize(sb, 512); |
fs/fat/namei_msdos.c
... | ... | @@ -227,11 +227,7 @@ |
227 | 227 | } |
228 | 228 | out: |
229 | 229 | unlock_super(sb); |
230 | - d_set_d_op(dentry, &msdos_dentry_operations); | |
231 | - dentry = d_splice_alias(inode, dentry); | |
232 | - if (dentry) | |
233 | - d_set_d_op(dentry, &msdos_dentry_operations); | |
234 | - return dentry; | |
230 | + return d_splice_alias(inode, dentry); | |
235 | 231 | |
236 | 232 | error: |
237 | 233 | unlock_super(sb); |
238 | 234 | |
239 | 235 | |
... | ... | @@ -661,21 +657,16 @@ |
661 | 657 | .getattr = fat_getattr, |
662 | 658 | }; |
663 | 659 | |
664 | -static int msdos_fill_super(struct super_block *sb, void *data, int silent) | |
660 | +static void setup(struct super_block *sb) | |
665 | 661 | { |
666 | - int res; | |
667 | - | |
668 | - lock_super(sb); | |
669 | - res = fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, 0); | |
670 | - if (res) { | |
671 | - unlock_super(sb); | |
672 | - return res; | |
673 | - } | |
674 | - | |
662 | + sb->s_d_op = &msdos_dentry_operations; | |
675 | 663 | sb->s_flags |= MS_NOATIME; |
676 | - d_set_d_op(sb->s_root, &msdos_dentry_operations); | |
677 | - unlock_super(sb); | |
678 | - return 0; | |
664 | +} | |
665 | + | |
666 | +static int msdos_fill_super(struct super_block *sb, void *data, int silent) | |
667 | +{ | |
668 | + return fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, | |
669 | + 0, setup); | |
679 | 670 | } |
680 | 671 | |
681 | 672 | static struct dentry *msdos_mount(struct file_system_type *fs_type, |
fs/fat/namei_vfat.c
... | ... | @@ -772,13 +772,10 @@ |
772 | 772 | |
773 | 773 | out: |
774 | 774 | unlock_super(sb); |
775 | - d_set_d_op(dentry, sb->s_root->d_op); | |
776 | 775 | dentry->d_time = dentry->d_parent->d_inode->i_version; |
777 | 776 | dentry = d_splice_alias(inode, dentry); |
778 | - if (dentry) { | |
779 | - d_set_d_op(dentry, sb->s_root->d_op); | |
777 | + if (dentry) | |
780 | 778 | dentry->d_time = dentry->d_parent->d_inode->i_version; |
781 | - } | |
782 | 779 | return dentry; |
783 | 780 | |
784 | 781 | error: |
785 | 782 | |
786 | 783 | |
787 | 784 | |
788 | 785 | |
... | ... | @@ -1066,24 +1063,18 @@ |
1066 | 1063 | .getattr = fat_getattr, |
1067 | 1064 | }; |
1068 | 1065 | |
1069 | -static int vfat_fill_super(struct super_block *sb, void *data, int silent) | |
1066 | +static void setup(struct super_block *sb) | |
1070 | 1067 | { |
1071 | - int res; | |
1072 | - | |
1073 | - lock_super(sb); | |
1074 | - res = fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, 1); | |
1075 | - if (res) { | |
1076 | - unlock_super(sb); | |
1077 | - return res; | |
1078 | - } | |
1079 | - | |
1080 | 1068 | if (MSDOS_SB(sb)->options.name_check != 's') |
1081 | - d_set_d_op(sb->s_root, &vfat_ci_dentry_ops); | |
1069 | + sb->s_d_op = &vfat_ci_dentry_ops; | |
1082 | 1070 | else |
1083 | - d_set_d_op(sb->s_root, &vfat_dentry_ops); | |
1071 | + sb->s_d_op = &vfat_dentry_ops; | |
1072 | +} | |
1084 | 1073 | |
1085 | - unlock_super(sb); | |
1086 | - return 0; | |
1074 | +static int vfat_fill_super(struct super_block *sb, void *data, int silent) | |
1075 | +{ | |
1076 | + return fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, | |
1077 | + 1, setup); | |
1087 | 1078 | } |
1088 | 1079 | |
1089 | 1080 | static struct dentry *vfat_mount(struct file_system_type *fs_type, |