* [PATCH v2 0/4] Fix update_changeattr
@ 2017-01-12 23:02 Trond Myklebust
2017-01-12 23:02 ` [PATCH v2 1/4] NFSv4: Call update_changeattr() from _nfs4_proc_open only if a file was created Trond Myklebust
0 siblings, 1 reply; 5+ messages in thread
From: Trond Myklebust @ 2017-01-12 23:02 UTC (permalink / raw)
To: linux-nfs
Several of the calls to update_changeattr() are causing the directory
attribute cache to be flushed in cases where it simply isn't neccessary.
---
v2: add patch to update the directory attribute cache timestamp
Trond Myklebust (4):
NFSv4: Call update_changeattr() from _nfs4_proc_open only if a file
was created
NFSv4: Don't apply change_info4 twice on rename within a directory
NFSv4: Don't call update_changeattr() unless the unlink is successful
NFSv4: update_changeattr should update the attribute timestamp
fs/nfs/nfs4proc.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
--
2.9.3
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v2 1/4] NFSv4: Call update_changeattr() from _nfs4_proc_open only if a file was created 2017-01-12 23:02 [PATCH v2 0/4] Fix update_changeattr Trond Myklebust @ 2017-01-12 23:02 ` Trond Myklebust 2017-01-12 23:02 ` [PATCH v2 2/4] NFSv4: Don't apply change_info4 twice on rename within a directory Trond Myklebust 0 siblings, 1 reply; 5+ messages in thread From: Trond Myklebust @ 2017-01-12 23:02 UTC (permalink / raw) To: linux-nfs We don't want to invalidate the directory attribute and data cache unless we know that a file was created, or the change attribute differs from the one in our cache. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> --- fs/nfs/nfs4proc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 700ed1fc1075..4010c33151ad 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2390,11 +2390,12 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) nfs_fattr_map_and_free_names(server, &data->f_attr); if (o_arg->open_flags & O_CREAT) { - update_changeattr(dir, &o_res->cinfo); if (o_arg->open_flags & O_EXCL) data->file_created = 1; else if (o_res->cinfo.before != o_res->cinfo.after) data->file_created = 1; + if (data->file_created || dir->i_version != o_res->cinfo.after) + update_changeattr(dir, &o_res->cinfo); } if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0) server->caps &= ~NFS_CAP_POSIX_LOCK; -- 2.9.3 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/4] NFSv4: Don't apply change_info4 twice on rename within a directory 2017-01-12 23:02 ` [PATCH v2 1/4] NFSv4: Call update_changeattr() from _nfs4_proc_open only if a file was created Trond Myklebust @ 2017-01-12 23:02 ` Trond Myklebust 2017-01-12 23:02 ` [PATCH v2 3/4] NFSv4: Don't call update_changeattr() unless the unlink is successful Trond Myklebust 0 siblings, 1 reply; 5+ messages in thread From: Trond Myklebust @ 2017-01-12 23:02 UTC (permalink / raw) To: linux-nfs If a file is renamed, but stays in the same directory, we will still receive 2 change_info4 structures describing the change to that directory, but we only want to apply it once. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> --- fs/nfs/nfs4proc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4010c33151ad..1e797bf74aaf 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4159,8 +4159,11 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir, if (nfs4_async_handle_error(task, res->server, NULL, &data->timeout) == -EAGAIN) return 0; - update_changeattr(old_dir, &res->old_cinfo); - update_changeattr(new_dir, &res->new_cinfo); + if (task->tk_status == 0) { + update_changeattr(old_dir, &res->old_cinfo); + if (new_dir != old_dir) + update_changeattr(new_dir, &res->new_cinfo); + } return 1; } -- 2.9.3 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 3/4] NFSv4: Don't call update_changeattr() unless the unlink is successful 2017-01-12 23:02 ` [PATCH v2 2/4] NFSv4: Don't apply change_info4 twice on rename within a directory Trond Myklebust @ 2017-01-12 23:02 ` Trond Myklebust 2017-01-12 23:02 ` [PATCH v2 4/4] NFSv4: update_changeattr should update the attribute timestamp Trond Myklebust 0 siblings, 1 reply; 5+ messages in thread From: Trond Myklebust @ 2017-01-12 23:02 UTC (permalink / raw) To: linux-nfs If the unlink wasn't successful, then the directory has presumably not changed. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> --- fs/nfs/nfs4proc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1e797bf74aaf..6a35204affa4 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4125,7 +4125,8 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) if (nfs4_async_handle_error(task, res->server, NULL, &data->timeout) == -EAGAIN) return 0; - update_changeattr(dir, &res->cinfo); + if (task->tk_status == 0) + update_changeattr(dir, &res->cinfo); return 1; } -- 2.9.3 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 4/4] NFSv4: update_changeattr should update the attribute timestamp 2017-01-12 23:02 ` [PATCH v2 3/4] NFSv4: Don't call update_changeattr() unless the unlink is successful Trond Myklebust @ 2017-01-12 23:02 ` Trond Myklebust 0 siblings, 0 replies; 5+ messages in thread From: Trond Myklebust @ 2017-01-12 23:02 UTC (permalink / raw) To: linux-nfs Otherwise, the attribute cache remains marked as being expired. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> --- fs/nfs/nfs4proc.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6a35204affa4..ecc151697fd4 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1082,7 +1082,8 @@ int nfs4_call_sync(struct rpc_clnt *clnt, return nfs4_call_sync_sequence(clnt, server, msg, args, res); } -static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) +static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo, + unsigned long timestamp) { struct nfs_inode *nfsi = NFS_I(dir); @@ -1098,6 +1099,7 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) NFS_INO_INVALID_ACL; } dir->i_version = cinfo->after; + nfsi->read_cache_jiffies = timestamp; nfsi->attr_gencount = nfs_inc_attr_generation_counter(); nfs_fscache_invalidate(dir); spin_unlock(&dir->i_lock); @@ -2395,7 +2397,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) else if (o_res->cinfo.before != o_res->cinfo.after) data->file_created = 1; if (data->file_created || dir->i_version != o_res->cinfo.after) - update_changeattr(dir, &o_res->cinfo); + update_changeattr(dir, &o_res->cinfo, + o_res->f_attr->time_start); } if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0) server->caps &= ~NFS_CAP_POSIX_LOCK; @@ -4073,11 +4076,12 @@ static int _nfs4_proc_remove(struct inode *dir, const struct qstr *name) .rpc_argp = &args, .rpc_resp = &res, }; + unsigned long timestamp = jiffies; int status; status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 1); if (status == 0) - update_changeattr(dir, &res.cinfo); + update_changeattr(dir, &res.cinfo, timestamp); return status; } @@ -4126,7 +4130,7 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) &data->timeout) == -EAGAIN) return 0; if (task->tk_status == 0) - update_changeattr(dir, &res->cinfo); + update_changeattr(dir, &res->cinfo, res->dir_attr->time_start); return 1; } @@ -4161,9 +4165,9 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir, return 0; if (task->tk_status == 0) { - update_changeattr(old_dir, &res->old_cinfo); + update_changeattr(old_dir, &res->old_cinfo, res->old_fattr->time_start); if (new_dir != old_dir) - update_changeattr(new_dir, &res->new_cinfo); + update_changeattr(new_dir, &res->new_cinfo, res->new_fattr->time_start); } return 1; } @@ -4201,7 +4205,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); if (!status) { - update_changeattr(dir, &res.cinfo); + update_changeattr(dir, &res.cinfo, res.fattr->time_start); status = nfs_post_op_update_inode(inode, res.fattr); if (!status) nfs_setsecurity(inode, res.fattr, res.label); @@ -4276,7 +4280,8 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_ int status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &data->msg, &data->arg.seq_args, &data->res.seq_res, 1); if (status == 0) { - update_changeattr(dir, &data->res.dir_cinfo); + update_changeattr(dir, &data->res.dir_cinfo, + data->res.fattr->time_start); status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, data->res.label); } return status; -- 2.9.3 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-01-12 23:02 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-01-12 23:02 [PATCH v2 0/4] Fix update_changeattr Trond Myklebust 2017-01-12 23:02 ` [PATCH v2 1/4] NFSv4: Call update_changeattr() from _nfs4_proc_open only if a file was created Trond Myklebust 2017-01-12 23:02 ` [PATCH v2 2/4] NFSv4: Don't apply change_info4 twice on rename within a directory Trond Myklebust 2017-01-12 23:02 ` [PATCH v2 3/4] NFSv4: Don't call update_changeattr() unless the unlink is successful Trond Myklebust 2017-01-12 23:02 ` [PATCH v2 4/4] NFSv4: update_changeattr should update the attribute timestamp Trond Myklebust
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).