Skip to content

Commit 587217f

Browse files
committed
Merge tag 'nfs-for-6.8-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull nfs client updates from Anna Schumaker: "New Features: - Always ask for type with READDIR - Remove nfs_writepage() Bugfixes: - Fix a suspicious RCU usage warning - Fix a blocklayoutdriver reference leak - Fix the block driver's calculation of layoutget size - Fix handling NFS4ERR_RETURNCONFLICT - Fix _xprt_switch_find_current_entry() - Fix v4.1 backchannel request timeouts - Don't add zero-length pnfs block devices - Use the parent cred in nfs_access_login_time() Cleanups: - A few improvements when dealing with referring calls from the server - Clean up various unused variables, struct fields, and function calls - Various tracepoint improvements" * tag 'nfs-for-6.8-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (21 commits) NFSv4.1: Use the nfs_client's rpc timeouts for backchannel SUNRPC: Fixup v4.1 backchannel request timeouts rpc_pipefs: Replace one label in bl_resolve_deviceid() nfs: Remove writepage NFS: drop unused nfs_direct_req bytes_left pNFS: Fix the pnfs block driver's calculation of layoutget size nfs: print fileid in lookup tracepoints nfs: rename the nfs_async_rename_done tracepoint nfs: add new tracepoint at nfs4 revalidate entry point SUNRPC: fix _xprt_switch_find_current_entry logic NFSv4.1/pnfs: Ensure we handle the error NFS4ERR_RETURNCONFLICT NFSv4.1: if referring calls are complete, trust the stateid argument NFSv4: Track the number of referring calls in struct cb_process_state NFS: Use parent's objective cred in nfs_access_login_time() NFSv4: Always ask for type with READDIR pnfs/blocklayout: Don't add zero-length pnfs_block_dev blocklayoutdriver: Fix reference leak of pnfs_device_node SUNRPC: Fix a suspicious RCU usage warning SUNRPC: Create a helper function for accessing the rpc_clnt's xprt_switch SUNRPC: Remove unused function rpc_clnt_xprt_switch_put() ...
2 parents 0d19d9e + 57331a5 commit 587217f

26 files changed

+181
-123
lines changed

fs/nfs/blocklayout/blocklayout.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,8 @@ bl_find_get_deviceid(struct nfs_server *server,
580580
nfs4_delete_deviceid(node->ld, node->nfs_client, id);
581581
goto retry;
582582
}
583+
584+
nfs4_put_deviceid_node(node);
583585
return ERR_PTR(-ENODEV);
584586
}
585587

@@ -893,10 +895,9 @@ bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
893895
}
894896

895897
if (pgio->pg_dreq == NULL)
896-
wb_size = pnfs_num_cont_bytes(pgio->pg_inode,
897-
req->wb_index);
898+
wb_size = pnfs_num_cont_bytes(pgio->pg_inode, req->wb_index);
898899
else
899-
wb_size = nfs_dreq_bytes_left(pgio->pg_dreq);
900+
wb_size = nfs_dreq_bytes_left(pgio->pg_dreq, req_offset(req));
900901

901902
pnfs_generic_pg_init_write(pgio, req, wb_size);
902903

