cascardo/linux.git
9 years agonfsd: add some comments to the nfsd4 object definitions
Jeff Layton [Tue, 5 Aug 2014 19:13:30 +0000 (15:13 -0400)]
nfsd: add some comments to the nfsd4 object definitions

Add some comments that describe what each of these objects is, and how
they related to one another.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: remove the client_mutex and the nfs4_lock/unlock_state wrappers
Jeff Layton [Wed, 30 Jul 2014 12:27:37 +0000 (08:27 -0400)]
nfsd: remove the client_mutex and the nfs4_lock/unlock_state wrappers

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: remove nfs4_lock_state: nfs4_state_shutdown_net
Jeff Layton [Wed, 30 Jul 2014 12:27:36 +0000 (08:27 -0400)]
nfsd: remove nfs4_lock_state: nfs4_state_shutdown_net

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: remove nfs4_lock_state: nfs4_laundromat
Jeff Layton [Wed, 30 Jul 2014 12:27:35 +0000 (08:27 -0400)]
nfsd: remove nfs4_lock_state: nfs4_laundromat

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Remove nfs4_lock_state(): reclaim_complete()
Trond Myklebust [Wed, 30 Jul 2014 12:27:34 +0000 (08:27 -0400)]
nfsd: Remove nfs4_lock_state(): reclaim_complete()

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Remove nfs4_lock_state(): setclientid, setclientid_confirm, renew
Trond Myklebust [Wed, 30 Jul 2014 12:27:33 +0000 (08:27 -0400)]
nfsd: Remove nfs4_lock_state(): setclientid, setclientid_confirm, renew

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Remove nfs4_lock_state(): exchange_id, create/destroy_session()
Trond Myklebust [Wed, 30 Jul 2014 12:27:32 +0000 (08:27 -0400)]
nfsd: Remove nfs4_lock_state(): exchange_id, create/destroy_session()

Also destroy_clientid and bind_conn_to_session.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Remove nfs4_lock_state(): nfsd4_open and nfsd4_open_confirm
Trond Myklebust [Wed, 30 Jul 2014 12:27:31 +0000 (08:27 -0400)]
nfsd: Remove nfs4_lock_state(): nfsd4_open and nfsd4_open_confirm

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Remove nfs4_lock_state(): nfsd4_delegreturn()
Trond Myklebust [Wed, 30 Jul 2014 12:27:30 +0000 (08:27 -0400)]
nfsd: Remove nfs4_lock_state(): nfsd4_delegreturn()

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Remove nfs4_lock_state(): nfsd4_open_downgrade + nfsd4_close
Trond Myklebust [Wed, 30 Jul 2014 12:27:29 +0000 (08:27 -0400)]
nfsd: Remove nfs4_lock_state(): nfsd4_open_downgrade + nfsd4_close

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Remove nfs4_lock_state(): nfsd4_lock/locku/lockt()
Trond Myklebust [Wed, 30 Jul 2014 12:27:28 +0000 (08:27 -0400)]
nfsd: Remove nfs4_lock_state(): nfsd4_lock/locku/lockt()

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Remove nfs4_lock_state(): nfsd4_release_lockowner
Trond Myklebust [Wed, 30 Jul 2014 12:27:27 +0000 (08:27 -0400)]
nfsd: Remove nfs4_lock_state(): nfsd4_release_lockowner

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Remove nfs4_lock_state(): nfsd4_test_stateid/nfsd4_free_stateid
Trond Myklebust [Wed, 30 Jul 2014 12:27:26 +0000 (08:27 -0400)]
nfsd: Remove nfs4_lock_state(): nfsd4_test_stateid/nfsd4_free_stateid

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Remove nfs4_lock_state(): nfs4_preprocess_stateid_op()
Trond Myklebust [Wed, 30 Jul 2014 12:27:25 +0000 (08:27 -0400)]
nfsd: Remove nfs4_lock_state(): nfs4_preprocess_stateid_op()

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: remove old fault injection infrastructure
Jeff Layton [Wed, 30 Jul 2014 12:27:24 +0000 (08:27 -0400)]
nfsd: remove old fault injection infrastructure

Remove the old nfsd_for_n_state function and move nfsd_find_client
higher up into the file to get rid of forward declaration. Remove
the struct nfsd_fault_inject_op arguments from the operations as
they are no longer needed by any of them.

Finally, remove the old "standard" get and set routines, which
also eliminates the client_mutex from this code.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: add more granular locking to *_delegations fault injectors
Jeff Layton [Wed, 30 Jul 2014 12:27:23 +0000 (08:27 -0400)]
nfsd: add more granular locking to *_delegations fault injectors

...instead of relying on the client_mutex.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: add more granular locking to forget_openowners fault injector
Jeff Layton [Wed, 30 Jul 2014 12:27:22 +0000 (08:27 -0400)]
nfsd: add more granular locking to forget_openowners fault injector

...instead of relying on the client_mutex.

Also, fix up the printk output that is generated when the file is read.
It currently says that it's reporting the number of open files, but
it's actually reporting the number of openowners.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: add more granular locking to forget_locks fault injector
Jeff Layton [Wed, 30 Jul 2014 12:27:21 +0000 (08:27 -0400)]
nfsd: add more granular locking to forget_locks fault injector

...instead of relying on the client_mutex.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: add a list_head arg to nfsd_foreach_client_lock
Jeff Layton [Wed, 30 Jul 2014 12:27:20 +0000 (08:27 -0400)]
nfsd: add a list_head arg to nfsd_foreach_client_lock

In a later patch, we'll want to collect the locks onto a list for later
destruction. If "func" is defined and "collect" is defined, then we'll
add the lock stateid to the list.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: add nfsd_inject_forget_clients
Jeff Layton [Wed, 30 Jul 2014 12:27:19 +0000 (08:27 -0400)]
nfsd: add nfsd_inject_forget_clients

