aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/delegation.c38
-rw-r--r--fs/nfs/delegation.h1
-rw-r--r--fs/nfs/nfs4proc.c18
3 files changed, 55 insertions, 2 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 44135af9894c..3976c177a7d0 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -31,11 +31,42 @@ static void nfs_free_delegation(struct nfs_delegation *delegation)
31 kfree(delegation); 31 kfree(delegation);
32} 32}
33 33
34static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
35{
36 struct inode *inode = state->inode;
37 struct file_lock *fl;
38 int status;
39
40 for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) {
41 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
42 continue;
43 if ((struct nfs_open_context *)fl->fl_file->private_data != ctx)
44 continue;
45 status = nfs4_lock_delegation_recall(state, fl);
46 if (status >= 0)
47 continue;
48 switch (status) {
49 default:
50 printk(KERN_ERR "%s: unhandled error %d.\n",
51 __FUNCTION__, status);
52 case -NFS4ERR_EXPIRED:
53 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
54 case -NFS4ERR_STALE_CLIENTID:
55 nfs4_schedule_state_recovery(NFS_SERVER(inode)->nfs4_state);
56 goto out_err;
57 }
58 }
59 return 0;
60out_err:
61 return status;
62}
63
34static void nfs_delegation_claim_opens(struct inode *inode) 64static void nfs_delegation_claim_opens(struct inode *inode)
35{ 65{
36 struct nfs_inode *nfsi = NFS_I(inode); 66 struct nfs_inode *nfsi = NFS_I(inode);
37 struct nfs_open_context *ctx; 67 struct nfs_open_context *ctx;
38 struct nfs4_state *state; 68 struct nfs4_state *state;
69 int err;
39 70
40again: 71again:
41 spin_lock(&inode->i_lock); 72 spin_lock(&inode->i_lock);
@@ -47,9 +78,12 @@ again:
47 continue; 78 continue;
48 get_nfs_open_context(ctx); 79 get_nfs_open_context(ctx);
49 spin_unlock(&inode->i_lock); 80 spin_unlock(&inode->i_lock);
50 if (nfs4_open_delegation_recall(ctx->dentry, state) < 0) 81 err = nfs4_open_delegation_recall(ctx->dentry, state);
51 return; 82 if (err >= 0)
83 err = nfs_delegation_claim_locks(ctx, state);
52 put_nfs_open_context(ctx); 84 put_nfs_open_context(ctx);
85 if (err != 0)
86 return;
53 goto again; 87 goto again;
54 } 88 }
55 spin_unlock(&inode->i_lock); 89 spin_unlock(&inode->i_lock);
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 8017846b561f..2fcc30de924b 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -38,6 +38,7 @@ void nfs_delegation_reap_unclaimed(struct nfs4_client *clp);
38/* NFSv4 delegation-related procedures */ 38/* NFSv4 delegation-related procedures */
39int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid); 39int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid);
40int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state); 40int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state);
41int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl);
41 42
42static inline int nfs_have_delegation(struct inode *inode, int flags) 43static inline int nfs_have_delegation(struct inode *inode, int flags)
43{ 44{
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 54ff465cf7cf..e6a9322a321f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3124,6 +3124,24 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
3124 return status; 3124 return status;
3125} 3125}
3126 3126
3127int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
3128{
3129 struct nfs_server *server = NFS_SERVER(state->inode);
3130 struct nfs4_exception exception = { };
3131 int err;
3132
3133 err = nfs4_set_lock_state(state, fl);
3134 if (err != 0)
3135 goto out;
3136 do {
3137 err = _nfs4_do_setlk(state, F_SETLK, fl, 0);
3138 if (err != -NFS4ERR_DELAY)
3139 break;
3140 err = nfs4_handle_exception(server, err, &exception);
3141 } while (exception.retry);
3142out:
3143 return err;
3144}
3127 3145
3128#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" 3146#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
3129 3147