From 1ad13dbc85911fcf15232342205c92e250335267 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 27 Oct 2016 18:42:04 -0400 Subject: NFSv4: Optimise away forced revalidation when we know the attributes are OK The NFS_INO_REVAL_FORCED flag needs to be set if we just got a delegation, and we see that there might still be some ambiguity as to whether or not our attribute or data cache are valid. In practice, this means that a call to nfs_check_inode_attributes() will have noticed a discrepancy between cached attributes and measured ones, so let's move the setting of NFS_INO_REVAL_FORCED to there. Signed-off-by: Trond Myklebust --- fs/nfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/nfs/inode.c') diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index bf4ec5ecc97e..3575e3408bd7 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1317,7 +1317,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat invalid |= NFS_INO_INVALID_ATIME; if (invalid != 0) - nfs_set_cache_invalid(inode, invalid); + nfs_set_cache_invalid(inode, invalid | NFS_INO_REVAL_FORCED); nfsi->read_cache_jiffies = fattr->time_start; return 0; -- cgit v1.2.3 From b184b5c38e4640585126e44ef84f2dbdd0d23d5a Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 13 Oct 2016 15:26:47 +1100 Subject: NFS: remove l_pid field from nfs_lockowner this field is not used in any important way and probably should have been removed by Commit: 8003d3c4aaa5 ("nfs4: treat lock owners as opaque values") which removed the pid argument from nfs4_get_lock_state. Except in unusual and uninteresting cases, two threads with the same ->tgid will have the same ->files pointer, so keeping them both for comparison brings no benefit. Acked-by: Jeff Layton Signed-off-by: NeilBrown Reviewed-by: Jeff Layton Signed-off-by: Trond Myklebust --- fs/nfs/inode.c | 3 --- fs/nfs/nfs4proc.c | 1 - fs/nfs/pagelist.c | 3 +-- fs/nfs/write.c | 3 +-- include/linux/nfs_fs.h | 1 - 5 files changed, 2 insertions(+), 9 deletions(-) (limited to 'fs/nfs/inode.c') diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 3575e3408bd7..fd9913249713 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -703,7 +703,6 @@ static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) { atomic_set(&l_ctx->count, 1); l_ctx->lockowner.l_owner = current->files; - l_ctx->lockowner.l_pid = current->tgid; INIT_LIST_HEAD(&l_ctx->list); atomic_set(&l_ctx->io_count, 0); } @@ -716,8 +715,6 @@ static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context do { if (pos->lockowner.l_owner != current->files) continue; - if (pos->lockowner.l_pid != current->tgid) - continue; atomic_inc(&pos->count); return pos; } while ((pos = list_entry(pos->list.next, typeof(*pos), list)) != head); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 5593b088c561..0d108f13ef16 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2947,7 +2947,6 @@ static int _nfs4_do_setattr(struct inode *inode, } else if (truncate && state != NULL) { struct nfs_lockowner lockowner = { .l_owner = current->files, - .l_pid = current->tgid, }; if (!nfs4_valid_open_stateid(state)) return -EBADF; diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 965db474f4b0..161f8b13bbaa 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -867,8 +867,7 @@ static void nfs_pageio_cleanup_mirroring(struct nfs_pageio_descriptor *pgio) static bool nfs_match_lock_context(const struct nfs_lock_context *l1, const struct nfs_lock_context *l2) { - return l1->lockowner.l_owner == l2->lockowner.l_owner - && l1->lockowner.l_pid == l2->lockowner.l_pid; + return l1->lockowner.l_owner == l2->lockowner.l_owner; } /** diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 53211838f72a..4d5897e6d6cb 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1151,8 +1151,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page) if (l_ctx && flctx && !(list_empty_careful(&flctx->flc_posix) && list_empty_careful(&flctx->flc_flock))) { - do_flush |= l_ctx->lockowner.l_owner != current->files - || l_ctx->lockowner.l_pid != current->tgid; + do_flush |= l_ctx->lockowner.l_owner != current->files; } nfs_release_request(req); if (!do_flush) diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 810124b33327..bf8a713c45b4 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -57,7 +57,6 @@ struct nfs_access_entry { struct nfs_lockowner { fl_owner_t l_owner; - pid_t l_pid; }; struct nfs_lock_context { -- cgit v1.2.3 From 532d4def2f95623a9b8b2cef7723e14521377911 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 13 Oct 2016 15:26:47 +1100 Subject: NFSv4: add flock_owner to open context An open file description (struct file) in a given process can be associated with two different lock owners. It can have a Posix lock owner which will be different in each process that has a fd on the file. It can have a Flock owner which will be the same in all processes. When searching for a lock stateid to use, we need to consider both of these owners So add a new "flock_owner" to the "nfs_open_context" (of which there is one for each open file description). This flock_owner does not need to be reference-counted as there is a 1-1 relation between 'struct file' and nfs open contexts, and it will never be part of a list of contexts. So there is no need for a 'flock_context' - just the owner is enough. The io_count included in the (Posix) lock_context provides no guarantee that all read-aheads that could use the state have completed, so not supporting it for flock locks in not a serious problem. Synchronization between flock and read-ahead can be added later if needed. When creating an open_context for a non-openning create call, we don't have a 'struct file' to pass in, so the lock context gets initialized with a NULL owner, but this will never be used. The flock_owner is not used at all in this patch, that will come later. Acked-by: Jeff Layton Signed-off-by: NeilBrown Reviewed-by: Jeff Layton Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 6 +++--- fs/nfs/inode.c | 7 +++++-- fs/nfs/nfs4file.c | 2 +- fs/nfs/nfs4proc.c | 2 +- include/linux/nfs_fs.h | 3 ++- 5 files changed, 12 insertions(+), 8 deletions(-) (limited to 'fs/nfs/inode.c') diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 5f1af4cd1a33..f1ecfcc632eb 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1467,9 +1467,9 @@ static fmode_t flags_to_mode(int flags) return res; } -static struct nfs_open_context *create_nfs_open_context(struct dentry *dentry, int open_flags) +static struct nfs_open_context *create_nfs_open_context(struct dentry *dentry, int open_flags, struct file *filp) { - return alloc_nfs_open_context(dentry, flags_to_mode(open_flags)); + return alloc_nfs_open_context(dentry, flags_to_mode(open_flags), filp); } static int do_open(struct inode *inode, struct file *filp) @@ -1554,7 +1554,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, return finish_no_open(file, dentry); } - ctx = create_nfs_open_context(dentry, open_flags); + ctx = create_nfs_open_context(dentry, open_flags, file); err = PTR_ERR(ctx); if (IS_ERR(ctx)) goto out; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index fd9913249713..3a7601fe9dee 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -796,7 +796,9 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync) } EXPORT_SYMBOL_GPL(nfs_close_context); -struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode) +struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, + fmode_t f_mode, + struct file *filp) { struct nfs_open_context *ctx; struct rpc_cred *cred = rpc_lookup_cred(); @@ -815,6 +817,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f ctx->mode = f_mode; ctx->flags = 0; ctx->error = 0; + ctx->flock_owner = (fl_owner_t)filp; nfs_init_lock_context(&ctx->lock_context); ctx->lock_context.open_context = ctx; INIT_LIST_HEAD(&ctx->list); @@ -939,7 +942,7 @@ int nfs_open(struct inode *inode, struct file *filp) { struct nfs_open_context *ctx; - ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode); + ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode, filp); if (IS_ERR(ctx)) return PTR_ERR(ctx); nfs_file_set_open_context(filp, ctx); diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 89a77950e0b0..0efba77789b9 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -57,7 +57,7 @@ nfs4_file_open(struct inode *inode, struct file *filp) parent = dget_parent(dentry); dir = d_inode(parent); - ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode); + ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode, filp); err = PTR_ERR(ctx); if (IS_ERR(ctx)) goto out; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0d108f13ef16..68a75bf431f8 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4008,7 +4008,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, struct nfs4_state *state; int status = 0; - ctx = alloc_nfs_open_context(dentry, FMODE_READ); + ctx = alloc_nfs_open_context(dentry, FMODE_READ, NULL); if (IS_ERR(ctx)) return PTR_ERR(ctx); diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index bf8a713c45b4..0adb02c4744d 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -70,6 +70,7 @@ struct nfs_lock_context { struct nfs4_state; struct nfs_open_context { struct nfs_lock_context lock_context; + fl_owner_t flock_owner; struct dentry *dentry; struct rpc_cred *cred; struct nfs4_state *state; @@ -357,7 +358,7 @@ extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx); extern void put_nfs_open_context(struct nfs_open_context *ctx); extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode); -extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode); +extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode, struct file *filp); extern void nfs_inode_attach_open_context(struct nfs_open_context *ctx); extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx); extern void nfs_file_clear_open_context(struct file *flip); -- cgit v1.2.3 From d51fdb87a611f8ef50518df7187173ae10469fd0 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 13 Oct 2016 15:26:47 +1100 Subject: NFS: discard nfs_lockowner structure. It now has only one field and is only used in one structure. So replaced it in that structure by the field it contains. Signed-off-by: NeilBrown Reviewed-by: Jeff Layton Signed-off-by: Trond Myklebust --- fs/nfs/inode.c | 4 ++-- fs/nfs/nfs4state.c | 2 +- fs/nfs/pagelist.c | 2 +- fs/nfs/write.c | 2 +- include/linux/nfs_fs.h | 6 +----- 5 files changed, 6 insertions(+), 10 deletions(-) (limited to 'fs/nfs/inode.c') diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 3a7601fe9dee..d79e0bac836e 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -702,7 +702,7 @@ EXPORT_SYMBOL_GPL(nfs_getattr); static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) { atomic_set(&l_ctx->count, 1); - l_ctx->lockowner.l_owner = current->files; + l_ctx->lockowner = current->files; INIT_LIST_HEAD(&l_ctx->list); atomic_set(&l_ctx->io_count, 0); } @@ -713,7 +713,7 @@ static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context struct nfs_lock_context *pos = head; do { - if (pos->lockowner.l_owner != current->files) + if (pos->lockowner != current->files) continue; atomic_inc(&pos->count); return pos; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 4f1de9be10c6..26b6b8b0cae3 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -953,7 +953,7 @@ static int nfs4_copy_lock_stateid(nfs4_stateid *dst, if (test_bit(LK_STATE_IN_USE, &state->flags) == 0) goto out; - fl_owner = l_ctx->lockowner.l_owner; + fl_owner = l_ctx->lockowner; fl_flock_owner = l_ctx->open_context->flock_owner; spin_lock(&state->state_lock); diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 161f8b13bbaa..6e629b856a00 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -867,7 +867,7 @@ static void nfs_pageio_cleanup_mirroring(struct nfs_pageio_descriptor *pgio) static bool nfs_match_lock_context(const struct nfs_lock_context *l1, const struct nfs_lock_context *l2) { - return l1->lockowner.l_owner == l2->lockowner.l_owner; + return l1->lockowner == l2->lockowner; } /** diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 4d5897e6d6cb..6e761f3f4cbf 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1151,7 +1151,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page) if (l_ctx && flctx && !(list_empty_careful(&flctx->flc_posix) && list_empty_careful(&flctx->flc_flock))) { - do_flush |= l_ctx->lockowner.l_owner != current->files; + do_flush |= l_ctx->lockowner != current->files; } nfs_release_request(req); if (!do_flush) diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 0adb02c4744d..db1002abc95e 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -55,15 +55,11 @@ struct nfs_access_entry { struct rcu_head rcu_head; }; -struct nfs_lockowner { - fl_owner_t l_owner; -}; - struct nfs_lock_context { atomic_t count; struct list_head list; struct nfs_open_context *open_context; - struct nfs_lockowner lockowner; + fl_owner_t lockowner; atomic_t io_count; }; -- cgit v1.2.3 From 1bcf4c5c597d1b1862cf54e65198f1c9e3cad29c Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 2 Dec 2016 09:15:37 -0500 Subject: NFS: Allow getattr to also report readdirplus cache hits If the use called stat() on an 'ls -l' workload, and the attribute cache was successfully revalidate by READDIRPLUS, then we want to report that back so that the readdir code continues to use readdirplus. Reviewed-by: Benjamin Coddington Tested-by: Benjamin Coddington Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 1 - fs/nfs/inode.c | 21 +++++++++++++++++---- fs/nfs/internal.h | 1 + 3 files changed, 18 insertions(+), 5 deletions(-) (limited to 'fs/nfs/inode.c') diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 22835150579a..f5702457c052 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -459,7 +459,6 @@ bool nfs_use_readdirplus(struct inode *dir, struct dir_context *ctx) * use of readdirplus to accelerate any future lookups in the same * directory. */ -static void nfs_advise_use_readdirplus(struct inode *dir) { struct nfs_inode *nfsi = NFS_I(dir); diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index d79e0bac836e..75f5a9cb2e66 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -634,15 +634,28 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, } EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); -static void nfs_request_parent_use_readdirplus(struct dentry *dentry) +static void nfs_readdirplus_parent_cache_miss(struct dentry *dentry) { struct dentry *parent; + if (!nfs_server_capable(d_inode(dentry), NFS_CAP_READDIRPLUS)) + return; parent = dget_parent(dentry); nfs_force_use_readdirplus(d_inode(parent)); dput(parent); } +static void nfs_readdirplus_parent_cache_hit(struct dentry *dentry) +{ + struct dentry *parent; + + if (!nfs_server_capable(d_inode(dentry), NFS_CAP_READDIRPLUS)) + return; + parent = dget_parent(dentry); + nfs_advise_use_readdirplus(d_inode(parent)); + dput(parent); +} + static bool nfs_need_revalidate_inode(struct inode *inode) { if (NFS_I(inode)->cache_validity & @@ -683,10 +696,10 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) if (need_atime || nfs_need_revalidate_inode(inode)) { struct nfs_server *server = NFS_SERVER(inode); - if (server->caps & NFS_CAP_READDIRPLUS) - nfs_request_parent_use_readdirplus(dentry); + nfs_readdirplus_parent_cache_miss(dentry); err = __nfs_revalidate_inode(server, inode); - } + } else + nfs_readdirplus_parent_cache_hit(dentry); if (!err) { generic_fillattr(inode, stat); stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode)); diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 4622d5f18e35..6b79c2ca9b9a 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -344,6 +344,7 @@ extern struct nfs_client *nfs_init_client(struct nfs_client *clp, const struct nfs_client_initdata *); /* dir.c */ +extern void nfs_advise_use_readdirplus(struct inode *dir); extern void nfs_force_use_readdirplus(struct inode *dir); extern unsigned long nfs_access_cache_count(struct shrinker *shrink, struct shrink_control *sc); -- cgit v1.2.3 From 10727772b93cc80c859b2e45bb32976d79b21990 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 4 Dec 2016 16:02:43 -0500 Subject: NFS: Fix incorrect mapping revalidation when holding a delegation We should only care about checking the attributes if the page cache is marked as dubious (using NFS_INO_REVAL_PAGECACHE) and the NFS_INO_REVAL_FORCED flag is set. Signed-off-by: Trond Myklebust --- fs/nfs/inode.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'fs/nfs/inode.c') diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 75f5a9cb2e66..df4d7ec348ed 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1114,9 +1114,15 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map static bool nfs_mapping_need_revalidate_inode(struct inode *inode) { - if (nfs_have_delegated_attributes(inode)) - return false; - return (NFS_I(inode)->cache_validity & NFS_INO_REVAL_PAGECACHE) + unsigned long cache_validity = NFS_I(inode)->cache_validity; + + if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) { + const unsigned long force_reval = + NFS_INO_REVAL_PAGECACHE|NFS_INO_REVAL_FORCED; + return (cache_validity & force_reval) == force_reval; + } + + return (cache_validity & NFS_INO_REVAL_PAGECACHE) || nfs_attribute_timeout(inode) || NFS_STALE(inode); } -- cgit v1.2.3 From 1cd9cb05f96e526f41bb4704caa95dc40ed08c5d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 4 Dec 2016 18:34:34 -0500 Subject: NFS: Only look at the change attribute cache state in nfs_check_verifier When looking at whether or not our dcache is valid, we really don't care about the general state of the directory attribute cache. Instead, we we only care about the state of the change attribute. This fixes a performance issue when the client is responsible for changing the directory contents; a number of NFSv4 operations will atomically update the directory change attribute, but may not return all the other attributes. Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 14 ++++++-------- fs/nfs/inode.c | 2 +- include/linux/nfs_fs.h | 1 + 3 files changed, 8 insertions(+), 9 deletions(-) (limited to 'fs/nfs/inode.c') diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index f5702457c052..7483722162fa 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1030,8 +1030,6 @@ EXPORT_SYMBOL_GPL(nfs_force_lookup_revalidate); static int nfs_check_verifier(struct inode *dir, struct dentry *dentry, int rcu_walk) { - int ret; - if (IS_ROOT(dentry)) return 1; if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONE) @@ -1039,12 +1037,12 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry, if (!nfs_verify_change_attribute(dir, dentry->d_time)) return 0; /* Revalidate nfsi->cache_change_attribute before we declare a match */ - if (rcu_walk) - ret = nfs_revalidate_inode_rcu(NFS_SERVER(dir), dir); - else - ret = nfs_revalidate_inode(NFS_SERVER(dir), dir); - if (ret < 0) - return 0; + if (nfs_mapping_need_revalidate_inode(dir)) { + if (rcu_walk) + return 0; + if (__nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0) + return 0; + } if (!nfs_verify_change_attribute(dir, dentry->d_time)) return 0; return 1; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index df4d7ec348ed..7de345fd8e1e 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1112,7 +1112,7 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map return 0; } -static bool nfs_mapping_need_revalidate_inode(struct inode *inode) +bool nfs_mapping_need_revalidate_inode(struct inode *inode) { unsigned long cache_validity = NFS_I(inode)->cache_validity; diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index db1002abc95e..cb631973839a 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -345,6 +345,7 @@ extern int nfs_attribute_cache_expired(struct inode *inode); extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode); extern int nfs_revalidate_inode_rcu(struct nfs_server *server, struct inode *inode); extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); +extern bool nfs_mapping_need_revalidate_inode(struct inode *inode); extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); extern int nfs_revalidate_mapping_rcu(struct inode *inode); extern int nfs_setattr(struct dentry *, struct iattr *); -- cgit v1.2.3