Commit 2a369153 authored by Trond Myklebust's avatar Trond Myklebust

NFS: Clean up helper function nfs4_select_rw_stateid()

We want to be able to pass on the information that the page was not
dirtied under a lock. Instead of adding a flag parameter, do this
by passing a pointer to a 'struct nfs_lock_owner' that may be NULL.

Also reuse this structure in struct nfs_lock_context to carry the
fl_owner_t and pid_t.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent b3c54de6
...@@ -547,8 +547,8 @@ EXPORT_SYMBOL_GPL(nfs_getattr); ...@@ -547,8 +547,8 @@ EXPORT_SYMBOL_GPL(nfs_getattr);
static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
{ {
atomic_set(&l_ctx->count, 1); atomic_set(&l_ctx->count, 1);
l_ctx->lockowner = current->files; l_ctx->lockowner.l_owner = current->files;
l_ctx->pid = current->tgid; l_ctx->lockowner.l_pid = current->tgid;
INIT_LIST_HEAD(&l_ctx->list); INIT_LIST_HEAD(&l_ctx->list);
} }
...@@ -557,9 +557,9 @@ static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context ...@@ -557,9 +557,9 @@ static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context
struct nfs_lock_context *pos; struct nfs_lock_context *pos;
list_for_each_entry(pos, &ctx->lock_context.list, list) { list_for_each_entry(pos, &ctx->lock_context.list, list) {
if (pos->lockowner != current->files) if (pos->lockowner.l_owner != current->files)
continue; continue;
if (pos->pid != current->tgid) if (pos->lockowner.l_pid != current->tgid)
continue; continue;
atomic_inc(&pos->count); atomic_inc(&pos->count);
return pos; return pos;
......
...@@ -351,7 +351,7 @@ extern void nfs41_handle_server_scope(struct nfs_client *, ...@@ -351,7 +351,7 @@ extern void nfs41_handle_server_scope(struct nfs_client *,
extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
extern void nfs4_select_rw_stateid(nfs4_stateid *, struct nfs4_state *, extern void nfs4_select_rw_stateid(nfs4_stateid *, struct nfs4_state *,
fmode_t, fl_owner_t, pid_t); fmode_t, const struct nfs_lockowner *);
extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask); extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask);
extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task); extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
......
...@@ -2013,8 +2013,12 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, ...@@ -2013,8 +2013,12 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
nfs_fattr_init(fattr); nfs_fattr_init(fattr);
if (state != NULL) { if (state != NULL) {
struct nfs_lockowner lockowner = {
.l_owner = current->files,
.l_pid = current->tgid,
};
nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE, nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE,
current->files, current->tgid); &lockowner);
} else if (nfs4_copy_delegation_stateid(&arg.stateid, inode, } else if (nfs4_copy_delegation_stateid(&arg.stateid, inode,
FMODE_WRITE)) { FMODE_WRITE)) {
/* Use that stateid */ /* Use that stateid */
......
...@@ -911,14 +911,22 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl) ...@@ -911,14 +911,22 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
} }
static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state, static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state,
fl_owner_t fl_owner, pid_t fl_pid) const struct nfs_lockowner *lockowner)
{ {
struct nfs4_lock_state *lsp; struct nfs4_lock_state *lsp;
fl_owner_t fl_owner;
pid_t fl_pid;
bool ret = false; bool ret = false;
if (lockowner == NULL)
goto out;
if (test_bit(LK_STATE_IN_USE, &state->flags) == 0) if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
goto out; goto out;
fl_owner = lockowner->l_owner;
fl_pid = lockowner->l_pid;
spin_lock(&state->state_lock); spin_lock(&state->state_lock);
lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE); lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE);
if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) { if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) {
...@@ -946,11 +954,11 @@ static void nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state) ...@@ -946,11 +954,11 @@ static void nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
* requests. * requests.
*/ */
void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state, void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state,
fmode_t fmode, fl_owner_t fl_owner, pid_t fl_pid) fmode_t fmode, const struct nfs_lockowner *lockowner)
{ {
if (nfs4_copy_delegation_stateid(dst, state->inode, fmode)) if (nfs4_copy_delegation_stateid(dst, state->inode, fmode))
return; return;
if (nfs4_copy_lock_stateid(dst, state, fl_owner, fl_pid)) if (nfs4_copy_lock_stateid(dst, state, lockowner))
return; return;
nfs4_copy_open_stateid(dst, state); nfs4_copy_open_stateid(dst, state);
} }
......
...@@ -1509,8 +1509,12 @@ static void encode_open_stateid(struct xdr_stream *xdr, ...@@ -1509,8 +1509,12 @@ static void encode_open_stateid(struct xdr_stream *xdr,
nfs4_stateid stateid; nfs4_stateid stateid;
if (ctx->state != NULL) { if (ctx->state != NULL) {
const struct nfs_lockowner *lockowner = NULL;
if (l_ctx != NULL)
lockowner = &l_ctx->lockowner;
nfs4_select_rw_stateid(&stateid, ctx->state, nfs4_select_rw_stateid(&stateid, ctx->state,
fmode, l_ctx->lockowner, l_ctx->pid); fmode, lockowner);
if (zero_seqid) if (zero_seqid)
stateid.seqid = 0; stateid.seqid = 0;
encode_nfs4_stateid(xdr, &stateid); encode_nfs4_stateid(xdr, &stateid);
......
...@@ -292,7 +292,9 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev, ...@@ -292,7 +292,9 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev,
{ {
if (req->wb_context->cred != prev->wb_context->cred) if (req->wb_context->cred != prev->wb_context->cred)
return false; return false;
if (req->wb_lock_context->lockowner != prev->wb_lock_context->lockowner) if (req->wb_lock_context->lockowner.l_owner != prev->wb_lock_context->lockowner.l_owner)
return false;
if (req->wb_lock_context->lockowner.l_pid != prev->wb_lock_context->lockowner.l_pid)
return false; return false;
if (req->wb_context->state != prev->wb_context->state) if (req->wb_context->state != prev->wb_context->state)
return false; return false;
......
...@@ -846,6 +846,7 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, ...@@ -846,6 +846,7 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
int nfs_flush_incompatible(struct file *file, struct page *page) int nfs_flush_incompatible(struct file *file, struct page *page)
{ {
struct nfs_open_context *ctx = nfs_file_open_context(file); struct nfs_open_context *ctx = nfs_file_open_context(file);
struct nfs_lock_context *l_ctx;
struct nfs_page *req; struct nfs_page *req;
int do_flush, status; int do_flush, status;
/* /*
...@@ -860,9 +861,12 @@ int nfs_flush_incompatible(struct file *file, struct page *page) ...@@ -860,9 +861,12 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
req = nfs_page_find_request(page); req = nfs_page_find_request(page);
if (req == NULL) if (req == NULL)
return 0; return 0;
do_flush = req->wb_page != page || req->wb_context != ctx || l_ctx = req->wb_lock_context;
req->wb_lock_context->lockowner != current->files || do_flush = req->wb_page != page || req->wb_context != ctx;
req->wb_lock_context->pid != current->tgid; if (l_ctx) {
do_flush |= l_ctx->lockowner.l_owner != current->files
|| l_ctx->lockowner.l_pid != current->tgid;
}
nfs_release_request(req); nfs_release_request(req);
if (!do_flush) if (!do_flush)
return 0; return 0;
......
...@@ -81,12 +81,16 @@ struct nfs_access_entry { ...@@ -81,12 +81,16 @@ struct nfs_access_entry {
int mask; int mask;
}; };
struct nfs_lockowner {
fl_owner_t l_owner;
pid_t l_pid;
};
struct nfs_lock_context { struct nfs_lock_context {
atomic_t count; atomic_t count;
struct list_head list; struct list_head list;
struct nfs_open_context *open_context; struct nfs_open_context *open_context;
fl_owner_t lockowner; struct nfs_lockowner lockowner;
pid_t pid;
}; };
struct nfs4_state; struct nfs4_state;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment