aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c41
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 *);
243static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); 244static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *);
244static int nfs_xdev_get_sb(struct file_system_type *fs_type, 245static 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);
247static void nfs_put_super(struct super_block *);
246static void nfs_kill_super(struct super_block *); 248static void nfs_kill_super(struct super_block *);
247static int nfs_remount(struct super_block *sb, int *flags, char *raw_data); 249static 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:
2253error_splat_root: 2257error_splat_root:
2254 dput(mntroot); 2258 dput(mntroot);
2255error_splat_super: 2259error_splat_super:
2260 if (server && !s->s_root)
2261 bdi_unregister(&server->backing_dev_info);
2262error_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 */
2271static 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 */
2263static void nfs_kill_super(struct super_block *s) 2281static 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
2352error_splat_super: 2369error_splat_super:
2370 if (server && !s->s_root)
2371 bdi_unregister(&server->backing_dev_info);
2372error_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:
2603error_splat_root: 2623error_splat_root:
2604 dput(mntroot); 2624 dput(mntroot);
2605error_splat_super: 2625error_splat_super:
2626 if (server && !s->s_root)
2627 bdi_unregister(&server->backing_dev_info);
2628error_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
2836error_splat_super: 2859error_splat_super:
2860 if (server && !s->s_root)
2861 bdi_unregister(&server->backing_dev_info);
2862error_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
2918error_splat_super: 2944error_splat_super:
2945 if (server && !s->s_root)
2946 bdi_unregister(&server->backing_dev_info);
2947error_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;