diff options
-rw-r--r-- | fs/nfs/delegation.c | 38 | ||||
-rw-r--r-- | fs/nfs/delegation.h | 1 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 18 |
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 | ||
34 | static 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; | ||
60 | out_err: | ||
61 | return status; | ||
62 | } | ||
63 | |||
34 | static void nfs_delegation_claim_opens(struct inode *inode) | 64 | static 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 | ||
40 | again: | 71 | again: |
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 */ |
39 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid); | 39 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid); |
40 | int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state); | 40 | int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state); |
41 | int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl); | ||
41 | 42 | ||
42 | static inline int nfs_have_delegation(struct inode *inode, int flags) | 43 | static 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 | ||
3127 | int 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); | ||
3142 | out: | ||
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 | ||