.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * linux/fs/nfs/inode.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
50 | 51 | #include "pnfs.h" |
---|
51 | 52 | #include "nfs.h" |
---|
52 | 53 | #include "netns.h" |
---|
| 54 | +#include "sysfs.h" |
---|
53 | 55 | |
---|
54 | 56 | #include "nfstrace.h" |
---|
55 | 57 | |
---|
.. | .. |
---|
60 | 62 | /* Default is to see 64-bit inode numbers */ |
---|
61 | 63 | static bool enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED; |
---|
62 | 64 | |
---|
63 | | -static void nfs_invalidate_inode(struct inode *); |
---|
64 | 65 | static int nfs_update_inode(struct inode *, struct nfs_fattr *); |
---|
65 | 66 | |
---|
66 | 67 | static struct kmem_cache * nfs_inode_cachep; |
---|
.. | .. |
---|
143 | 144 | |
---|
144 | 145 | /** |
---|
145 | 146 | * nfs_sync_mapping - helper to flush all mmapped dirty data to disk |
---|
| 147 | + * @mapping: pointer to struct address_space |
---|
146 | 148 | */ |
---|
147 | 149 | int nfs_sync_mapping(struct address_space *mapping) |
---|
148 | 150 | { |
---|
.. | .. |
---|
191 | 193 | |
---|
192 | 194 | return nfs_check_cache_invalid_not_delegated(inode, flags); |
---|
193 | 195 | } |
---|
| 196 | +EXPORT_SYMBOL_GPL(nfs_check_cache_invalid); |
---|
| 197 | + |
---|
| 198 | +#ifdef CONFIG_NFS_V4_2 |
---|
| 199 | +static bool nfs_has_xattr_cache(const struct nfs_inode *nfsi) |
---|
| 200 | +{ |
---|
| 201 | + return nfsi->xattr_cache != NULL; |
---|
| 202 | +} |
---|
| 203 | +#else |
---|
| 204 | +static bool nfs_has_xattr_cache(const struct nfs_inode *nfsi) |
---|
| 205 | +{ |
---|
| 206 | + return false; |
---|
| 207 | +} |
---|
| 208 | +#endif |
---|
194 | 209 | |
---|
195 | 210 | static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) |
---|
196 | 211 | { |
---|
.. | .. |
---|
202 | 217 | flags &= ~NFS_INO_INVALID_OTHER; |
---|
203 | 218 | flags &= ~(NFS_INO_INVALID_CHANGE |
---|
204 | 219 | | NFS_INO_INVALID_SIZE |
---|
205 | | - | NFS_INO_REVAL_PAGECACHE); |
---|
206 | | - } |
---|
| 220 | + | NFS_INO_REVAL_PAGECACHE |
---|
| 221 | + | NFS_INO_INVALID_XATTR); |
---|
| 222 | + } else if (flags & NFS_INO_REVAL_PAGECACHE) |
---|
| 223 | + flags |= NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_SIZE; |
---|
207 | 224 | |
---|
| 225 | + if (!nfs_has_xattr_cache(nfsi)) |
---|
| 226 | + flags &= ~NFS_INO_INVALID_XATTR; |
---|
208 | 227 | if (inode->i_mapping->nrpages == 0) |
---|
209 | | - flags &= ~NFS_INO_INVALID_DATA; |
---|
| 228 | + flags &= ~(NFS_INO_INVALID_DATA|NFS_INO_DATA_INVAL_DEFER); |
---|
210 | 229 | nfsi->cache_validity |= flags; |
---|
211 | 230 | if (flags & NFS_INO_INVALID_DATA) |
---|
212 | 231 | nfs_fscache_invalidate(inode); |
---|
.. | .. |
---|
231 | 250 | | NFS_INO_INVALID_DATA |
---|
232 | 251 | | NFS_INO_INVALID_ACCESS |
---|
233 | 252 | | NFS_INO_INVALID_ACL |
---|
| 253 | + | NFS_INO_INVALID_XATTR |
---|
234 | 254 | | NFS_INO_REVAL_PAGECACHE); |
---|
235 | 255 | } else |
---|
236 | 256 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR |
---|
237 | 257 | | NFS_INO_INVALID_ACCESS |
---|
238 | 258 | | NFS_INO_INVALID_ACL |
---|
| 259 | + | NFS_INO_INVALID_XATTR |
---|
239 | 260 | | NFS_INO_REVAL_PAGECACHE); |
---|
240 | 261 | nfs_zap_label_cache_locked(nfsi); |
---|
241 | 262 | } |
---|
.. | .. |
---|
281 | 302 | * Invalidate, but do not unhash, the inode. |
---|
282 | 303 | * NB: must be called with inode->i_lock held! |
---|
283 | 304 | */ |
---|
284 | | -static void nfs_invalidate_inode(struct inode *inode) |
---|
| 305 | +static void nfs_set_inode_stale_locked(struct inode *inode) |
---|
285 | 306 | { |
---|
286 | 307 | set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); |
---|
287 | 308 | nfs_zap_caches_locked(inode); |
---|
| 309 | + trace_nfs_set_inode_stale(inode); |
---|
| 310 | +} |
---|
| 311 | + |
---|
| 312 | +void nfs_set_inode_stale(struct inode *inode) |
---|
| 313 | +{ |
---|
| 314 | + spin_lock(&inode->i_lock); |
---|
| 315 | + nfs_set_inode_stale_locked(inode); |
---|
| 316 | + spin_unlock(&inode->i_lock); |
---|
288 | 317 | } |
---|
289 | 318 | |
---|
290 | 319 | struct nfs_find_desc { |
---|
.. | .. |
---|
307 | 336 | |
---|
308 | 337 | if (NFS_FILEID(inode) != fattr->fileid) |
---|
309 | 338 | return 0; |
---|
310 | | - if ((S_IFMT & inode->i_mode) != (S_IFMT & fattr->mode)) |
---|
| 339 | + if (inode_wrong_type(inode, fattr->mode)) |
---|
311 | 340 | return 0; |
---|
312 | 341 | if (nfs_compare_fh(NFS_FH(inode), fh)) |
---|
313 | 342 | return 0; |
---|
.. | .. |
---|
501 | 530 | nfsi->read_cache_jiffies = fattr->time_start; |
---|
502 | 531 | nfsi->attr_gencount = fattr->gencount; |
---|
503 | 532 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) |
---|
504 | | - inode->i_atime = timespec_to_timespec64(fattr->atime); |
---|
| 533 | + inode->i_atime = fattr->atime; |
---|
505 | 534 | else if (nfs_server_capable(inode, NFS_CAP_ATIME)) |
---|
506 | 535 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME); |
---|
507 | 536 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) |
---|
508 | | - inode->i_mtime = timespec_to_timespec64(fattr->mtime); |
---|
| 537 | + inode->i_mtime = fattr->mtime; |
---|
509 | 538 | else if (nfs_server_capable(inode, NFS_CAP_MTIME)) |
---|
510 | 539 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_MTIME); |
---|
511 | 540 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) |
---|
512 | | - inode->i_ctime = timespec_to_timespec64(fattr->ctime); |
---|
| 541 | + inode->i_ctime = fattr->ctime; |
---|
513 | 542 | else if (nfs_server_capable(inode, NFS_CAP_CTIME)) |
---|
514 | 543 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_CTIME); |
---|
515 | 544 | if (fattr->valid & NFS_ATTR_FATTR_CHANGE) |
---|
.. | .. |
---|
532 | 561 | inode->i_gid = fattr->gid; |
---|
533 | 562 | else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP)) |
---|
534 | 563 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER); |
---|
| 564 | + if (nfs_server_capable(inode, NFS_CAP_XATTR)) |
---|
| 565 | + nfs_set_cache_invalid(inode, NFS_INO_INVALID_XATTR); |
---|
535 | 566 | if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) |
---|
536 | 567 | inode->i_blocks = fattr->du.nfs2.blocks; |
---|
537 | 568 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { |
---|
.. | .. |
---|
650 | 681 | i_size_write(inode, offset); |
---|
651 | 682 | /* Optimisation */ |
---|
652 | 683 | if (offset == 0) |
---|
653 | | - NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_DATA; |
---|
| 684 | + NFS_I(inode)->cache_validity &= ~(NFS_INO_INVALID_DATA | |
---|
| 685 | + NFS_INO_DATA_INVAL_DEFER); |
---|
654 | 686 | NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_SIZE; |
---|
655 | 687 | |
---|
656 | 688 | spin_unlock(&inode->i_lock); |
---|
.. | .. |
---|
694 | 726 | if ((attr->ia_valid & ATTR_GID) != 0) |
---|
695 | 727 | inode->i_gid = attr->ia_gid; |
---|
696 | 728 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) |
---|
697 | | - inode->i_ctime = timespec_to_timespec64(fattr->ctime); |
---|
| 729 | + inode->i_ctime = fattr->ctime; |
---|
698 | 730 | else |
---|
699 | 731 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE |
---|
700 | 732 | | NFS_INO_INVALID_CTIME); |
---|
.. | .. |
---|
705 | 737 | NFS_I(inode)->cache_validity &= ~(NFS_INO_INVALID_ATIME |
---|
706 | 738 | | NFS_INO_INVALID_CTIME); |
---|
707 | 739 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) |
---|
708 | | - inode->i_atime = timespec_to_timespec64(fattr->atime); |
---|
| 740 | + inode->i_atime = fattr->atime; |
---|
709 | 741 | else if (attr->ia_valid & ATTR_ATIME_SET) |
---|
710 | 742 | inode->i_atime = attr->ia_atime; |
---|
711 | 743 | else |
---|
712 | 744 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME); |
---|
713 | 745 | |
---|
714 | 746 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) |
---|
715 | | - inode->i_ctime = timespec_to_timespec64(fattr->ctime); |
---|
| 747 | + inode->i_ctime = fattr->ctime; |
---|
716 | 748 | else |
---|
717 | 749 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE |
---|
718 | 750 | | NFS_INO_INVALID_CTIME); |
---|
.. | .. |
---|
721 | 753 | NFS_I(inode)->cache_validity &= ~(NFS_INO_INVALID_MTIME |
---|
722 | 754 | | NFS_INO_INVALID_CTIME); |
---|
723 | 755 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) |
---|
724 | | - inode->i_mtime = timespec_to_timespec64(fattr->mtime); |
---|
| 756 | + inode->i_mtime = fattr->mtime; |
---|
725 | 757 | else if (attr->ia_valid & ATTR_MTIME_SET) |
---|
726 | 758 | inode->i_mtime = attr->ia_mtime; |
---|
727 | 759 | else |
---|
728 | 760 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_MTIME); |
---|
729 | 761 | |
---|
730 | 762 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) |
---|
731 | | - inode->i_ctime = timespec_to_timespec64(fattr->ctime); |
---|
| 763 | + inode->i_ctime = fattr->ctime; |
---|
732 | 764 | else |
---|
733 | 765 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE |
---|
734 | 766 | | NFS_INO_INVALID_CTIME); |
---|
.. | .. |
---|
783 | 815 | |
---|
784 | 816 | trace_nfs_getattr_enter(inode); |
---|
785 | 817 | |
---|
786 | | - if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync) |
---|
| 818 | + if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync) { |
---|
| 819 | + nfs_readdirplus_parent_cache_hit(path->dentry); |
---|
787 | 820 | goto out_no_update; |
---|
| 821 | + } |
---|
788 | 822 | |
---|
789 | 823 | /* Flush out writes to the server in order to update c/mtime. */ |
---|
790 | 824 | if ((request_mask & (STATX_CTIME | STATX_MTIME)) && |
---|
.. | .. |
---|
819 | 853 | do_update |= cache_validity & NFS_INO_INVALID_ATIME; |
---|
820 | 854 | if (request_mask & (STATX_CTIME|STATX_MTIME)) |
---|
821 | 855 | do_update |= cache_validity & NFS_INO_REVAL_PAGECACHE; |
---|
| 856 | + if (request_mask & STATX_BLOCKS) |
---|
| 857 | + do_update |= cache_validity & NFS_INO_INVALID_BLOCKS; |
---|
822 | 858 | if (do_update) { |
---|
823 | 859 | /* Update the attribute cache */ |
---|
824 | 860 | if (!(server->flags & NFS_MOUNT_NOAC)) |
---|
.. | .. |
---|
854 | 890 | |
---|
855 | 891 | static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx) |
---|
856 | 892 | { |
---|
857 | | - struct nfs_lock_context *head = &ctx->lock_context; |
---|
858 | | - struct nfs_lock_context *pos = head; |
---|
| 893 | + struct nfs_lock_context *pos; |
---|
859 | 894 | |
---|
860 | | - do { |
---|
| 895 | + list_for_each_entry_rcu(pos, &ctx->lock_context.list, list) { |
---|
861 | 896 | if (pos->lockowner != current->files) |
---|
862 | 897 | continue; |
---|
863 | | - refcount_inc(&pos->count); |
---|
864 | | - return pos; |
---|
865 | | - } while ((pos = list_entry(pos->list.next, typeof(*pos), list)) != head); |
---|
| 898 | + if (refcount_inc_not_zero(&pos->count)) |
---|
| 899 | + return pos; |
---|
| 900 | + } |
---|
866 | 901 | return NULL; |
---|
867 | 902 | } |
---|
868 | 903 | |
---|
.. | .. |
---|
871 | 906 | struct nfs_lock_context *res, *new = NULL; |
---|
872 | 907 | struct inode *inode = d_inode(ctx->dentry); |
---|
873 | 908 | |
---|
874 | | - spin_lock(&inode->i_lock); |
---|
| 909 | + rcu_read_lock(); |
---|
875 | 910 | res = __nfs_find_lock_context(ctx); |
---|
| 911 | + rcu_read_unlock(); |
---|
876 | 912 | if (res == NULL) { |
---|
877 | | - spin_unlock(&inode->i_lock); |
---|
878 | 913 | new = kmalloc(sizeof(*new), GFP_KERNEL); |
---|
879 | 914 | if (new == NULL) |
---|
880 | 915 | return ERR_PTR(-ENOMEM); |
---|
.. | .. |
---|
882 | 917 | spin_lock(&inode->i_lock); |
---|
883 | 918 | res = __nfs_find_lock_context(ctx); |
---|
884 | 919 | if (res == NULL) { |
---|
885 | | - list_add_tail(&new->list, &ctx->lock_context.list); |
---|
886 | | - new->open_context = ctx; |
---|
887 | | - res = new; |
---|
888 | | - new = NULL; |
---|
| 920 | + new->open_context = get_nfs_open_context(ctx); |
---|
| 921 | + if (new->open_context) { |
---|
| 922 | + list_add_tail_rcu(&new->list, |
---|
| 923 | + &ctx->lock_context.list); |
---|
| 924 | + res = new; |
---|
| 925 | + new = NULL; |
---|
| 926 | + } else |
---|
| 927 | + res = ERR_PTR(-EBADF); |
---|
889 | 928 | } |
---|
| 929 | + spin_unlock(&inode->i_lock); |
---|
| 930 | + kfree(new); |
---|
890 | 931 | } |
---|
891 | | - spin_unlock(&inode->i_lock); |
---|
892 | | - kfree(new); |
---|
893 | 932 | return res; |
---|
894 | 933 | } |
---|
895 | 934 | EXPORT_SYMBOL_GPL(nfs_get_lock_context); |
---|
.. | .. |
---|
901 | 940 | |
---|
902 | 941 | if (!refcount_dec_and_lock(&l_ctx->count, &inode->i_lock)) |
---|
903 | 942 | return; |
---|
904 | | - list_del(&l_ctx->list); |
---|
| 943 | + list_del_rcu(&l_ctx->list); |
---|
905 | 944 | spin_unlock(&inode->i_lock); |
---|
906 | | - kfree(l_ctx); |
---|
| 945 | + put_nfs_open_context(ctx); |
---|
| 946 | + kfree_rcu(l_ctx, rcu_head); |
---|
907 | 947 | } |
---|
908 | 948 | EXPORT_SYMBOL_GPL(nfs_put_lock_context); |
---|
909 | 949 | |
---|
.. | .. |
---|
948 | 988 | struct file *filp) |
---|
949 | 989 | { |
---|
950 | 990 | struct nfs_open_context *ctx; |
---|
951 | | - struct rpc_cred *cred = rpc_lookup_cred(); |
---|
952 | | - if (IS_ERR(cred)) |
---|
953 | | - return ERR_CAST(cred); |
---|
954 | 991 | |
---|
955 | 992 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); |
---|
956 | | - if (!ctx) { |
---|
957 | | - put_rpccred(cred); |
---|
| 993 | + if (!ctx) |
---|
958 | 994 | return ERR_PTR(-ENOMEM); |
---|
959 | | - } |
---|
960 | 995 | nfs_sb_active(dentry->d_sb); |
---|
961 | 996 | ctx->dentry = dget(dentry); |
---|
962 | | - ctx->cred = cred; |
---|
| 997 | + if (filp) |
---|
| 998 | + ctx->cred = get_cred(filp->f_cred); |
---|
| 999 | + else |
---|
| 1000 | + ctx->cred = get_current_cred(); |
---|
| 1001 | + ctx->ll_cred = NULL; |
---|
963 | 1002 | ctx->state = NULL; |
---|
964 | 1003 | ctx->mode = f_mode; |
---|
965 | 1004 | ctx->flags = 0; |
---|
.. | .. |
---|
975 | 1014 | |
---|
976 | 1015 | struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) |
---|
977 | 1016 | { |
---|
978 | | - if (ctx != NULL) |
---|
979 | | - refcount_inc(&ctx->lock_context.count); |
---|
980 | | - return ctx; |
---|
| 1017 | + if (ctx != NULL && refcount_inc_not_zero(&ctx->lock_context.count)) |
---|
| 1018 | + return ctx; |
---|
| 1019 | + return NULL; |
---|
981 | 1020 | } |
---|
982 | 1021 | EXPORT_SYMBOL_GPL(get_nfs_open_context); |
---|
983 | 1022 | |
---|
.. | .. |
---|
986 | 1025 | struct inode *inode = d_inode(ctx->dentry); |
---|
987 | 1026 | struct super_block *sb = ctx->dentry->d_sb; |
---|
988 | 1027 | |
---|
989 | | - if (!list_empty(&ctx->list)) { |
---|
990 | | - if (!refcount_dec_and_lock(&ctx->lock_context.count, &inode->i_lock)) |
---|
991 | | - return; |
---|
992 | | - list_del(&ctx->list); |
---|
993 | | - spin_unlock(&inode->i_lock); |
---|
994 | | - } else if (!refcount_dec_and_test(&ctx->lock_context.count)) |
---|
| 1028 | + if (!refcount_dec_and_test(&ctx->lock_context.count)) |
---|
995 | 1029 | return; |
---|
| 1030 | + if (!list_empty(&ctx->list)) { |
---|
| 1031 | + spin_lock(&inode->i_lock); |
---|
| 1032 | + list_del_rcu(&ctx->list); |
---|
| 1033 | + spin_unlock(&inode->i_lock); |
---|
| 1034 | + } |
---|
996 | 1035 | if (inode != NULL) |
---|
997 | 1036 | NFS_PROTO(inode)->close_context(ctx, is_sync); |
---|
998 | | - if (ctx->cred != NULL) |
---|
999 | | - put_rpccred(ctx->cred); |
---|
| 1037 | + put_cred(ctx->cred); |
---|
1000 | 1038 | dput(ctx->dentry); |
---|
1001 | 1039 | nfs_sb_deactive(sb); |
---|
| 1040 | + put_rpccred(ctx->ll_cred); |
---|
1002 | 1041 | kfree(ctx->mdsthreshold); |
---|
1003 | | - kfree(ctx); |
---|
| 1042 | + kfree_rcu(ctx, rcu_head); |
---|
1004 | 1043 | } |
---|
1005 | 1044 | |
---|
1006 | 1045 | void put_nfs_open_context(struct nfs_open_context *ctx) |
---|
.. | .. |
---|
1024 | 1063 | struct nfs_inode *nfsi = NFS_I(inode); |
---|
1025 | 1064 | |
---|
1026 | 1065 | spin_lock(&inode->i_lock); |
---|
1027 | | - if (ctx->mode & FMODE_WRITE) |
---|
1028 | | - list_add(&ctx->list, &nfsi->open_files); |
---|
1029 | | - else |
---|
1030 | | - list_add_tail(&ctx->list, &nfsi->open_files); |
---|
| 1066 | + if (list_empty(&nfsi->open_files) && |
---|
| 1067 | + (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER)) |
---|
| 1068 | + nfsi->cache_validity |= NFS_INO_INVALID_DATA | |
---|
| 1069 | + NFS_INO_REVAL_FORCED; |
---|
| 1070 | + list_add_tail_rcu(&ctx->list, &nfsi->open_files); |
---|
1031 | 1071 | spin_unlock(&inode->i_lock); |
---|
1032 | 1072 | } |
---|
1033 | 1073 | EXPORT_SYMBOL_GPL(nfs_inode_attach_open_context); |
---|
.. | .. |
---|
1044 | 1084 | /* |
---|
1045 | 1085 | * Given an inode, search for an open context with the desired characteristics |
---|
1046 | 1086 | */ |
---|
1047 | | -struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode) |
---|
| 1087 | +struct nfs_open_context *nfs_find_open_context(struct inode *inode, const struct cred *cred, fmode_t mode) |
---|
1048 | 1088 | { |
---|
1049 | 1089 | struct nfs_inode *nfsi = NFS_I(inode); |
---|
1050 | 1090 | struct nfs_open_context *pos, *ctx = NULL; |
---|
1051 | 1091 | |
---|
1052 | | - spin_lock(&inode->i_lock); |
---|
1053 | | - list_for_each_entry(pos, &nfsi->open_files, list) { |
---|
1054 | | - if (cred != NULL && pos->cred != cred) |
---|
| 1092 | + rcu_read_lock(); |
---|
| 1093 | + list_for_each_entry_rcu(pos, &nfsi->open_files, list) { |
---|
| 1094 | + if (cred != NULL && cred_fscmp(pos->cred, cred) != 0) |
---|
1055 | 1095 | continue; |
---|
1056 | 1096 | if ((pos->mode & (FMODE_READ|FMODE_WRITE)) != mode) |
---|
1057 | 1097 | continue; |
---|
1058 | 1098 | if (!test_bit(NFS_CONTEXT_FILE_OPEN, &pos->flags)) |
---|
1059 | 1099 | continue; |
---|
1060 | 1100 | ctx = get_nfs_open_context(pos); |
---|
1061 | | - break; |
---|
| 1101 | + if (ctx) |
---|
| 1102 | + break; |
---|
1062 | 1103 | } |
---|
1063 | | - spin_unlock(&inode->i_lock); |
---|
| 1104 | + rcu_read_unlock(); |
---|
1064 | 1105 | return ctx; |
---|
1065 | 1106 | } |
---|
1066 | 1107 | |
---|
.. | .. |
---|
1079 | 1120 | if (ctx->error < 0) |
---|
1080 | 1121 | invalidate_inode_pages2(inode->i_mapping); |
---|
1081 | 1122 | filp->private_data = NULL; |
---|
1082 | | - spin_lock(&inode->i_lock); |
---|
1083 | | - list_move_tail(&ctx->list, &NFS_I(inode)->open_files); |
---|
1084 | | - spin_unlock(&inode->i_lock); |
---|
1085 | 1123 | put_nfs_open_context_sync(ctx); |
---|
1086 | 1124 | } |
---|
1087 | 1125 | } |
---|
.. | .. |
---|
1101 | 1139 | nfs_fscache_open_file(inode, filp); |
---|
1102 | 1140 | return 0; |
---|
1103 | 1141 | } |
---|
1104 | | -EXPORT_SYMBOL_GPL(nfs_open); |
---|
1105 | 1142 | |
---|
1106 | 1143 | /* |
---|
1107 | 1144 | * This function is called whenever some part of NFS notices that |
---|
.. | .. |
---|
1151 | 1188 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) getattr failed, error=%d\n", |
---|
1152 | 1189 | inode->i_sb->s_id, |
---|
1153 | 1190 | (unsigned long long)NFS_FILEID(inode), status); |
---|
1154 | | - if (status == -ESTALE) { |
---|
1155 | | - nfs_zap_caches(inode); |
---|
| 1191 | + switch (status) { |
---|
| 1192 | + case -ETIMEDOUT: |
---|
| 1193 | + /* A soft timeout occurred. Use cached information? */ |
---|
| 1194 | + if (server->flags & NFS_MOUNT_SOFTREVAL) |
---|
| 1195 | + status = 0; |
---|
| 1196 | + break; |
---|
| 1197 | + case -ESTALE: |
---|
1156 | 1198 | if (!S_ISDIR(inode->i_mode)) |
---|
1157 | | - set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); |
---|
| 1199 | + nfs_set_inode_stale(inode); |
---|
| 1200 | + else |
---|
| 1201 | + nfs_zap_caches(inode); |
---|
1158 | 1202 | } |
---|
1159 | 1203 | goto err_out; |
---|
1160 | 1204 | } |
---|
.. | .. |
---|
1193 | 1237 | |
---|
1194 | 1238 | /** |
---|
1195 | 1239 | * nfs_revalidate_inode - Revalidate the inode attributes |
---|
1196 | | - * @server - pointer to nfs_server struct |
---|
1197 | | - * @inode - pointer to inode struct |
---|
| 1240 | + * @server: pointer to nfs_server struct |
---|
| 1241 | + * @inode: pointer to inode struct |
---|
1198 | 1242 | * |
---|
1199 | 1243 | * Updates inode attribute information by retrieving the data from the server. |
---|
1200 | 1244 | */ |
---|
.. | .. |
---|
1264 | 1308 | |
---|
1265 | 1309 | /** |
---|
1266 | 1310 | * nfs_revalidate_mapping - Revalidate the pagecache |
---|
1267 | | - * @inode - pointer to host inode |
---|
1268 | | - * @mapping - pointer to mapping |
---|
| 1311 | + * @inode: pointer to host inode |
---|
| 1312 | + * @mapping: pointer to mapping |
---|
1269 | 1313 | */ |
---|
1270 | 1314 | int nfs_revalidate_mapping(struct inode *inode, |
---|
1271 | 1315 | struct address_space *mapping) |
---|
.. | .. |
---|
1314 | 1358 | |
---|
1315 | 1359 | set_bit(NFS_INO_INVALIDATING, bitlock); |
---|
1316 | 1360 | smp_wmb(); |
---|
1317 | | - nfsi->cache_validity &= ~NFS_INO_INVALID_DATA; |
---|
| 1361 | + nfsi->cache_validity &= ~(NFS_INO_INVALID_DATA| |
---|
| 1362 | + NFS_INO_DATA_INVAL_DEFER); |
---|
1318 | 1363 | spin_unlock(&inode->i_lock); |
---|
1319 | 1364 | trace_nfs_invalidate_mapping_enter(inode); |
---|
1320 | 1365 | ret = nfs_invalidate_mapping(inode, mapping); |
---|
.. | .. |
---|
1331 | 1376 | { |
---|
1332 | 1377 | struct inode *inode = &nfsi->vfs_inode; |
---|
1333 | 1378 | |
---|
1334 | | - assert_spin_locked(&inode->i_lock); |
---|
1335 | | - |
---|
1336 | 1379 | if (!S_ISREG(inode->i_mode)) |
---|
1337 | 1380 | return false; |
---|
1338 | 1381 | if (list_empty(&nfsi->open_files)) |
---|
1339 | 1382 | return false; |
---|
1340 | | - /* Note: This relies on nfsi->open_files being ordered with writers |
---|
1341 | | - * being placed at the head of the list. |
---|
1342 | | - * See nfs_inode_attach_open_context() |
---|
1343 | | - */ |
---|
1344 | | - return (list_first_entry(&nfsi->open_files, |
---|
1345 | | - struct nfs_open_context, |
---|
1346 | | - list)->mode & FMODE_WRITE) == FMODE_WRITE; |
---|
| 1383 | + return inode_is_open_for_write(inode); |
---|
1347 | 1384 | } |
---|
1348 | 1385 | |
---|
1349 | 1386 | static bool nfs_file_has_buffered_writers(struct nfs_inode *nfsi) |
---|
.. | .. |
---|
1353 | 1390 | |
---|
1354 | 1391 | static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) |
---|
1355 | 1392 | { |
---|
1356 | | - struct timespec ts; |
---|
| 1393 | + struct timespec64 ts; |
---|
1357 | 1394 | |
---|
1358 | 1395 | if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE) |
---|
1359 | 1396 | && (fattr->valid & NFS_ATTR_FATTR_CHANGE) |
---|
.. | .. |
---|
1361 | 1398 | inode_set_iversion_raw(inode, fattr->change_attr); |
---|
1362 | 1399 | if (S_ISDIR(inode->i_mode)) |
---|
1363 | 1400 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA); |
---|
| 1401 | + else if (nfs_server_capable(inode, NFS_CAP_XATTR)) |
---|
| 1402 | + nfs_set_cache_invalid(inode, NFS_INO_INVALID_XATTR); |
---|
1364 | 1403 | } |
---|
1365 | 1404 | /* If we have atomic WCC data, we may update some attributes */ |
---|
1366 | | - ts = timespec64_to_timespec(inode->i_ctime); |
---|
| 1405 | + ts = inode->i_ctime; |
---|
1367 | 1406 | if ((fattr->valid & NFS_ATTR_FATTR_PRECTIME) |
---|
1368 | 1407 | && (fattr->valid & NFS_ATTR_FATTR_CTIME) |
---|
1369 | | - && timespec_equal(&ts, &fattr->pre_ctime)) { |
---|
1370 | | - inode->i_ctime = timespec_to_timespec64(fattr->ctime); |
---|
| 1408 | + && timespec64_equal(&ts, &fattr->pre_ctime)) { |
---|
| 1409 | + inode->i_ctime = fattr->ctime; |
---|
1371 | 1410 | } |
---|
1372 | 1411 | |
---|
1373 | | - ts = timespec64_to_timespec(inode->i_mtime); |
---|
| 1412 | + ts = inode->i_mtime; |
---|
1374 | 1413 | if ((fattr->valid & NFS_ATTR_FATTR_PREMTIME) |
---|
1375 | 1414 | && (fattr->valid & NFS_ATTR_FATTR_MTIME) |
---|
1376 | | - && timespec_equal(&ts, &fattr->pre_mtime)) { |
---|
1377 | | - inode->i_mtime = timespec_to_timespec64(fattr->mtime); |
---|
| 1415 | + && timespec64_equal(&ts, &fattr->pre_mtime)) { |
---|
| 1416 | + inode->i_mtime = fattr->mtime; |
---|
1378 | 1417 | if (S_ISDIR(inode->i_mode)) |
---|
1379 | 1418 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA); |
---|
1380 | 1419 | } |
---|
.. | .. |
---|
1388 | 1427 | |
---|
1389 | 1428 | /** |
---|
1390 | 1429 | * nfs_check_inode_attributes - verify consistency of the inode attribute cache |
---|
1391 | | - * @inode - pointer to inode |
---|
1392 | | - * @fattr - updated attributes |
---|
| 1430 | + * @inode: pointer to inode |
---|
| 1431 | + * @fattr: updated attributes |
---|
1393 | 1432 | * |
---|
1394 | 1433 | * Verifies the attribute cache. If we have just changed the attributes, |
---|
1395 | 1434 | * so that fattr carries weak cache consistency data, then it may |
---|
.. | .. |
---|
1400 | 1439 | struct nfs_inode *nfsi = NFS_I(inode); |
---|
1401 | 1440 | loff_t cur_size, new_isize; |
---|
1402 | 1441 | unsigned long invalid = 0; |
---|
1403 | | - struct timespec ts; |
---|
| 1442 | + struct timespec64 ts; |
---|
1404 | 1443 | |
---|
1405 | 1444 | if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) |
---|
1406 | 1445 | return 0; |
---|
1407 | 1446 | |
---|
| 1447 | + if (!(fattr->valid & NFS_ATTR_FATTR_FILEID)) { |
---|
| 1448 | + /* Only a mounted-on-fileid? Just exit */ |
---|
| 1449 | + if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) |
---|
| 1450 | + return 0; |
---|
1408 | 1451 | /* Has the inode gone and changed behind our back? */ |
---|
1409 | | - if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) |
---|
| 1452 | + } else if (nfsi->fileid != fattr->fileid) { |
---|
| 1453 | + /* Is this perhaps the mounted-on fileid? */ |
---|
| 1454 | + if ((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) && |
---|
| 1455 | + nfsi->fileid == fattr->mounted_on_fileid) |
---|
| 1456 | + return 0; |
---|
1410 | 1457 | return -ESTALE; |
---|
1411 | | - if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) |
---|
| 1458 | + } |
---|
| 1459 | + if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && inode_wrong_type(inode, fattr->mode)) |
---|
1412 | 1460 | return -ESTALE; |
---|
| 1461 | + |
---|
1413 | 1462 | |
---|
1414 | 1463 | if (!nfs_file_has_buffered_writers(nfsi)) { |
---|
1415 | 1464 | /* Verify a few of the more important attributes */ |
---|
.. | .. |
---|
1417 | 1466 | invalid |= NFS_INO_INVALID_CHANGE |
---|
1418 | 1467 | | NFS_INO_REVAL_PAGECACHE; |
---|
1419 | 1468 | |
---|
1420 | | - ts = timespec64_to_timespec(inode->i_mtime); |
---|
1421 | | - if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec_equal(&ts, &fattr->mtime)) |
---|
| 1469 | + ts = inode->i_mtime; |
---|
| 1470 | + if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec64_equal(&ts, &fattr->mtime)) |
---|
1422 | 1471 | invalid |= NFS_INO_INVALID_MTIME; |
---|
1423 | 1472 | |
---|
1424 | | - ts = timespec64_to_timespec(inode->i_ctime); |
---|
1425 | | - if ((fattr->valid & NFS_ATTR_FATTR_CTIME) && !timespec_equal(&ts, &fattr->ctime)) |
---|
| 1473 | + ts = inode->i_ctime; |
---|
| 1474 | + if ((fattr->valid & NFS_ATTR_FATTR_CTIME) && !timespec64_equal(&ts, &fattr->ctime)) |
---|
1426 | 1475 | invalid |= NFS_INO_INVALID_CTIME; |
---|
1427 | 1476 | |
---|
1428 | 1477 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) { |
---|
.. | .. |
---|
1452 | 1501 | if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink) |
---|
1453 | 1502 | invalid |= NFS_INO_INVALID_OTHER; |
---|
1454 | 1503 | |
---|
1455 | | - ts = timespec64_to_timespec(inode->i_atime); |
---|
1456 | | - if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec_equal(&ts, &fattr->atime)) |
---|
| 1504 | + ts = inode->i_atime; |
---|
| 1505 | + if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec64_equal(&ts, &fattr->atime)) |
---|
1457 | 1506 | invalid |= NFS_INO_INVALID_ATIME; |
---|
1458 | 1507 | |
---|
1459 | 1508 | if (invalid != 0) |
---|
.. | .. |
---|
1589 | 1638 | |
---|
1590 | 1639 | /** |
---|
1591 | 1640 | * nfs_inode_attrs_need_update - check if the inode attributes need updating |
---|
1592 | | - * @inode - pointer to inode |
---|
1593 | | - * @fattr - attributes |
---|
| 1641 | + * @inode: pointer to inode |
---|
| 1642 | + * @fattr: attributes |
---|
1594 | 1643 | * |
---|
1595 | 1644 | * Attempt to divine whether or not an RPC call reply carrying stale |
---|
1596 | 1645 | * attributes got scheduled after another call carrying updated ones. |
---|
.. | .. |
---|
1631 | 1680 | |
---|
1632 | 1681 | /** |
---|
1633 | 1682 | * nfs_refresh_inode - try to update the inode attribute cache |
---|
1634 | | - * @inode - pointer to inode |
---|
1635 | | - * @fattr - updated attributes |
---|
| 1683 | + * @inode: pointer to inode |
---|
| 1684 | + * @fattr: updated attributes |
---|
1636 | 1685 | * |
---|
1637 | 1686 | * Check that an RPC call that returned attributes has not overlapped with |
---|
1638 | 1687 | * other recent updates of the inode metadata, then decide whether it is |
---|
.. | .. |
---|
1666 | 1715 | |
---|
1667 | 1716 | /** |
---|
1668 | 1717 | * nfs_post_op_update_inode - try to update the inode attribute cache |
---|
1669 | | - * @inode - pointer to inode |
---|
1670 | | - * @fattr - updated attributes |
---|
| 1718 | + * @inode: pointer to inode |
---|
| 1719 | + * @fattr: updated attributes |
---|
1671 | 1720 | * |
---|
1672 | 1721 | * After an operation that has changed the inode metadata, mark the |
---|
1673 | 1722 | * attribute cache as being invalid, then try to update it. |
---|
.. | .. |
---|
1696 | 1745 | |
---|
1697 | 1746 | /** |
---|
1698 | 1747 | * nfs_post_op_update_inode_force_wcc_locked - update the inode attribute cache |
---|
1699 | | - * @inode - pointer to inode |
---|
1700 | | - * @fattr - updated attributes |
---|
| 1748 | + * @inode: pointer to inode |
---|
| 1749 | + * @fattr: updated attributes |
---|
1701 | 1750 | * |
---|
1702 | 1751 | * After an operation that has changed the inode metadata, mark the |
---|
1703 | 1752 | * attribute cache as being invalid, then try to update it. Fake up |
---|
.. | .. |
---|
1725 | 1774 | } |
---|
1726 | 1775 | if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 && |
---|
1727 | 1776 | (fattr->valid & NFS_ATTR_FATTR_PRECTIME) == 0) { |
---|
1728 | | - fattr->pre_ctime = timespec64_to_timespec(inode->i_ctime); |
---|
| 1777 | + fattr->pre_ctime = inode->i_ctime; |
---|
1729 | 1778 | fattr->valid |= NFS_ATTR_FATTR_PRECTIME; |
---|
1730 | 1779 | } |
---|
1731 | 1780 | if ((fattr->valid & NFS_ATTR_FATTR_MTIME) != 0 && |
---|
1732 | 1781 | (fattr->valid & NFS_ATTR_FATTR_PREMTIME) == 0) { |
---|
1733 | | - fattr->pre_mtime = timespec64_to_timespec(inode->i_mtime); |
---|
| 1782 | + fattr->pre_mtime = inode->i_mtime; |
---|
1734 | 1783 | fattr->valid |= NFS_ATTR_FATTR_PREMTIME; |
---|
1735 | 1784 | } |
---|
1736 | 1785 | if ((fattr->valid & NFS_ATTR_FATTR_SIZE) != 0 && |
---|
.. | .. |
---|
1742 | 1791 | status = nfs_post_op_update_inode_locked(inode, fattr, |
---|
1743 | 1792 | NFS_INO_INVALID_CHANGE |
---|
1744 | 1793 | | NFS_INO_INVALID_CTIME |
---|
1745 | | - | NFS_INO_INVALID_MTIME); |
---|
| 1794 | + | NFS_INO_INVALID_MTIME |
---|
| 1795 | + | NFS_INO_INVALID_BLOCKS); |
---|
1746 | 1796 | return status; |
---|
1747 | 1797 | } |
---|
1748 | 1798 | |
---|
1749 | 1799 | /** |
---|
1750 | 1800 | * nfs_post_op_update_inode_force_wcc - try to update the inode attribute cache |
---|
1751 | | - * @inode - pointer to inode |
---|
1752 | | - * @fattr - updated attributes |
---|
| 1801 | + * @inode: pointer to inode |
---|
| 1802 | + * @fattr: updated attributes |
---|
1753 | 1803 | * |
---|
1754 | 1804 | * After an operation that has changed the inode metadata, mark the |
---|
1755 | 1805 | * attribute cache as being invalid, then try to update it. Fake up |
---|
.. | .. |
---|
1769 | 1819 | } |
---|
1770 | 1820 | EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc); |
---|
1771 | 1821 | |
---|
1772 | | - |
---|
1773 | | -static inline bool nfs_fileid_valid(struct nfs_inode *nfsi, |
---|
1774 | | - struct nfs_fattr *fattr) |
---|
1775 | | -{ |
---|
1776 | | - bool ret1 = true, ret2 = true; |
---|
1777 | | - |
---|
1778 | | - if (fattr->valid & NFS_ATTR_FATTR_FILEID) |
---|
1779 | | - ret1 = (nfsi->fileid == fattr->fileid); |
---|
1780 | | - if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) |
---|
1781 | | - ret2 = (nfsi->fileid == fattr->mounted_on_fileid); |
---|
1782 | | - return ret1 || ret2; |
---|
1783 | | -} |
---|
1784 | 1822 | |
---|
1785 | 1823 | /* |
---|
1786 | 1824 | * Many nfs protocol calls return the new file attributes after |
---|
.. | .. |
---|
1812 | 1850 | nfs_display_fhandle_hash(NFS_FH(inode)), |
---|
1813 | 1851 | atomic_read(&inode->i_count), fattr->valid); |
---|
1814 | 1852 | |
---|
1815 | | - if (!nfs_fileid_valid(nfsi, fattr)) { |
---|
| 1853 | + if (!(fattr->valid & NFS_ATTR_FATTR_FILEID)) { |
---|
| 1854 | + /* Only a mounted-on-fileid? Just exit */ |
---|
| 1855 | + if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) |
---|
| 1856 | + return 0; |
---|
| 1857 | + /* Has the inode gone and changed behind our back? */ |
---|
| 1858 | + } else if (nfsi->fileid != fattr->fileid) { |
---|
| 1859 | + /* Is this perhaps the mounted-on fileid? */ |
---|
| 1860 | + if ((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) && |
---|
| 1861 | + nfsi->fileid == fattr->mounted_on_fileid) |
---|
| 1862 | + return 0; |
---|
1816 | 1863 | printk(KERN_ERR "NFS: server %s error: fileid changed\n" |
---|
1817 | 1864 | "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", |
---|
1818 | 1865 | NFS_SERVER(inode)->nfs_client->cl_hostname, |
---|
.. | .. |
---|
1824 | 1871 | /* |
---|
1825 | 1872 | * Make sure the inode's type hasn't changed. |
---|
1826 | 1873 | */ |
---|
1827 | | - if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) { |
---|
| 1874 | + if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && inode_wrong_type(inode, fattr->mode)) { |
---|
1828 | 1875 | /* |
---|
1829 | 1876 | * Big trouble! The inode has become a different object. |
---|
1830 | 1877 | */ |
---|
.. | .. |
---|
1852 | 1899 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR |
---|
1853 | 1900 | | NFS_INO_INVALID_ATIME |
---|
1854 | 1901 | | NFS_INO_REVAL_FORCED |
---|
1855 | | - | NFS_INO_REVAL_PAGECACHE); |
---|
| 1902 | + | NFS_INO_REVAL_PAGECACHE |
---|
| 1903 | + | NFS_INO_INVALID_BLOCKS); |
---|
1856 | 1904 | |
---|
1857 | 1905 | /* Do atomic weak cache consistency updates */ |
---|
1858 | 1906 | nfs_wcc_update_inode(inode, fattr); |
---|
1859 | 1907 | |
---|
1860 | 1908 | if (pnfs_layoutcommit_outstanding(inode)) { |
---|
1861 | | - nfsi->cache_validity |= save_cache_validity & NFS_INO_INVALID_ATTR; |
---|
| 1909 | + nfsi->cache_validity |= |
---|
| 1910 | + save_cache_validity & |
---|
| 1911 | + (NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME | |
---|
| 1912 | + NFS_INO_INVALID_MTIME | NFS_INO_INVALID_SIZE | |
---|
| 1913 | + NFS_INO_REVAL_FORCED); |
---|
1862 | 1914 | cache_revalidated = false; |
---|
1863 | 1915 | } |
---|
1864 | 1916 | |
---|
.. | .. |
---|
1869 | 1921 | if (!(have_writers || have_delegation)) { |
---|
1870 | 1922 | invalid |= NFS_INO_INVALID_DATA |
---|
1871 | 1923 | | NFS_INO_INVALID_ACCESS |
---|
1872 | | - | NFS_INO_INVALID_ACL; |
---|
| 1924 | + | NFS_INO_INVALID_ACL |
---|
| 1925 | + | NFS_INO_INVALID_XATTR; |
---|
1873 | 1926 | /* Force revalidate of all attributes */ |
---|
1874 | 1927 | save_cache_validity |= NFS_INO_INVALID_CTIME |
---|
1875 | 1928 | | NFS_INO_INVALID_MTIME |
---|
.. | .. |
---|
1880 | 1933 | dprintk("NFS: change_attr change on server for file %s/%ld\n", |
---|
1881 | 1934 | inode->i_sb->s_id, |
---|
1882 | 1935 | inode->i_ino); |
---|
1883 | | - } |
---|
| 1936 | + } else if (!have_delegation) |
---|
| 1937 | + nfsi->cache_validity |= NFS_INO_DATA_INVAL_DEFER; |
---|
1884 | 1938 | inode_set_iversion_raw(inode, fattr->change_attr); |
---|
1885 | 1939 | attr_changed = true; |
---|
1886 | 1940 | } |
---|
.. | .. |
---|
1893 | 1947 | } |
---|
1894 | 1948 | |
---|
1895 | 1949 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) { |
---|
1896 | | - inode->i_mtime = timespec_to_timespec64(fattr->mtime); |
---|
| 1950 | + inode->i_mtime = fattr->mtime; |
---|
1897 | 1951 | } else if (server->caps & NFS_CAP_MTIME) { |
---|
1898 | 1952 | nfsi->cache_validity |= save_cache_validity & |
---|
1899 | 1953 | (NFS_INO_INVALID_MTIME |
---|
.. | .. |
---|
1902 | 1956 | } |
---|
1903 | 1957 | |
---|
1904 | 1958 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) { |
---|
1905 | | - inode->i_ctime = timespec_to_timespec64(fattr->ctime); |
---|
| 1959 | + inode->i_ctime = fattr->ctime; |
---|
1906 | 1960 | } else if (server->caps & NFS_CAP_CTIME) { |
---|
1907 | 1961 | nfsi->cache_validity |= save_cache_validity & |
---|
1908 | 1962 | (NFS_INO_INVALID_CTIME |
---|
.. | .. |
---|
1940 | 1994 | |
---|
1941 | 1995 | |
---|
1942 | 1996 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) |
---|
1943 | | - inode->i_atime = timespec_to_timespec64(fattr->atime); |
---|
| 1997 | + inode->i_atime = fattr->atime; |
---|
1944 | 1998 | else if (server->caps & NFS_CAP_ATIME) { |
---|
1945 | 1999 | nfsi->cache_validity |= save_cache_validity & |
---|
1946 | 2000 | (NFS_INO_INVALID_ATIME |
---|
.. | .. |
---|
2013 | 2067 | inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used); |
---|
2014 | 2068 | } else if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) |
---|
2015 | 2069 | inode->i_blocks = fattr->du.nfs2.blocks; |
---|
2016 | | - else |
---|
| 2070 | + else { |
---|
| 2071 | + nfsi->cache_validity |= save_cache_validity & |
---|
| 2072 | + (NFS_INO_INVALID_BLOCKS |
---|
| 2073 | + | NFS_INO_REVAL_FORCED); |
---|
2017 | 2074 | cache_revalidated = false; |
---|
| 2075 | + } |
---|
2018 | 2076 | |
---|
2019 | 2077 | /* Update attrtimeo value if we're out of the unstable period */ |
---|
2020 | 2078 | if (attr_changed) { |
---|
.. | .. |
---|
2052 | 2110 | * lookup validation will know that the inode is bad. |
---|
2053 | 2111 | * (But we fall through to invalidate the caches.) |
---|
2054 | 2112 | */ |
---|
2055 | | - nfs_invalidate_inode(inode); |
---|
| 2113 | + nfs_set_inode_stale_locked(inode); |
---|
2056 | 2114 | return -ESTALE; |
---|
2057 | 2115 | } |
---|
2058 | 2116 | |
---|
.. | .. |
---|
2067 | 2125 | #if IS_ENABLED(CONFIG_NFS_V4) |
---|
2068 | 2126 | nfsi->nfs4_acl = NULL; |
---|
2069 | 2127 | #endif /* CONFIG_NFS_V4 */ |
---|
| 2128 | +#ifdef CONFIG_NFS_V4_2 |
---|
| 2129 | + nfsi->xattr_cache = NULL; |
---|
| 2130 | +#endif |
---|
2070 | 2131 | return &nfsi->vfs_inode; |
---|
2071 | 2132 | } |
---|
2072 | 2133 | EXPORT_SYMBOL_GPL(nfs_alloc_inode); |
---|
2073 | 2134 | |
---|
2074 | | -static void nfs_i_callback(struct rcu_head *head) |
---|
| 2135 | +void nfs_free_inode(struct inode *inode) |
---|
2075 | 2136 | { |
---|
2076 | | - struct inode *inode = container_of(head, struct inode, i_rcu); |
---|
2077 | 2137 | kmem_cache_free(nfs_inode_cachep, NFS_I(inode)); |
---|
2078 | 2138 | } |
---|
2079 | | - |
---|
2080 | | -void nfs_destroy_inode(struct inode *inode) |
---|
2081 | | -{ |
---|
2082 | | - call_rcu(&inode->i_rcu, nfs_i_callback); |
---|
2083 | | -} |
---|
2084 | | -EXPORT_SYMBOL_GPL(nfs_destroy_inode); |
---|
| 2139 | +EXPORT_SYMBOL_GPL(nfs_free_inode); |
---|
2085 | 2140 | |
---|
2086 | 2141 | static inline void nfs4_init_once(struct nfs_inode *nfsi) |
---|
2087 | 2142 | { |
---|
.. | .. |
---|
2105 | 2160 | atomic_long_set(&nfsi->nrequests, 0); |
---|
2106 | 2161 | atomic_long_set(&nfsi->commit_info.ncommit, 0); |
---|
2107 | 2162 | atomic_set(&nfsi->commit_info.rpcs_out, 0); |
---|
2108 | | -#ifdef CONFIG_PREEMPT_RT_BASE |
---|
2109 | | - sema_init(&nfsi->rmdir_sem, 1); |
---|
2110 | | -#else |
---|
2111 | 2163 | init_rwsem(&nfsi->rmdir_sem); |
---|
2112 | | -#endif |
---|
2113 | 2164 | mutex_init(&nfsi->commit_mutex); |
---|
2114 | 2165 | nfs4_init_once(nfsi); |
---|
| 2166 | + nfsi->cache_change_attribute = 0; |
---|
2115 | 2167 | } |
---|
2116 | 2168 | |
---|
2117 | 2169 | static int __init nfs_init_inodecache(void) |
---|
.. | .. |
---|
2179 | 2231 | |
---|
2180 | 2232 | static void nfs_net_exit(struct net *net) |
---|
2181 | 2233 | { |
---|
2182 | | - struct nfs_net *nn = net_generic(net, nfs_net_id); |
---|
2183 | | - |
---|
2184 | 2234 | nfs_fs_proc_net_exit(net); |
---|
2185 | | - nfs_cleanup_cb_ident_idr(net); |
---|
2186 | | - WARN_ON_ONCE(!list_empty(&nn->nfs_client_list)); |
---|
2187 | | - WARN_ON_ONCE(!list_empty(&nn->nfs_volume_list)); |
---|
| 2235 | + nfs_clients_exit(net); |
---|
2188 | 2236 | } |
---|
2189 | 2237 | |
---|
2190 | 2238 | static struct pernet_operations nfs_net_ops = { |
---|
.. | .. |
---|
2200 | 2248 | static int __init init_nfs_fs(void) |
---|
2201 | 2249 | { |
---|
2202 | 2250 | int err; |
---|
| 2251 | + |
---|
| 2252 | + err = nfs_sysfs_init(); |
---|
| 2253 | + if (err < 0) |
---|
| 2254 | + goto out10; |
---|
2203 | 2255 | |
---|
2204 | 2256 | err = register_pernet_subsys(&nfs_net_ops); |
---|
2205 | 2257 | if (err < 0) |
---|
.. | .. |
---|
2264 | 2316 | out8: |
---|
2265 | 2317 | unregister_pernet_subsys(&nfs_net_ops); |
---|
2266 | 2318 | out9: |
---|
| 2319 | + nfs_sysfs_exit(); |
---|
| 2320 | +out10: |
---|
2267 | 2321 | return err; |
---|
2268 | 2322 | } |
---|
2269 | 2323 | |
---|
.. | .. |
---|
2280 | 2334 | unregister_nfs_fs(); |
---|
2281 | 2335 | nfs_fs_proc_exit(); |
---|
2282 | 2336 | nfsiod_stop(); |
---|
| 2337 | + nfs_sysfs_exit(); |
---|
2283 | 2338 | } |
---|
2284 | 2339 | |
---|
2285 | 2340 | /* Not quite true; I just maintain it */ |
---|
2286 | 2341 | MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); |
---|
2287 | 2342 | MODULE_LICENSE("GPL"); |
---|
| 2343 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
---|
2288 | 2344 | module_param(enable_ino64, bool, 0644); |
---|
2289 | 2345 | |
---|
2290 | 2346 | module_init(init_nfs_fs) |
---|