Skip to content

Commit 4f40c63

Browse files
committed
Merge tag 'nfs-for-6.11-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client updates from Anna Schumaker: "New Features: - Add support for large folios - Implement rpcrdma generic device removal notification - Add client support for attribute delegations - Use a LAYOUTRETURN during reboot recovery to report layoutstats and errors - Improve throughput for random buffered writes - Add NVMe support to pnfs/blocklayout Bugfixes: - Fix rpcrdma_reqs_reset() - Avoid soft lockups when using UDP - Fix an nfs/blocklayout premature PR key unregestration - Another fix for EXCHGID4_FLAG_USE_PNFS_DS for DS server - Do not extend writes to the entire folio - Pass explicit offset and count values to tracepoints - Fix a race to wake up sleeping SUNRPC sync tasks - Fix gss_status tracepoint output Cleanups: - Add missing MODULE_DESCRIPTION() macros - Add blocklayout / SCSI layout tracepoints - Remove asm-generic headers from xprtrdma verbs.c - Remove unused 'struct mnt_fhstatus' - Other delegation related cleanups - Other folio related cleanups - Other pNFS related cleanups - Other xprtrdma cleanups" * tag 'nfs-for-6.11-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (63 commits) SUNRPC: Fixup gss_status tracepoint error output SUNRPC: Fix a race to wake a sync task nfs: split nfs_read_folio nfs: pass explicit offset/count to trace events nfs: do not extend writes to the entire folio nfs/blocklayout: add support for NVMe nfs: remove nfs_page_length nfs: remove the unused max_deviceinfo_size field from struct pnfs_layoutdriver_type nfs: don't reuse partially completed requests in nfs_lock_and_join_requests nfs: move nfs_wait_on_request to write.c nfs: fold nfs_page_group_lock_subrequests into nfs_lock_and_join_requests nfs: fold nfs_folio_find_and_lock_request into nfs_lock_and_join_requests nfs: simplify nfs_folio_find_and_lock_request nfs: remove nfs_folio_private_request nfs: remove dead code for the old swap over NFS implementation NFSv4.1 another fix for EXCHGID4_FLAG_USE_PNFS_DS for DS server nfs: Block on write congestion nfs: Properly initialize server->writeback nfs: Drop pointless check from nfs_commit_release_pages() nfs/blocklayout: SCSI layout trace points for reservation key reg/unreg ...
2 parents 51ed42a + b9fae9f commit 4f40c63

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1682
-811
lines changed

