Skip to content

Commit 8e7757d

Browse files
committed
Merge tag 'nfs-for-4.14-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Hightlights include: Stable bugfixes: - Fix mirror allocation in the writeback code to avoid a use after free - Fix the O_DSYNC writes to use the correct byte range - Fix 2 use after free issues in the I/O code Features: - Writeback fixes to split up the inode->i_lock in order to reduce contention - RPC client receive fixes to reduce the amount of time the xprt->transport_lock is held when receiving data from a socket into am XDR buffer. - Ditto fixes to reduce contention between call side users of the rdma rb_lock, and its use in rpcrdma_reply_handler. - Re-arrange rdma stats to reduce false cacheline sharing. - Various rdma cleanups and optimisations. - Refactor the NFSv4.1 exchange id code and clean up the code. - Const-ify all instances of struct rpc_xprt_ops Bugfixes: - Fix the NFSv2 'sec=' mount option. - NFSv4.1: don't use machine credentials for CLOSE when using 'sec=sys' - Fix the NFSv3 GRANT callback when the port changes on the server. - Fix livelock issues with COMMIT - NFSv4: Use correct inode in _nfs4_opendata_to_nfs4_state() when doing and NFSv4.1 open by filehandle" * tag 'nfs-for-4.14-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (69 commits) NFS: Count the bytes of skipped subrequests in nfs_lock_and_join_requests() NFS: Don't hold the group lock when calling nfs_release_request() NFS: Remove pnfs_generic_transfer_commit_list() NFS: nfs_lock_and_join_requests and nfs_scan_commit_list can deadlock NFS: Fix 2 use after free issues in the I/O code NFS: Sync the correct byte range during synchronous writes lockd: Delete an error message for a failed memory allocation in reclaimer() NFS: remove jiffies field from access cache NFS: flush data when locking a file to ensure cache coherence for mmap. SUNRPC: remove some dead code. NFS: don't expect errors from mempool_alloc(). xprtrdma: Use xprt_pin_rqst in rpcrdma_reply_handler xprtrdma: Re-arrange struct rx_stats NFS: Fix NFSv2 security settings NFSv4.1: don't use machine credentials for CLOSE when using 'sec=sys' SUNRPC: ECONNREFUSED should cause a rebind. NFS: Remove unused parameter gfp_flags from nfs_pageio_init() NFSv4: Fix up mirror allocation SUNRPC: Add a separate spinlock to protect the RPC request receive list SUNRPC: Cleanup xs_tcp_read_common() ...
2 parents dd198ce + 1bd5d6d commit 8e7757d

36 files changed

+1228
-1133
lines changed

fs/lockd/clntlock.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,8 @@ reclaimer(void *ptr)
235235
struct net *net = host->net;
236236

237237
req = kmalloc(sizeof(*req), GFP_KERNEL);
238-
if (!req) {
239-
printk(KERN_ERR "lockd: reclaimer unable to alloc memory."
240-
" Locks for %s won't be reclaimed!\n",
241-
host->h_name);
238+
if (!req)
242239
return 0;
243-
}
244240

245241
allow_signal(SIGKILL);
246242

fs/nfs/callback_proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
5151
goto out_iput;
5252
res->size = i_size_read(inode);
5353
res->change_attr = delegation->change_attr;
54-
if (nfsi->nrequests != 0)
54+
if (nfs_have_writebacks(inode))
5555
res->change_attr++;
5656
res->ctime = inode->i_ctime;
5757
res->mtime = inode->i_mtime;

fs/nfs/delegation.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ bool nfs4_delegation_flush_on_close(const struct inode *inode)
10891089
delegation = rcu_dereference(nfsi->delegation);
10901090
if (delegation == NULL || !(delegation->type & FMODE_WRITE))
10911091
goto out;
1092-
if (nfsi->nrequests < delegation->pagemod_limit)
1092+
if (atomic_long_read(&nfsi->nrequests) < delegation->pagemod_limit)
10931093
ret = false;
10941094
out:
10951095
rcu_read_unlock();

fs/nfs/dir.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2260,7 +2260,6 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str
22602260
spin_lock(&inode->i_lock);
22612261
retry = false;
22622262
}
2263-
res->jiffies = cache->jiffies;
22642263
res->cred = cache->cred;
22652264
res->mask = cache->mask;
22662265
list_move_tail(&cache->lru, &nfsi->access_cache_entry_lru);
@@ -2296,7 +2295,6 @@ static int nfs_access_get_cached_rcu(struct inode *inode, struct rpc_cred *cred,
22962295
goto out;
22972296
if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS))
22982297
goto out;
2299-
res->jiffies = cache->jiffies;
23002298
res->cred = cache->cred;
23012299
res->mask = cache->mask;
23022300
err = 0;
@@ -2344,7 +2342,6 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
23442342
if (cache == NULL)
23452343
return;
23462344
RB_CLEAR_NODE(&cache->rb_node);
2347-
cache->jiffies = set->jiffies;
23482345
cache->cred = get_rpccred(set->cred);
23492346
cache->mask = set->mask;
23502347