...which uses the client_lock for protection instead of client_mutex.
Also remove nfsd_forget_client as there are no more callers.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: add a forget_client set_clnt routine
Jeff Layton [Wed, 30 Jul 2014 12:27:18 +0000 (08:27 -0400)]
nfsd: add a forget_client set_clnt routine

...that relies on the client_lock instead of client_mutex.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: add a forget_clients "get" routine with proper locking
Jeff Layton [Wed, 30 Jul 2014 12:27:17 +0000 (08:27 -0400)]
nfsd: add a forget_clients "get" routine with proper locking

Add a new "get" routine for forget_clients that relies on the
client_lock instead of the client_mutex.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: abstract out the get and set routines into the fault injection ops
Jeff Layton [Wed, 30 Jul 2014 12:27:16 +0000 (08:27 -0400)]
nfsd: abstract out the get and set routines into the fault injection ops

Now that we've added more granular locking in other places, it's time
to address the fault injection code. This code is currently quite
reliant on the client_mutex for protection. Start to change this by
adding a new set of fault injection op vectors.

For now they all use the legacy ones. In later patches we'll add new
routines that can deal with more granular locking.

Also, move some of the printk routines into the callers to make the
results of the operations more uniform.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: protect clid and verifier generation with client_lock
Jeff Layton [Wed, 30 Jul 2014 12:27:15 +0000 (08:27 -0400)]
nfsd: protect clid and verifier generation with client_lock

The clid counter is a global counter currently. Move it to be a per-net
property so that it can be properly protected by the nn->client_lock
instead of relying on the client_mutex.

The verifier generator is also potentially racy if there are two
simultaneous callers. Generate the verifier when we generate the clid
value, so it's also created under the client_lock. With this, there's
no need to keep two counters as they'd always be in sync anyway, so
just use the clientid_counter for both.

As Trond points out, what would be best is to eventually move this
code to use IDR instead of the hash tables. That would also help ensure
uniqueness, but that's probably best done as a separate project.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: don't destroy clients that are busy
Jeff Layton [Wed, 30 Jul 2014 12:27:14 +0000 (08:27 -0400)]
nfsd: don't destroy clients that are busy

It's possible that we'll have an in-progress call on some of the clients
while a rogue EXCHANGE_ID or DESTROY_CLIENTID call comes in. Be sure to
try and mark the client expired first, so that the refcount is
respected.

This will only be a problem once the client_mutex is removed.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agoNFSD: Put the reference of nfs4_file when freeing stid
Kinglong Mee [Tue, 5 Aug 2014 13:20:27 +0000 (21:20 +0800)]
NFSD: Put the reference of nfs4_file when freeing stid

After testing nfs4 lock, I restart the nfsd service, got messages as,

[ 5677.403419] nfsd: last server has exited, flushing export cache
[ 5677.463728] =============================================================================
[ 5677.463942] BUG nfsd4_files (Tainted: G    B      OE): Objects remaining in nfsd4_files on kmem_cache_close()
[ 5677.464055] -----------------------------------------------------------------------------

[ 5677.464203] INFO: Slab 0xffffea0000233400 objects=28 used=1 fp=0xffff880008cd3d98 flags=0x3ffc0000004080
[ 5677.464318] CPU: 0 PID: 3772 Comm: rmmod Tainted: G    B      OE 3.16.0-rc2+ #29
[ 5677.464420] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/31/2013
[ 5677.464538]  0000000000000000 0000000036af2c9f ffff88000ce97d68 ffffffff816eacfa
[ 5677.464643]  ffffea0000233400 ffff88000ce97e40 ffffffff811cda44 ffffffff00000020
[ 5677.464774]  ffff88000ce97e50 ffff88000ce97e00 656a624f00000008 616d657220737463
[ 5677.464875] Call Trace:
[ 5677.464925]  [<ffffffff816eacfa>] dump_stack+0x45/0x56
[ 5677.464983]  [<ffffffff811cda44>] slab_err+0xb4/0xe0
[ 5677.465040]  [<ffffffff811d0457>] ? __kmalloc+0x117/0x290
[ 5677.465099]  [<ffffffff81100eec>] ? on_each_cpu_cond+0xac/0xf0
[ 5677.465158]  [<ffffffff811d1bc0>] ? kmem_cache_close+0x110/0x2e0
[ 5677.465218]  [<ffffffff811d1be0>] kmem_cache_close+0x130/0x2e0
[ 5677.465279]  [<ffffffff8135a0c1>] ? kobject_cleanup+0x91/0x1b0
[ 5677.465338]  [<ffffffff811d22be>] __kmem_cache_shutdown+0xe/0x10
[ 5677.465399]  [<ffffffff8119bd28>] kmem_cache_destroy+0x48/0x100
[ 5677.465466]  [<ffffffffa05ef78d>] nfsd4_free_slabs+0x2d/0x50 [nfsd]
[ 5677.465530]  [<ffffffffa05fa987>] exit_nfsd+0x34/0x6ad [nfsd]
[ 5677.465589]  [<ffffffff81104ac2>] SyS_delete_module+0x162/0x200
[ 5677.465649]  [<ffffffff81013b69>] ? do_notify_resume+0x59/0x90
[ 5677.465759]  [<ffffffff816f2369>] system_call_fastpath+0x16/0x1b
[ 5677.465822] INFO: Object 0xffff880008cd0000 @offset=0
[ 5677.465882] INFO: Allocated in nfsd4_process_open1+0x61/0x350 [nfsd] age=7599 cpu=0 pid=3253
[ 5677.466115]  __slab_alloc+0x3b0/0x4b1
[ 5677.466166]  kmem_cache_alloc+0x1e4/0x240
[ 5677.466220]  nfsd4_process_open1+0x61/0x350 [nfsd]
[ 5677.466276]  nfsd4_open+0xee/0x860 [nfsd]
[ 5677.466329]  nfsd4_proc_compound+0x4d7/0x7f0 [nfsd]
[ 5677.466384]  nfsd_dispatch+0xbb/0x200 [nfsd]
[ 5677.466447]  svc_process_common+0x453/0x6f0 [sunrpc]
[ 5677.466506]  svc_process+0x103/0x170 [sunrpc]
[ 5677.466559]  nfsd+0x117/0x190 [nfsd]
[ 5677.466609]  kthread+0xd8/0xf0
[ 5677.466656]  ret_from_fork+0x7c/0xb0
[ 5677.466775] kmem_cache_destroy nfsd4_files: Slab cache still has objects
[ 5677.466839] CPU: 0 PID: 3772 Comm: rmmod Tainted: G    B      OE 3.16.0-rc2+ #29
[ 5677.466937] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/31/2013
[ 5677.467049]  0000000000000000 0000000036af2c9f ffff88000ce97eb0 ffffffff816eacfa
[ 5677.467150]  ffff880020bb2d00 ffff88000ce97ed0 ffffffff8119bdd9 0000000000000000
[ 5677.467250]  ffffffffa06065c0 ffff88000ce97ee0 ffffffffa05ef78d ffff88000ce97ef0
[ 5677.467351] Call Trace:
[ 5677.467397]  [<ffffffff816eacfa>] dump_stack+0x45/0x56
[ 5677.467454]  [<ffffffff8119bdd9>] kmem_cache_destroy+0xf9/0x100
[ 5677.467516]  [<ffffffffa05ef78d>] nfsd4_free_slabs+0x2d/0x50 [nfsd]
[ 5677.467579]  [<ffffffffa05fa987>] exit_nfsd+0x34/0x6ad [nfsd]
[ 5677.467639]  [<ffffffff81104ac2>] SyS_delete_module+0x162/0x200
[ 5677.467765]  [<ffffffff81013b69>] ? do_notify_resume+0x59/0x90
[ 5677.467826]  [<ffffffff816f2369>] system_call_fastpath+0x16/0x1b

Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
Reviewed-by: Jeff Layton <jlayton@primarydata.com>
Fixes: 11b9164adad7 "nfsd: Add a struct nfs4_file field to struct nfs4_stid"
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: don't destroy client if mark_client_expired_locked fails
Jeff Layton [Wed, 30 Jul 2014 12:27:13 +0000 (08:27 -0400)]
nfsd: don't destroy client if mark_client_expired_locked fails

