android_kernel_motorola_sm6225/fs/nfsd
Jeff Layton baeb4ff0e5 nfsd: make deny mode enforcement more efficient and close races in it
The current enforcement of deny modes is both inefficient and scattered
across several places, which makes it hard to guarantee atomicity. The
inefficiency is a problem now, and the lack of atomicity will mean races
once the client_mutex is removed.

First, we address the inefficiency. We have to track deny modes on a
per-stateid basis to ensure that open downgrades are sane, but when the
server goes to enforce them it has to walk the entire list of stateids
and check against each one.

Instead of doing that, maintain a per-nfs4_file deny mode. When a file
is opened, we simply set any deny bits in that mode that were specified
in the OPEN call. We can then use that unified deny mode to do a simple
check to see whether there are any conflicts without needing to walk the
entire stateid list.

The only time we'll need to walk the entire list of stateids is when a
stateid that has a deny mode on it is being released, or one is having
its deny mode downgraded. In that case, we must walk the entire list and
recalculate the fi_share_deny field. Since deny modes are pretty rare
today, this should be very rare under normal workloads.

To address the potential for races once the client_mutex is removed,
protect fi_share_deny with the fi_lock. In nfs4_get_vfs_file, check to
make sure that any deny mode we want to apply won't conflict with
existing access. If that's ok, then have nfs4_file_get_access check that
new access to the file won't conflict with existing deny modes.

If that also passes, then get file access references, set the correct
access and deny bits in the stateid, and update the fi_share_deny field.
If opening the file or truncating it fails, then unwind the whole mess
and return the appropriate error.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2014-07-11 11:06:32 -04:00
..
acl.h nfsd4: remove nfs4_acl_new 2014-07-08 17:14:27 -04:00
auth.c NFSD: Cleanup unused variable in nfsd_setuser() 2014-05-30 17:32:21 -04:00
auth.h nfsd: Remove nfsd_luid, nfsd_lgid, nfsd_ruid and nfsd_rgid 2013-02-13 06:15:51 -08:00
cache.h nfsd: get rid of unused function definition 2014-01-02 17:53:23 -05:00
current_stateid.h nfsd41: use current stateid by value 2012-02-15 11:20:45 -05:00
export.c NFSD: Using exp_get for export getting 2014-06-23 11:31:36 -04:00
export.h NFSD: Using exp_get for export getting 2014-06-23 11:31:36 -04:00
fault_inject.c nfsd: properly handle embedded newlines in fault_injection input 2014-06-23 11:31:38 -04:00
idmap.h nfsd4: use xdr_reserve_space in attribute encoding 2014-05-28 14:52:34 -04:00
Kconfig nfsd: fix Kconfig syntax 2013-10-26 15:37:26 -04:00
lockd.c nfsd: Remove deprecated nfsctl system call and related code. 2011-07-15 18:58:42 -04:00
Makefile NFSD: Added fault injection 2011-11-07 21:10:47 -05:00
netns.h nfsd: NFSv4 lock-owners are not associated to a specific file 2014-07-09 20:54:58 -04:00
nfs2acl.c nfsd: Remove assignments inside conditions 2014-05-22 15:52:23 -04:00
nfs3acl.c nfsd: Remove assignments inside conditions 2014-05-22 15:52:23 -04:00
nfs3proc.c NFSD: Remove iattr parameter from nfsd_symlink() 2014-07-08 17:14:31 -04:00
nfs3xdr.c NFSD: Using min/max/min_t/max_t for calculate 2014-06-23 11:31:36 -04:00
nfs4acl.c nfsd4: remove nfs4_acl_new 2014-07-08 17:14:27 -04:00
nfs4callback.c nfsd: set timeparms.to_maxval in setup_callback_client 2014-04-18 14:34:31 +02:00
nfs4idmap.c nfsd4: use xdr_reserve_space in attribute encoding 2014-05-28 14:52:34 -04:00
nfs4proc.c nfsd: Convert nfs4_check_open_reclaim() to work with lookup_clientid() 2014-07-09 20:55:07 -04:00
nfs4recover.c nfsd: switch to %p[dD] 2013-10-24 23:34:51 -04:00
nfs4state.c nfsd: make deny mode enforcement more efficient and close races in it 2014-07-11 11:06:32 -04:00
nfs4xdr.c NFSD: Fix memory leak in encoding denied lock 2014-07-09 20:55:08 -04:00
nfscache.c nfsd: clean up sparse endianness warnings in nfscache.c 2014-06-23 11:31:37 -04:00
nfsctl.c nfsd: add a new /proc/fs/nfsd/max_connections file 2014-07-08 17:14:32 -04:00
nfsd.h NFSD: Get rid of empty function nfs4_state_init 2014-05-08 14:59:52 -04:00
nfsfh.c nfsd: add appropriate __force directives to filehandle generation code 2014-06-23 11:31:37 -04:00
nfsfh.h nfsd: add appropriate __force directives to filehandle generation code 2014-06-23 11:31:37 -04:00
nfsproc.c nfsd: add a nfserrno mapping for -E2BIG to nfserr_fbig 2014-07-09 20:55:03 -04:00
nfssvc.c nfsd: add a new /proc/fs/nfsd/max_connections file 2014-07-08 17:14:32 -04:00
nfsxdr.c NFSD: Using min/max/min_t/max_t for calculate 2014-06-23 11:31:36 -04:00
state.h nfsd: make deny mode enforcement more efficient and close races in it 2014-07-11 11:06:32 -04:00
stats.c nfsd: move <linux/nfsd/stats.h> to fs/nfsd 2014-05-06 17:54:55 -04:00
stats.h nfsd: move <linux/nfsd/stats.h> to fs/nfsd 2014-05-06 17:54:55 -04:00
vfs.c nfsd: properly convert return from commit_metadata to __be32 2014-07-09 20:55:02 -04:00
vfs.h NFSD: Remove iattr parameter from nfsd_symlink() 2014-07-08 17:14:31 -04:00
xdr.h nfsd: handle vfs_getattr errors in acl protocol 2013-02-26 02:46:09 -05:00
xdr3.h nfsd: fix encode_entryplus_baggage stack usage 2014-01-23 13:50:27 -05:00
xdr4.h nfsd: Allow struct nfsd4_compound_state to cache the nfs4_client 2014-07-09 20:55:04 -04:00
xdr4cb.h nfsd4: check backchannel attributes on create_session 2013-04-09 16:53:56 -04:00