Skip to content

Commit d796319

Browse files
committed
Merge: RHEL-9.8 early NFS Fixes/Stable updates
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/7249 Let's update ~~RHEL-9.7~~ RHEL-9.8 with upstream work marked for stable and fixes here. v4 incoming - added server-side TLS fix v5 - dropped four spurious net/tls/ fixes JIRA: https://issues.redhat.com/browse/RHEL-108616 Signed-off-by: Benjamin Coddington <bcodding@redhat.com> Approved-by: Scott Mayhew <smayhew@redhat.com> Approved-by: Rafael Aquini <raquini@redhat.com> Approved-by: Olga Kornievskaia <okorniev@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Patrick Talbert <ptalbert@redhat.com>
2 parents 9b7fdef + 3b825a8 commit d796319

Some content is hidden

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

52 files changed

+768
-339
lines changed

fs/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ config GRACE_PERIOD
359359
config LOCKD
360360
tristate
361361
depends on FILE_LOCKING
362+
select CRC32
362363
select GRACE_PERIOD
363364

364365
config LOCKD_V4

fs/nfs/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
config NFS_FS
33
tristate "NFS client support"
44
depends on INET && FILE_LOCKING && MULTIUSER
5+
select CRC32
56
select LOCKD
67
select SUNRPC
78
select NFS_ACL_SUPPORT if NFS_V3_ACL
@@ -194,7 +195,6 @@ config NFS_USE_KERNEL_DNS
194195
config NFS_DEBUG
195196
bool
196197
depends on NFS_FS && SUNRPC_DEBUG
197-
select CRC32
198198
default y
199199

200200
config NFS_DISABLE_UDP_SUPPORT

fs/nfs/client.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,44 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp,
664664
}
665665
EXPORT_SYMBOL_GPL(nfs_init_client);
666666

