| .. | .. |
|---|
| 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 | { |
|---|
| .. | .. |
|---|
| 2108 | 2163 | init_rwsem(&nfsi->rmdir_sem); |
|---|
| 2109 | 2164 | mutex_init(&nfsi->commit_mutex); |
|---|
| 2110 | 2165 | nfs4_init_once(nfsi); |
|---|
| 2166 | + nfsi->cache_change_attribute = 0; |
|---|
| 2111 | 2167 | } |
|---|
| 2112 | 2168 | |
|---|
| 2113 | 2169 | static int __init nfs_init_inodecache(void) |
|---|
| .. | .. |
|---|
| 2175 | 2231 | |
|---|
| 2176 | 2232 | static void nfs_net_exit(struct net *net) |
|---|
| 2177 | 2233 | { |
|---|
| 2178 | | - struct nfs_net *nn = net_generic(net, nfs_net_id); |
|---|
| 2179 | | - |
|---|
| 2180 | 2234 | nfs_fs_proc_net_exit(net); |
|---|
| 2181 | | - nfs_cleanup_cb_ident_idr(net); |
|---|
| 2182 | | - WARN_ON_ONCE(!list_empty(&nn->nfs_client_list)); |
|---|
| 2183 | | - WARN_ON_ONCE(!list_empty(&nn->nfs_volume_list)); |
|---|
| 2235 | + nfs_clients_exit(net); |
|---|
| 2184 | 2236 | } |
|---|
| 2185 | 2237 | |
|---|
| 2186 | 2238 | static struct pernet_operations nfs_net_ops = { |
|---|
| .. | .. |
|---|
| 2196 | 2248 | static int __init init_nfs_fs(void) |
|---|
| 2197 | 2249 | { |
|---|
| 2198 | 2250 | int err; |
|---|
| 2251 | + |
|---|
| 2252 | + err = nfs_sysfs_init(); |
|---|
| 2253 | + if (err < 0) |
|---|
| 2254 | + goto out10; |
|---|
| 2199 | 2255 | |
|---|
| 2200 | 2256 | err = register_pernet_subsys(&nfs_net_ops); |
|---|
| 2201 | 2257 | if (err < 0) |
|---|
| .. | .. |
|---|
| 2260 | 2316 | out8: |
|---|
| 2261 | 2317 | unregister_pernet_subsys(&nfs_net_ops); |
|---|
| 2262 | 2318 | out9: |
|---|
| 2319 | + nfs_sysfs_exit(); |
|---|
| 2320 | +out10: |
|---|
| 2263 | 2321 | return err; |
|---|
| 2264 | 2322 | } |
|---|
| 2265 | 2323 | |
|---|
| .. | .. |
|---|
| 2276 | 2334 | unregister_nfs_fs(); |
|---|
| 2277 | 2335 | nfs_fs_proc_exit(); |
|---|
| 2278 | 2336 | nfsiod_stop(); |
|---|
| 2337 | + nfs_sysfs_exit(); |
|---|
| 2279 | 2338 | } |
|---|
| 2280 | 2339 | |
|---|
| 2281 | 2340 | /* Not quite true; I just maintain it */ |
|---|
| 2282 | 2341 | MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); |
|---|
| 2283 | 2342 | MODULE_LICENSE("GPL"); |
|---|
| 2343 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 2284 | 2344 | module_param(enable_ino64, bool, 0644); |
|---|
| 2285 | 2345 | |
|---|
| 2286 | 2346 | module_init(init_nfs_fs) |
|---|