fs/nfs/blocklayout/blocklayout.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -564,25 +564,32 @@ bl_find_get_deviceid(struct nfs_server *server,
564564
gfp_t gfp_mask)
565565
{
566566
struct nfs4_deviceid_node *node;
567-
unsigned long start, end;
567+
int err = -ENODEV;
568568

569569
retry:
570570
node = nfs4_find_get_deviceid(server, id, cred, gfp_mask);
571571
if (!node)
572572
return ERR_PTR(-ENODEV);
573573

574-
if (test_bit(NFS_DEVICEID_UNAVAILABLE, &node->flags) == 0)
575-
return node;
574+
if (test_bit(NFS_DEVICEID_UNAVAILABLE, &node->flags)) {
575+
unsigned long end = jiffies;
576+
unsigned long start = end - PNFS_DEVICE_RETRY_TIMEOUT;
576577

577-
end = jiffies;
578-
start = end - PNFS_DEVICE_RETRY_TIMEOUT;
579-
if (!time_in_range(node->timestamp_unavailable, start, end)) {
580-
nfs4_delete_deviceid(node->ld, node->nfs_client, id);
581-
goto retry;
578+
if (!time_in_range(node->timestamp_unavailable, start, end)) {
579+
nfs4_delete_deviceid(node->ld, node->nfs_client, id);
580+
goto retry;
581+
}
582+
goto out_put;
582583
}
583584

585+
if (!bl_register_dev(container_of(node, struct pnfs_block_dev, node)))
586+
goto out_put;
587+
588+
return node;
589+
590+
out_put:
584591
nfs4_put_deviceid_node(node);
585-
return ERR_PTR(-ENODEV);
592+
return ERR_PTR(err);
586593
}
587594

588595
static int

fs/nfs/blocklayout/blocklayout.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,20 +104,26 @@ struct pnfs_block_dev {
104104
u64 start;
105105
u64 len;
106106

107+
enum pnfs_block_volume_type type;
107108
u32 nr_children;
108109
struct pnfs_block_dev *children;
109110
u64 chunk_size;
110111

111112
struct file *bdev_file;
112113
u64 disk_offset;
114+
unsigned long flags;
113115

114116
u64 pr_key;
115-
bool pr_registered;
116117

117118
bool (*map)(struct pnfs_block_dev *dev, u64 offset,
118119
struct pnfs_block_dev_map *map);
119120
};
120121

122+
/* pnfs_block_dev flag bits */
123+
enum {
124+
PNFS_BDEV_REGISTERED = 0,
125+
};
126+
121127
/* sector_t fields are all in 512-byte sectors */
122128
struct pnfs_block_extent {
123129
union {
@@ -172,6 +178,7 @@ struct bl_msg_hdr {
172178
#define BL_DEVICE_REQUEST_ERR 0x2 /* User level process fails */
173179

174180
/* dev.c */
181+
bool bl_register_dev(struct pnfs_block_dev *d);
175182
struct nfs4_deviceid_node *bl_alloc_deviceid_node(struct nfs_server *server,
176183
struct pnfs_device *pdev, gfp_t gfp_mask);
177184
void bl_free_deviceid_node(struct nfs4_deviceid_node *d);

fs/nfs/blocklayout/dev.c

Lines changed: 87 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,90 @@
1010
#include <linux/pr.h>
1111

1212
#include "blocklayout.h"
13+
#include "../nfs4trace.h"
1314

1415
#define NFSDBG_FACILITY NFSDBG_PNFS_LD
1516

17+
static void bl_unregister_scsi(struct pnfs_block_dev *dev)
18+
{
19+
struct block_device *bdev = file_bdev(dev->bdev_file);
20+
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
21+
int status;
22+
23+
if (!test_and_clear_bit(PNFS_BDEV_REGISTERED, &dev->flags))
24+
return;
25+
26+
status = ops->pr_register(bdev, dev->pr_key, 0, false);
27+
if (status)
28+
trace_bl_pr_key_unreg_err(bdev, dev->pr_key, status);
29+
else
30+
trace_bl_pr_key_unreg(bdev, dev->pr_key);
31+
}
32+
33+
static bool bl_register_scsi(struct pnfs_block_dev *dev)
34+
{
35+
struct block_device *bdev = file_bdev(dev->bdev_file);
36+
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
37+
int status;
38+
39+
if (test_and_set_bit(PNFS_BDEV_REGISTERED, &dev->flags))
40+
return true;
41+
42+
status = ops->pr_register(bdev, 0, dev->pr_key, true);
43+
if (status) {
44+
trace_bl_pr_key_reg_err(bdev, dev->pr_key, status);
45+
return false;
46+
}
47+
trace_bl_pr_key_reg(bdev, dev->pr_key);
48+
return true;
49+
}
50+
51+
static void bl_unregister_dev(struct pnfs_block_dev *dev)
52+
{
53+
u32 i;
54+
55+
if (dev->nr_children) {
56+
for (i = 0; i < dev->nr_children; i++)
57+
bl_unregister_dev(&dev->children[i]);
58+
return;
59+
}
60+
61+
if (dev->type == PNFS_BLOCK_VOLUME_SCSI)
62+
bl_unregister_scsi(dev);
63+
}
64+
65+
bool bl_register_dev(struct pnfs_block_dev *dev)
66+
{
67+
u32 i;
68+
69+
if (dev->nr_children) {
70+
for (i = 0; i < dev->nr_children; i++) {
71+
if (!bl_register_dev(&dev->children[i])) {
72+
while (i > 0)
73+
bl_unregister_dev(&dev->children[--i]);
74+
return false;
75+
}
76+
}
77+
return true;
78+
}
79+
80+
if (dev->type == PNFS_BLOCK_VOLUME_SCSI)
81+
return bl_register_scsi(dev);
82+
return true;
83+
}
84+
1685
static void
1786
bl_free_device(struct pnfs_block_dev *dev)
1887
{
88+
bl_unregister_dev(dev);
89+
1990
if (dev->nr_children) {
2091
int i;
2192

2293
for (i = 0; i < dev->nr_children; i++)
2394
bl_free_device(&dev->children[i]);
2495
kfree(dev->children);
2596
} else {
26-
if (dev->pr_registered) {
27-
const struct pr_ops *ops =
28-
file_bdev(dev->bdev_file)->bd_disk->fops->pr_ops;
29-
int error;
30-
31-
error = ops->pr_register(file_bdev(dev->bdev_file),
32-
dev->pr_key, 0, false);
33-
if (error)
34-
pr_err("failed to unregister PR key.\n");
35-
}
36-
3797
if (dev->bdev_file)
3898
fput(dev->bdev_file);
3999
}
@@ -314,7 +374,7 @@ bl_open_path(struct pnfs_block_volume *v, const char *prefix)
314374
bdev_file = bdev_file_open_by_path(devname, BLK_OPEN_READ | BLK_OPEN_WRITE,
315375
NULL, NULL);
316376
if (IS_ERR(bdev_file)) {
317-
pr_warn("pNFS: failed to open device %s (%ld)\n",
377+
dprintk("failed to open device %s (%ld)\n",
318378
devname, PTR_ERR(bdev_file));
319379
}
320380

@@ -327,8 +387,9 @@ bl_parse_scsi(struct nfs_server *server, struct pnfs_block_dev *d,
327387
struct pnfs_block_volume *volumes, int idx, gfp_t gfp_mask)
328388
{
329389
struct pnfs_block_volume *v = &volumes[idx];
330-
struct file *bdev_file;
390+
struct block_device *bdev;
331391
const struct pr_ops *ops;
392+
struct file *bdev_file;
332393
int error;
333394

334395
if (!bl_validate_designator(v))
@@ -344,35 +405,30 @@ bl_parse_scsi(struct nfs_server *server, struct pnfs_block_dev *d,
344405
if (IS_ERR(bdev_file))
345406
bdev_file = bl_open_path(v, "wwn-0x");
346407
if (IS_ERR(bdev_file))
408+
bdev_file = bl_open_path(v, "nvme-eui.");
409+
if (IS_ERR(bdev_file)) {
410+
pr_warn("pNFS: no device found for volume %*phN\n",
411+
v->scsi.designator_len, v->scsi.designator);
347412
return PTR_ERR(bdev_file);
413+
}
348414
d->bdev_file = bdev_file;
415+
bdev = file_bdev(bdev_file);
349416

350-
d->len = bdev_nr_bytes(file_bdev(d->bdev_file));
417+
d->len = bdev_nr_bytes(bdev);
351418
d->map = bl_map_simple;
352419
d->pr_key = v->scsi.pr_key;
353420

354421
if (d->len == 0)
355422
return -ENODEV;
356423

357-
pr_info("pNFS: using block device %s (reservation key 0x%llx)\n",
358-
file_bdev(d->bdev_file)->bd_disk->disk_name, d->pr_key);
359-
360-
ops = file_bdev(d->bdev_file)->bd_disk->fops->pr_ops;
424+
ops = bdev->bd_disk->fops->pr_ops;
361425
if (!ops) {
362426
pr_err("pNFS: block device %s does not support reservations.",
363-
file_bdev(d->bdev_file)->bd_disk->disk_name);
427+
bdev->bd_disk->disk_name);
364428
error = -EINVAL;
365429
goto out_blkdev_put;
366430
}
367431

368-
error = ops->pr_register(file_bdev(d->bdev_file), 0, d->pr_key, true);
369-
if (error) {
370-
pr_err("pNFS: failed to register key for block device %s.",
371-
file_bdev(d->bdev_file)->bd_disk->disk_name);
372-
goto out_blkdev_put;
373-
}
374-
375-
d->pr_registered = true;
376432
return 0;
377433

378434
out_blkdev_put:
@@ -458,7 +514,9 @@ static int
458514
bl_parse_deviceid(struct nfs_server *server, struct pnfs_block_dev *d,
459515
struct pnfs_block_volume *volumes, int idx, gfp_t gfp_mask)
460516
{
461-
switch (volumes[idx].type) {
517+
d->type = volumes[idx].type;
518+
519+
switch (d->type) {
462520
case PNFS_BLOCK_VOLUME_SIMPLE:
463521
return bl_parse_simple(server, d, volumes, idx, gfp_mask);
464522
case PNFS_BLOCK_VOLUME_SLICE:
@@ -470,7 +528,7 @@ bl_parse_deviceid(struct nfs_server *server, struct pnfs_block_dev *d,
470528
case PNFS_BLOCK_VOLUME_SCSI:
471529
return bl_parse_scsi(server, d, volumes, idx, gfp_mask);
472530
default:
473-
dprintk("unsupported volume type: %d\n", volumes[idx].type);
531+
dprintk("unsupported volume type: %d\n", d->type);
474532
return -EIO;
475533
}
476534
}

fs/nfs/callback.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ struct cb_compound_hdr_res {
4646

4747
struct cb_getattrargs {
4848
struct nfs_fh fh;
49-
uint32_t bitmap[2];
49+
uint32_t bitmap[3];
5050
};
5151

5252
struct cb_getattrres {
5353
__be32 status;
54-
uint32_t bitmap[2];
54+
uint32_t bitmap[3];
5555
uint64_t size;
5656
uint64_t change_attr;
57+
struct timespec64 atime;
5758
struct timespec64 ctime;
5859
struct timespec64 mtime;
5960
};

fs/nfs/callback_proc.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
3737
if (!cps->clp) /* Always set for v4.0. Set in cb_sequence for v4.1 */
3838
goto out;
3939

40-
res->bitmap[0] = res->bitmap[1] = 0;
40+
memset(res->bitmap, 0, sizeof(res->bitmap));
4141
res->status = htonl(NFS4ERR_BADHANDLE);
4242

4343
dprintk_rcu("NFS: GETATTR callback request from %s\n",
@@ -59,12 +59,16 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
5959
res->change_attr = delegation->change_attr;
6060
if (nfs_have_writebacks(inode))
6161
res->change_attr++;
62+
res->atime = inode_get_atime(inode);
6263
res->ctime = inode_get_ctime(inode);
6364
res->mtime = inode_get_mtime(inode);
64-
res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
65-
args->bitmap[0];
66-
res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) &
67-
args->bitmap[1];
65+
res->bitmap[0] = (FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE) &
66+
args->bitmap[0];
67+
res->bitmap[1] = (FATTR4_WORD1_TIME_ACCESS |
68+
FATTR4_WORD1_TIME_METADATA |
69+
FATTR4_WORD1_TIME_MODIFY) & args->bitmap[1];
70+
res->bitmap[2] = (FATTR4_WORD2_TIME_DELEG_ACCESS |
71+
FATTR4_WORD2_TIME_DELEG_MODIFY) & args->bitmap[2];
6872
res->status = 0;
6973
out_iput:
7074
rcu_read_unlock();
@@ -319,9 +323,10 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
319323
int stat;
320324

321325
if (args->cbl_recall_type == RETURN_FSID)
322-
stat = pnfs_destroy_layouts_byfsid(clp, &args->cbl_fsid, true);
326+
stat = pnfs_layout_destroy_byfsid(clp, &args->cbl_fsid,
327+
PNFS_LAYOUT_BULK_RETURN);
323328
else
324-
stat = pnfs_destroy_layouts_byclid(clp, true);
329+
stat = pnfs_layout_destroy_byclid(clp, PNFS_LAYOUT_BULK_RETURN);
325330
if (stat != 0)
326331
return NFS4ERR_DELAY;
327332
return NFS4ERR_NOMATCHING_LAYOUT;

fs/nfs/callback_xdr.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@
2525
#define CB_OP_GETATTR_BITMAP_MAXSZ (4 * 4) // bitmap length, 3 bitmaps
2626
#define CB_OP_GETATTR_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \
2727
CB_OP_GETATTR_BITMAP_MAXSZ + \
28-
/* change, size, ctime, mtime */\
29-
(2 + 2 + 3 + 3) * 4)
28+
/* change, size, atime, ctime,
29+
* mtime, deleg_atime, deleg_mtime */\
30+
(2 + 2 + 3 + 3 + 3 + 3 + 3) * 4)
3031
#define CB_OP_RECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
3132

3233
#if defined(CONFIG_NFS_V4_1)
@@ -635,6 +636,13 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec64 *
635636
return 0;
636637
}
637638

639+
static __be32 encode_attr_atime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
640+
{
641+
if (!(bitmap[1] & FATTR4_WORD1_TIME_ACCESS))
642+
return 0;
643+
return encode_attr_time(xdr,time);
644+
}
645+
638646
static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
639647
{
640648
if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA))
@@ -649,6 +657,24 @@ static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap,
649657
return encode_attr_time(xdr,time);
650658
}
651659

660+
static __be32 encode_attr_delegatime(struct xdr_stream *xdr,
661+
const uint32_t *bitmap,
662+
const struct timespec64 *time)
663+
{
664+
if (!(bitmap[2] & FATTR4_WORD2_TIME_DELEG_ACCESS))
665+
return 0;
666+
return encode_attr_time(xdr,time);
667+
}
668+
669+
static __be32 encode_attr_delegmtime(struct xdr_stream *xdr,
670+
const uint32_t *bitmap,
671+
const struct timespec64 *time)
672+
{
673+
if (!(bitmap[2] & FATTR4_WORD2_TIME_DELEG_MODIFY))
674+
return 0;
675+
return encode_attr_time(xdr,time);
676+
}
677+
652678
static __be32 encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound_hdr_res *hdr)
653679
{
654680
__be32 status;
@@ -697,12 +723,21 @@ static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr,
697723
if (unlikely(status != 0))
698724
goto out;
699725
status = encode_attr_size(xdr, res->bitmap, res->size);
726+
if (unlikely(status != 0))
727+
goto out;
728+
status = encode_attr_atime(xdr, res->bitmap, &res->atime);
700729
if (unlikely(status != 0))
701730
goto out;
702731
status = encode_attr_ctime(xdr, res->bitmap, &res->ctime);
703732
if (unlikely(status != 0))
704733
goto out;
705734
status = encode_attr_mtime(xdr, res->bitmap, &res->mtime);
735+
if (unlikely(status != 0))
736+
goto out;
737+
status = encode_attr_delegatime(xdr, res->bitmap, &res->atime);
738+
if (unlikely(status != 0))
739+
goto out;
740+
status = encode_attr_delegmtime(xdr, res->bitmap, &res->mtime);
706741
*savep = htonl((unsigned int)((char *)xdr->p - (char *)(savep+1)));
707742
out:
708743
return status;

0 commit comments

Comments
 (0)