summaryrefslogtreecommitdiff
path: root/fs/nfsd/nfs4state.c
AgeCommit message (Collapse)AuthorFilesLines
2011-09-01nfsd4: centralize handling of replay ownersJ. Bruce Fields1-21/+4
Set the stateowner associated with a replay in one spot in nfs4_preprocess_seqid_op() and keep it in cstate. This allows removing a few lines of boilerplate from all the nfs4_preprocess_seqid_op() callers. Also turn ENCODE_SEQID_OP_TAIL into a function while we're here. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-09-01nfsd4: make delegation stateid's seqid start at 1J. Bruce Fields1-4/+4
Thanks to Casey for reminding me that 5661 gives a special meaning to a value of 0 in the stateid's seqid field, so all stateid's should start out with si_generation 1. We were doing that in the open and lock cases for minorversion 1, but not for the delegation stateid, and not for openstateid's with v4.0. It doesn't *really* matter much for v4.0 or for delegation stateid's (which never get the seqid field incremented), but we may as well do the same for all of them. Reported-by: Casey Bodley <cbodley@citi.umich.edu> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-09-01nfsd4: simplify stateid generation code, fix wraparoundJ. Bruce Fields1-29/+23
Follow the recommendation from rfc3530bis for stateid generation number wraparound, simplify some code, and fix or remove incorrect comments. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-09-01nfsd4: consolidate lock & open stateid tablesJ. Bruce Fields1-48/+15
There's no reason to have two separate hash tables for open and lock stateid's. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-09-01nfsd4: simplify distinguishing lock & open stateid'sJ. Bruce Fields1-6/+3
The trick free_stateid is using is a little cheesy, and we'll have more uses for this field later. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-08-27nfsd4: remove redundant is_open_owner checkJ. Bruce Fields1-2/+0
When called with OPEN_STATE, preprocess_seqid_op only returns an open stateid, hence only an open owner. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-08-27nfsd4: get lock checks out of preprocess_seqid_opJ. Bruce Fields1-29/+20
We've got some lock-specific code here in nfs4_preprocess_seqid_op which is only used by nfsd4_lock(). Move it to the caller. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-08-27nfsd4: simplify lock openmode checkJ. Bruce Fields1-10/+5
Note that the special handling for the lock stateid case is already done by nfs4_check_openmode() (as of 02921914170e3b7fea1cd82dac9713685d2de5e2 "nfsd4: fix openmode checking on IO using lock stateid") so we no longer need these two cases in the caller. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-08-27nfsd4: remove HAS_SESSIONJ. Bruce Fields1-20/+10
This flag doesn't really buy us anything. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-08-27nfsd4: cleanup lock/stateowner initializationJ. Bruce Fields1-48/+52
Share some common code, stop doing silly things like initializing a list head immediately before adding it to a list, etc. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-08-27nfsd4: name openowner data structures more clearlyJ. Bruce Fields1-18/+18
These appear to be generic (for both open and lock owners), but they're actually just for open owners. This has confused me more than once. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-08-27nfsd4: replace some macros by functionsJ. Bruce Fields1-15/+38
For all the usual reasons. (Type safety, readability.) Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-08-27nfsd4: stop using nfserr_resource for transitory errorsJ. Bruce Fields1-7/+7
The server is returning nfserr_resource for both permanent errors and for errors (like allocation failures) that might be resolved by retrying later. Save nfserr_resource for the former and use delay/jukebox for the latter. Cc: stable@kernel.org Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-08-27nfsd4: simplify recovery dir settingJ. Bruce Fields1-40/+1
Move around some of this code, simplify a bit. Reviewed-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-08-27nfsd4: it's OK to return nfserr_symlinkJ. Bruce Fields1-5/+1
The nfsd4 code has a bunch of special exceptions for error returns which map nfserr_symlink to other errors. In fact, the spec makes it clear that nfserr_symlink is to be preferred over less specific errors where possible. The patch that introduced it back in 2.6.4 is "kNFSd: correct symlink related error returns.", which claims that these special exceptions are represent an NFSv4 break from v2/v3 tradition--when in fact the symlink error was introduced with v4. I suspect what happened was pynfs tests were written that were overly faithful to the (known-incomplete) rfc3530 error return lists, and then code was fixed up mindlessly to make the tests pass. Delete these unnecessary exceptions. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-07-23nfsd: don't break lease on CLAIM_DELEGATE_CURCasey Bodley1-6/+12
CLAIM_DELEGATE_CUR is used in response to a broken lease; allowing it to break the lease and return EAGAIN leaves the client unable to make progress in returning the delegation nfs4_get_vfs_file() now takes struct nfsd4_open for access to the claim type, and calls nfsd_open() with NFSD_MAY_NOT_BREAK_LEASE when claim type is CLAIM_DELEGATE_CUR Signed-off-by: Casey Bodley <cbodley@citi.umich.edu> Cc: stable@kernel.org Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-07-21locks: rename lock-manager opsJ. Bruce Fields1-2/+2
Both the filesystem and the lock manager can associate operations with a lock. Confusingly, one of them (fl_release_private) actually has the same name in both operation structures. It would save some confusion to give the lock-manager ops different names. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-07-16nfsd41: check the size of requestMi Jinlong1-0/+12
Check in SEQUENCE that the request doesn't exceed maxreq_sz for the given session. Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-07-16nfsd41: error out when client sets maxreq_sz or maxresp_sz too smallMi Jinlong1-0/+27
According to RFC5661, 18.36.3, "if the client selects a value for ca_maxresponsesize such that a replier on a channel could never send a response,the server SHOULD return NFS4ERR_TOOSMALL in the CREATE_SESSION reply." So, error out when the client sets a maxreq_sz less than the minimum possible SEQUENCE request size, or sets a maxresp_sz less than the minimum possible SEQUENCE reply size. Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-07-16nfsd4: fix file leak on open_downgradeJ. Bruce Fields1-23/+8
Stateid's hold a read reference for a read open, a write reference for a write open, and an additional one of each for each read+write open. The latter wasn't getting put on a downgrade, so something like: open RW open R downgrade to R was resulting in a file leak. Also fix an imbalance in an error path. Regression from 7d94784293096c0a46897acdb83be5abd9278ece "nfsd4: fix downgrade/lock logic". Cc: stable@kernel.org Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-07-16nfsd4: remember to put RW access on stateid destructionJ. Bruce Fields1-11/+6
Without this, for example, open read open read+write close will result in a struct file leak. Regression from 7d94784293096c0a46897acdb83be5abd9278ece "nfsd4: fix downgrade/lock logic". Cc: stable@kernel.org Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-07-16NFSD: Added TEST_STATEID operationBryan Schumaker1-0/+38
This operation is used by the client to check the validity of a list of stateids. Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-07-16NFSD: added FREE_STATEID operationBryan Schumaker1-0/+118
This operation is used by the client to tell the server to free a stateid. Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-05-29Merge branch 'for-2.6.40' of git://linux-nfs.org/~bfields/linuxLinus Torvalds1-9/+33
* 'for-2.6.40' of git://linux-nfs.org/~bfields/linux: (22 commits) nfsd: make local functions static NFSD: Remove unused variable from nfsd4_decode_bind_conn_to_session() NFSD: Check status from nfsd4_map_bcts_dir() NFSD: Remove setting unused variable in nfsd_vfs_read() nfsd41: error out on repeated RECLAIM_COMPLETE nfsd41: compare request's opcnt with session's maxops at nfsd4_sequence nfsd v4.1 lOCKT clientid field must be ignored nfsd41: add flag checking for create_session nfsd41: make sure nfs server process OPEN with EXCLUSIVE4_1 correctly nfsd4: fix wrongsec handling for PUTFH + op cases nfsd4: make fh_verify responsibility of nfsd_lookup_dentry caller nfsd4: introduce OPDESC helper nfsd4: allow fh_verify caller to skip pseudoflavor checks nfsd: distinguish functions of NFSD_MAY_* flags svcrpc: complete svsk processing on cb receive failure svcrpc: take advantage of tcp autotuning SUNRPC: Don't wait for full record to receive tcp data svcrpc: copy cb reply instead of pages svcrpc: close connection if client sends short packet svcrpc: note network-order types in svc_process_calldir ...
2011-05-18nfsd: make local functions staticDaniel Mack1-2/+2
This also fixes a number of sparse warnings. Signed-off-by: Daniel Mack <zonque@gmail.com> Cc: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: J. Bruce Fields <bfields@fieldses.org> Cc: Neil Brown <neilb@suse.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-04-30NFSD: Check status from nfsd4_map_bcts_dir()Bryan Schumaker1-2/+3
Compiling gave me this warning: fs/nfsd/nfs4state.c: In function ‘nfsd4_bind_conn_to_session’: fs/nfsd/nfs4state.c:1623:9: warning: variable ‘status’ set but not used [-Wunused-but-set-variable] The local variable "status" was being set by nfsd4_map_bcts_dir() and then ignored before calling nfsd4_new_conn(). Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-04-30nfsd41: error out on repeated RECLAIM_COMPLETEMi Jinlong1-5/+14
Servers are supposed to return nfserr_complete_already to clients that attempt to send multiple RECLAIM_COMPLETEs. Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-04-30nfsd41: compare request's opcnt with session's maxops at nfsd4_sequenceMi Jinlong1-0/+11
Make sure nfs server errors out if request contains more ops than channel allows. Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com> [bfields@redhat.com: use helper function] Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-04-30nfsd41: add flag checking for create_sessionMi Jinlong1-0/+3
Teach the NFS server to reject invalid create_session flags. Also do some minor formatting adjustments. Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-04-20nfsd4: Fix filp leakOGAWA Hirofumi1-1/+1
23fcf2ec93fb8573a653408316af599939ff9a8e (nfsd4: fix oops on lock failure) The above patch breaks free path for stp->st_file. If stp was inserted into sop->so_stateids, we have to free stp->st_file refcount. Because stp->st_file refcount itself is taken whether or not any refcounts are taken on the stp->st_file->fi_fds[]. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Cc: stable@kernel.org Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-04-18nfsd4: fix struct file leak on delegationJ. Bruce Fields1-0/+1
Introduced by acfdf5c383b38f7f4dddae41b97c97f1ae058f49. Cc: stable@kernel.org Reported-by: Gerhard Heift <ml-nfs-linux-20110412-ef47@gheift.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-04-12Merge branch 'for-2.6.39' of git://linux-nfs.org/~bfields/linuxLinus Torvalds1-3/+6
* 'for-2.6.39' of git://linux-nfs.org/~bfields/linux: nfsd4: fix oops on lock failure nfsd: fix auth_domain reference leak on nlm operations
2011-04-10nfsd4: fix oops on lock failureJ. Bruce Fields1-3/+6
Lock stateid's can have access_bmap 0 if they were only partially initialized (due to a failed lock request); handle that case in free_generic_stateid. ------------[ cut here ]------------ kernel BUG at fs/nfsd/nfs4state.c:380! invalid opcode: 0000 [#1] SMP last sysfs file: /sys/kernel/mm/ksm/run Modules linked in: nfs fscache md4 nls_utf8 cifs ip6table_filter ip6_tables ebtable_nat ebtables ipt_MASQUERADE iptable_nat nf_nat bridge stp llc nfsd lockd nfs_acl auth_rpcgss sunrpc ipv6 ppdev parport_pc parport pcnet32 mii pcspkr microcode i2c_piix4 BusLogic floppy [last unloaded: mperf] Pid: 1468, comm: nfsd Not tainted 2.6.38+ #120 VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform EIP: 0060:[<e24f180d>] EFLAGS: 00010297 CPU: 0 EIP is at nfs4_access_to_omode+0x1c/0x29 [nfsd] EAX: ffffffff EBX: dd758120 ECX: 00000000 EDX: 00000004 ESI: dd758120 EDI: ddfe657c EBP: dd54dde0 ESP: dd54dde0 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 Process nfsd (pid: 1468, ti=dd54c000 task=ddc92580 task.ti=dd54c000) Stack: dd54ddf0 e24f19ca 00000000 ddfe6560 dd54de08 e24f1a5d dd758130 deee3a20 ddfe6560 31270000 dd54df1c e24f52fd 0000000f dd758090 e2505dd0 0be304cf dbb51d68 0000000e ddfe657c ddcd8020 dd758130 dd758128 dd7580d8 dd54de68 Call Trace: [<e24f19ca>] free_generic_stateid+0x1c/0x3e [nfsd] [<e24f1a5d>] release_lockowner+0x71/0x8a [nfsd] [<e24f52fd>] nfsd4_lock+0x617/0x66c [nfsd] [<e24e57b6>] ? nfsd_setuser+0x199/0x1bb [nfsd] [<e24e056c>] ? nfsd_setuser_and_check_port+0x65/0x81 [nfsd] [<c07a0052>] ? _cond_resched+0x8/0x1c [<c04ca61f>] ? slab_pre_alloc_hook.clone.33+0x23/0x27 [<c04cac01>] ? kmem_cache_alloc+0x1a/0xd2 [<c04835a0>] ? __call_rcu+0xd7/0xdd [<e24e0dfb>] ? fh_verify+0x401/0x452 [nfsd] [<e24f0b61>] ? nfsd4_encode_operation+0x52/0x117 [nfsd] [<e24ea0d7>] ? nfsd4_putfh+0x33/0x3b [nfsd] [<e24f4ce6>] ? nfsd4_delegreturn+0xd4/0xd4 [nfsd] [<e24ea2c9>] nfsd4_proc_compound+0x1ea/0x33e [nfsd] [<e24de6ee>] nfsd_dispatch+0xd1/0x1a5 [nfsd] [<e1d6e1c7>] svc_process_common+0x282/0x46f [sunrpc] [<e1d6e578>] svc_process+0xdc/0xfa [sunrpc] [<e24de0fa>] nfsd+0xd6/0x115 [nfsd] [<e24de024>] ? nfsd_shutdown+0x24/0x24 [nfsd] [<c0454322>] kthread+0x62/0x67 [<c04542c0>] ? kthread_worker_fn+0x114/0x114 [<c07a6ebe>] kernel_thread_helper+0x6/0x10 Code: eb 05 b8 00 00 27 4f 8d 65 f4 5b 5e 5f 5d c3 83 e0 03 55 83 f8 02 89 e5 74 17 83 f8 03 74 05 48 75 09 eb 09 b8 02 00 00 00 eb 0b <0f> 0b 31 c0 eb 05 b8 01 00 00 00 5d c3 55 89 e5 57 56 89 d6 8d EIP: [<e24f180d>] nfs4_access_to_omode+0x1c/0x29 [nfsd] SS:ESP 0068:dd54dde0 ---[ end trace 2b0bf6c6557cb284 ]--- The trace route is: -> nfsd4_lock() -> if (lock->lk_is_new) { -> alloc_init_lock_stateid() 3739: stp->st_access_bmap = 0; ->if (status && lock->lk_is_new && lock_sop) -> release_lockowner() -> free_generic_stateid() -> nfs4_access_bmap_to_omode() -> nfs4_access_to_omode() 380: BUG(); ***** This problem was introduced by 0997b173609b9229ece28941c118a2a9b278796e. Reported-by: Mi Jinlong <mijinlong@cn.fujitsu.com> Tested-by: Mi Jinlong <mijinlong@cn.fujitsu.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-03-31Fix common misspellingsLucas De Marchi1-2/+2
Fixes generated by 'codespell' and manually reviewed. Signed-off-by: Lucas De Marchi <lucas.demarchi@profusion.mobi>
2011-03-17Merge create_session decoding fix into for-2.6.39J. Bruce Fields1-6/+7
This needs a further fixup!
2011-03-16nfs41: make sure nfs server return right ca_maxresponsesize_cachedMi Jinlong1-1/+2
According to rfc5661, ca_maxresponsesize_cached: Like ca_maxresponsesize, but the maximum size of a reply that will be stored in the reply cache (Section 2.10.6.1). For each channel, the server MAY decrease this value, but MUST NOT increase it. the latest kernel(2.6.38-rc8) may increase the value for ignoring request's ca_maxresponsesize_cached value. We should not ignore it. Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-03-09nfsd4: fix struct file leakJ. Bruce Fields1-11/+21
Make sure we properly reference count the struct files that a lock depends on, and release them when the lock stateid is released. This fixes a major leak of struct files when using locking over nfsv4. Cc: stable@kernel.org Reported-by: Rick Koshi <nfs-bug-report@more-right-rudder.com> Tested-by: Ivo Přikryl <prikryl@eurosat.cz> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-03-09nfsd4: minor nfs4state.c reshufflingJ. Bruce Fields1-64/+61
Minor cleanup in preparation for a bugfix--moving some code to avoid forward references, etc. No change in functionality. Cc: stable@kernel.org Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-03-07nfsd: kill unused macro definitionShan Wei1-1/+1
These macros had never been used for several years. So, remove them. Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-03-07nfsd4: fix bad pointer on failure to find delegationJ. Bruce Fields1-6/+7
In case of a nonempty list, the return on error here is obviously bogus; it ends up being a pointer to the list head instead of to any valid delegation on the list. In particular, if nfsd4_delegreturn() hits this case, and you're quite unlucky, then renew_client may oops, and it may take an embarassingly long time to figure out why. Facepalm. BUG: unable to handle kernel NULL pointer dereference at 0000000000000090 IP: [<ffffffff81292965>] nfsd4_delegreturn+0x125/0x200 ... Cc: stable@kernel.org Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-02-14nfsd4: acquire only one lease per fileJ. Bruce Fields1-40/+55
Instead of acquiring one lease each time another client opens a file, nfsd can acquire just one lease to represent all of them, and reference count it to determine when to release it. This fixes a regression introduced by c45821d263a8a5109d69a9e8942b8d65bcd5f31a "locks: eliminate fl_mylease callback": after that patch, only the struct file * is used to determine who owns a given lease. But since we recently converted the server to share a single struct file per open, if we acquire multiple leases on the same file from nfsd, it then becomes impossible on unlocking a lease to determine which of those leases (all of whom share the same struct file *) we meant to remove. Thanks to Takashi Iwai <tiwai@suse.de> for catching a bug in a previous version of this patch. Tested-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-02-14nfsd4: modify fi_delegations under recall_lockJ. Bruce Fields1-4/+4
Modify fi_delegations only under the recall_lock, allowing us to use that list on lease breaks. Also some trivial cleanup to simplify later changes. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-02-14nfsd4: remove unused deleg dprintk's.J. Bruce Fields1-4/+0
These aren't all that useful, and get in the way of the next steps. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-02-14nfsd4: split lease setting into separate functionJ. Bruce Fields1-13/+19
Splitting some code into a separate function which we'll be adding some more to. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-02-14nfsd4: fix leak on allocation errorJ. Bruce Fields1-8/+10
Also share some common exit code. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-02-14nfsd4: add helper function for lease setupJ. Bruce Fields1-12/+21
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-02-14nfsd4: split up nfsd_break_deleg_cbJ. Bruce Fields1-18/+16
We'll be adding some more code here soon. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-01-15Merge branch 'for-2.6.38' of git://linux-nfs.org/~bfields/linuxLinus Torvalds1-98/+145
* 'for-2.6.38' of git://linux-nfs.org/~bfields/linux: (62 commits) nfsd4: fix callback restarting nfsd: break lease on unlink, link, and rename nfsd4: break lease on nfsd setattr nfsd: don't support msnfs export option nfsd4: initialize cb_per_client nfsd4: allow restarting callbacks nfsd4: simplify nfsd4_cb_prepare nfsd4: give out delegations more quickly in 4.1 case nfsd4: add helper function to run callbacks nfsd4: make sure sequence flags are set after destroy_session nfsd4: re-probe callback on connection loss nfsd4: set sequence flag when backchannel is down nfsd4: keep finer-grained callback status rpc: allow xprt_class->setup to return a preexisting xprt rpc: keep backchannel xprt as long as server connection rpc: move sk_bc_xprt to svc_xprt nfsd4: allow backchannel recovery nfsd4: support BIND_CONN_TO_SESSION nfsd4: modify session list under cl_lock Documentation: fl_mylease no longer exists ... Fix up conflicts in fs/nfsd/vfs.c with the vfs-scale work. The vfs-scale work touched some msnfs cases, and this merge removes support for that entirely, so the conflict was trivial to resolve.
2011-01-11nfsd4: allow restarting callbacksJ. Bruce Fields1-0/+1
If we lose the backchannel and then the client repairs the problem, resend any callbacks. We use a new cb_done flag to track whether there is still work to be done for the callback or whether it can be destroyed with the rpc. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2011-01-11nfsd4: give out delegations more quickly in 4.1 caseJ. Bruce Fields1-2/+15
Signed-off-by: J. Bruce Fields <bfields@redhat.com>