If it fails, it means that the client is in use and so destroying it
would be bad. Currently, the client_mutex prevents this from happening
but once we remove it, we won't be able to do this.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: move unhash_client_locked call into mark_client_expired_locked
Jeff Layton [Wed, 30 Jul 2014 12:27:12 +0000 (08:27 -0400)]
nfsd: move unhash_client_locked call into mark_client_expired_locked

All the callers except for the fault injection code call it directly
afterward, and in the fault injection case it won't hurt to do so
anyway.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: protect the close_lru list and oo_last_closed_stid with client_lock
Jeff Layton [Wed, 30 Jul 2014 12:27:11 +0000 (08:27 -0400)]
nfsd: protect the close_lru list and oo_last_closed_stid with client_lock

Currently, it's protected by the client_mutex. Move it so that the list
and the fields in the openowner are protected by the client_lock.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Add lockdep assertions to document the nfs4_client/session locking
Trond Myklebust [Wed, 30 Jul 2014 12:27:10 +0000 (08:27 -0400)]
nfsd: Add lockdep assertions to document the nfs4_client/session locking

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Ensure lookup_clientid() takes client_lock
Trond Myklebust [Wed, 30 Jul 2014 12:27:09 +0000 (08:27 -0400)]
nfsd: Ensure lookup_clientid() takes client_lock

Ensure that the client lookup is done safely under the client_lock, so
we're not relying on the client_mutex.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Protect nfsd4_destroy_clientid using client_lock
Trond Myklebust [Wed, 30 Jul 2014 12:27:08 +0000 (08:27 -0400)]
nfsd: Protect nfsd4_destroy_clientid using client_lock

...instead of relying on the client_mutex.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Protect session creation and client confirm using client_lock
Jeff Layton [Wed, 30 Jul 2014 12:27:07 +0000 (08:27 -0400)]
nfsd: Protect session creation and client confirm using client_lock

In particular, we want to ensure that the move_to_confirmed() is
protected by the nn->client_lock spin lock, so that we can use that when
looking up the clientid etc. instead of relying on the client_mutex.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Protect unconfirmed client creation using client_lock
Trond Myklebust [Wed, 30 Jul 2014 12:27:06 +0000 (08:27 -0400)]
nfsd: Protect unconfirmed client creation using client_lock

...instead of relying on the client_mutex.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Move create_client() call outside the lock
Trond Myklebust [Wed, 30 Jul 2014 12:27:05 +0000 (08:27 -0400)]
nfsd: Move create_client() call outside the lock

For efficiency reasons, and because we want to use spin locks instead
of relying on the client_mutex.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Don't require client_lock in free_client
Trond Myklebust [Wed, 30 Jul 2014 12:27:04 +0000 (08:27 -0400)]
nfsd: Don't require client_lock in free_client

The struct nfs_client is supposed to be invisible and unreferenced
before it gets here.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Ensure that the laundromat unhashes the client before releasing locks
Trond Myklebust [Wed, 30 Jul 2014 12:27:03 +0000 (08:27 -0400)]
nfsd: Ensure that the laundromat unhashes the client before releasing locks

If we leave the client on the confirmed/unconfirmed tables, and leave
the sessions visible on the sessionid_hashtbl, then someone might
find them before we've had a chance to destroy them.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Ensure struct nfs4_client is unhashed before we try to destroy it
Trond Myklebust [Wed, 30 Jul 2014 12:27:02 +0000 (08:27 -0400)]
nfsd: Ensure struct nfs4_client is unhashed before we try to destroy it