fs/nfs/blocklayout/dev.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,9 @@ bl_parse_scsi(struct nfs_server *server, struct pnfs_block_dev *d,
351351
d->map = bl_map_simple;
352352
d->pr_key = v->scsi.pr_key;
353353

354+
if (d->len == 0)
355+
return -ENODEV;
356+
354357
pr_info("pNFS: using block device %s (reservation key 0x%llx)\n",
355358
d->bdev_handle->bdev->bd_disk->disk_name, d->pr_key);
356359

fs/nfs/blocklayout/rpc_pipefs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b,
7575
msg->len = sizeof(*bl_msg) + b->simple.len;
7676
msg->data = kzalloc(msg->len, gfp_mask);
7777
if (!msg->data)
78-
goto out_free_data;
78+
goto out_unlock;
7979

8080
bl_msg = msg->data;
8181
bl_msg->type = BL_DEVICE_MOUNT;

fs/nfs/callback.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ enum nfs4_callback_procnum {
2121

2222
struct nfs4_slot;
2323
struct cb_process_state {
24-
__be32 drc_status;
2524
struct nfs_client *clp;
2625
struct nfs4_slot *slot;
27-
u32 minorversion;
2826
struct net *net;
27+
u32 minorversion;
28+
__be32 drc_status;
29+
unsigned int referring_calls;
2930
};
3031

3132
struct cb_compound_hdr_arg {

fs/nfs/callback_proc.c

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ static struct inode *nfs_layout_find_inode(struct nfs_client *clp,
207207
* Enforce RFC5661 section 12.5.5.2.1. (Layout Recall and Return Sequencing)
208208
*/
209209
static u32 pnfs_check_callback_stateid(struct pnfs_layout_hdr *lo,
210-
const nfs4_stateid *new)
210+
const nfs4_stateid *new,
211+
struct cb_process_state *cps)
211212
{
212213
u32 oldseq, newseq;
213214

@@ -221,28 +222,29 @@ static u32 pnfs_check_callback_stateid(struct pnfs_layout_hdr *lo,
221222

222223
newseq = be32_to_cpu(new->seqid);
223224
/* Are we already in a layout recall situation? */
224-
if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags) &&
225-
lo->plh_return_seq != 0) {
226-
if (newseq < lo->plh_return_seq)
227-
return NFS4ERR_OLD_STATEID;
228-
if (newseq > lo->plh_return_seq)
229-
return NFS4ERR_DELAY;
230-
goto out;
231-
}
225+
if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
226+
return NFS4ERR_DELAY;
232227

233-
/* Check that the stateid matches what we think it should be. */
228+
/*
229+
* Check that the stateid matches what we think it should be.
230+
* Note that if the server sent us a list of referring calls,
231+
* and we know that those have completed, then we trust the
232+
* stateid argument is correct.
233+
*/
234234
oldseq = be32_to_cpu(lo->plh_stateid.seqid);
235-
if (newseq > oldseq + 1)
235+
if (newseq > oldseq + 1 && !cps->referring_calls)
236236
return NFS4ERR_DELAY;
237+
237238
/* Crazy server! */
238239
if (newseq <= oldseq)
239240
return NFS4ERR_OLD_STATEID;
240-
out:
241+
241242
return NFS_OK;
242243
}
243244

244245
static u32 initiate_file_draining(struct nfs_client *clp,
245-
struct cb_layoutrecallargs *args)
246+
struct cb_layoutrecallargs *args,
247+
struct cb_process_state *cps)
246248
{
247249
struct inode *ino;
248250
struct pnfs_layout_hdr *lo;
@@ -266,7 +268,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
266268
goto out;
267269
}
268270
pnfs_get_layout_hdr(lo);
269-
rv = pnfs_check_callback_stateid(lo, &args->cbl_stateid);
271+
rv = pnfs_check_callback_stateid(lo, &args->cbl_stateid, cps);
270272
if (rv != NFS_OK)
271273
goto unlock;
272274

@@ -326,10 +328,11 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
326328
}
327329

328330
static u32 do_callback_layoutrecall(struct nfs_client *clp,
329-
struct cb_layoutrecallargs *args)
331+
struct cb_layoutrecallargs *args,
332+
struct cb_process_state *cps)
330333
{
331334
if (args->cbl_recall_type == RETURN_FILE)
332-
return initiate_file_draining(clp, args);
335+
return initiate_file_draining(clp, args, cps);
333336
return initiate_bulk_draining(clp, args);
334337
}
335338

@@ -340,19 +343,20 @@ __be32 nfs4_callback_layoutrecall(void *argp, void *resp,
340343
u32 res = NFS4ERR_OP_NOT_IN_SESSION;
341344

342345
if (cps->clp)
343-
res = do_callback_layoutrecall(cps->clp, args);
346+
res = do_callback_layoutrecall(cps->clp, args, cps);
344347
return cpu_to_be32(res);
345348
}
346349

347-
static void pnfs_recall_all_layouts(struct nfs_client *clp)
350+
static void pnfs_recall_all_layouts(struct nfs_client *clp,
351+
struct cb_process_state *cps)
348352
{
349353
struct cb_layoutrecallargs args;
350354

351355
/* Pretend we got a CB_LAYOUTRECALL(ALL) */
352356
memset(&args, 0, sizeof(args));
353357
args.cbl_recall_type = RETURN_ALL;
354358
/* FIXME we ignore errors, what should we do? */
355-
do_callback_layoutrecall(clp, &args);
359+
do_callback_layoutrecall(clp, &args, cps);
356360
}
357361

