Skip to content

Commit 12bf0b6

Browse files
committed
Merge tag 'nfs-for-5.7-5' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes from Trond Myklebust: "Highlights include: Stable fixes: - nfs: fix NULL deference in nfs4_get_valid_delegation Bugfixes: - Fix corruption of the return value in cachefiles_read_or_alloc_pages() - Fix several fscache cookie issues - Fix a fscache queuing race that can trigger a BUG_ON - NFS: Fix two use-after-free regressions due to the RPC_TASK_CRED_NOREF flag - SUNRPC: Fix a use-after-free regression in rpc_free_client_work() - SUNRPC: Fix a race when tearing down the rpc client debugfs directory - SUNRPC: Signalled ASYNC tasks need to exit - NFSv3: fix rpc receive buffer size for MOUNT call" * tag 'nfs-for-5.7-5' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: NFSv3: fix rpc receive buffer size for MOUNT call SUNRPC: 'Directory with parent 'rpc_clnt' already present!' NFS/pnfs: Don't use RPC_TASK_CRED_NOREF with pnfs NFS: Don't use RPC_TASK_CRED_NOREF with delegreturn SUNRPC: Signalled ASYNC tasks need to exit nfs: fix NULL deference in nfs4_get_valid_delegation SUNRPC: fix use-after-free in rpc_free_client_work() cachefiles: Fix race between read_waiter and read_copier involving op->to_do NFSv4: Fix fscache cookie aux_data to ensure change_attr is included NFS: Fix fscache super_cookie allocation NFS: Fix fscache super_cookie index_key from changing after umount cachefiles: Fix corruption of the return value in cachefiles_read_or_alloc_pages()
2 parents f85c159 + 8eed292 commit 12bf0b6

File tree

10 files changed

+42
-38
lines changed

10 files changed

+42
-38
lines changed

fs/cachefiles/rdwr.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ static int cachefiles_read_waiter(wait_queue_entry_t *wait, unsigned mode,
6060
object = container_of(op->op.object, struct cachefiles_object, fscache);
6161
spin_lock(&object->work_lock);
6262
list_add_tail(&monitor->op_link, &op->to_do);
63+
fscache_enqueue_retrieval(op);
6364
spin_unlock(&object->work_lock);
6465

65-
fscache_enqueue_retrieval(op);
6666
fscache_put_retrieval(op);
6767
return 0;
6868
}
@@ -398,7 +398,7 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
398398
struct inode *inode;
399399
sector_t block;
400400
unsigned shift;
401-
int ret;
401+
int ret, ret2;
402402

403403
object = container_of(op->op.object,
404404
struct cachefiles_object, fscache);
@@ -430,8 +430,8 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
430430
block = page->index;
431431
block <<= shift;
432432

433-
ret = bmap(inode, &block);
434-
ASSERT(ret < 0);
433+
ret2 = bmap(inode, &block);
434+
ASSERT(ret2 == 0);
435435

436436
_debug("%llx -> %llx",
437437
(unsigned long long) (page->index << shift),
@@ -739,8 +739,8 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
739739
block = page->index;
740740
block <<= shift;
741741

742-
ret = bmap(inode, &block);
743-
ASSERT(!ret);
742+
ret2 = bmap(inode, &block);
743+
ASSERT(ret2 == 0);
744744

745745
_debug("%llx -> %llx",
746746
(unsigned long long) (page->index << shift),

fs/nfs/fscache.c

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,6 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int
118118

119119
nfss->fscache_key = NULL;
120120
nfss->fscache = NULL;
121-
if (!(nfss->options & NFS_OPTION_FSCACHE))
122-
return;
123121
if (!uniq) {
124122
uniq = "";
125123
ulen = 1;
@@ -188,7 +186,8 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int
188186
/* create a cache index for looking up filehandles */
189187
nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache,
190188
&nfs_fscache_super_index_def,
191-
key, sizeof(*key) + ulen,
189+
&key->key,
190+
sizeof(key->key) + ulen,
192191
NULL, 0,
193192
nfss, 0, true);
194193
dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n",
@@ -226,6 +225,19 @@ void nfs_fscache_release_super_cookie(struct super_block *sb)
226225
}
227226
}
228227

228+
static void nfs_fscache_update_auxdata(struct nfs_fscache_inode_auxdata *auxdata,
229+
struct nfs_inode *nfsi)
230+
{
231+
memset(auxdata, 0, sizeof(*auxdata));
232+
auxdata->mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec;
233+
auxdata->mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec;
234+
auxdata->ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec;
235+
auxdata->ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec;
236+
237+
if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
238+
auxdata->change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode);
239+
}
240+
229241
/*
230242
* Initialise the per-inode cache cookie pointer for an NFS inode.
231243
*/
@@ -239,14 +251,7 @@ void nfs_fscache_init_inode(struct inode *inode)
239251
if (!(nfss->fscache && S_ISREG(inode->i_mode)))
240252
return;
241253

242-
memset(&auxdata, 0, sizeof(auxdata));
243-
auxdata.mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec;
244-
auxdata.mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec;
245-
auxdata.ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec;
246-
auxdata.ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec;
247-
248-
if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
249-
auxdata.change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode);
254+
nfs_fscache_update_auxdata(&auxdata, nfsi);
250255

251256
nfsi->fscache = fscache_acquire_cookie(NFS_SB(inode->i_sb)->fscache,
252257
&nfs_fscache_inode_object_def,
@@ -266,11 +271,7 @@ void nfs_fscache_clear_inode(struct inode *inode)
266271

267272
dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", nfsi, cookie);
268273

269-
memset(&auxdata, 0, sizeof(auxdata));
270-
auxdata.mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec;
271-
auxdata.mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec;
272-
auxdata.ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec;
273-
auxdata.ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec;
274+
nfs_fscache_update_auxdata(&auxdata, nfsi);
274275
fscache_relinquish_cookie(cookie, &auxdata, false);
275276
nfsi->fscache = NULL;
276277
}
@@ -310,11 +311,7 @@ void nfs_fscache_open_file(struct inode *inode, struct file *filp)
310311
if (!fscache_cookie_valid(cookie))
311312
return;
312313

313-
memset(&auxdata, 0, sizeof(auxdata));
314-
auxdata.mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec;
315-
auxdata.mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec;
316-
auxdata.ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec;
317-
auxdata.ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec;
314+
nfs_fscache_update_auxdata(&auxdata, nfsi);
318315

319316
if (inode_is_open_for_write(inode)) {
320317
dfprintk(FSCACHE, "NFS: nfsi 0x%p disabling cache\n", nfsi);

fs/nfs/mount_clnt.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@
3030
#define encode_dirpath_sz (1 + XDR_QUADLEN(MNTPATHLEN))
3131
#define MNT_status_sz (1)
3232
#define MNT_fhandle_sz XDR_QUADLEN(NFS2_FHSIZE)
33+
#define MNT_fhandlev3_sz XDR_QUADLEN(NFS3_FHSIZE)
3334
#define MNT_authflav3_sz (1 + NFS_MAX_SECFLAVORS)
3435

3536
/*
3637
* XDR argument and result sizes
3738
*/
3839
#define MNT_enc_dirpath_sz encode_dirpath_sz
3940
#define MNT_dec_mountres_sz (MNT_status_sz + MNT_fhandle_sz)
40-
#define MNT_dec_mountres3_sz (MNT_status_sz + MNT_fhandle_sz + \
41+
#define MNT_dec_mountres3_sz (MNT_status_sz + MNT_fhandlev3_sz + \
4142
MNT_authflav3_sz)
4243

4344
/*

fs/nfs/nfs4proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6347,7 +6347,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred,
63476347
.rpc_client = server->client,
63486348
.rpc_message = &msg,
63496349
.callback_ops = &nfs4_delegreturn_ops,
6350-
.flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF | RPC_TASK_TIMEOUT,
6350+
.flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT,
63516351
};
63526352
int status = 0;
63536353

fs/nfs/nfs4state.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,9 +734,9 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner)
734734
state = new;
735735
state->owner = owner;
736736
atomic_inc(&owner->so_count);
737-
list_add_rcu(&state->inode_states, &nfsi->open_states);
738737
ihold(inode);
739738
state->inode = inode;
739+
list_add_rcu(&state->inode_states, &nfsi->open_states);
740740
spin_unlock(&inode->i_lock);
741741
/* Note: The reclaim code dictates that we add stateless
742742
* and read-only stateids to the end of the list */