When we remove the client_mutex protection, we will need to ensure
that it can't be found by other threads while we're destroying it.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd4: fix out of date comment
J. Bruce Fields [Thu, 31 Jul 2014 20:10:08 +0000 (16:10 -0400)]
nfsd4: fix out of date comment

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agoNFSD: Decrease nfsd_users in nfsd_startup_generic fail
Kinglong Mee [Wed, 30 Jul 2014 13:26:05 +0000 (21:26 +0800)]
NFSD: Decrease nfsd_users in nfsd_startup_generic fail

A memory allocation failure could cause nfsd_startup_generic to fail, in
which case nfsd_users wouldn't be incorrectly left elevated.

After nfsd restarts nfsd_startup_generic will then succeed without doing
anything--the first consequence is likely nfs4_start_net finding a bad
laundry_wq and crashing.

Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
Fixes: 4539f14981ce "nfsd: replace boolean nfsd_up flag by users counter"
Cc: stable@vger.kernel.org
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: rename unhash_generic_stateid to unhash_ol_stateid
Jeff Layton [Wed, 30 Jul 2014 01:34:43 +0000 (21:34 -0400)]
nfsd: rename unhash_generic_stateid to unhash_ol_stateid

...to better match other functions that deal with open/lock stateids.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: don't thrash the cl_lock while freeing an open stateid
Jeff Layton [Wed, 30 Jul 2014 01:34:42 +0000 (21:34 -0400)]
nfsd: don't thrash the cl_lock while freeing an open stateid

When we remove the client_mutex, we'll have a potential race between
FREE_STATEID and CLOSE.

The root of the problem is that we are walking the st_locks list,
dropping the spinlock and then trying to release the persistent
reference to the lockstateid. In between, a FREE_STATEID call can come
along and take the lock, find the stateid and then try to put the
reference. That leads to a double put.

Fix this by not releasing the cl_lock in order to release each lock
stateid. Use put_generic_stateid_locked to unhash them and gather them
onto a list, and free_ol_stateid_reaplist to free any that end up on the
list.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: reduce cl_lock thrashing in release_openowner
Jeff Layton [Wed, 30 Jul 2014 01:34:41 +0000 (21:34 -0400)]
nfsd: reduce cl_lock thrashing in release_openowner

Releasing an openowner is a bit inefficient as it can potentially thrash
the cl_lock if you have a lot of stateids attached to it. Once we remove
the client_mutex, it'll also potentially be dangerous to do this.

Add some functions to make it easier to defer the part of putting a
generic stateid reference that needs to be done outside the cl_lock while
doing the parts that must be done while holding it under a single lock.

First we unhash each open stateid. Then we call
put_generic_stateid_locked which will put the reference to an
nfs4_ol_stateid. If it turns out to be the last reference, it'll go
ahead and remove the stid from the IDR tree and put it onto the reaplist
using the st_locks list_head.

Then, after dropping the lock we'll call free_ol_stateid_reaplist to
walk the list of stateids that are fully unhashed and ready to be freed,
and free each of them. This function can sleep, so it must be done
outside any spinlocks.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: close potential race in nfsd4_free_stateid
Jeff Layton [Wed, 30 Jul 2014 01:34:40 +0000 (21:34 -0400)]
nfsd: close potential race in nfsd4_free_stateid

Once we remove the client_mutex, it'll be possible for the sc_type of a
lock stateid to change after it's found and checked, but before we can
go to destroy it. If that happens, we can end up putting the persistent
reference to the stateid more than once, and unhash it more than once.

Fix this by unhashing the lock stateid prior to dropping the cl_lock but
after finding it.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: optimize destroy_lockowner cl_lock thrashing
Jeff Layton [Wed, 30 Jul 2014 01:34:39 +0000 (21:34 -0400)]
nfsd: optimize destroy_lockowner cl_lock thrashing

Reduce the cl_lock trashing in destroy_lockowner. Unhash all of the
lockstateids on the lockowner's list. Put the reference under the lock
and see if it was the last one. If so, then add it to a private list
to be destroyed after we drop the lock.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: add locking to stateowner release
Jeff Layton [Wed, 30 Jul 2014 01:34:38 +0000 (21:34 -0400)]
nfsd: add locking to stateowner release

Once we remove the client_mutex, we'll need to properly protect
the stateowner reference counts using the cl_lock.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: clean up and reorganize release_lockowner
Jeff Layton [Wed, 30 Jul 2014 01:34:37 +0000 (21:34 -0400)]
nfsd: clean up and reorganize release_lockowner

Do more within the main loop, and simplify the function a bit. Also,
there's no need to take a stateowner reference unless we're going to call
release_lockowner.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Move the open owner hash table into struct nfs4_client
Trond Myklebust [Wed, 30 Jul 2014 01:34:36 +0000 (21:34 -0400)]
nfsd: Move the open owner hash table into struct nfs4_client

Preparation for removing the client_mutex.

Convert the open owner hash table into a per-client table and protect it
using the nfs4_client->cl_lock spin lock.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Protect adding/removing lock owners using client_lock
Trond Myklebust [Wed, 30 Jul 2014 01:34:35 +0000 (21:34 -0400)]
nfsd: Protect adding/removing lock owners using client_lock

Once we remove client mutex protection, we'll need to ensure that
stateowner lookup and creation are atomic between concurrent compounds.
Ensure that alloc_init_lock_stateowner checks the hashtable under the
client_lock before adding a new element.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Protect adding/removing open state owners using client_lock
Trond Myklebust [Wed, 30 Jul 2014 01:34:34 +0000 (21:34 -0400)]
nfsd: Protect adding/removing open state owners using client_lock

Once we remove client mutex protection, we'll need to ensure that
stateowner lookup and creation are atomic between concurrent compounds.
Ensure that alloc_init_open_stateowner checks the hashtable under the
client_lock before adding a new element.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: don't allow CLOSE to proceed until refcount on stateid drops
Jeff Layton [Wed, 30 Jul 2014 01:34:33 +0000 (21:34 -0400)]
nfsd: don't allow CLOSE to proceed until refcount on stateid drops

