diff options
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r-- | fs/nfs/super.c | 148 |
1 files changed, 119 insertions, 29 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 90be551b80c1..b4148fc00f9f 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> |
@@ -175,14 +176,16 @@ static const match_table_t nfs_mount_option_tokens = { | |||
175 | }; | 176 | }; |
176 | 177 | ||
177 | enum { | 178 | enum { |
178 | Opt_xprt_udp, Opt_xprt_tcp, Opt_xprt_rdma, | 179 | Opt_xprt_udp, Opt_xprt_udp6, Opt_xprt_tcp, Opt_xprt_tcp6, Opt_xprt_rdma, |
179 | 180 | ||
180 | Opt_xprt_err | 181 | Opt_xprt_err |
181 | }; | 182 | }; |
182 | 183 | ||
183 | static const match_table_t nfs_xprt_protocol_tokens = { | 184 | static const match_table_t nfs_xprt_protocol_tokens = { |
184 | { Opt_xprt_udp, "udp" }, | 185 | { Opt_xprt_udp, "udp" }, |
186 | { Opt_xprt_udp6, "udp6" }, | ||
185 | { Opt_xprt_tcp, "tcp" }, | 187 | { Opt_xprt_tcp, "tcp" }, |
188 | { Opt_xprt_tcp6, "tcp6" }, | ||
186 | { Opt_xprt_rdma, "rdma" }, | 189 | { Opt_xprt_rdma, "rdma" }, |
187 | 190 | ||
188 | { Opt_xprt_err, NULL } | 191 | { Opt_xprt_err, NULL } |
@@ -241,6 +244,7 @@ static int nfs_show_stats(struct seq_file *, struct vfsmount *); | |||
241 | 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 *); |
242 | 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, |
243 | 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 *); | ||
244 | static void nfs_kill_super(struct super_block *); | 248 | static void nfs_kill_super(struct super_block *); |
245 | 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); |
246 | 250 | ||
@@ -264,6 +268,7 @@ static const struct super_operations nfs_sops = { | |||
264 | .alloc_inode = nfs_alloc_inode, | 268 | .alloc_inode = nfs_alloc_inode, |
265 | .destroy_inode = nfs_destroy_inode, | 269 | .destroy_inode = nfs_destroy_inode, |
266 | .write_inode = nfs_write_inode, | 270 | .write_inode = nfs_write_inode, |
271 | .put_super = nfs_put_super, | ||
267 | .statfs = nfs_statfs, | 272 | .statfs = nfs_statfs, |
268 | .clear_inode = nfs_clear_inode, | 273 | .clear_inode = nfs_clear_inode, |
269 | .umount_begin = nfs_umount_begin, | 274 | .umount_begin = nfs_umount_begin, |
@@ -333,6 +338,7 @@ static const struct super_operations nfs4_sops = { | |||
333 | .alloc_inode = nfs_alloc_inode, | 338 | .alloc_inode = nfs_alloc_inode, |
334 | .destroy_inode = nfs_destroy_inode, | 339 | .destroy_inode = nfs_destroy_inode, |
335 | .write_inode = nfs_write_inode, | 340 | .write_inode = nfs_write_inode, |
341 | .put_super = nfs_put_super, | ||
336 | .statfs = nfs_statfs, | 342 | .statfs = nfs_statfs, |
337 | .clear_inode = nfs4_clear_inode, | 343 | .clear_inode = nfs4_clear_inode, |
338 | .umount_begin = nfs_umount_begin, | 344 | .umount_begin = nfs_umount_begin, |
@@ -492,6 +498,45 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour) | |||
492 | return sec_flavours[i].str; | 498 | return sec_flavours[i].str; |
493 | } | 499 | } |
494 | 500 | ||
501 | static void nfs_show_mountd_netid(struct seq_file *m, struct nfs_server *nfss, | ||
502 | int showdefaults) | ||
503 | { | ||
504 | struct sockaddr *sap = (struct sockaddr *) &nfss->mountd_address; | ||
505 | |||
506 | seq_printf(m, ",mountproto="); | ||
507 | switch (sap->sa_family) { | ||
508 | case AF_INET: | ||
509 | switch (nfss->mountd_protocol) { | ||
510 | case IPPROTO_UDP: | ||
511 | seq_printf(m, RPCBIND_NETID_UDP); | ||
512 | break; | ||
513 | case IPPROTO_TCP: | ||
514 | seq_printf(m, RPCBIND_NETID_TCP); | ||
515 | break; | ||
516 | default: | ||
517 | if (showdefaults) | ||
518 | seq_printf(m, "auto"); | ||
519 | } | ||
520 | break; | ||
521 | case AF_INET6: | ||
522 | switch (nfss->mountd_protocol) { | ||
523 | case IPPROTO_UDP: | ||
524 | seq_printf(m, RPCBIND_NETID_UDP6); | ||
525 | break; | ||
526 | case IPPROTO_TCP: | ||
527 | seq_printf(m, RPCBIND_NETID_TCP6); | ||
528 | break; | ||
529 | default: | ||
530 | if (showdefaults) | ||
531 | seq_printf(m, "auto"); | ||
532 | } | ||
533 | break; | ||
534 | default: | ||
535 | if (showdefaults) | ||
536 | seq_printf(m, "auto"); | ||
537 | } | ||
538 | } | ||
539 | |||
495 | static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, | 540 | static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, |
496 | int showdefaults) | 541 | int showdefaults) |
497 | { | 542 | { |
@@ -505,7 +550,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, | |||
505 | } | 550 | } |
506 | case AF_INET6: { | 551 | case AF_INET6: { |
507 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; | 552 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; |
508 | seq_printf(m, ",mountaddr=%pI6", &sin6->sin6_addr); | 553 | seq_printf(m, ",mountaddr=%pI6c", &sin6->sin6_addr); |
509 | break; | 554 | break; |
510 | } | 555 | } |
511 | default: | 556 | default: |
@@ -518,17 +563,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, | |||
518 | if (nfss->mountd_port || showdefaults) | 563 | if (nfss->mountd_port || showdefaults) |
519 | seq_printf(m, ",mountport=%u", nfss->mountd_port); | 564 | seq_printf(m, ",mountport=%u", nfss->mountd_port); |
520 | 565 | ||
521 | switch (nfss->mountd_protocol) { | 566 | nfs_show_mountd_netid(m, nfss, showdefaults); |
522 | case IPPROTO_UDP: | ||
523 | seq_printf(m, ",mountproto=udp"); | ||
524 | break; | ||
525 | case IPPROTO_TCP: | ||
526 | seq_printf(m, ",mountproto=tcp"); | ||
527 | break; | ||
528 | default: | ||
529 | if (showdefaults) | ||
530 | seq_printf(m, ",mountproto=auto"); | ||
531 | } | ||
532 | } | 567 | } |
533 | 568 | ||
534 | /* | 569 | /* |
@@ -578,7 +613,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, | |||
578 | seq_puts(m, nfs_infop->nostr); | 613 | seq_puts(m, nfs_infop->nostr); |
579 | } | 614 | } |
580 | seq_printf(m, ",proto=%s", | 615 | seq_printf(m, ",proto=%s", |
581 | rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO)); | 616 | rpc_peeraddr2str(nfss->client, RPC_DISPLAY_NETID)); |
582 | if (version == 4) { | 617 | if (version == 4) { |
583 | if (nfss->port != NFS_PORT) | 618 | if (nfss->port != NFS_PORT) |
584 | seq_printf(m, ",port=%u", nfss->port); | 619 | seq_printf(m, ",port=%u", nfss->port); |
@@ -714,8 +749,6 @@ static void nfs_umount_begin(struct super_block *sb) | |||
714 | struct nfs_server *server; | 749 | struct nfs_server *server; |
715 | struct rpc_clnt *rpc; | 750 | struct rpc_clnt *rpc; |
716 | 751 | ||
717 | lock_kernel(); | ||
718 | |||
719 | server = NFS_SB(sb); | 752 | server = NFS_SB(sb); |
720 | /* -EIO all pending I/O */ | 753 | /* -EIO all pending I/O */ |
721 | rpc = server->client_acl; | 754 | rpc = server->client_acl; |
@@ -724,8 +757,6 @@ static void nfs_umount_begin(struct super_block *sb) | |||
724 | rpc = server->client; | 757 | rpc = server->client; |
725 | if (!IS_ERR(rpc)) | 758 | if (!IS_ERR(rpc)) |
726 | rpc_killall_tasks(rpc); | 759 | rpc_killall_tasks(rpc); |
727 | |||
728 | unlock_kernel(); | ||
729 | } | 760 | } |
730 | 761 | ||
731 | static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version) | 762 | static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version) |
@@ -734,8 +765,6 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve | |||
734 | 765 | ||
735 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 766 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
736 | if (data) { | 767 | if (data) { |
737 | data->rsize = NFS_MAX_FILE_IO_SIZE; | ||
738 | data->wsize = NFS_MAX_FILE_IO_SIZE; | ||
739 | data->acregmin = NFS_DEF_ACREGMIN; | 768 | data->acregmin = NFS_DEF_ACREGMIN; |
740 | data->acregmax = NFS_DEF_ACREGMAX; | 769 | data->acregmax = NFS_DEF_ACREGMAX; |
741 | data->acdirmin = NFS_DEF_ACDIRMIN; | 770 | data->acdirmin = NFS_DEF_ACDIRMIN; |
@@ -887,6 +916,8 @@ static int nfs_parse_mount_options(char *raw, | |||
887 | { | 916 | { |
888 | char *p, *string, *secdata; | 917 | char *p, *string, *secdata; |
889 | int rc, sloppy = 0, invalid_option = 0; | 918 | int rc, sloppy = 0, invalid_option = 0; |
919 | unsigned short protofamily = AF_UNSPEC; | ||
920 | unsigned short mountfamily = AF_UNSPEC; | ||
890 | 921 | ||
891 | if (!raw) { | 922 | if (!raw) { |
892 | dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); | 923 | dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); |
@@ -1232,12 +1263,17 @@ static int nfs_parse_mount_options(char *raw, | |||
1232 | token = match_token(string, | 1263 | token = match_token(string, |
1233 | nfs_xprt_protocol_tokens, args); | 1264 | nfs_xprt_protocol_tokens, args); |
1234 | 1265 | ||
1266 | protofamily = AF_INET; | ||
1235 | switch (token) { | 1267 | switch (token) { |
1268 | case Opt_xprt_udp6: | ||
1269 | protofamily = AF_INET6; | ||
1236 | case Opt_xprt_udp: | 1270 | case Opt_xprt_udp: |
1237 | mnt->flags &= ~NFS_MOUNT_TCP; | 1271 | mnt->flags &= ~NFS_MOUNT_TCP; |
1238 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; | 1272 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; |
1239 | kfree(string); | 1273 | kfree(string); |
1240 | break; | 1274 | break; |
1275 | case Opt_xprt_tcp6: | ||
1276 | protofamily = AF_INET6; | ||
1241 | case Opt_xprt_tcp: | 1277 | case Opt_xprt_tcp: |
1242 | mnt->flags |= NFS_MOUNT_TCP; | 1278 | mnt->flags |= NFS_MOUNT_TCP; |
1243 | mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; | 1279 | mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; |
@@ -1265,10 +1301,15 @@ static int nfs_parse_mount_options(char *raw, | |||
1265 | nfs_xprt_protocol_tokens, args); | 1301 | nfs_xprt_protocol_tokens, args); |
1266 | kfree(string); | 1302 | kfree(string); |
1267 | 1303 | ||
1304 | mountfamily = AF_INET; | ||
1268 | switch (token) { | 1305 | switch (token) { |
1306 | case Opt_xprt_udp6: | ||
1307 | mountfamily = AF_INET6; | ||
1269 | case Opt_xprt_udp: | 1308 | case Opt_xprt_udp: |
1270 | mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; | 1309 | mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; |
1271 | break; | 1310 | break; |
1311 | case Opt_xprt_tcp6: | ||
1312 | mountfamily = AF_INET6; | ||
1272 | case Opt_xprt_tcp: | 1313 | case Opt_xprt_tcp: |
1273 | mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; | 1314 | mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; |
1274 | break; | 1315 | break; |
@@ -1367,8 +1408,33 @@ static int nfs_parse_mount_options(char *raw, | |||
1367 | if (!sloppy && invalid_option) | 1408 | if (!sloppy && invalid_option) |
1368 | return 0; | 1409 | return 0; |
1369 | 1410 | ||
1411 | /* | ||
1412 | * verify that any proto=/mountproto= options match the address | ||
1413 | * familiies in the addr=/mountaddr= options. | ||
1414 | */ | ||
1415 | if (protofamily != AF_UNSPEC && | ||
1416 | protofamily != mnt->nfs_server.address.ss_family) | ||
1417 | goto out_proto_mismatch; | ||
1418 | |||
1419 | if (mountfamily != AF_UNSPEC) { | ||
1420 | if (mnt->mount_server.addrlen) { | ||
1421 | if (mountfamily != mnt->mount_server.address.ss_family) | ||
1422 | goto out_mountproto_mismatch; | ||
1423 | } else { | ||
1424 | if (mountfamily != mnt->nfs_server.address.ss_family) | ||
1425 | goto out_mountproto_mismatch; | ||
1426 | } | ||
1427 | } | ||
1428 | |||
1370 | return 1; | 1429 | return 1; |
1371 | 1430 | ||
1431 | out_mountproto_mismatch: | ||
1432 | printk(KERN_INFO "NFS: mount server address does not match mountproto= " | ||
1433 | "option\n"); | ||
1434 | return 0; | ||
1435 | out_proto_mismatch: | ||
1436 | printk(KERN_INFO "NFS: server address does not match proto= option\n"); | ||
1437 | return 0; | ||
1372 | out_invalid_address: | 1438 | out_invalid_address: |
1373 | printk(KERN_INFO "NFS: bad IP address specified: %s\n", p); | 1439 | printk(KERN_INFO "NFS: bad IP address specified: %s\n", p); |
1374 | return 0; | 1440 | return 0; |
@@ -1881,7 +1947,6 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) | |||
1881 | if (data == NULL) | 1947 | if (data == NULL) |
1882 | return -ENOMEM; | 1948 | return -ENOMEM; |
1883 | 1949 | ||
1884 | lock_kernel(); | ||
1885 | /* fill out struct with values from existing mount */ | 1950 | /* fill out struct with values from existing mount */ |
1886 | data->flags = nfss->flags; | 1951 | data->flags = nfss->flags; |
1887 | data->rsize = nfss->rsize; | 1952 | data->rsize = nfss->rsize; |
@@ -1907,7 +1972,6 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) | |||
1907 | error = nfs_compare_remount_data(nfss, data); | 1972 | error = nfs_compare_remount_data(nfss, data); |
1908 | out: | 1973 | out: |
1909 | kfree(data); | 1974 | kfree(data); |
1910 | unlock_kernel(); | ||
1911 | return error; | 1975 | return error; |
1912 | } | 1976 | } |
1913 | 1977 | ||
@@ -2123,6 +2187,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
2123 | if (data->version == 4) { | 2187 | if (data->version == 4) { |
2124 | error = nfs4_try_mount(flags, dev_name, data, mnt); | 2188 | error = nfs4_try_mount(flags, dev_name, data, mnt); |
2125 | kfree(data->client_address); | 2189 | kfree(data->client_address); |
2190 | kfree(data->nfs_server.export_path); | ||
2126 | goto out; | 2191 | goto out; |
2127 | } | 2192 | } |
2128 | #endif /* CONFIG_NFS_V4 */ | 2193 | #endif /* CONFIG_NFS_V4 */ |
@@ -2151,7 +2216,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
2151 | } else { | 2216 | } else { |
2152 | error = nfs_bdi_register(server); | 2217 | error = nfs_bdi_register(server); |
2153 | if (error) | 2218 | if (error) |
2154 | goto error_splat_super; | 2219 | goto error_splat_bdi; |
2155 | } | 2220 | } |
2156 | 2221 | ||
2157 | if (!s->s_root) { | 2222 | if (!s->s_root) { |
@@ -2193,11 +2258,25 @@ out_err_nosb: | |||
2193 | error_splat_root: | 2258 | error_splat_root: |
2194 | dput(mntroot); | 2259 | dput(mntroot); |
2195 | error_splat_super: | 2260 | error_splat_super: |
2261 | if (server && !s->s_root) | ||
2262 | bdi_unregister(&server->backing_dev_info); | ||
2263 | error_splat_bdi: | ||
2196 | deactivate_locked_super(s); | 2264 | deactivate_locked_super(s); |
2197 | goto out; | 2265 | goto out; |
2198 | } | 2266 | } |
2199 | 2267 | ||
2200 | /* | 2268 | /* |
2269 | * Ensure that we unregister the bdi before kill_anon_super | ||
2270 | * releases the device name | ||
2271 | */ | ||
2272 | static void nfs_put_super(struct super_block *s) | ||
2273 | { | ||
2274 | struct nfs_server *server = NFS_SB(s); | ||
2275 | |||
2276 | bdi_unregister(&server->backing_dev_info); | ||
2277 | } | ||
2278 | |||
2279 | /* | ||
2201 | * Destroy an NFS2/3 superblock | 2280 | * Destroy an NFS2/3 superblock |
2202 | */ | 2281 | */ |
2203 | static void nfs_kill_super(struct super_block *s) | 2282 | static void nfs_kill_super(struct super_block *s) |
@@ -2205,7 +2284,6 @@ static void nfs_kill_super(struct super_block *s) | |||
2205 | struct nfs_server *server = NFS_SB(s); | 2284 | struct nfs_server *server = NFS_SB(s); |
2206 | 2285 | ||
2207 | kill_anon_super(s); | 2286 | kill_anon_super(s); |
2208 | bdi_unregister(&server->backing_dev_info); | ||
2209 | nfs_fscache_release_super_cookie(s); | 2287 | nfs_fscache_release_super_cookie(s); |
2210 | nfs_free_server(server); | 2288 | nfs_free_server(server); |
2211 | } | 2289 | } |
@@ -2253,7 +2331,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
2253 | } else { | 2331 | } else { |
2254 | error = nfs_bdi_register(server); | 2332 | error = nfs_bdi_register(server); |
2255 | if (error) | 2333 | if (error) |
2256 | goto error_splat_super; | 2334 | goto error_splat_bdi; |
2257 | } | 2335 | } |
2258 | 2336 | ||
2259 | if (!s->s_root) { | 2337 | if (!s->s_root) { |
@@ -2290,6 +2368,9 @@ out_err_noserver: | |||
2290 | return error; | 2368 | return error; |
2291 | 2369 | ||
2292 | error_splat_super: | 2370 | error_splat_super: |
2371 | if (server && !s->s_root) | ||
2372 | bdi_unregister(&server->backing_dev_info); | ||
2373 | error_splat_bdi: | ||
2293 | deactivate_locked_super(s); | 2374 | deactivate_locked_super(s); |
2294 | dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error); | 2375 | dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error); |
2295 | return error; | 2376 | return error; |
@@ -2505,7 +2586,7 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type, | |||
2505 | } else { | 2586 | } else { |
2506 | error = nfs_bdi_register(server); | 2587 | error = nfs_bdi_register(server); |
2507 | if (error) | 2588 | if (error) |
2508 | goto error_splat_super; | 2589 | goto error_splat_bdi; |
2509 | } | 2590 | } |
2510 | 2591 | ||
2511 | if (!s->s_root) { | 2592 | if (!s->s_root) { |
@@ -2543,6 +2624,9 @@ out_free: | |||
2543 | error_splat_root: | 2624 | error_splat_root: |
2544 | dput(mntroot); | 2625 | dput(mntroot); |
2545 | error_splat_super: | 2626 | error_splat_super: |
2627 | if (server && !s->s_root) | ||
2628 | bdi_unregister(&server->backing_dev_info); | ||
2629 | error_splat_bdi: | ||
2546 | deactivate_locked_super(s); | 2630 | deactivate_locked_super(s); |
2547 | goto out; | 2631 | goto out; |
2548 | } | 2632 | } |
@@ -2574,7 +2658,7 @@ static void nfs_fix_devname(const struct path *path, struct vfsmount *mnt) | |||
2574 | devname = nfs_path(path->mnt->mnt_devname, | 2658 | devname = nfs_path(path->mnt->mnt_devname, |
2575 | path->mnt->mnt_root, path->dentry, | 2659 | path->mnt->mnt_root, path->dentry, |
2576 | page, PAGE_SIZE); | 2660 | page, PAGE_SIZE); |
2577 | if (devname == NULL) | 2661 | if (IS_ERR(devname)) |
2578 | goto out_freepage; | 2662 | goto out_freepage; |
2579 | tmp = kstrdup(devname, GFP_KERNEL); | 2663 | tmp = kstrdup(devname, GFP_KERNEL); |
2580 | if (tmp == NULL) | 2664 | if (tmp == NULL) |
@@ -2738,7 +2822,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
2738 | } else { | 2822 | } else { |
2739 | error = nfs_bdi_register(server); | 2823 | error = nfs_bdi_register(server); |
2740 | if (error) | 2824 | if (error) |
2741 | goto error_splat_super; | 2825 | goto error_splat_bdi; |
2742 | } | 2826 | } |
2743 | 2827 | ||
2744 | if (!s->s_root) { | 2828 | if (!s->s_root) { |
@@ -2774,6 +2858,9 @@ out_err_noserver: | |||
2774 | return error; | 2858 | return error; |
2775 | 2859 | ||
2776 | error_splat_super: | 2860 | error_splat_super: |
2861 | if (server && !s->s_root) | ||
2862 | bdi_unregister(&server->backing_dev_info); | ||
2863 | error_splat_bdi: | ||
2777 | deactivate_locked_super(s); | 2864 | deactivate_locked_super(s); |
2778 | dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error); | 2865 | dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error); |
2779 | return error; | 2866 | return error; |
@@ -2820,7 +2907,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type, | |||
2820 | } else { | 2907 | } else { |
2821 | error = nfs_bdi_register(server); | 2908 | error = nfs_bdi_register(server); |
2822 | if (error) | 2909 | if (error) |
2823 | goto error_splat_super; | 2910 | goto error_splat_bdi; |
2824 | } | 2911 | } |
2825 | 2912 | ||
2826 | if (!s->s_root) { | 2913 | if (!s->s_root) { |
@@ -2856,6 +2943,9 @@ out_err_noserver: | |||
2856 | return error; | 2943 | return error; |
2857 | 2944 | ||
2858 | error_splat_super: | 2945 | error_splat_super: |
2946 | if (server && !s->s_root) | ||
2947 | bdi_unregister(&server->backing_dev_info); | ||
2948 | error_splat_bdi: | ||
2859 | deactivate_locked_super(s); | 2949 | deactivate_locked_super(s); |
2860 | dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error); | 2950 | dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error); |
2861 | return error; | 2951 | return error; |