@@ -2432,7 +2429,6 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
24322429
cache.mask = NFS_MAY_LOOKUP | NFS_MAY_EXECUTE
24332430
| NFS_MAY_WRITE | NFS_MAY_READ;
24342431
cache.cred = cred;
2435-
cache.jiffies = jiffies;
24362432
status = NFS_PROTO(inode)->access(inode, &cache);
24372433
if (status != 0) {
24382434
if (status == -ESTALE) {

fs/nfs/direct.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,13 +616,13 @@ nfs_direct_write_scan_commit_list(struct inode *inode,
616616
struct list_head *list,
617617
struct nfs_commit_info *cinfo)
618618
{
619-
spin_lock(&cinfo->inode->i_lock);
619+
mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
620620
#ifdef CONFIG_NFS_V4_1
621621
if (cinfo->ds != NULL && cinfo->ds->nwritten != 0)
622622
NFS_SERVER(inode)->pnfs_curr_ld->recover_commit_reqs(list, cinfo);
623623
#endif
624624
nfs_scan_commit_list(&cinfo->mds->list, list, cinfo, 0);
625-
spin_unlock(&cinfo->inode->i_lock);
625+
mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
626626
}
627627

628628
static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)

fs/nfs/file.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -631,11 +631,11 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
631631
if (result <= 0)
632632
goto out;
633633

634-
result = generic_write_sync(iocb, result);
635-
if (result < 0)
636-
goto out;
637634
written = result;
638635
iocb->ki_pos += written;
636+
result = generic_write_sync(iocb, written);
637+
if (result < 0)
638+
goto out;
639639

640640
/* Return error values */
641641
if (nfs_need_check_write(file, inode)) {
@@ -744,15 +744,18 @@ do_setlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
744744
goto out;
745745

746746
/*
747-
* Revalidate the cache if the server has time stamps granular
748-
* enough to detect subsecond changes. Otherwise, clear the
749-
* cache to prevent missing any changes.
747+
* Invalidate cache to prevent missing any changes. If
748+
* the file is mapped, clear the page cache as well so
749+
* those mappings will be loaded.
750750
*
751751
* This makes locking act as a cache coherency point.
752752
*/
753753
nfs_sync_mapping(filp->f_mapping);
754-
if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
754+
if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) {
755755
nfs_zap_caches(inode);
756+
if (mapping_mapped(filp->f_mapping))
757+
nfs_revalidate_mapping(inode, filp->f_mapping);
758+
}
756759
out:
757760
return status;
758761
}

fs/nfs/inode.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,7 +1285,6 @@ static bool nfs_file_has_buffered_writers(struct nfs_inode *nfsi)
12851285

12861286
static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
12871287
{
1288-
struct nfs_inode *nfsi = NFS_I(inode);
12891288
unsigned long ret = 0;
12901289

12911290
if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
@@ -1315,7 +1314,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
13151314
if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE)
13161315
&& (fattr->valid & NFS_ATTR_FATTR_SIZE)
13171316
&& i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size)
1318-
&& nfsi->nrequests == 0) {
1317+
&& !nfs_have_writebacks(inode)) {
13191318
i_size_write(inode, nfs_size_to_loff_t(fattr->size));
13201319
ret |= NFS_INO_INVALID_ATTR;
13211320
}
@@ -1823,7 +1822,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
18231822
if (new_isize != cur_isize) {
18241823
/* Do we perhaps have any outstanding writes, or has
18251824
* the file grown beyond our last write? */
1826-
if (nfsi->nrequests == 0 || new_isize > cur_isize) {
1825+
if (!nfs_have_writebacks(inode) || new_isize > cur_isize) {
18271826
i_size_write(inode, new_isize);
18281827
if (!have_writers)
18291828
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
@@ -2012,10 +2011,11 @@ static void init_once(void *foo)
20122011
INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
20132012
INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
20142013
INIT_LIST_HEAD(&nfsi->commit_info.list);
2015-
nfsi->nrequests = 0;
2016-
nfsi->commit_info.ncommit = 0;
2014+
atomic_long_set(&nfsi->nrequests, 0);
2015+
atomic_long_set(&nfsi->commit_info.ncommit, 0);
20172016
atomic_set(&nfsi->commit_info.rpcs_out, 0);
20182017
init_rwsem(&nfsi->rmdir_sem);
2018+
mutex_init(&nfsi->commit_mutex);
20192019
nfs4_init_once(nfsi);
20202020
}
20212021

fs/nfs/internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@ int nfs_iocounter_wait(struct nfs_lock_context *l_ctx);
251251
extern const struct nfs_pageio_ops nfs_pgio_rw_ops;
252252
struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *);
253253
void nfs_pgio_header_free(struct nfs_pgio_header *);
254-
void nfs_pgio_data_destroy(struct nfs_pgio_header *);
255254
int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
256255
int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
257256
struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops,

fs/nfs/nfs4_fs.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,17 @@ _nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
303303
struct rpc_cred *newcred = NULL;
304304
rpc_authflavor_t flavor;
305305

306+
if (sp4_mode == NFS_SP4_MACH_CRED_CLEANUP ||
307+
sp4_mode == NFS_SP4_MACH_CRED_PNFS_CLEANUP) {
308+
/* Using machine creds for cleanup operations
309+
* is only relevent if the client credentials
310+
* might expire. So don't bother for
311+
* RPC_AUTH_UNIX. If file was only exported to
312+
* sec=sys, the PUTFH would fail anyway.
313+
*/
314+
if ((*clntp)->cl_auth->au_flavor == RPC_AUTH_UNIX)
315+
return false;
316+
}
306317
if (test_bit(sp4_mode, &clp->cl_sp4_flags)) {
307318
spin_lock(&clp->cl_lock);
308319
if (clp->cl_machine_cred != NULL)

0 commit comments

Comments
 (0)