Skip to content

Commit bd6607e

Browse files
committed
Merge: RHEL-9.5: NFS fixes and stable
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/4941 Fixes and stable updates for NFS RHEL-9.5 JIRA: https://issues.redhat.com/browse/RHEL-53004 BREW: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=63139189 Signed-off-by: Benjamin Coddington <bcodding@redhat.com> Approved-by: Steve Dickson <steved@redhat.com> Approved-by: Scott Mayhew <smayhew@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Lucas Zampieri <lzampier@redhat.com>
2 parents f442280 + 682f6ba commit bd6607e

File tree

27 files changed

+158
-89
lines changed

27 files changed

+158
-89
lines changed

fs/nfs/dir.c

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,9 +1804,10 @@ __nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags,
18041804
if (parent != READ_ONCE(dentry->d_parent))
18051805
return -ECHILD;
18061806
} else {
1807-
/* Wait for unlink to complete */
1807+
/* Wait for unlink to complete - see unblock_revalidate() */
18081808
wait_var_event(&dentry->d_fsdata,
1809-
dentry->d_fsdata != NFS_FSDATA_BLOCKED);
1809+
smp_load_acquire(&dentry->d_fsdata)
1810+
!= NFS_FSDATA_BLOCKED);
18101811
parent = dget_parent(dentry);
18111812
ret = reval(d_inode(parent), dentry, flags);
18121813
dput(parent);
@@ -1819,6 +1820,29 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
18191820
return __nfs_lookup_revalidate(dentry, flags, nfs_do_lookup_revalidate);
18201821
}
18211822

1823+
static void block_revalidate(struct dentry *dentry)
1824+
{
1825+
/* old devname - just in case */
1826+
kfree(dentry->d_fsdata);
1827+
1828+
/* Any new reference that could lead to an open
1829+
* will take ->d_lock in lookup_open() -> d_lookup().
1830+
* Holding this lock ensures we cannot race with
1831+
* __nfs_lookup_revalidate() and removes and need
1832+
* for further barriers.
1833+
*/
1834+
lockdep_assert_held(&dentry->d_lock);
1835+
1836+
dentry->d_fsdata = NFS_FSDATA_BLOCKED;
1837+
}
1838+
1839+
static void unblock_revalidate(struct dentry *dentry)
1840+
{
1841+
/* store_release ensures wait_var_event() sees the update */
1842+
smp_store_release(&dentry->d_fsdata, NULL);
1843+
wake_up_var(&dentry->d_fsdata);
1844+
}
1845+
18221846
/*
18231847
* A weaker form of d_revalidate for revalidating just the d_inode(dentry)
18241848
* when we don't really care about the dentry name. This is called when a
@@ -2503,15 +2527,12 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
25032527
spin_unlock(&dentry->d_lock);
25042528
goto out;
25052529
}
2506-
/* old devname */
2507-
kfree(dentry->d_fsdata);
2508-
dentry->d_fsdata = NFS_FSDATA_BLOCKED;
2530+
block_revalidate(dentry);
25092531

25102532
spin_unlock(&dentry->d_lock);
25112533
error = nfs_safe_remove(dentry);
25122534
nfs_dentry_remove_handle_error(dir, dentry, error);
2513-
dentry->d_fsdata = NULL;
2514-
wake_up_var(&dentry->d_fsdata);
2535+
unblock_revalidate(dentry);
25152536
out:
25162537
trace_nfs_unlink_exit(dir, dentry, error);
25172538
return error;
@@ -2618,8 +2639,7 @@ nfs_unblock_rename(struct rpc_task *task, struct nfs_renamedata *data)
26182639
{
26192640
struct dentry *new_dentry = data->new_dentry;
26202641

2621-
new_dentry->d_fsdata = NULL;
2622-
wake_up_var(&new_dentry->d_fsdata);
2642+
unblock_revalidate(new_dentry);
26232643
}
26242644

26252645
/*
@@ -2681,11 +2701,6 @@ int nfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
26812701
if (WARN_ON(new_dentry->d_flags & DCACHE_NFSFS_RENAMED) ||
26822702
WARN_ON(new_dentry->d_fsdata == NFS_FSDATA_BLOCKED))
26832703
goto out;
2684-
if (new_dentry->d_fsdata) {
2685-
/* old devname */
2686-
kfree(new_dentry->d_fsdata);
2687-
new_dentry->d_fsdata = NULL;
2688-
}
26892704