Once we remove client_mutex protection, it'll be possible to have an
in-flight operation using an openstateid when a CLOSE call comes in.
If that happens, we can't just put the sc_file reference and clear its
pointer without risking an oops.

Fix this by ensuring that v4.0 CLOSE operations wait for the refcount
to drop before proceeding to do so.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: make openstateids hold references to their openowners
Jeff Layton [Wed, 30 Jul 2014 01:34:32 +0000 (21:34 -0400)]
nfsd: make openstateids hold references to their openowners

Change it so that only openstateids hold persistent references to
openowners. References can still be held by compounds in progress.

With this, we can get rid of NFS4_OO_NEW. It's possible that we
will create a new openowner in the process of doing the open, but
something later fails. In the meantime, another task could find
that openowner and start using it on a successful open. If that
occurs we don't necessarily want to tear it down, just put the
reference that the failing compound holds.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: clean up refcounting for lockowners
Jeff Layton [Wed, 30 Jul 2014 01:34:31 +0000 (21:34 -0400)]
nfsd: clean up refcounting for lockowners

Ensure that lockowner references are only held by lockstateids and
operations that are in-progress. With this, we can get rid of
release_lockowner_if_empty, which will be racy once we remove
client_mutex protection.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Make lock stateid take a reference to the lockowner
Trond Myklebust [Wed, 30 Jul 2014 01:34:30 +0000 (21:34 -0400)]
nfsd: Make lock stateid take a reference to the lockowner

A necessary step toward client_mutex removal.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: add an operation for unhashing a stateowner
Jeff Layton [Wed, 30 Jul 2014 01:34:29 +0000 (21:34 -0400)]
nfsd: add an operation for unhashing a stateowner

Allow stateowners to be unhashed and destroyed when the last reference
is put. The unhashing must be idempotent. In a future patch, we'll add
some locking around it, but for now it's only protected by the
client_mutex.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: clean up lockowner refcounting when finding them
Jeff Layton [Wed, 30 Jul 2014 01:34:28 +0000 (21:34 -0400)]
nfsd: clean up lockowner refcounting when finding them

Ensure that when finding or creating a lockowner, that we get a
reference to it. For now, we also take an extra reference when a
lockowner is created that can be put when release_lockowner is called,
but we'll remove that in a later patch once we change how references are
held.

Since we no longer destroy lockowners in the event of an error in
nfsd4_lock, we must change how the seqid gets bumped in the lk_is_new
case. Instead of doing so on creation, do it manually in nfsd4_lock.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Add a mutex to protect the NFSv4.0 open owner replay cache
Jeff Layton [Wed, 30 Jul 2014 01:34:27 +0000 (21:34 -0400)]
nfsd: Add a mutex to protect the NFSv4.0 open owner replay cache

We don't want to rely on the client_mutex for protection in the case of
NFSv4 open owners. Instead, we add a mutex that will only be taken for
NFSv4.0 state mutating operations, and that will be released once the
entire compound is done.

Also, ensure that nfsd4_cstate_assign_replay/nfsd4_cstate_clear_replay
take a reference to the stateowner when they are using it for NFSv4.0
open and lock replay caching.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Add reference counting to state owners
Jeff Layton [Wed, 30 Jul 2014 01:34:26 +0000 (21:34 -0400)]
nfsd: Add reference counting to state owners

The way stateowners are managed today is somewhat awkward. They need to
be explicitly destroyed, even though the stateids reference them. This
will be particularly problematic when we remove the client_mutex.

We may create a new stateowner and attempt to open a file or set a lock,
and have that fail. In the meantime, another RPC may come in that uses
that same stateowner and succeed. We can't have the first task tearing
down the stateowner in that situation.

To fix this, we need to change how stateowners are tracked altogether.
Refcount them and only destroy them once all stateids that reference
them have been destroyed. This patch starts by adding the refcounting
necessary to do that.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Migrate the stateid reference into nfs4_find_stateid_by_type()
Trond Myklebust [Wed, 30 Jul 2014 01:34:25 +0000 (21:34 -0400)]
nfsd: Migrate the stateid reference into nfs4_find_stateid_by_type()

Allow nfs4_find_stateid_by_type to take the stateid reference, while
still holding the &cl->cl_lock. Necessary step toward client_mutex
removal.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Migrate the stateid reference into nfs4_lookup_stateid()
Trond Myklebust [Wed, 30 Jul 2014 01:34:24 +0000 (21:34 -0400)]
nfsd: Migrate the stateid reference into nfs4_lookup_stateid()

Allow nfs4_lookup_stateid to take the stateid reference, instead
of having all the callers do so.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Migrate the stateid reference into nfs4_preprocess_seqid_op
Trond Myklebust [Wed, 30 Jul 2014 01:34:23 +0000 (21:34 -0400)]
nfsd: Migrate the stateid reference into nfs4_preprocess_seqid_op

Allow nfs4_preprocess_seqid_op to take the stateid reference, instead
of having all the callers do so.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Add reference counting to nfs4_preprocess_confirmed_seqid_op
Trond Myklebust [Wed, 30 Jul 2014 01:34:22 +0000 (21:34 -0400)]
nfsd: Add reference counting to nfs4_preprocess_confirmed_seqid_op

Ensure that all the callers put the open stateid after use.
Necessary step toward client_mutex removal.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: nfsd4_open_confirm() must reference the open stateid
Trond Myklebust [Wed, 30 Jul 2014 01:34:21 +0000 (21:34 -0400)]
nfsd: nfsd4_open_confirm() must reference the open stateid

Ensure that nfsd4_open_confirm() keeps a reference to the open
stateid until it is done working with it.

Necessary step toward client_mutex removal.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Prepare nfsd4_close() for open stateid referencing
Trond Myklebust [Wed, 30 Jul 2014 01:34:20 +0000 (21:34 -0400)]
nfsd: Prepare nfsd4_close() for open stateid referencing

