NFS client bugfixes for Linux 4.10
Bugfixes: - Fix invalid fget()/fput() calls when doing file locking - Fix multiple directory cache invalidation issues due to the client failing to recognise that the directory wasn't changed. - Fix client recovery when server reboots multiple times -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJYfSXZAAoJEGcL54qWCgDy3K8P/0YGi1J5VoWkcMD5+Ljh2H3O AV1oZ3EWLXH2jlJZmX7A1A9ReOEmsYmCX+8QM2ZWbBZI+vIzEJEWd7fU+nhtgfiq pcw29CSpeBhfcqSswlRE6ouxKpmufnzhwbuGcy9WUTyGYaz1k05/4YHTunyxiZr6 QRHL2Y0YkU0cWD1FHwoOkQr8ft7kdQ4iXHru9utttdYsb4vJnX9ShLpaLW5MDBqS hPd1ivJHPlWiOVEzLSlTHBvTvw8j5PjhsRQ/q5UwiDvQQDoWL7/qnP4nxZee44mh MQ+61/0WxS+ohMkIYrZ6hPezk2QX/i7JRQvBPNU07U/+TqtsWX/F5+OerCeQ4/6W RhP7XDjJV8TpeeJcUU58r1aoEpaWRt9cmtwBWMKBu9tTHCFyRXHsaIh1ZR+Hy85e HUiiaD4rPldr+ZbCcTwR5bSSkF96WaRF9B3L8Nvgys9v4wwO6LuTnHv5uY8H7ct5 I66nL14drrA+jC01D+SuMl0AnFhrCp7mJyJbrZDvXBJ9hxzzgEj/Jz3IC0mc0SxI ZjFhQoG2NjV2oJ0PTu9RMUw+Fex0yz6PsXoHLKr45VXkkwQL3Uldq6SVWfkkzqUk SPFTYD49i9TqCHhGZEzm7kGNM6ASUDKQtAloiUA2QvL6v178RLwG2sjYxy2kEApz s208kzh8He79iMLEkphR =K8F7 -----END PGP SIGNATURE----- Merge tag 'nfs-for-4.10-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs Pull NFS client bugfixes from Trond Myklebust: - fix invalid fget()/fput() calls when doing file locking - fix multiple directory cache invalidation issues due to the client failing to recognise that the directory wasn't changed - fix client recovery when server reboots multiple times * tag 'nfs-for-4.10-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: NFSv4: Fix client recovery when server reboots multiple times NFSv4: update_changeattr should update the attribute timestamp NFSv4: Don't call update_changeattr() unless the unlink is successful NFSv4: Don't apply change_info4 twice on rename within a directory NFSv4: Call update_changeattr() from _nfs4_proc_open only if a file was created nfs: Don't take a reference on fl->fl_file for LOCK operation
This commit is contained in:
commit
5cf7a0f344
@ -38,7 +38,6 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/printk.h>
|
||||
@ -1083,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);
|
||||
|
||||
@ -1099,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);
|
||||
@ -2391,11 +2392,13 @@ 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,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -4125,7 +4129,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, res->dir_attr->time_start);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -4159,8 +4164,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, res->old_fattr->time_start);
|
||||
if (new_dir != old_dir)
|
||||
update_changeattr(new_dir, &res->new_cinfo, res->new_fattr->time_start);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -4197,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);
|
||||
@ -4272,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;
|
||||
@ -6127,7 +6136,6 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
|
||||
p->server = server;
|
||||
atomic_inc(&lsp->ls_count);
|
||||
p->ctx = get_nfs_open_context(ctx);
|
||||
get_file(fl->fl_file);
|
||||
memcpy(&p->fl, fl, sizeof(p->fl));
|
||||
return p;
|
||||
out_free_seqid:
|
||||
@ -6240,7 +6248,6 @@ static void nfs4_lock_release(void *calldata)
|
||||
nfs_free_seqid(data->arg.lock_seqid);
|
||||
nfs4_put_lock_state(data->lsp);
|
||||
put_nfs_open_context(data->ctx);
|
||||
fput(data->fl.fl_file);
|
||||
kfree(data);
|
||||
dprintk("%s: done!\n", __func__);
|
||||
}
|
||||
|
@ -1729,7 +1729,6 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
|
||||
break;
|
||||
case -NFS4ERR_STALE_CLIENTID:
|
||||
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
|
||||
nfs4_state_clear_reclaim_reboot(clp);
|
||||
nfs4_state_start_reclaim_reboot(clp);
|
||||
break;
|
||||
case -NFS4ERR_EXPIRED:
|
||||
|
Loading…
Reference in New Issue
Block a user