26902705
spin_lock(&new_dentry->d_lock);
26912706
if (d_count(new_dentry) > 2) {
@@ -2707,7 +2722,7 @@ int nfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
27072722
new_dentry = dentry;
27082723
new_inode = NULL;
27092724
} else {
2710-
new_dentry->d_fsdata = NFS_FSDATA_BLOCKED;
2725+
block_revalidate(new_dentry);
27112726
must_unblock = true;
27122727
spin_unlock(&new_dentry->d_lock);
27132728
}
@@ -2719,6 +2734,8 @@ int nfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
27192734
task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry,
27202735
must_unblock ? nfs_unblock_rename : NULL);
27212736
if (IS_ERR(task)) {
2737+
if (must_unblock)
2738+
unblock_revalidate(new_dentry);
27222739
error = PTR_ERR(task);
27232740
goto out;
27242741
}

fs/nfs/direct.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ int nfs_swap_rw(struct kiocb *iocb, struct iov_iter *iter)
141141
{
142142
ssize_t ret;
143143

144-
VM_BUG_ON(iov_iter_count(iter) != PAGE_SIZE);
145-
146144
if (iov_iter_rw(iter) == READ)
147145
ret = nfs_file_direct_read(iocb, iter, true);
148146
else

fs/nfs/file.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ static void nfs_invalidate_folio(struct folio *folio, size_t offset,
412412
/* Cancel any unstarted writes on this page */
413413
nfs_wb_folio_cancel(inode, folio);
414414
folio_wait_fscache(folio);
415-
trace_nfs_invalidate_folio(inode, folio);
415+
trace_nfs_invalidate_folio(inode, folio_pos(folio) + offset, length);
416416
}
417417

418418
/*
@@ -480,7 +480,8 @@ static int nfs_launder_folio(struct folio *folio)
480480

481481
folio_wait_fscache(folio);
482482
ret = nfs_wb_folio(inode, folio);
483-
trace_nfs_launder_folio_done(inode, folio, ret);
483+
trace_nfs_launder_folio_done(inode, folio_pos(folio),
484+
folio_size(folio), ret);
484485
return ret;
485486
}
486487

fs/nfs/filelayout/filelayout.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
883883
NFS4_MAX_UINT64,
884884
IOMODE_READ,
885885
false,
886-
GFP_KERNEL);
886+
nfs_io_gfp_mask());
887887
if (IS_ERR(pgio->pg_lseg)) {
888888
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
889889
pgio->pg_lseg = NULL;
@@ -907,7 +907,7 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
907907
NFS4_MAX_UINT64,
908908
IOMODE_RW,
909909
false,
910-
GFP_NOFS);
910+
nfs_io_gfp_mask());
911911
if (IS_ERR(pgio->pg_lseg)) {
912912
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
913913
pgio->pg_lseg = NULL;

fs/nfs/fs_context.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,9 +1111,12 @@ static int nfs23_parse_monolithic(struct fs_context *fc,
11111111
ctx->acdirmax = data->acdirmax;
11121112
ctx->need_mount = false;
11131113

1114-
memcpy(sap, &data->addr, sizeof(data->addr));
1115-
ctx->nfs_server.addrlen = sizeof(data->addr);
1116-
ctx->nfs_server.port = ntohs(data->addr.sin_port);
1114+
if (!is_remount_fc(fc)) {
1115+
memcpy(sap, &data->addr, sizeof(data->addr));
1116+
ctx->nfs_server.addrlen = sizeof(data->addr);
1117+
ctx->nfs_server.port = ntohs(data->addr.sin_port);
1118+
}
1119+
11171120
if (sap->ss_family != AF_INET ||
11181121
!nfs_verify_server_address(sap))
11191122
goto out_no_address;

fs/nfs/internal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,9 +710,9 @@ unsigned long nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
710710
if ((bsize & (bsize - 1)) || nrbitsp) {
711711
unsigned char nrbits;
712712

713-
for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--)
713+
for (nrbits = 31; nrbits && !(bsize & (1UL << nrbits)); nrbits--)
714714
;
715-
bsize = 1 << nrbits;
715+
bsize = 1UL << nrbits;
716716
if (nrbitsp)
717717
*nrbitsp = nrbits;
718718
}

fs/nfs/nfs4client.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,8 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
231231
__set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags);
232232
__set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
233233
__set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags);
234-
235-
if (test_bit(NFS_CS_DS, &cl_init->init_flags))
236-
__set_bit(NFS_CS_DS, &clp->cl_flags);
234+
if (test_bit(NFS_CS_PNFS, &cl_init->init_flags))
235+
__set_bit(NFS_CS_PNFS, &clp->cl_flags);
237236
/*
238237
* Set up the connection to the server before we add add to the
239238
* global list.
@@ -1011,7 +1010,6 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
10111010
if (mds_srv->flags & NFS_MOUNT_NORESVPORT)
10121011
__set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
10131012

1014-
__set_bit(NFS_CS_DS, &cl_init.init_flags);
10151013
__set_bit(NFS_CS_PNFS, &cl_init.init_flags);
10161014
cl_init.max_connect = NFS_MAX_TRANSPORTS;
10171015
/*

fs/nfs/nfs4proc.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4028,6 +4028,23 @@ static void test_fs_location_for_trunking(struct nfs4_fs_location *location,
40284028
}
40294029
}
40304030

4031+
static bool _is_same_nfs4_pathname(struct nfs4_pathname *path1,
4032+
struct nfs4_pathname *path2)
4033+
{
4034+
int i;
4035+
4036+
if (path1->ncomponents != path2->ncomponents)
4037+
return false;
4038+
for (i = 0; i < path1->ncomponents; i++) {
4039+
if (path1->components[i].len != path2->components[i].len)
4040+
return false;
4041+
if (memcmp(path1->components[i].data, path2->components[i].data,
4042+
path1->components[i].len))
4043+
return false;
4044+
}
4045+
return true;
4046+
}
4047+
40314048
static int _nfs4_discover_trunking(struct nfs_server *server,
40324049
struct nfs_fh *fhandle)
40334050
{
@@ -4061,9 +4078,13 @@ static int _nfs4_discover_trunking(struct nfs_server *server,
40614078
if (status)
40624079
goto out_free_3;
40634080

4064-
for (i = 0; i < locations->nlocations; i++)
4081+
for (i = 0; i < locations->nlocations; i++) {
4082+
if (!_is_same_nfs4_pathname(&locations->fs_path,
4083+
&locations->locations[i].rootpath))
4084+
continue;
40654085
test_fs_location_for_trunking(&locations->locations[i], clp,
40664086
server);
4087+
}
40674088
out_free_3:
40684089
kfree(locations->fattr);
40694090
out_free_2:
@@ -5461,7 +5482,7 @@ static bool nfs4_read_plus_not_supported(struct rpc_task *task,
54615482
struct rpc_message *msg = &task->tk_msg;
54625483

54635484
if (msg->rpc_proc == &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS] &&
5464-
server->caps & NFS_CAP_READ_PLUS && task->tk_status == -ENOTSUPP) {
5485+
task->tk_status == -ENOTSUPP) {
54655486
server->caps &= ~NFS_CAP_READ_PLUS;
54665487
msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ];
54675488
rpc_restart_call_prepare(task);
@@ -8820,7 +8841,7 @@ nfs4_run_exchange_id(struct nfs_client *clp, const struct cred *cred,
88208841
#ifdef CONFIG_NFS_V4_1_MIGRATION
88218842
calldata->args.flags |= EXCHGID4_FLAG_SUPP_MOVED_MIGR;
88228843
#endif
8823-
if (test_bit(NFS_CS_DS, &clp->cl_flags))
8844+
if (test_bit(NFS_CS_PNFS, &clp->cl_flags))
88248845
calldata->args.flags |= EXCHGID4_FLAG_USE_PNFS_DS;
88258846
msg.rpc_argp = &calldata->args;
88268847
msg.rpc_resp = &calldata->res;

fs/nfs/nfstrace.h

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -939,18 +939,19 @@ TRACE_EVENT(nfs_sillyrename_unlink,
939939
DECLARE_EVENT_CLASS(nfs_folio_event,
940940
TP_PROTO(
941941
const struct inode *inode,
942-
struct folio *folio
942+
loff_t offset,
943+
size_t count
943944
),
944945

945-
TP_ARGS(inode, folio),
946+
TP_ARGS(inode, offset, count),
946947

947948
TP_STRUCT__entry(
948949
__field(dev_t, dev)
949950
__field(u32, fhandle)
950951
__field(u64, fileid)
951952
__field(u64, version)
952953
__field(loff_t, offset)
953-
__field(u32, count)
954+
__field(size_t, count)
954955
),
955956

956957
TP_fast_assign(
@@ -960,13 +961,13 @@ DECLARE_EVENT_CLASS(nfs_folio_event,
960961
__entry->fileid = nfsi->fileid;
961962
__entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
962963
__entry->version = inode_peek_iversion_raw(inode);
963-
__entry->offset = folio_file_pos(folio);
964-
__entry->count = nfs_folio_length(folio);
964+
__entry->offset = offset,
965+
__entry->count = count;
965966
),
966967

967968
TP_printk(
968969
"fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu "
969-
"offset=%lld count=%u",
970+
"offset=%lld count=%zu",
970971
MAJOR(__entry->dev), MINOR(__entry->dev),
971972
(unsigned long long)__entry->fileid,
972973
__entry->fhandle, __entry->version,
@@ -978,18 +979,20 @@ DECLARE_EVENT_CLASS(nfs_folio_event,
978979
DEFINE_EVENT(nfs_folio_event, name, \
979980
TP_PROTO( \
980981
const struct inode *inode, \
981-
struct folio *folio \
982+
loff_t offset, \
983+
size_t count \
982984
), \
983-
TP_ARGS(inode, folio))
985+
TP_ARGS(inode, offset, count))
984986

985987
DECLARE_EVENT_CLASS(nfs_folio_event_done,
986988
TP_PROTO(
987989
const struct inode *inode,
988-
struct folio *folio,
990+
loff_t offset,
991+
size_t count,
989992
int ret
990993
),
991994

992-
TP_ARGS(inode, folio, ret),
995+
TP_ARGS(inode, offset, count, ret),
993996

994997
TP_STRUCT__entry(
995998
__field(dev_t, dev)
@@ -998,7 +1001,7 @@ DECLARE_EVENT_CLASS(nfs_folio_event_done,
9981001
__field(u64, fileid)
9991002
__field(u64, version)
10001003
__field(loff_t, offset)
1001-
__field(u32, count)
1004+
__field(size_t, count)
10021005
),
10031006

10041007
TP_fast_assign(
@@ -1008,14 +1011,14 @@ DECLARE_EVENT_CLASS(nfs_folio_event_done,
10081011
__entry->fileid = nfsi->fileid;
10091012
__entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
10101013
__entry->version = inode_peek_iversion_raw(inode);
1011-
__entry->offset = folio_file_pos(folio);
1012-
__entry->count = nfs_folio_length(folio);
1014+
__entry->offset = offset,
1015+
__entry->count = count,
10131016
__entry->ret = ret;
10141017
),
10151018

10161019
TP_printk(
10171020
"fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu "
1018-
"offset=%lld count=%u ret=%d",
1021+
"offset=%lld count=%zu ret=%d",
10191022
MAJOR(__entry->dev), MINOR(__entry->dev),
10201023
(unsigned long long)__entry->fileid,
10211024
__entry->fhandle, __entry->version,
@@ -1027,10 +1030,11 @@ DECLARE_EVENT_CLASS(nfs_folio_event_done,
10271030
DEFINE_EVENT(nfs_folio_event_done, name, \
10281031
TP_PROTO( \
10291032
const struct inode *inode, \
1030-
struct folio *folio, \
1033+
loff_t offset, \
1034+
size_t count, \
10311035
int ret \
10321036
), \
1033-
TP_ARGS(inode, folio, ret))
1037+
TP_ARGS(inode, offset, count, ret))
10341038

10351039
DEFINE_NFS_FOLIO_EVENT(nfs_aop_readpage);
10361040
DEFINE_NFS_FOLIO_EVENT_DONE(nfs_aop_readpage_done);

fs/nfs/read.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,13 +332,15 @@ int nfs_read_add_folio(struct nfs_pageio_descriptor *pgio,
332332
int nfs_read_folio(struct file *file, struct folio *folio)
333333
{
334334
struct inode *inode = file_inode(file);
335+
loff_t pos = folio_pos(folio);
336+
size_t len = folio_size(folio);
335337
struct nfs_pageio_descriptor pgio;
336338
struct nfs_open_context *ctx;
337339
int ret;
338340

339-
trace_nfs_aop_readpage(inode, folio);
341+
trace_nfs_aop_readpage(inode, pos, len);
340342
nfs_inc_stats(inode, NFSIOS_VFSREADPAGE);
341-
task_io_account_read(folio_size(folio));
343+
task_io_account_read(len);
342344

343345
/*
344346
* Try to flush any pending writes to the file..
@@ -381,7 +383,7 @@ int nfs_read_folio(struct file *file, struct folio *folio)
381383
out_put:
382384
put_nfs_open_context(ctx);
383385
out:
384-
trace_nfs_aop_readpage_done(inode, folio, ret);
386+
trace_nfs_aop_readpage_done(inode, pos, len, ret);
385387
return ret;
386388
out_unlock:
387389
folio_unlock(folio);

0 commit comments

Comments
 (0)