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 | ||
