diff options
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r-- | fs/nfs/super.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ce907efc5508..e01637240eeb 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/vfs.h> | 48 | #include <linux/vfs.h> |
49 | #include <linux/inet.h> | 49 | #include <linux/inet.h> |
50 | #include <linux/in6.h> | 50 | #include <linux/in6.h> |
51 | #include <linux/slab.h> | ||
51 | #include <net/ipv6.h> | 52 | #include <net/ipv6.h> |
52 | #include <linux/netdevice.h> | 53 | #include <linux/netdevice.h> |
53 | #include <linux/nfs_xdr.h> | 54 | #include <linux/nfs_xdr.h> |
@@ -243,6 +244,7 @@ static int nfs_show_stats(struct seq_file *, struct vfsmount *); | |||
243 | static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); | 244 | static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); |
244 | static int nfs_xdev_get_sb(struct file_system_type *fs_type, | 245 | static int nfs_xdev_get_sb(struct file_system_type *fs_type, |
245 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); | 246 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); |
247 | static void nfs_put_super(struct super_block *); | ||
246 | static void nfs_kill_super(struct super_block *); | 248 | static void nfs_kill_super(struct super_block *); |
247 | static int nfs_remount(struct super_block *sb, int *flags, char *raw_data); | 249 | static int nfs_remount(struct super_block *sb, int *flags, char *raw_data); |
248 | 250 | ||
@@ -266,6 +268,7 @@ static const struct super_operations nfs_sops = { | |||
266 | .alloc_inode = nfs_alloc_inode, | 268 | .alloc_inode = nfs_alloc_inode, |
267 | .destroy_inode = nfs_destroy_inode, | 269 | .destroy_inode = nfs_destroy_inode, |
268 | .write_inode = nfs_write_inode, | 270 | .write_inode = nfs_write_inode, |
271 | .put_super = nfs_put_super, | ||
269 | .statfs = nfs_statfs, | 272 | .statfs = nfs_statfs, |
270 | .clear_inode = nfs_clear_inode, | 273 | .clear_inode = nfs_clear_inode, |
271 | .umount_begin = nfs_umount_begin, | 274 | .umount_begin = nfs_umount_begin, |
@@ -335,6 +338,7 @@ static const struct super_operations nfs4_sops = { | |||
335 | .alloc_inode = nfs_alloc_inode, | 338 | .alloc_inode = nfs_alloc_inode, |
336 | .destroy_inode = nfs_destroy_inode, | 339 | .destroy_inode = nfs_destroy_inode, |
337 | .write_inode = nfs_write_inode, | 340 | .write_inode = nfs_write_inode, |
341 | .put_super = nfs_put_super, | ||
338 | .statfs = nfs_statfs, | 342 | .statfs = nfs_statfs, |
339 | .clear_inode = nfs4_clear_inode, | 343 | .clear_inode = nfs4_clear_inode, |
340 | .umount_begin = nfs_umount_begin, | 344 | .umount_begin = nfs_umount_begin, |
@@ -2211,7 +2215,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
2211 | } else { | 2215 | } else { |
2212 | error = nfs_bdi_register(server); | 2216 | error = nfs_bdi_register(server); |
2213 | if (error) | 2217 | if (error) |
2214 | goto error_splat_super; | 2218 | goto error_splat_bdi; |
2215 | } | 2219 | } |
2216 | 2220 | ||
2217 | if (!s->s_root) { | 2221 | if (!s->s_root) { |
@@ -2253,11 +2257,25 @@ out_err_nosb: | |||
2253 | error_splat_root: | 2257 | error_splat_root: |
2254 | dput(mntroot); | 2258 | dput(mntroot); |
2255 | error_splat_super: | 2259 | error_splat_super: |
2260 | if (server && !s->s_root) | ||
2261 | bdi_unregister(&server->backing_dev_info); | ||
2262 | error_splat_bdi: | ||
2256 | deactivate_locked_super(s); | 2263 | deactivate_locked_super(s); |
2257 | goto out; | 2264 | goto out; |
2258 | } | 2265 | } |
2259 | 2266 | ||
2260 | /* | 2267 | /* |
2268 | * Ensure that we unregister the bdi before kill_anon_super | ||
2269 | * releases the device name | ||
2270 | */ | ||
2271 | static void nfs_put_super(struct super_block *s) | ||
2272 | { | ||
2273 | struct nfs_server *server = NFS_SB(s); | ||
2274 | |||
2275 | bdi_unregister(&server->backing_dev_info); | ||
2276 | } | ||
2277 | |||
2278 | /* | ||
2261 | * Destroy an NFS2/3 superblock | 2279 | * Destroy an NFS2/3 superblock |
2262 | */ | 2280 | */ |
2263 | static void nfs_kill_super(struct super_block *s) | 2281 | static void nfs_kill_super(struct super_block *s) |
@@ -2265,7 +2283,6 @@ static void nfs_kill_super(struct super_block *s) | |||
2265 | struct nfs_server *server = NFS_SB(s); | 2283 | struct nfs_server *server = NFS_SB(s); |
2266 | 2284 | ||
2267 | kill_anon_super(s); | 2285 | kill_anon_super(s); |
2268 | bdi_unregister(&server->backing_dev_info); | ||
2269 | nfs_fscache_release_super_cookie(s); | 2286 | nfs_fscache_release_super_cookie(s); |
2270 | nfs_free_server(server); | 2287 | nfs_free_server(server); |
2271 | } | 2288 | } |
@@ -2313,7 +2330,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
2313 | } else { | 2330 | } else { |
2314 | error = nfs_bdi_register(server); | 2331 | error = nfs_bdi_register(server); |
2315 | if (error) | 2332 | if (error) |
2316 | goto error_splat_super; | 2333 | goto error_splat_bdi; |
2317 | } | 2334 | } |
2318 | 2335 | ||
2319 | if (!s->s_root) { | 2336 | if (!s->s_root) { |
@@ -2350,6 +2367,9 @@ out_err_noserver: | |||
2350 | return error; | 2367 | return error; |
2351 | 2368 | ||
2352 | error_splat_super: | 2369 | error_splat_super: |
2370 | if (server && !s->s_root) | ||
2371 | bdi_unregister(&server->backing_dev_info); | ||
2372 | error_splat_bdi: | ||
2353 | deactivate_locked_super(s); | 2373 | deactivate_locked_super(s); |
2354 | dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error); | 2374 | dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error); |
2355 | return error; | 2375 | return error; |
@@ -2565,7 +2585,7 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type, | |||
2565 | } else { | 2585 | } else { |
2566 | error = nfs_bdi_register(server); | 2586 | error = nfs_bdi_register(server); |
2567 | if (error) | 2587 | if (error) |
2568 | goto error_splat_super; | 2588 | goto error_splat_bdi; |
2569 | } | 2589 | } |
2570 | 2590 | ||
2571 | if (!s->s_root) { | 2591 | if (!s->s_root) { |
@@ -2603,6 +2623,9 @@ out_free: | |||
2603 | error_splat_root: | 2623 | error_splat_root: |
2604 | dput(mntroot); | 2624 | dput(mntroot); |
2605 | error_splat_super: | 2625 | error_splat_super: |
2626 | if (server && !s->s_root) | ||
2627 | bdi_unregister(&server->backing_dev_info); | ||
2628 | error_splat_bdi: | ||
2606 | deactivate_locked_super(s); | 2629 | deactivate_locked_super(s); |
2607 | goto out; | 2630 | goto out; |
2608 | } | 2631 | } |
@@ -2798,7 +2821,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
2798 | } else { | 2821 | } else { |
2799 | error = nfs_bdi_register(server); | 2822 | error = nfs_bdi_register(server); |
2800 | if (error) | 2823 | if (error) |
2801 | goto error_splat_super; | 2824 | goto error_splat_bdi; |
2802 | } | 2825 | } |
2803 | 2826 | ||
2804 | if (!s->s_root) { | 2827 | if (!s->s_root) { |
@@ -2834,6 +2857,9 @@ out_err_noserver: | |||
2834 | return error; | 2857 | return error; |
2835 | 2858 | ||
2836 | error_splat_super: | 2859 | error_splat_super: |
2860 | if (server && !s->s_root) | ||
2861 | bdi_unregister(&server->backing_dev_info); | ||
2862 | error_splat_bdi: | ||
2837 | deactivate_locked_super(s); | 2863 | deactivate_locked_super(s); |
2838 | dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error); | 2864 | dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error); |
2839 | return error; | 2865 | return error; |
@@ -2880,7 +2906,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type, | |||
2880 | } else { | 2906 | } else { |
2881 | error = nfs_bdi_register(server); | 2907 | error = nfs_bdi_register(server); |
2882 | if (error) | 2908 | if (error) |
2883 | goto error_splat_super; | 2909 | goto error_splat_bdi; |
2884 | } | 2910 | } |
2885 | 2911 | ||
2886 | if (!s->s_root) { | 2912 | if (!s->s_root) { |
@@ -2916,6 +2942,9 @@ out_err_noserver: | |||
2916 | return error; | 2942 | return error; |
2917 | 2943 | ||
2918 | error_splat_super: | 2944 | error_splat_super: |
2945 | if (server && !s->s_root) | ||
2946 | bdi_unregister(&server->backing_dev_info); | ||
2947 | error_splat_bdi: | ||
2919 | deactivate_locked_super(s); | 2948 | deactivate_locked_super(s); |
2920 | dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error); | 2949 | dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error); |
2921 | return error; | 2950 | return error; |