fs/nfs/pagelist.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
752752
.callback_ops = call_ops,
753753
.callback_data = hdr,
754754
.workqueue = nfsiod_workqueue,
755-
.flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF | flags,
755+
.flags = RPC_TASK_ASYNC | flags,
756756
};
757757

758758
hdr->rw_ops->rw_initiate(hdr, &msg, rpc_ops, &task_setup_data, how);
@@ -950,7 +950,8 @@ static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc)
950950
hdr->cred,
951951
NFS_PROTO(hdr->inode),
952952
desc->pg_rpc_callops,
953-
desc->pg_ioflags, 0);
953+
desc->pg_ioflags,
954+
RPC_TASK_CRED_NOREF);
954955
return ret;
955956
}
956957

fs/nfs/pnfs_nfs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,8 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
536536
nfs_init_commit(data, NULL, NULL, cinfo);
537537
nfs_initiate_commit(NFS_CLIENT(inode), data,
538538
NFS_PROTO(data->inode),
539-
data->mds_ops, how, 0);
539+
data->mds_ops, how,
540+
RPC_TASK_CRED_NOREF);
540541
} else {
541542
nfs_init_commit(data, NULL, data->lseg, cinfo);
542543
initiate_commit(data, how);

fs/nfs/super.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1189,7 +1189,6 @@ static void nfs_get_cache_cookie(struct super_block *sb,
11891189
uniq = ctx->fscache_uniq;
11901190
ulen = strlen(ctx->fscache_uniq);
11911191
}
1192-
return;
11931192
}
11941193

11951194
nfs_fscache_get_super_cookie(sb, uniq, ulen);

fs/nfs/write.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,7 +1695,7 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data,
16951695
.callback_ops = call_ops,
16961696
.callback_data = data,
16971697
.workqueue = nfsiod_workqueue,
1698-
.flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF | flags,
1698+
.flags = RPC_TASK_ASYNC | flags,
16991699
.priority = priority,
17001700
};
17011701
/* Set up the initial task struct. */
@@ -1813,7 +1813,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
18131813
nfs_init_commit(data, head, NULL, cinfo);
18141814
atomic_inc(&cinfo->mds->rpcs_out);
18151815
return nfs_initiate_commit(NFS_CLIENT(inode), data, NFS_PROTO(inode),
1816-
data->mds_ops, how, 0);
1816+
data->mds_ops, how, RPC_TASK_CRED_NOREF);
18171817
}
18181818

18191819
/*

net/sunrpc/clnt.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,9 @@ static void rpc_free_client_work(struct work_struct *work)
889889
* here.
890890
*/
891891
rpc_clnt_debugfs_unregister(clnt);
892+
rpc_free_clid(clnt);
892893
rpc_clnt_remove_pipedir(clnt);
894+
xprt_put(rcu_dereference_raw(clnt->cl_xprt));
893895

894896
kfree(clnt);
895897
rpciod_down();
@@ -907,10 +909,8 @@ rpc_free_client(struct rpc_clnt *clnt)
907909
rpc_unregister_client(clnt);
908910
rpc_free_iostats(clnt->cl_metrics);
909911
clnt->cl_metrics = NULL;
910-
xprt_put(rcu_dereference_raw(clnt->cl_xprt));
911912
xprt_iter_destroy(&clnt->cl_xpi);
912913
put_cred(clnt->cl_cred);
913-
rpc_free_clid(clnt);
914914

915915
INIT_WORK(&clnt->cl_work, rpc_free_client_work);
916916
schedule_work(&clnt->cl_work);
@@ -2433,6 +2433,11 @@ rpc_check_timeout(struct rpc_task *task)
24332433
{
24342434
struct rpc_clnt *clnt = task->tk_client;
24352435

2436+
if (RPC_SIGNALLED(task)) {
2437+
rpc_call_rpcerror(task, -ERESTARTSYS);
2438+
return;
2439+
}
2440+
24362441
if (xprt_adjust_timeout(task->tk_rqstp) == 0)
24372442
return;
24382443

0 commit comments

Comments
 (0)