Prepare nfsd4_close for a future where nfs4_preprocess_seqid_op()
hands it a fully referenced open stateid. Necessary step toward
client_mutex removal.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: nfsd4_process_open2() must reference the open stateid
Trond Myklebust [Wed, 30 Jul 2014 01:34:19 +0000 (21:34 -0400)]
nfsd: nfsd4_process_open2() must reference the open stateid

Ensure that nfsd4_process_open2() keeps a reference to the open
stateid until it is done working with it. Necessary step toward
client_mutex removal.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: nfsd4_process_open2() must reference the delegation stateid
Trond Myklebust [Wed, 30 Jul 2014 01:34:18 +0000 (21:34 -0400)]
nfsd: nfsd4_process_open2() must reference the delegation stateid

Ensure that nfsd4_process_open2() keeps a reference to the delegation
stateid until it is done working with it. Necessary step toward
client_mutex removal.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Ensure that nfs4_open_delegation() references the delegation stateid
Trond Myklebust [Wed, 30 Jul 2014 01:34:17 +0000 (21:34 -0400)]
nfsd: Ensure that nfs4_open_delegation() references the delegation stateid

Ensure that nfs4_open_delegation() keeps a reference to the delegation
stateid until it is done working with it. Necessary step toward
client_mutex removal.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: nfsd4_locku() must reference the lock stateid
Trond Myklebust [Wed, 30 Jul 2014 01:34:16 +0000 (21:34 -0400)]
nfsd: nfsd4_locku() must reference the lock stateid

Ensure that nfsd4_locku() keeps a reference to the lock stateid
until it is done working with it. Necessary step toward client_mutex
removal.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Add reference counting to lock stateids
Trond Myklebust [Wed, 30 Jul 2014 01:34:15 +0000 (21:34 -0400)]
nfsd: Add reference counting to lock stateids

Ensure that nfsd4_lock() references the lock stateid while it is
manipulating it. Not currently necessary, but will be once the
client_mutex is removed.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: ensure atomicity in nfsd4_free_stateid and nfsd4_validate_stateid
Jeff Layton [Wed, 30 Jul 2014 01:34:14 +0000 (21:34 -0400)]
nfsd: ensure atomicity in nfsd4_free_stateid and nfsd4_validate_stateid

Hold the cl_lock over the bulk of these functions. In addition to
ensuring that they aren't freed prematurely, this will also help prevent
a potential race that could be introduced later. Once we remove the
client_mutex, it'll be possible for FREE_STATEID and CLOSE to race and
for both to try to put the "persistent" reference to the stateid.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: clean up races in lock stateid searching and creation
Jeff Layton [Wed, 30 Jul 2014 01:34:13 +0000 (21:34 -0400)]
nfsd: clean up races in lock stateid searching and creation

Preparation for removal of the client_mutex.

Currently, no lock aside from the client_mutex is held when calling
find_lock_state. Ensure that the cl_lock is held by adding a lockdep
assertion.

Once we remove the client_mutex, it'll be possible for another thread to
race in and insert a lock state for the same file after we search but
before we insert a new one. Ensure that doesn't happen by redoing the
search after allocating a new stid that we plan to insert. If one is
found just put the one that was allocated.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Add locking to protect the state owner lists
Jeff Layton [Wed, 30 Jul 2014 01:34:12 +0000 (21:34 -0400)]
nfsd: Add locking to protect the state owner lists

Change to using the clp->cl_lock for this. For now, there's a lot of
cl_lock thrashing, but in later patches we'll eliminate that and close
the potential races that can occur when releasing the cl_lock while
walking the lists. For now, the client_mutex prevents those races.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: do filp_close in sc_free callback for lock stateids
Jeff Layton [Wed, 30 Jul 2014 01:34:11 +0000 (21:34 -0400)]
nfsd: do filp_close in sc_free callback for lock stateids

Releasing locks when we unhash the stateid instead of doing so only when
the stateid is actually released will be problematic in later patches
when we need to protect the unhashing with spinlocks. Move it into the
sc_free operation instead.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd4: use cl_lock to synchronize all stateid idr calls
Jeff Layton [Wed, 30 Jul 2014 01:34:10 +0000 (21:34 -0400)]
nfsd4: use cl_lock to synchronize all stateid idr calls

Currently, this is serialized by the client_mutex, which is slated for
removal. Add finer-grained locking here. Also, do some cleanup around
find_stateid to prepare for taking references.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Benny Halevy <bhalevy@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Add a struct nfs4_file field to struct nfs4_stid
Trond Myklebust [Wed, 30 Jul 2014 01:34:08 +0000 (21:34 -0400)]
nfsd: Add a struct nfs4_file field to struct nfs4_stid

All stateids are associated with a nfs4_file. Let's consolidate.
Replace delegation->dl_file with the dl_stid.sc_file, and
nfs4_ol_stateid->st_file with st_stid.sc_file.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Add reference counting to the lock and open stateids
Trond Myklebust [Wed, 30 Jul 2014 01:34:06 +0000 (21:34 -0400)]
nfsd: Add reference counting to the lock and open stateids

When we remove the client_mutex, we'll need to be able to ensure that
these objects aren't destroyed while we're not holding locks.

Add a ->free() callback to the struct nfs4_stid, so that we can
release a reference to the stid without caring about the contents.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: print status when nfsd4_open fails to open file it just created
Jeff Layton [Wed, 30 Jul 2014 01:37:44 +0000 (21:37 -0400)]
nfsd: print status when nfsd4_open fails to open file it just created

It's possible for nfsd to fail opening a file that it has just created.
When that happens, we throw a WARN but it doesn't include any info about
the error code. Print the status code to give us a bit more info.