358362
__be32 nfs4_callback_devicenotify(void *argp, void *resp,
@@ -450,6 +454,7 @@ static int referring_call_exists(struct nfs_client *clp,
450454
__acquires(lock)
451455
{
452456
int status = 0;
457+
int found = 0;
453458
int i, j;
454459
struct nfs4_session *session;
455460
struct nfs4_slot_table *tbl;
@@ -478,11 +483,12 @@ static int referring_call_exists(struct nfs_client *clp,
478483
spin_lock(lock);
479484
if (status)
480485
goto out;
486+
found++;
481487
}
482488
}
483489

484490
out:
485-
return status;
491+
return status < 0 ? status : found;
486492
}
487493

488494
__be32 nfs4_callback_sequence(void *argp, void *resp,
@@ -493,6 +499,7 @@ __be32 nfs4_callback_sequence(void *argp, void *resp,
493499
struct nfs4_slot_table *tbl;
494500
struct nfs4_slot *slot;
495501
struct nfs_client *clp;
502+
int ret;
496503
int i;
497504
__be32 status = htonl(NFS4ERR_BADSESSION);
498505

@@ -552,11 +559,13 @@ __be32 nfs4_callback_sequence(void *argp, void *resp,
552559
* related callback was received before the response to the original
553560
* call.
554561
*/
555-
if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists,
556-
&tbl->slot_tbl_lock) < 0) {
562+
ret = referring_call_exists(clp, args->csa_nrclists, args->csa_rclists,
563+
&tbl->slot_tbl_lock);
564+
if (ret < 0) {
557565
status = htonl(NFS4ERR_DELAY);
558566
goto out_unlock;
559567
}
568+
cps->referring_calls = ret;
560569

561570
/*
562571
* RFC5661 20.9.3
@@ -617,7 +626,7 @@ __be32 nfs4_callback_recallany(void *argp, void *resp,
617626
nfs_expire_unused_delegation_types(cps->clp, flags);
618627

619628
if (args->craa_type_mask & BIT(RCA4_TYPE_MASK_FILE_LAYOUT))
620-
pnfs_recall_all_layouts(cps->clp);
629+
pnfs_recall_all_layouts(cps->clp, cps);
621630

622631
if (args->craa_type_mask & BIT(PNFS_FF_RCA4_TYPE_MASK_READ)) {
623632
set_bit(NFS4CLNT_RECALL_ANY_LAYOUT_READ, &cps->clp->cl_state);

fs/nfs/callback_xdr.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,11 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)
967967
nops--;
968968
}
969969

970+
if (svc_is_backchannel(rqstp) && cps.clp) {
971+
rqstp->bc_to_initval = cps.clp->cl_rpcclient->cl_timeout->to_initval;
972+
rqstp->bc_to_retries = cps.clp->cl_rpcclient->cl_timeout->to_retries;
973+
}
974+
970975
*hdr_res.status = status;
971976
*hdr_res.nops = htonl(nops);
972977
nfs4_cb_free_slot(&cps);

fs/nfs/dir.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2194,6 +2194,8 @@ nfs4_do_lookup_revalidate(struct inode *dir, struct dentry *dentry,
21942194
{
21952195
struct inode *inode;
21962196

2197+
trace_nfs_lookup_revalidate_enter(dir, dentry, flags);
2198+
21972199
if (!(flags & LOOKUP_OPEN) || (flags & LOOKUP_DIRECTORY))
21982200
goto full_reval;
21992201
if (d_mountpoint(dentry))
@@ -2963,7 +2965,7 @@ static u64 nfs_access_login_time(const struct task_struct *task,
29632965
rcu_read_lock();
29642966
for (;;) {
29652967
parent = rcu_dereference(task->real_parent);
2966-
pcred = rcu_dereference(parent->cred);
2968+
pcred = __task_cred(parent);
29672969
if (parent == task || cred_fscmp(pcred, cred) != 0)
29682970
break;
29692971
task = parent;

fs/nfs/direct.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,10 @@ static void nfs_direct_req_release(struct nfs_direct_req *dreq)
205205
kref_put(&dreq->kref, nfs_direct_req_free);
206206
}
207207

208-
ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq)
208+
ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset)
209209
{
210-
return dreq->bytes_left;
210+
loff_t start = offset - dreq->io_start;
211+
return dreq->max_count - start;
211212
}
212213
EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left);
213214

@@ -368,7 +369,6 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
368369
bytes -= req_len;
369370
requested_bytes += req_len;
370371
pos += req_len;
371-
dreq->bytes_left -= req_len;
372372
}
373373
nfs_direct_release_pages(pagevec, npages);
374374
kvfree(pagevec);
@@ -440,7 +440,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter,
440440
goto out;
441441

442442
dreq->inode = inode;
443-
dreq->bytes_left = dreq->max_count = count;
443+
dreq->max_count = count;
444444
dreq->io_start = iocb->ki_pos;
445445
dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
446446
l_ctx = nfs_get_lock_context(dreq->ctx);
@@ -873,7 +873,6 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
873873
bytes -= req_len;
874874
requested_bytes += req_len;
875875
pos += req_len;
876-
dreq->bytes_left -= req_len;
877876

878877
if (defer) {
879878
nfs_mark_request_commit(req, NULL, &cinfo, 0);
@@ -980,7 +979,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter,
980979
goto out;
981980

982981
dreq->inode = inode;
983-
dreq->bytes_left = dreq->max_count = count;
982+
dreq->max_count = count;
984983
dreq->io_start = pos;
985984
dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
986985
l_ctx = nfs_get_lock_context(dreq->ctx);

fs/nfs/file.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,6 @@ const struct address_space_operations nfs_file_aops = {
558558
.read_folio = nfs_read_folio,
559559
.readahead = nfs_readahead,
560560
.dirty_folio = filemap_dirty_folio,
561-
.writepage = nfs_writepage,
562561
.writepages = nfs_writepages,
563562
.write_begin = nfs_write_begin,
564563
.write_end = nfs_write_end,

fs/nfs/internal.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry);
655655
/* direct.c */
656656
void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
657657
struct nfs_direct_req *dreq);
658-
extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq);
658+
extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset);
659659

660660
/* nfs4proc.c */
661661
extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
@@ -936,7 +936,6 @@ struct nfs_direct_req {
936936
loff_t io_start; /* Start offset for I/O */
937937
ssize_t count, /* bytes actually processed */
938938
max_count, /* max expected count */
939-
bytes_left, /* bytes left to be sent */
940939
error; /* any reported error */
941940
struct completion completion; /* wait for i/o completion */
942941

0 commit comments

Comments
 (0)