Merge tag 'nfs-for-4.13-2' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client bugfixes from Anna Schumaker:
"Stable bugfix:
- Fix error reporting regression
Bugfixes:
- Fix setting filelayout ds address race
- Fix subtle access bug when using ACLs
- Fix setting mnt3_counts array size
- Fix a couple of pNFS commit races"
* tag 'nfs-for-4.13-2' of git://git.linux-nfs.org/projects/anna/linux-nfs:
NFS/filelayout: Fix racy setting of fl->dsaddr in filelayout_check_deviceid()
NFS: Be more careful about mapping file permissions
NFS: Store the raw NFS access mask in the inode's access cache
NFSv3: Convert nfs3_proc_access() to use nfs_access_set_mask()
NFS: Refactor NFS access to kernel access mask calculation
net/sunrpc/xprt_sock: fix regression in connection error reporting.
nfs: count correct array for mnt3_counts array size
Revert commit 722f0b8911
("pNFS: Don't send COMMITs to the DSes if...")
pNFS/flexfiles: Handle expired layout segments in ff_layout_initiate_commit()
NFS: Fix another COMMIT race in pNFS
NFS: Fix a COMMIT race in pNFS
mount: copy the port field into the cloned nfs_server structure.
NFS: Don't run wake_up_bit() when nobody is waiting...
nfs: add export operations
This commit is contained in:
47
fs/nfs/dir.c
47
fs/nfs/dir.c
@@ -2372,16 +2372,40 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_access_add_cache);
|
||||
|
||||
#define NFS_MAY_READ (NFS4_ACCESS_READ)
|
||||
#define NFS_MAY_WRITE (NFS4_ACCESS_MODIFY | \
|
||||
NFS4_ACCESS_EXTEND | \
|
||||
NFS4_ACCESS_DELETE)
|
||||
#define NFS_FILE_MAY_WRITE (NFS4_ACCESS_MODIFY | \
|
||||
NFS4_ACCESS_EXTEND)
|
||||
#define NFS_DIR_MAY_WRITE NFS_MAY_WRITE
|
||||
#define NFS_MAY_LOOKUP (NFS4_ACCESS_LOOKUP)
|
||||
#define NFS_MAY_EXECUTE (NFS4_ACCESS_EXECUTE)
|
||||
static int
|
||||
nfs_access_calc_mask(u32 access_result, umode_t umode)
|
||||
{
|
||||
int mask = 0;
|
||||
|
||||
if (access_result & NFS_MAY_READ)
|
||||
mask |= MAY_READ;
|
||||
if (S_ISDIR(umode)) {
|
||||
if ((access_result & NFS_DIR_MAY_WRITE) == NFS_DIR_MAY_WRITE)
|
||||
mask |= MAY_WRITE;
|
||||
if ((access_result & NFS_MAY_LOOKUP) == NFS_MAY_LOOKUP)
|
||||
mask |= MAY_EXEC;
|
||||
} else if (S_ISREG(umode)) {
|
||||
if ((access_result & NFS_FILE_MAY_WRITE) == NFS_FILE_MAY_WRITE)
|
||||
mask |= MAY_WRITE;
|
||||
if ((access_result & NFS_MAY_EXECUTE) == NFS_MAY_EXECUTE)
|
||||
mask |= MAY_EXEC;
|
||||
} else if (access_result & NFS_MAY_WRITE)
|
||||
mask |= MAY_WRITE;
|
||||
return mask;
|
||||
}
|
||||
|
||||
void nfs_access_set_mask(struct nfs_access_entry *entry, u32 access_result)
|
||||
{
|
||||
entry->mask = 0;
|
||||
if (access_result & NFS4_ACCESS_READ)
|
||||
entry->mask |= MAY_READ;
|
||||
if (access_result &
|
||||
(NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE))
|
||||
entry->mask |= MAY_WRITE;
|
||||
if (access_result & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
|
||||
entry->mask |= MAY_EXEC;
|
||||
entry->mask = access_result;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_access_set_mask);
|
||||
|
||||
@@ -2389,6 +2413,7 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
|
||||
{
|
||||
struct nfs_access_entry cache;
|
||||
bool may_block = (mask & MAY_NOT_BLOCK) == 0;
|
||||
int cache_mask;
|
||||
int status;
|
||||
|
||||
trace_nfs_access_enter(inode);
|
||||
@@ -2404,7 +2429,8 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
|
||||
goto out;
|
||||
|
||||
/* Be clever: ask server to check for all possible rights */
|
||||
cache.mask = MAY_EXEC | MAY_WRITE | MAY_READ;
|
||||
cache.mask = NFS_MAY_LOOKUP | NFS_MAY_EXECUTE
|
||||
| NFS_MAY_WRITE | NFS_MAY_READ;
|
||||
cache.cred = cred;
|
||||
cache.jiffies = jiffies;
|
||||
status = NFS_PROTO(inode)->access(inode, &cache);
|
||||
@@ -2418,7 +2444,8 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
|
||||
}
|
||||
nfs_access_add_cache(inode, &cache);
|
||||
out_cached:
|
||||
if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
|
||||
cache_mask = nfs_access_calc_mask(cache.mask, inode->i_mode);
|
||||
if ((mask & ~cache_mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
|
||||
status = -EACCES;
|
||||
out:
|
||||
trace_nfs_access_exit(inode, status);
|
||||
|
Reference in New Issue
Block a user