aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/delegation.c19
-rw-r--r--fs/nfs/delegation.h1
-rw-r--r--fs/nfs/nfs4proc.c27
3 files changed, 33 insertions, 14 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index c6f07c1c71e6..d3be923d4e43 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -421,3 +421,22 @@ void nfs_delegation_reap_unclaimed(struct nfs4_client *clp)
421 nfs_free_delegation(delegation); 421 nfs_free_delegation(delegation);
422 } 422 }
423} 423}
424
425int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
426{
427 struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state;
428 struct nfs_inode *nfsi = NFS_I(inode);
429 struct nfs_delegation *delegation;
430 int res = 0;
431
432 if (nfsi->delegation_state == 0)
433 return 0;
434 spin_lock(&clp->cl_lock);
435 delegation = nfsi->delegation;
436 if (delegation != NULL) {
437 memcpy(dst->data, delegation->stateid.data, sizeof(dst->data));
438 res = 1;
439 }
440 spin_unlock(&clp->cl_lock);
441 return res;
442}
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 7a0b2bfce771..3858694652fa 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -41,6 +41,7 @@ void nfs_delegation_reap_unclaimed(struct nfs4_client *clp);
41int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid); 41int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid);
42int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state); 42int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state);
43int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl); 43int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl);
44int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode);
44 45
45static inline int nfs_have_delegation(struct inode *inode, int flags) 46static inline int nfs_have_delegation(struct inode *inode, int flags)
46{ 47{
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index bad1eae5608a..62aed077fc2a 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1018,12 +1018,12 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry,
1018 return res; 1018 return res;
1019} 1019}
1020 1020
1021static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr, 1021static int _nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr,
1022 struct nfs_fh *fhandle, struct iattr *sattr, 1022 struct iattr *sattr, struct nfs4_state *state)
1023 struct nfs4_state *state)
1024{ 1023{
1024 struct nfs_server *server = NFS_SERVER(inode);
1025 struct nfs_setattrargs arg = { 1025 struct nfs_setattrargs arg = {
1026 .fh = fhandle, 1026 .fh = NFS_FH(inode),
1027 .iap = sattr, 1027 .iap = sattr,
1028 .server = server, 1028 .server = server,
1029 .bitmask = server->attr_bitmask, 1029 .bitmask = server->attr_bitmask,
@@ -1042,7 +1042,9 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr,
1042 1042
1043 nfs_fattr_init(fattr); 1043 nfs_fattr_init(fattr);
1044 1044
1045 if (state != NULL) { 1045 if (nfs4_copy_delegation_stateid(&arg.stateid, inode)) {
1046 /* Use that stateid */
1047 } else if (state != NULL) {
1046 msg.rpc_cred = state->owner->so_cred; 1048 msg.rpc_cred = state->owner->so_cred;
1047 nfs4_copy_stateid(&arg.stateid, state, current->files); 1049 nfs4_copy_stateid(&arg.stateid, state, current->files);
1048 } else 1050 } else
@@ -1054,16 +1056,15 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr,
1054 return status; 1056 return status;
1055} 1057}
1056 1058
1057static int nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr, 1059static int nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr,
1058 struct nfs_fh *fhandle, struct iattr *sattr, 1060 struct iattr *sattr, struct nfs4_state *state)
1059 struct nfs4_state *state)
1060{ 1061{
1062 struct nfs_server *server = NFS_SERVER(inode);
1061 struct nfs4_exception exception = { }; 1063 struct nfs4_exception exception = { };
1062 int err; 1064 int err;
1063 do { 1065 do {
1064 err = nfs4_handle_exception(server, 1066 err = nfs4_handle_exception(server,
1065 _nfs4_do_setattr(server, fattr, fhandle, sattr, 1067 _nfs4_do_setattr(inode, fattr, sattr, state),
1066 state),
1067 &exception); 1068 &exception);
1068 } while (exception.retry); 1069 } while (exception.retry);
1069 return err; 1070 return err;
@@ -1504,8 +1505,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
1504 if (ctx != NULL) 1505 if (ctx != NULL)
1505 state = ctx->state; 1506 state = ctx->state;
1506 1507
1507 status = nfs4_do_setattr(NFS_SERVER(inode), fattr, 1508 status = nfs4_do_setattr(inode, fattr, sattr, state);
1508 NFS_FH(inode), sattr, state);
1509 if (status == 0) 1509 if (status == 0)
1510 nfs_setattr_update_inode(inode, sattr); 1510 nfs_setattr_update_inode(inode, sattr);
1511 if (ctx != NULL) 1511 if (ctx != NULL)
@@ -1824,8 +1824,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
1824 d_instantiate(dentry, igrab(state->inode)); 1824 d_instantiate(dentry, igrab(state->inode));
1825 if (flags & O_EXCL) { 1825 if (flags & O_EXCL) {
1826 struct nfs_fattr fattr; 1826 struct nfs_fattr fattr;
1827 status = nfs4_do_setattr(NFS_SERVER(dir), &fattr, 1827 status = nfs4_do_setattr(state->inode, &fattr, sattr, state);
1828 NFS_FH(state->inode), sattr, state);
1829 if (status == 0) 1828 if (status == 0)
1830 nfs_setattr_update_inode(state->inode, sattr); 1829 nfs_setattr_update_inode(state->inode, sattr);
1831 } 1830 }