667+
static void nfs4_server_set_init_caps(struct nfs_server *server)
668+
{
669+
#if IS_ENABLED(CONFIG_NFS_V4)
670+
/* Set the basic capabilities */
671+
server->caps = server->nfs_client->cl_mvops->init_caps;
672+
if (server->flags & NFS_MOUNT_NORDIRPLUS)
673+
server->caps &= ~NFS_CAP_READDIRPLUS;
674+
if (server->nfs_client->cl_proto == XPRT_TRANSPORT_RDMA)
675+
server->caps &= ~NFS_CAP_READ_PLUS;
676+
677+
/*
678+
* Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
679+
* authentication.
680+
*/
681+
if (nfs4_disable_idmapping &&
682+
server->client->cl_auth->au_flavor == RPC_AUTH_UNIX)
683+
server->caps |= NFS_CAP_UIDGID_NOMAP;
684+
#endif
685+
}
686+
687+
void nfs_server_set_init_caps(struct nfs_server *server)
688+
{
689+
switch (server->nfs_client->rpc_ops->version) {
690+
case 2:
691+
server->caps = NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;
692+
break;
693+
case 3:
694+
server->caps = NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;
695+
if (!(server->flags & NFS_MOUNT_NORDIRPLUS))
696+
server->caps |= NFS_CAP_READDIRPLUS;
697+
break;
698+
default:
699+
nfs4_server_set_init_caps(server);
700+
break;
701+
}
702+
}
703+
EXPORT_SYMBOL_GPL(nfs_server_set_init_caps);
704+
667705
/*
668706
* Create a version 2 or 3 client
669707
*/
@@ -705,7 +743,6 @@ static int nfs_init_server(struct nfs_server *server,
705743
/* Initialise the client representation from the mount data */
706744
server->flags = ctx->flags;
707745
server->options = ctx->options;
708-
server->caps |= NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;
709746

710747
switch (clp->rpc_ops->version) {
711748
case 2:
@@ -741,6 +778,8 @@ static int nfs_init_server(struct nfs_server *server,
741778
if (error < 0)
742779
goto error;
743780

781+
nfs_server_set_init_caps(server);
782+
744783
/* Preserve the values of mount_server-related mount options */
745784
if (ctx->mount_server.addrlen) {
746785
memcpy(&server->mountd_address, &ctx->mount_server.address,
@@ -830,6 +869,8 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
830869

831870
if (fsinfo->xattr_support)
832871
server->caps |= NFS_CAP_XATTR;
872+
else
873+
server->caps &= ~NFS_CAP_XATTR;
833874
#endif
834875
}
835876

@@ -915,7 +956,6 @@ void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *sour
915956
target->acregmax = source->acregmax;
916957
target->acdirmin = source->acdirmin;
917958
target->acdirmax = source->acdirmax;
918-
target->caps = source->caps;
919959
target->options = source->options;
920960
target->auth_info = source->auth_info;
921961
target->port = source->port;
@@ -1149,6 +1189,8 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
11491189
if (error < 0)
11501190
goto out_free_server;
11511191

1192+
nfs_server_set_init_caps(server);
1193+
11521194
/* probe the filesystem info for this server filesystem */
11531195
error = nfs_probe_server(server, fh);
11541196
if (error < 0)

fs/nfs/delegation.c

Lines changed: 79 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ static void nfs_mark_return_delegation(struct nfs_server *server,
7979
struct nfs_delegation *delegation)
8080
{
8181
set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
82+
set_bit(NFS4SERV_DELEGRETURN, &server->delegation_flags);
8283
set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
8384
}
8485

@@ -330,14 +331,16 @@ nfs_start_delegation_return(struct nfs_inode *nfsi)
330331
}
331332

332333
static void nfs_abort_delegation_return(struct nfs_delegation *delegation,
333-
struct nfs_client *clp, int err)
334+
struct nfs_server *server, int err)
334335
{
335-
336336
spin_lock(&delegation->lock);
337337
clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
338338
if (err == -EAGAIN) {
339339
set_bit(NFS_DELEGATION_RETURN_DELAYED, &delegation->flags);
340-
set_bit(NFS4CLNT_DELEGRETURN_DELAYED, &clp->cl_state);
340+
set_bit(NFS4SERV_DELEGRETURN_DELAYED,
341+
&server->delegation_flags);
342+
set_bit(NFS4CLNT_DELEGRETURN_DELAYED,
343+
&server->nfs_client->cl_state);
341344
}
342345
spin_unlock(&delegation->lock);
343346
}
@@ -547,7 +550,7 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
547550
*/
548551
static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation *delegation, int issync)
549552
{
550-
struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
553+
struct nfs_server *server = NFS_SERVER(inode);
551554
unsigned int mode = O_WRONLY | O_RDWR;
552555
int err = 0;
553556

@@ -569,11 +572,11 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation
569572
/*
570573
* Guard against state recovery
571574
*/
572-
err = nfs4_wait_clnt_recover(clp);
575+
err = nfs4_wait_clnt_recover(server->nfs_client);
573576
}
574577

575578
if (err) {
576-
nfs_abort_delegation_return(delegation, clp, err);
579+
nfs_abort_delegation_return(delegation, server, err);
577580
goto out;
578581
}
579582

@@ -590,17 +593,6 @@ static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
590593

591594
if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
592595
ret = true;
593-
else if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags)) {
594-
struct inode *inode;
595-
596-
spin_lock(&delegation->lock);
597-
inode = delegation->inode;
598-
if (inode && list_empty(&NFS_I(inode)->open_files))
599-
ret = true;
600-
spin_unlock(&delegation->lock);
601-
}
602-
if (ret)
603-
clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
604596
if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags) ||
605597
test_bit(NFS_DELEGATION_RETURN_DELAYED, &delegation->flags) ||
606598
test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
@@ -619,6 +611,9 @@ static int nfs_server_return_marked_delegations(struct nfs_server *server,
619611
struct nfs_delegation *place_holder_deleg = NULL;
620612
int err = 0;
621613

614+
if (!test_and_clear_bit(NFS4SERV_DELEGRETURN,
615+
&server->delegation_flags))
616+
return 0;
622617
restart:
623618
/*
624619
* To avoid quadratic looping we hold a reference
@@ -670,6 +665,7 @@ static int nfs_server_return_marked_delegations(struct nfs_server *server,
670665
cond_resched();
671666
if (!err)
672667
goto restart;
668+
set_bit(NFS4SERV_DELEGRETURN, &server->delegation_flags);
673669
set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
674670
goto out;
675671
}
@@ -684,13 +680,17 @@ static bool nfs_server_clear_delayed_delegations(struct nfs_server *server)
684680
struct nfs_delegation *d;
685681
bool ret = false;
686682

683+
if (!test_and_clear_bit(NFS4SERV_DELEGRETURN_DELAYED,
684+
&server->delegation_flags))
685+
goto out;
687686
list_for_each_entry_rcu (d, &server->delegations, super_list) {
688687
if (!test_bit(NFS_DELEGATION_RETURN_DELAYED, &d->flags))
689688
continue;
690689
nfs_mark_return_delegation(server, d);
691690
clear_bit(NFS_DELEGATION_RETURN_DELAYED, &d->flags);
692691
ret = true;
693692
}
693+
out:
694694
return ret;
695695
}
696696

@@ -780,6 +780,43 @@ int nfs4_inode_return_delegation(struct inode *inode)
780780
return 0;
781781
}
782782

783+
/**
784+
* nfs4_inode_set_return_delegation_on_close - asynchronously return a delegation
785+
* @inode: inode to process
786+
*
787+
* This routine is called to request that the delegation be returned as soon
788+
* as the file is closed. If the file is already closed, the delegation is
789+
* immediately returned.
790+
*/
791+
void nfs4_inode_set_return_delegation_on_close(struct inode *inode)
792+
{
793+
struct nfs_delegation *delegation;
794+
struct nfs_delegation *ret = NULL;
795+
796+
if (!inode)
797+
return;
798+
rcu_read_lock();
799+
delegation = nfs4_get_valid_delegation(inode);
800+
if (!delegation)
801+
goto out;
802+
spin_lock(&delegation->lock);
803+
if (!delegation->inode)
804+
goto out_unlock;
805+
if (list_empty(&NFS_I(inode)->open_files) &&
806+
!test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
807+
/* Refcount matched in nfs_end_delegation_return() */
808+
ret = nfs_get_delegation(delegation);
809+
} else
810+
set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
811+
out_unlock:
812+
spin_unlock(&delegation->lock);
813+
if (ret)
814+
nfs_clear_verifier_delegated(inode);
815+
out:
816+
rcu_read_unlock();
817+
nfs_end_delegation_return(inode, ret, 0);
818+
}
819+
783820
/**
784821
* nfs4_inode_return_delegation_on_close - asynchronously return a delegation
785822
* @inode: inode to process
@@ -841,11 +878,25 @@ int nfs4_inode_make_writeable(struct inode *inode)
841878
return nfs4_inode_return_delegation(inode);
842879
}
843880

844-
static void nfs_mark_return_if_closed_delegation(struct nfs_server *server,
845-
struct nfs_delegation *delegation)
881+
static void
882+
nfs_mark_return_if_closed_delegation(struct nfs_server *server,
883+
struct nfs_delegation *delegation)
846884
{
847-
set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
848-
set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
885+
struct inode *inode;
886+
887+
if (test_bit(NFS_DELEGATION_RETURN, &delegation->flags) ||
888+
test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags))
889+
return;
890+
spin_lock(&delegation->lock);
891+
inode = delegation->inode;
892+
if (!inode)
893+
goto out;
894+
if (list_empty(&NFS_I(inode)->open_files))
895+
nfs_mark_return_delegation(server, delegation);
896+
else
897+
set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
898+
out:
899+
spin_unlock(&delegation->lock);
849900
}
850901

851902
static bool nfs_server_mark_return_all_delegations(struct nfs_server *server)
@@ -1245,6 +1296,7 @@ static void nfs_mark_test_expired_delegation(struct nfs_server *server,
12451296
return;
12461297
clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
12471298
set_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
1299+
set_bit(NFS4SERV_DELEGATION_EXPIRED, &server->delegation_flags);
12481300
set_bit(NFS4CLNT_DELEGATION_EXPIRED, &server->nfs_client->cl_state);
12491301
}
12501302

@@ -1323,6 +1375,9 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server,
13231375
nfs4_stateid stateid;
13241376
unsigned long gen = ++server->delegation_gen;
13251377

1378+
if (!test_and_clear_bit(NFS4SERV_DELEGATION_EXPIRED,
1379+
&server->delegation_flags))
1380+
return 0;
13261381
restart:
13271382
rcu_read_lock();
13281383
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
@@ -1352,6 +1407,9 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server,
13521407
goto restart;
13531408
}
13541409
nfs_inode_mark_test_expired_delegation(server,inode);
1410+
set_bit(NFS4SERV_DELEGATION_EXPIRED, &server->delegation_flags);
1411+
set_bit(NFS4CLNT_DELEGATION_EXPIRED,
1412+
&server->nfs_client->cl_state);
13551413
iput(inode);
13561414
return -EAGAIN;
13571415
}

fs/nfs/delegation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
4949
unsigned long pagemod_limit, u32 deleg_type);
5050
int nfs4_inode_return_delegation(struct inode *inode);
5151
void nfs4_inode_return_delegation_on_close(struct inode *inode);
52+
void nfs4_inode_set_return_delegation_on_close(struct inode *inode);
5253
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
5354
void nfs_inode_evict_delegation(struct inode *inode);
5455

fs/nfs/direct.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include <linux/uaccess.h>
5757
#include <linux/atomic.h>
5858

59+
#include "delegation.h"
5960
#include "internal.h"
6061
#include "iostat.h"
6162
#include "pnfs.h"
@@ -286,6 +287,8 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
286287
nfs_direct_count_bytes(dreq, hdr);
287288
spin_unlock(&dreq->lock);
288289

290+
nfs_update_delegated_atime(dreq->inode);
291+
289292
while (!list_empty(&hdr->pages)) {
290293
struct nfs_page *req = nfs_list_entry(hdr->pages.next);
291294
struct page *page = req->wb_page;
@@ -770,6 +773,7 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
770773

771774
spin_lock(&inode->i_lock);
772775
nfs_direct_file_adjust_size_locked(inode, dreq->io_start, dreq->count);
776+
nfs_update_delegated_mtime_locked(dreq->inode);
773777
spin_unlock(&inode->i_lock);
774778

775779
while (!list_empty(&hdr->pages)) {

fs/nfs/export.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,21 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
6666
{
6767
struct nfs_fattr *fattr = NULL;
6868
struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw);
69-
size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size;
69+
size_t fh_size = offsetof(struct nfs_fh, data);
7070
const struct nfs_rpc_ops *rpc_ops;
7171
struct dentry *dentry;
7272
struct inode *inode;
73-
int len = EMBED_FH_OFF + XDR_QUADLEN(fh_size);
73+
int len = EMBED_FH_OFF;
7474
u32 *p = fid->raw;
7575
int ret;
7676

77+
/* Initial check of bounds */
78+
if (fh_len < len + XDR_QUADLEN(fh_size) ||
79+
fh_len > XDR_QUADLEN(NFS_MAXFHSIZE))
80+
return NULL;
81+
/* Calculate embedded filehandle size */
82+
fh_size += server_fh->size;
83+
len += XDR_QUADLEN(fh_size);
7784
/* NULL translates to ESTALE */
7885
if (fh_len < len || fh_type != len)
7986
return NULL;

fs/nfs/file.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <linux/pagemap.h>
3030
#include <linux/gfp.h>
3131
#include <linux/swap.h>
32+
#include <linux/compaction.h>
3233

3334
#include <linux/uaccess.h>
3435
#include <linux/filelock.h>
@@ -429,7 +430,7 @@ static bool nfs_release_folio(struct folio *folio, gfp_t gfp)
429430
/* If the private flag is set, then the folio is not freeable */
430431
if (folio_test_private(folio)) {
431432
if ((current_gfp_context(gfp) & GFP_KERNEL) != GFP_KERNEL ||
432-
current_is_kswapd())
433+
current_is_kswapd() || current_is_kcompactd())
433434
return false;
434435
if (nfs_wb_folio(folio->mapping->host, folio) < 0)
435436
return false;

0 commit comments

Comments
 (0)