Merge tag 'nfs-for-3.17-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Highlights include: - stable fix for a bug in nfs3_list_one_acl() - speed up NFS path walks by supporting LOOKUP_RCU - more read/write code cleanups - pNFS fixes for layout return on close - fixes for the RCU handling in the rpcsec_gss code - more NFS/RDMA fixes" * tag 'nfs-for-3.17-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (79 commits) nfs: reject changes to resvport and sharecache during remount NFS: Avoid infinite loop when RELEASE_LOCKOWNER getting expired error SUNRPC: remove all refcounting of groupinfo from rpcauth_lookupcred NFS: fix two problems in lookup_revalidate in RCU-walk NFS: allow lockless access to access_cache NFS: teach nfs_lookup_verify_inode to handle LOOKUP_RCU NFS: teach nfs_neg_need_reval to understand LOOKUP_RCU NFS: support RCU_WALK in nfs_permission() sunrpc/auth: allow lockless (rcu) lookup of credential cache. NFS: prepare for RCU-walk support but pushing tests later in code. NFS: nfs4_lookup_revalidate: only evaluate parent if it will be used. NFS: add checks for returned value of try_module_get() nfs: clear_request_commit while holding i_lock pnfs: add pnfs_put_lseg_async pnfs: find swapped pages on pnfs commit lists too nfs: fix comment and add warn_on for PG_INODE_REF nfs: check wait_on_bit_lock err in page_group_lock sunrpc: remove "ec" argument from encrypt_v2 operation sunrpc: clean up sparse endianness warnings in gss_krb5_wrap.c sunrpc: clean up sparse endianness warnings in gss_krb5_seal.c ...
This commit is contained in:
@@ -787,33 +787,36 @@ void nfs4_close_sync(struct nfs4_state *state, fmode_t fmode)
|
||||
* that is compatible with current->files
|
||||
*/
|
||||
static struct nfs4_lock_state *
|
||||
__nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type)
|
||||
__nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
|
||||
{
|
||||
struct nfs4_lock_state *pos;
|
||||
list_for_each_entry(pos, &state->lock_states, ls_locks) {
|
||||
if (type != NFS4_ANY_LOCK_TYPE && pos->ls_owner.lo_type != type)
|
||||
if (pos->ls_owner != fl_owner)
|
||||
continue;
|
||||
switch (pos->ls_owner.lo_type) {
|
||||
case NFS4_POSIX_LOCK_TYPE:
|
||||
if (pos->ls_owner.lo_u.posix_owner != fl_owner)
|
||||
continue;
|
||||
break;
|
||||
case NFS4_FLOCK_LOCK_TYPE:
|
||||
if (pos->ls_owner.lo_u.flock_owner != fl_pid)
|
||||
continue;
|
||||
}
|
||||
atomic_inc(&pos->ls_count);
|
||||
return pos;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
free_lock_state_work(struct work_struct *work)
|
||||
{
|
||||
struct nfs4_lock_state *lsp = container_of(work,
|
||||
struct nfs4_lock_state, ls_release);
|
||||
struct nfs4_state *state = lsp->ls_state;
|
||||
struct nfs_server *server = state->owner->so_server;
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
|
||||
clp->cl_mvops->free_lock_state(server, lsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a compatible lock_state. If no initialized lock_state structure
|
||||
* exists, return an uninitialized one.
|
||||
*
|
||||
*/
|
||||
static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type)
|
||||
static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
|
||||
{
|
||||
struct nfs4_lock_state *lsp;
|
||||
struct nfs_server *server = state->owner->so_server;
|
||||
@@ -824,21 +827,12 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
|
||||
nfs4_init_seqid_counter(&lsp->ls_seqid);
|
||||
atomic_set(&lsp->ls_count, 1);
|
||||
lsp->ls_state = state;
|
||||
lsp->ls_owner.lo_type = type;
|
||||
switch (lsp->ls_owner.lo_type) {
|
||||
case NFS4_FLOCK_LOCK_TYPE:
|
||||
lsp->ls_owner.lo_u.flock_owner = fl_pid;
|
||||
break;
|
||||
case NFS4_POSIX_LOCK_TYPE:
|
||||
lsp->ls_owner.lo_u.posix_owner = fl_owner;
|
||||
break;
|
||||
default:
|
||||
goto out_free;
|
||||
}
|
||||
lsp->ls_owner = fl_owner;
|
||||
lsp->ls_seqid.owner_id = ida_simple_get(&server->lockowner_id, 0, 0, GFP_NOFS);
|
||||
if (lsp->ls_seqid.owner_id < 0)
|
||||
goto out_free;
|
||||
INIT_LIST_HEAD(&lsp->ls_locks);
|
||||
INIT_WORK(&lsp->ls_release, free_lock_state_work);
|
||||
return lsp;
|
||||
out_free:
|
||||
kfree(lsp);
|
||||
@@ -857,13 +851,13 @@ void nfs4_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp
|
||||
* exists, return an uninitialized one.
|
||||
*
|
||||
*/
|
||||
static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner, pid_t pid, unsigned int type)
|
||||
static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner)
|
||||
{
|
||||
struct nfs4_lock_state *lsp, *new = NULL;
|
||||
|
||||
for(;;) {
|
||||
spin_lock(&state->state_lock);
|
||||
lsp = __nfs4_find_lock_state(state, owner, pid, type);
|
||||
lsp = __nfs4_find_lock_state(state, owner);
|
||||
if (lsp != NULL)
|
||||
break;
|
||||
if (new != NULL) {
|
||||
@@ -874,7 +868,7 @@ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_
|
||||
break;
|
||||
}
|
||||
spin_unlock(&state->state_lock);
|
||||
new = nfs4_alloc_lock_state(state, owner, pid, type);
|
||||
new = nfs4_alloc_lock_state(state, owner);
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
}
|
||||
@@ -902,13 +896,12 @@ void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
|
||||
if (list_empty(&state->lock_states))
|
||||
clear_bit(LK_STATE_IN_USE, &state->flags);
|
||||
spin_unlock(&state->state_lock);
|
||||
server = state->owner->so_server;
|
||||
if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
|
||||
clp->cl_mvops->free_lock_state(server, lsp);
|
||||
} else
|
||||
if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags))
|
||||
queue_work(nfsiod_workqueue, &lsp->ls_release);
|
||||
else {
|
||||
server = state->owner->so_server;
|
||||
nfs4_free_lock_state(server, lsp);
|
||||
}
|
||||
}
|
||||
|
||||
static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
|
||||
@@ -935,13 +928,7 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
|
||||
|
||||
if (fl->fl_ops != NULL)
|
||||
return 0;
|
||||
if (fl->fl_flags & FL_POSIX)
|
||||
lsp = nfs4_get_lock_state(state, fl->fl_owner, 0, NFS4_POSIX_LOCK_TYPE);
|
||||
else if (fl->fl_flags & FL_FLOCK)
|
||||
lsp = nfs4_get_lock_state(state, NULL, fl->fl_pid,
|
||||
NFS4_FLOCK_LOCK_TYPE);
|
||||
else
|
||||
return -EINVAL;
|
||||
lsp = nfs4_get_lock_state(state, fl->fl_owner);
|
||||
if (lsp == NULL)
|
||||
return -ENOMEM;
|
||||
fl->fl_u.nfs4_fl.owner = lsp;
|
||||
@@ -955,7 +942,6 @@ static int nfs4_copy_lock_stateid(nfs4_stateid *dst,
|
||||
{
|
||||
struct nfs4_lock_state *lsp;
|
||||
fl_owner_t fl_owner;
|
||||
pid_t fl_pid;
|
||||
int ret = -ENOENT;
|
||||
|
||||
|
||||
@@ -966,9 +952,8 @@ static int nfs4_copy_lock_stateid(nfs4_stateid *dst,
|
||||
goto out;
|
||||
|
||||
fl_owner = lockowner->l_owner;
|
||||
fl_pid = lockowner->l_pid;
|
||||
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);
|
||||
if (lsp && test_bit(NFS_LOCK_LOST, &lsp->ls_flags))
|
||||
ret = -EIO;
|
||||
else if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) {
|
||||
|
Reference in New Issue
Block a user