Commit 3f82ff55168e92859119bf348e9e0bd6714d2fea
Committed by
Al Viro
1 parent
33c8e57c86
Exists in
master
and in
39 other branches
nilfs2: get rid of sget use for checking if current mount is present
This stops using sget() for checking if an r/w-mount or an r/o-mount exists on the device. This elimination uses a back pointer to the current mount added to nilfs object. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 2 changed files with 35 additions and 60 deletions Side-by-side Diff
fs/nilfs2/super.c
... | ... | @@ -67,8 +67,6 @@ |
67 | 67 | |
68 | 68 | static void nilfs_write_super(struct super_block *sb); |
69 | 69 | static int nilfs_remount(struct super_block *sb, int *flags, char *data); |
70 | -static int test_exclusive_mount(struct file_system_type *fs_type, | |
71 | - struct block_device *bdev, int flags); | |
72 | 70 | |
73 | 71 | /** |
74 | 72 | * nilfs_error() - report failure condition on a filesystem |
... | ... | @@ -329,6 +327,10 @@ |
329 | 327 | nilfs_commit_super(sbi, 1); |
330 | 328 | up_write(&nilfs->ns_sem); |
331 | 329 | } |
330 | + down_write(&nilfs->ns_sem); | |
331 | + if (nilfs->ns_current == sbi) | |
332 | + nilfs->ns_current = NULL; | |
333 | + up_write(&nilfs->ns_sem); | |
332 | 334 | |
333 | 335 | nilfs_detach_checkpoint(sbi); |
334 | 336 | put_nilfs(sbi->s_nilfs); |
... | ... | @@ -880,6 +882,11 @@ |
880 | 882 | goto failed_root; |
881 | 883 | } |
882 | 884 | |
885 | + down_write(&nilfs->ns_sem); | |
886 | + if (!nilfs_test_opt(sbi, SNAPSHOT)) | |
887 | + nilfs->ns_current = sbi; | |
888 | + up_write(&nilfs->ns_sem); | |
889 | + | |
883 | 890 | return 0; |
884 | 891 | |
885 | 892 | failed_root: |
886 | 893 | |
887 | 894 | |
888 | 895 | |
... | ... | @@ -958,14 +965,16 @@ |
958 | 965 | * by fsck since we originally mounted the partition.) |
959 | 966 | */ |
960 | 967 | down(&sb->s_bdev->bd_mount_sem); |
961 | - /* Check existing RW-mount */ | |
962 | - if (test_exclusive_mount(sb->s_type, sb->s_bdev, 0)) { | |
968 | + down_read(&nilfs->ns_sem); | |
969 | + if (nilfs->ns_current && nilfs->ns_current != sbi) { | |
963 | 970 | printk(KERN_WARNING "NILFS (device %s): couldn't " |
964 | - "remount because a RW-mount exists.\n", | |
971 | + "remount because an RW-mount exists.\n", | |
965 | 972 | sb->s_id); |
973 | + up_read(&nilfs->ns_sem); | |
966 | 974 | err = -EBUSY; |
967 | 975 | goto rw_remount_failed; |
968 | 976 | } |
977 | + up_read(&nilfs->ns_sem); | |
969 | 978 | if (sbi->s_snapshot_cno != nilfs_last_cno(nilfs)) { |
970 | 979 | printk(KERN_WARNING "NILFS (device %s): couldn't " |
971 | 980 | "remount because the current RO-mount is not " |
... | ... | @@ -984,6 +993,7 @@ |
984 | 993 | |
985 | 994 | down_write(&nilfs->ns_sem); |
986 | 995 | nilfs_setup_super(sbi); |
996 | + nilfs->ns_current = sbi; | |
987 | 997 | up_write(&nilfs->ns_sem); |
988 | 998 | |
989 | 999 | up(&sb->s_bdev->bd_mount_sem); |
... | ... | @@ -1118,10 +1128,23 @@ |
1118 | 1128 | } |
1119 | 1129 | |
1120 | 1130 | down(&sd.bdev->bd_mount_sem); |
1121 | - if (!sd.cno && | |
1122 | - (err = test_exclusive_mount(fs_type, sd.bdev, flags ^ MS_RDONLY))) { | |
1123 | - err = (err < 0) ? : -EBUSY; | |
1124 | - goto failed_unlock; | |
1131 | + | |
1132 | + if (!sd.cno) { | |
1133 | + /* | |
1134 | + * Check if an exclusive mount exists or not. | |
1135 | + * Snapshot mounts coexist with a current mount | |
1136 | + * (i.e. rw-mount or ro-mount), whereas rw-mount and | |
1137 | + * ro-mount are mutually exclusive. | |
1138 | + */ | |
1139 | + down_read(&nilfs->ns_sem); | |
1140 | + if (nilfs->ns_current && | |
1141 | + ((nilfs->ns_current->s_super->s_flags ^ flags) | |
1142 | + & MS_RDONLY)) { | |
1143 | + up_read(&nilfs->ns_sem); | |
1144 | + err = -EBUSY; | |
1145 | + goto failed_unlock; | |
1146 | + } | |
1147 | + up_read(&nilfs->ns_sem); | |
1125 | 1148 | } |
1126 | 1149 | |
1127 | 1150 | /* |
... | ... | @@ -1180,57 +1203,6 @@ |
1180 | 1203 | * put_nilfs() and unlocking bd_mount_sem need the block device. |
1181 | 1204 | */ |
1182 | 1205 | return err; |
1183 | -} | |
1184 | - | |
1185 | -static int nilfs_test_bdev_super3(struct super_block *s, void *data) | |
1186 | -{ | |
1187 | - struct nilfs_super_data *sd = data; | |
1188 | - int ret; | |
1189 | - | |
1190 | - if (s->s_bdev != sd->bdev) | |
1191 | - return 0; | |
1192 | - if (down_read_trylock(&s->s_umount)) { | |
1193 | - ret = (s->s_flags & MS_RDONLY) && s->s_root && | |
1194 | - nilfs_test_opt(NILFS_SB(s), SNAPSHOT); | |
1195 | - up_read(&s->s_umount); | |
1196 | - if (ret) | |
1197 | - return 0; /* ignore snapshot mounts */ | |
1198 | - } | |
1199 | - return !((sd->flags ^ s->s_flags) & MS_RDONLY); | |
1200 | -} | |
1201 | - | |
1202 | -static int __false_bdev_super(struct super_block *s, void *data) | |
1203 | -{ | |
1204 | -#if 0 /* XXX: workaround for lock debug. This is not good idea */ | |
1205 | - up_write(&s->s_umount); | |
1206 | -#endif | |
1207 | - return -EFAULT; | |
1208 | -} | |
1209 | - | |
1210 | -/** | |
1211 | - * test_exclusive_mount - check whether an exclusive RW/RO mount exists or not. | |
1212 | - * fs_type: filesystem type | |
1213 | - * bdev: block device | |
1214 | - * flag: 0 (check rw-mount) or MS_RDONLY (check ro-mount) | |
1215 | - * res: pointer to an integer to store result | |
1216 | - * | |
1217 | - * This function must be called within a section protected by bd_mount_mutex. | |
1218 | - */ | |
1219 | -static int test_exclusive_mount(struct file_system_type *fs_type, | |
1220 | - struct block_device *bdev, int flags) | |
1221 | -{ | |
1222 | - struct super_block *s; | |
1223 | - struct nilfs_super_data sd = { .flags = flags, .bdev = bdev }; | |
1224 | - | |
1225 | - s = sget(fs_type, nilfs_test_bdev_super3, __false_bdev_super, &sd); | |
1226 | - if (IS_ERR(s)) { | |
1227 | - if (PTR_ERR(s) != -EFAULT) | |
1228 | - return PTR_ERR(s); | |
1229 | - return 0; /* Not found */ | |
1230 | - } | |
1231 | - up_write(&s->s_umount); | |
1232 | - deactivate_super(s); | |
1233 | - return 1; /* Found */ | |
1234 | 1206 | } |
1235 | 1207 | |
1236 | 1208 | struct file_system_type nilfs_fs_type = { |
fs/nilfs2/the_nilfs.h
... | ... | @@ -50,6 +50,7 @@ |
50 | 50 | * @ns_sem: semaphore for shared states |
51 | 51 | * @ns_writer_mutex: mutex protecting ns_writer attach/detach |
52 | 52 | * @ns_writer_refcount: number of referrers on ns_writer |
53 | + * @ns_current: back pointer to current mount | |
53 | 54 | * @ns_sbh: buffer heads of on-disk super blocks |
54 | 55 | * @ns_sbp: pointers to super block data |
55 | 56 | * @ns_sbwtime: previous write time of super blocks |
... | ... | @@ -97,6 +98,8 @@ |
97 | 98 | struct rw_semaphore ns_sem; |
98 | 99 | struct mutex ns_writer_mutex; |
99 | 100 | atomic_t ns_writer_refcount; |
101 | + | |
102 | + struct nilfs_sb_info *ns_current; | |
100 | 103 | |
101 | 104 | /* |
102 | 105 | * used for |