diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 136 |
1 files changed, 110 insertions, 26 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index ce727047ee87..c93639e6cf68 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include "iostat.h" | 48 | #include "iostat.h" |
49 | #include "internal.h" | 49 | #include "internal.h" |
50 | #include "fscache.h" | 50 | #include "fscache.h" |
51 | #include "dns_resolve.h" | ||
52 | #include "pnfs.h" | 51 | #include "pnfs.h" |
53 | #include "nfs.h" | 52 | #include "nfs.h" |
54 | #include "netns.h" | 53 | #include "netns.h" |
@@ -162,11 +161,19 @@ static void nfs_zap_caches_locked(struct inode *inode) | |||
162 | 161 | ||
163 | memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); | 162 | memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); |
164 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { | 163 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { |
165 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | ||
166 | nfs_fscache_invalidate(inode); | 164 | nfs_fscache_invalidate(inode); |
167 | } else { | 165 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
168 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 166 | | NFS_INO_INVALID_LABEL |
169 | } | 167 | | NFS_INO_INVALID_DATA |
168 | | NFS_INO_INVALID_ACCESS | ||
169 | | NFS_INO_INVALID_ACL | ||
170 | | NFS_INO_REVAL_PAGECACHE; | ||
171 | } else | ||
172 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | ||
173 | | NFS_INO_INVALID_LABEL | ||
174 | | NFS_INO_INVALID_ACCESS | ||
175 | | NFS_INO_INVALID_ACL | ||
176 | | NFS_INO_REVAL_PAGECACHE; | ||
170 | } | 177 | } |
171 | 178 | ||
172 | void nfs_zap_caches(struct inode *inode) | 179 | void nfs_zap_caches(struct inode *inode) |
@@ -257,12 +264,72 @@ nfs_init_locked(struct inode *inode, void *opaque) | |||
257 | return 0; | 264 | return 0; |
258 | } | 265 | } |
259 | 266 | ||
267 | #ifdef CONFIG_NFS_V4_SECURITY_LABEL | ||
268 | void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, | ||
269 | struct nfs4_label *label) | ||
270 | { | ||
271 | int error; | ||
272 | |||
273 | if (label == NULL) | ||
274 | return; | ||
275 | |||
276 | if (nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL) == 0) | ||
277 | return; | ||
278 | |||
279 | if (NFS_SERVER(inode)->nfs_client->cl_minorversion < 2) | ||
280 | return; | ||
281 | |||
282 | if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) { | ||
283 | error = security_inode_notifysecctx(inode, label->label, | ||
284 | label->len); | ||
285 | if (error) | ||
286 | printk(KERN_ERR "%s() %s %d " | ||
287 | "security_inode_notifysecctx() %d\n", | ||
288 | __func__, | ||
289 | (char *)label->label, | ||
290 | label->len, error); | ||
291 | } | ||
292 | } | ||
293 | |||
294 | struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) | ||
295 | { | ||
296 | struct nfs4_label *label = NULL; | ||
297 | int minor_version = server->nfs_client->cl_minorversion; | ||
298 | |||
299 | if (minor_version < 2) | ||
300 | return label; | ||
301 | |||
302 | if (!(server->caps & NFS_CAP_SECURITY_LABEL)) | ||
303 | return label; | ||
304 | |||
305 | label = kzalloc(sizeof(struct nfs4_label), flags); | ||
306 | if (label == NULL) | ||
307 | return ERR_PTR(-ENOMEM); | ||
308 | |||
309 | label->label = kzalloc(NFS4_MAXLABELLEN, flags); | ||
310 | if (label->label == NULL) { | ||
311 | kfree(label); | ||
312 | return ERR_PTR(-ENOMEM); | ||
313 | } | ||
314 | label->len = NFS4_MAXLABELLEN; | ||
315 | |||
316 | return label; | ||
317 | } | ||
318 | EXPORT_SYMBOL_GPL(nfs4_label_alloc); | ||
319 | #else | ||
320 | void inline nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, | ||
321 | struct nfs4_label *label) | ||
322 | { | ||
323 | } | ||
324 | #endif | ||
325 | EXPORT_SYMBOL_GPL(nfs_setsecurity); | ||
326 | |||
260 | /* | 327 | /* |
261 | * This is our front-end to iget that looks up inodes by file handle | 328 | * This is our front-end to iget that looks up inodes by file handle |
262 | * instead of inode number. | 329 | * instead of inode number. |
263 | */ | 330 | */ |
264 | struct inode * | 331 | struct inode * |
265 | nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | 332 | nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, struct nfs4_label *label) |
266 | { | 333 | { |
267 | struct nfs_find_desc desc = { | 334 | struct nfs_find_desc desc = { |
268 | .fh = fh, | 335 | .fh = fh, |
@@ -384,6 +451,9 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
384 | */ | 451 | */ |
385 | inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used); | 452 | inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used); |
386 | } | 453 | } |
454 | |||
455 | nfs_setsecurity(inode, fattr, label); | ||
456 | |||
387 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); | 457 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); |
388 | nfsi->attrtimeo_timestamp = now; | 458 | nfsi->attrtimeo_timestamp = now; |
389 | nfsi->access_cache = RB_ROOT; | 459 | nfsi->access_cache = RB_ROOT; |
@@ -393,6 +463,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
393 | unlock_new_inode(inode); | 463 | unlock_new_inode(inode); |
394 | } else | 464 | } else |
395 | nfs_refresh_inode(inode, fattr); | 465 | nfs_refresh_inode(inode, fattr); |
466 | nfs_setsecurity(inode, fattr, label); | ||
396 | dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", | 467 | dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", |
397 | inode->i_sb->s_id, | 468 | inode->i_sb->s_id, |
398 | (long long)NFS_FILEID(inode), | 469 | (long long)NFS_FILEID(inode), |
@@ -449,7 +520,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
449 | NFS_PROTO(inode)->return_delegation(inode); | 520 | NFS_PROTO(inode)->return_delegation(inode); |
450 | error = NFS_PROTO(inode)->setattr(dentry, fattr, attr); | 521 | error = NFS_PROTO(inode)->setattr(dentry, fattr, attr); |
451 | if (error == 0) | 522 | if (error == 0) |
452 | nfs_refresh_inode(inode, fattr); | 523 | error = nfs_refresh_inode(inode, fattr); |
453 | nfs_free_fattr(fattr); | 524 | nfs_free_fattr(fattr); |
454 | out: | 525 | out: |
455 | return error; | 526 | return error; |
@@ -713,16 +784,23 @@ EXPORT_SYMBOL_GPL(put_nfs_open_context); | |||
713 | * Ensure that mmap has a recent RPC credential for use when writing out | 784 | * Ensure that mmap has a recent RPC credential for use when writing out |
714 | * shared pages | 785 | * shared pages |
715 | */ | 786 | */ |
716 | void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) | 787 | void nfs_inode_attach_open_context(struct nfs_open_context *ctx) |
717 | { | 788 | { |
718 | struct inode *inode = file_inode(filp); | 789 | struct inode *inode = ctx->dentry->d_inode; |
719 | struct nfs_inode *nfsi = NFS_I(inode); | 790 | struct nfs_inode *nfsi = NFS_I(inode); |
720 | 791 | ||
721 | filp->private_data = get_nfs_open_context(ctx); | ||
722 | spin_lock(&inode->i_lock); | 792 | spin_lock(&inode->i_lock); |
723 | list_add(&ctx->list, &nfsi->open_files); | 793 | list_add(&ctx->list, &nfsi->open_files); |
724 | spin_unlock(&inode->i_lock); | 794 | spin_unlock(&inode->i_lock); |
725 | } | 795 | } |
796 | EXPORT_SYMBOL_GPL(nfs_inode_attach_open_context); | ||
797 | |||
798 | void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) | ||
799 | { | ||
800 | filp->private_data = get_nfs_open_context(ctx); | ||
801 | if (list_empty(&ctx->list)) | ||
802 | nfs_inode_attach_open_context(ctx); | ||
803 | } | ||
726 | EXPORT_SYMBOL_GPL(nfs_file_set_open_context); | 804 | EXPORT_SYMBOL_GPL(nfs_file_set_open_context); |
727 | 805 | ||
728 | /* | 806 | /* |
@@ -748,10 +826,11 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c | |||
748 | 826 | ||
749 | static void nfs_file_clear_open_context(struct file *filp) | 827 | static void nfs_file_clear_open_context(struct file *filp) |
750 | { | 828 | { |
751 | struct inode *inode = file_inode(filp); | ||
752 | struct nfs_open_context *ctx = nfs_file_open_context(filp); | 829 | struct nfs_open_context *ctx = nfs_file_open_context(filp); |
753 | 830 | ||
754 | if (ctx) { | 831 | if (ctx) { |
832 | struct inode *inode = ctx->dentry->d_inode; | ||
833 | |||
755 | filp->private_data = NULL; | 834 | filp->private_data = NULL; |
756 | spin_lock(&inode->i_lock); | 835 | spin_lock(&inode->i_lock); |
757 | list_move_tail(&ctx->list, &NFS_I(inode)->open_files); | 836 | list_move_tail(&ctx->list, &NFS_I(inode)->open_files); |
@@ -790,6 +869,7 @@ int | |||
790 | __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | 869 | __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) |
791 | { | 870 | { |
792 | int status = -ESTALE; | 871 | int status = -ESTALE; |
872 | struct nfs4_label *label = NULL; | ||
793 | struct nfs_fattr *fattr = NULL; | 873 | struct nfs_fattr *fattr = NULL; |
794 | struct nfs_inode *nfsi = NFS_I(inode); | 874 | struct nfs_inode *nfsi = NFS_I(inode); |
795 | 875 | ||
@@ -807,7 +887,14 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
807 | goto out; | 887 | goto out; |
808 | 888 | ||
809 | nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); | 889 | nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); |
810 | status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr); | 890 | |
891 | label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL); | ||
892 | if (IS_ERR(label)) { | ||
893 | status = PTR_ERR(label); | ||
894 | goto out; | ||
895 | } | ||
896 | |||
897 | status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr, label); | ||
811 | if (status != 0) { | 898 | if (status != 0) { |
812 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", | 899 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", |
813 | inode->i_sb->s_id, | 900 | inode->i_sb->s_id, |
@@ -817,7 +904,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
817 | if (!S_ISDIR(inode->i_mode)) | 904 | if (!S_ISDIR(inode->i_mode)) |
818 | set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); | 905 | set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); |
819 | } | 906 | } |
820 | goto out; | 907 | goto err_out; |
821 | } | 908 | } |
822 | 909 | ||
823 | status = nfs_refresh_inode(inode, fattr); | 910 | status = nfs_refresh_inode(inode, fattr); |
@@ -825,7 +912,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
825 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", | 912 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", |
826 | inode->i_sb->s_id, | 913 | inode->i_sb->s_id, |
827 | (long long)NFS_FILEID(inode), status); | 914 | (long long)NFS_FILEID(inode), status); |
828 | goto out; | 915 | goto err_out; |
829 | } | 916 | } |
830 | 917 | ||
831 | if (nfsi->cache_validity & NFS_INO_INVALID_ACL) | 918 | if (nfsi->cache_validity & NFS_INO_INVALID_ACL) |
@@ -835,7 +922,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
835 | inode->i_sb->s_id, | 922 | inode->i_sb->s_id, |
836 | (long long)NFS_FILEID(inode)); | 923 | (long long)NFS_FILEID(inode)); |
837 | 924 | ||
838 | out: | 925 | err_out: |
926 | nfs4_label_free(label); | ||
927 | out: | ||
839 | nfs_free_fattr(fattr); | 928 | nfs_free_fattr(fattr); |
840 | return status; | 929 | return status; |
841 | } | 930 | } |
@@ -863,7 +952,8 @@ static int nfs_attribute_cache_expired(struct inode *inode) | |||
863 | */ | 952 | */ |
864 | int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | 953 | int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) |
865 | { | 954 | { |
866 | if (!(NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATTR) | 955 | if (!(NFS_I(inode)->cache_validity & |
956 | (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) | ||
867 | && !nfs_attribute_cache_expired(inode)) | 957 | && !nfs_attribute_cache_expired(inode)) |
868 | return NFS_STALE(inode) ? -ESTALE : 0; | 958 | return NFS_STALE(inode) ? -ESTALE : 0; |
869 | return __nfs_revalidate_inode(server, inode); | 959 | return __nfs_revalidate_inode(server, inode); |
@@ -1243,6 +1333,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1243 | spin_lock(&inode->i_lock); | 1333 | spin_lock(&inode->i_lock); |
1244 | status = nfs_post_op_update_inode_locked(inode, fattr); | 1334 | status = nfs_post_op_update_inode_locked(inode, fattr); |
1245 | spin_unlock(&inode->i_lock); | 1335 | spin_unlock(&inode->i_lock); |
1336 | |||
1246 | return status; | 1337 | return status; |
1247 | } | 1338 | } |
1248 | EXPORT_SYMBOL_GPL(nfs_post_op_update_inode); | 1339 | EXPORT_SYMBOL_GPL(nfs_post_op_update_inode); |
@@ -1483,7 +1574,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1483 | inode->i_blocks = fattr->du.nfs2.blocks; | 1574 | inode->i_blocks = fattr->du.nfs2.blocks; |
1484 | 1575 | ||
1485 | /* Update attrtimeo value if we're out of the unstable period */ | 1576 | /* Update attrtimeo value if we're out of the unstable period */ |
1486 | if (invalid & NFS_INO_INVALID_ATTR) { | 1577 | if (invalid & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) { |
1487 | nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE); | 1578 | nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE); |
1488 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); | 1579 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); |
1489 | nfsi->attrtimeo_timestamp = now; | 1580 | nfsi->attrtimeo_timestamp = now; |
@@ -1496,6 +1587,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1496 | } | 1587 | } |
1497 | } | 1588 | } |
1498 | invalid &= ~NFS_INO_INVALID_ATTR; | 1589 | invalid &= ~NFS_INO_INVALID_ATTR; |
1590 | invalid &= ~NFS_INO_INVALID_LABEL; | ||
1499 | /* Don't invalidate the data if we were to blame */ | 1591 | /* Don't invalidate the data if we were to blame */ |
1500 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) | 1592 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) |
1501 | || S_ISLNK(inode->i_mode))) | 1593 | || S_ISLNK(inode->i_mode))) |
@@ -1638,12 +1730,11 @@ EXPORT_SYMBOL_GPL(nfs_net_id); | |||
1638 | static int nfs_net_init(struct net *net) | 1730 | static int nfs_net_init(struct net *net) |
1639 | { | 1731 | { |
1640 | nfs_clients_init(net); | 1732 | nfs_clients_init(net); |
1641 | return nfs_dns_resolver_cache_init(net); | 1733 | return 0; |
1642 | } | 1734 | } |
1643 | 1735 | ||
1644 | static void nfs_net_exit(struct net *net) | 1736 | static void nfs_net_exit(struct net *net) |
1645 | { | 1737 | { |
1646 | nfs_dns_resolver_cache_destroy(net); | ||
1647 | nfs_cleanup_cb_ident_idr(net); | 1738 | nfs_cleanup_cb_ident_idr(net); |
1648 | } | 1739 | } |
1649 | 1740 | ||
@@ -1661,10 +1752,6 @@ static int __init init_nfs_fs(void) | |||
1661 | { | 1752 | { |
1662 | int err; | 1753 | int err; |
1663 | 1754 | ||
1664 | err = nfs_dns_resolver_init(); | ||
1665 | if (err < 0) | ||
1666 | goto out10;; | ||
1667 | |||
1668 | err = register_pernet_subsys(&nfs_net_ops); | 1755 | err = register_pernet_subsys(&nfs_net_ops); |
1669 | if (err < 0) | 1756 | if (err < 0) |
1670 | goto out9; | 1757 | goto out9; |
@@ -1730,8 +1817,6 @@ out7: | |||
1730 | out8: | 1817 | out8: |
1731 | unregister_pernet_subsys(&nfs_net_ops); | 1818 | unregister_pernet_subsys(&nfs_net_ops); |
1732 | out9: | 1819 | out9: |
1733 | nfs_dns_resolver_destroy(); | ||
1734 | out10: | ||
1735 | return err; | 1820 | return err; |
1736 | } | 1821 | } |
1737 | 1822 | ||
@@ -1744,7 +1829,6 @@ static void __exit exit_nfs_fs(void) | |||
1744 | nfs_destroy_nfspagecache(); | 1829 | nfs_destroy_nfspagecache(); |
1745 | nfs_fscache_unregister(); | 1830 | nfs_fscache_unregister(); |
1746 | unregister_pernet_subsys(&nfs_net_ops); | 1831 | unregister_pernet_subsys(&nfs_net_ops); |
1747 | nfs_dns_resolver_destroy(); | ||
1748 | #ifdef CONFIG_PROC_FS | 1832 | #ifdef CONFIG_PROC_FS |
1749 | rpc_proc_unregister(&init_net, "nfs"); | 1833 | rpc_proc_unregister(&init_net, "nfs"); |
1750 | #endif | 1834 | #endif |