Our QA group hit some of these warnings under some very heavy stress
testing. My suspicion is that they hit the file-max limit, but it's hard
to know for sure. Go ahead and add a -ENFILE mapping to
nfserr_serverfault to make the error more distinct (and correct).

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agoSUNRPC: Allow svc_reserve() to notify TCP socket that space has been freed
Trond Myklebust [Fri, 25 Jul 2014 03:59:33 +0000 (23:59 -0400)]
SUNRPC: Allow svc_reserve() to notify TCP socket that space has been freed

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agoSUNRPC: svc_tcp_write_space: don't clear SOCK_NOSPACE prematurely
Trond Myklebust [Fri, 25 Jul 2014 03:59:32 +0000 (23:59 -0400)]
SUNRPC: svc_tcp_write_space: don't clear SOCK_NOSPACE prematurely

If requests are queued in the socket inbuffer waiting for an
svc_tcp_has_wspace() requirement to be satisfied, then we do not want
to clear the SOCK_NOSPACE flag until we've satisfied that requirement.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agoSUNRPC: Reduce contention in svc_xprt_enqueue()
Trond Myklebust [Fri, 25 Jul 2014 03:59:31 +0000 (23:59 -0400)]
SUNRPC: Reduce contention in svc_xprt_enqueue()

Ensure that all calls to svc_xprt_enqueue() except svc_xprt_received()
check the value of XPT_BUSY, before attempting to grab spinlocks etc.
This is to avoid situations such as the following "perf" trace,
which shows heavy contention on the pool spinlock:

    54.15%            nfsd  [kernel.kallsyms]        [k] _raw_spin_lock_bh
                      |
                      --- _raw_spin_lock_bh
                         |
                         |--71.43%-- svc_xprt_enqueue
                         |          |
                         |          |--50.31%-- svc_reserve
                         |          |
                         |          |--31.35%-- svc_xprt_received
                         |          |
                         |          |--18.34%-- svc_tcp_data_ready
...

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: remove dl_fh field from struct nfs4_delegation
Jeff Layton [Fri, 25 Jul 2014 11:34:27 +0000 (07:34 -0400)]
nfsd: remove dl_fh field from struct nfs4_delegation

Now that the nfs4_file has a filehandle in it, we no longer need to
keep a per-delegation copy of it. Switch to using the one in the
nfs4_file instead.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: give block_delegation and delegation_blocked its own spinlock
Jeff Layton [Fri, 25 Jul 2014 11:34:26 +0000 (07:34 -0400)]
nfsd: give block_delegation and delegation_blocked its own spinlock

The state lock can be fairly heavily contended, and there's no reason
that nfs4_file lookups and delegation_blocked should be mutually
exclusive.  Let's give the new block_delegation code its own spinlock.
It does mean that we'll need to take a different lock in the delegation
break code, but that's not generally as critical to performance.

Cc: Neil Brown <neilb@suse.de>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: clean up nfs4_set_delegation
Jeff Layton [Fri, 25 Jul 2014 11:34:25 +0000 (07:34 -0400)]
nfsd: clean up nfs4_set_delegation

Move the alloc_init_deleg call into nfs4_set_delegation and change the
function to return a pointer to the delegation or an IS_ERR return. This
allows us to skip allocating a delegation if the file has already
experienced a lease conflict.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: clean up arguments to nfs4_open_delegation
Jeff Layton [Fri, 25 Jul 2014 11:34:24 +0000 (07:34 -0400)]
nfsd: clean up arguments to nfs4_open_delegation

No need to pass in a net pointer since we can derive that.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: drop unused stp arg to alloc_init_deleg
Jeff Layton [Fri, 25 Jul 2014 11:34:23 +0000 (07:34 -0400)]
nfsd: drop unused stp arg to alloc_init_deleg

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Convert delegation counter to an atomic_long_t type
Trond Myklebust [Fri, 25 Jul 2014 11:34:22 +0000 (07:34 -0400)]
nfsd: Convert delegation counter to an atomic_long_t type

We want to convert to an atomic type so that we don't need to lock
across the call to alloc_init_deleg(). Then convert to a long type so
that we match the size of 'max_delegations'.

None of this is a problem today, but it will be once we remove
client_mutex protection.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: ensure that clp->cl_revoked list is protected by clp->cl_lock
Jeff Layton [Fri, 25 Jul 2014 11:34:21 +0000 (07:34 -0400)]
nfsd: ensure that clp->cl_revoked list is protected by clp->cl_lock

Currently, both destroy_revoked_delegation and revoke_delegation
manipulate the cl_revoked list without any locking aside from the
client_mutex. Ensure that the clp->cl_lock is held when manipulating it,
except for the list walking in destroy_client. At that point, the client
should no longer be in use, and so it should be safe to walk the list
without any locking. That also means that we don't need to do the
list_splice_init there either.

Also, the fact that revoke_delegation deletes dl_recall_lru list_head
without any locking makes it difficult to know whether it's doing so
safely in all cases. Move the list_del_init calls into the callers, and
add a WARN_ON in the event that t's passed a delegation that has a
non-empty list_head.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: fully unhash delegations when revoking them
Jeff Layton [Fri, 25 Jul 2014 11:34:20 +0000 (07:34 -0400)]
nfsd: fully unhash delegations when revoking them

Ensure that the delegations cannot be found by the laundromat etc once
we add them to the various 'revoke' lists.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: simplify stateid allocation and file handling
Trond Myklebust [Fri, 25 Jul 2014 11:34:19 +0000 (07:34 -0400)]
nfsd: simplify stateid allocation and file handling

Don't allow stateids to clear the open file pointer until they are
being destroyed. In a later patches we'll want to rely on the fact that
we have a valid file pointer when dealing with the stateid and this
will save us from having to do a lot of NULL pointer checks before
doing so.

Also, move to allocating stateids with kzalloc and get rid of the
explicit zeroing of fields.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Do not let nfs4_file pin the struct inode
Jeff Layton [Wed, 23 Jul 2014 20:17:41 +0000 (16:17 -0400)]
nfsd: Do not let nfs4_file pin the struct inode

Remove the fi_inode field in struct nfs4_file in order to remove the
possibility of struct nfs4_file pinning the inode when it does not have
any open state.

The only place we still need to get to an inode is in check_for_locks,
so change it to use find_any_file and use the inode from any that it
finds. If it doesn't find one, then just assume there aren't any.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: nfs4_check_fh - make it actually check the filehandle
Trond Myklebust [Wed, 23 Jul 2014 20:17:40 +0000 (16:17 -0400)]
nfsd: nfs4_check_fh - make it actually check the filehandle

...instead of just checking the inode that corresponds to it.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Use the filehandle to look up the struct nfs4_file instead of inode
Trond Myklebust [Wed, 23 Jul 2014 20:17:39 +0000 (16:17 -0400)]
nfsd: Use the filehandle to look up the struct nfs4_file instead of inode

This makes more sense anyway since an inode pointer value can change
even when the filehandle doesn't.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Store the filehandle with the struct nfs4_file
Trond Myklebust [Wed, 23 Jul 2014 20:17:38 +0000 (16:17 -0400)]
nfsd: Store the filehandle with the struct nfs4_file

For use when we may not have a struct inode.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd4: convert comma to semicolon
Himangi Saraogi [Wed, 23 Jul 2014 14:42:31 +0000 (20:12 +0530)]
nfsd4: convert comma to semicolon

Replace a comma between expression statements by a semicolon. This changes
the semantics of the code, but given the current indentation appears to be
what is intended.

A simplified version of the Coccinelle semantic patch that performs this
transformation is as follows:
// <smpl>
@r@
expression e1,e2;
@@

 e1
-,
+;
 e2;
// </smpl>

Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
Acked-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agosvcrdma: Double the default credit limit
Chuck Lever [Tue, 22 Jul 2014 21:48:04 +0000 (17:48 -0400)]
svcrdma: Double the default credit limit

The RDMA credit limit controls how many concurrent RPCs are allowed
per connection.

An NFS/RDMA client and server exchange their credit limits in the
RPC/RDMA headers. The Linux client and the Solaris client and server
allow 32 credits. The Linux server allows only 16, which limits its
performance.

Set the server's default credit limit to 32, like the other well-
known implementations, so the out-of-the-shrinkwrap performance of
the Linux server is better.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: ensure that st_access_bmap and st_deny_bmap are initialized to 0
Jeff Layton [Wed, 23 Jul 2014 17:46:49 +0000 (13:46 -0400)]
nfsd: ensure that st_access_bmap and st_deny_bmap are initialized to 0

Open stateids must be initialized with the st_access_bmap and
st_deny_bmap set to 0, so that nfs4_get_vfs_file can properly record
their state in old_access_bmap and old_deny_bmap.

This bug was introduced in commit baeb4ff0e502 (nfsd: make deny mode
enforcement more efficient and close races in it) and was causing the
refcounts to end up incorrect when nfs4_get_vfs_file returned an error
after bumping the refcounts. This made it impossible to unmount the
underlying filesystem after running pynfs tests that involve deny modes.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agosvcrdma: Add zero padding if the client doesn't send it
Chuck Lever [Tue, 22 Jul 2014 20:00:40 +0000 (16:00 -0400)]
svcrdma: Add zero padding if the client doesn't send it

See RFC 5666 section 3.7: clients don't have to send zero XDR
padding.

BugLink: https://bugzilla.linux-nfs.org/show_bug.cgi?id=246
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: bump dl_time when unhashing delegation
Jeff Layton [Tue, 22 Jul 2014 17:52:06 +0000 (13:52 -0400)]
nfsd: bump dl_time when unhashing delegation

There's a potential race between a lease break and DELEGRETURN call.

Suppose a lease break comes in and queues the workqueue job for a
delegation, but it doesn't run just yet. Then, a DELEGRETURN comes in
finds the delegation and calls destroy_delegation on it to unhash it and
put its primary reference.

Next, the workqueue job runs and queues the delegation back onto the
del_recall_lru list, issues the CB_RECALL and puts the final reference.
With that, the final reference to the delegation is put, but it's still
on the LRU list.

When we go to unhash a delegation, it's because we intend to get rid of
it soon afterward, so we don't want lease breaks to mess with it once
that occurs. Fix this by bumping the dl_time whenever we unhash a
delegation, to ensure that lease breaks don't monkey with it.

I believe this is a regression due to commit 02e1215f9f7 (nfsd: Avoid
taking state_lock while holding inode lock in nfsd_break_one_deleg).
Prior to that, the state_lock was held in the lm_break callback itself,
and that would have prevented this race.

Cc: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: Move the delegation reference counter into the struct nfs4_stid
Trond Myklebust [Mon, 21 Jul 2014 13:34:58 +0000 (09:34 -0400)]
nfsd: Move the delegation reference counter into the struct nfs4_stid

We will want to add reference counting to the lock stateid and open
stateids too in later patches.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
9 years agonfsd: fix race that grants unrecallable delegation
Jeff Layton [Mon, 21 Jul 2014 13:34:57 +0000 (09:34 -0400)]
nfsd: fix race that grants unrecallable delegation

If nfs4_setlease succesfully acquires a new delegation, then another
task breaks the delegation before we reach hash_delegation_locked, then
the breaking task will see an empty fi_delegations list and do nothing.
The client will receive an open reply incorrectly granting a delegation
and will never receive a recall.

Move more of the delegation fields to be protected by the fi_lock. It's
more granular than the state_lock and in later patches we'll want to
be able to rely on it in addition to the state_lock.

Attempt to acquire a delegation. If that succeeds, take the spinlocks
and then check to see if the file has had a conflict show up since then.
If it has, then we assume that the lease is no longer valid and that
we shouldn't hand out a delegation.

There's also one more potential (but very unlikely) problem. If the
lease is broken before the delegation is hashed, then it could leak.
In the event that the fi_delegations list is empty, reset the
fl_break_time to jiffies so that it's cleaned up ASAP by
the normal lease handling code.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>