Skip to content

Commit a01c9fe

Browse files
committed
Merge tag 'nfsd-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull nfsd updates from Chuck Lever: "The bulk of the patches for this release are optimizations, code clean-ups, and minor bug fixes. One new feature to mention is that NFSD administrators now have the ability to revoke NFSv4 open and lock state. NFSD's NFSv3 support has had this capability for some time. As always I am grateful to NFSD contributors, reviewers, and testers" * tag 'nfsd-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (75 commits) NFSD: Clean up nfsd4_encode_replay() NFSD: send OP_CB_RECALL_ANY to clients when number of delegations reaches its limit NFSD: Document nfsd_setattr() fill-attributes behavior nfsd: Fix NFSv3 atomicity bugs in nfsd_setattr() nfsd: Fix a regression in nfsd_setattr() NFSD: OP_CB_RECALL_ANY should recall both read and write delegations NFSD: handle GETATTR conflict with write delegation NFSD: add support for CB_GETATTR callback NFSD: Document the phases of CREATE_SESSION NFSD: Fix the NFSv4.1 CREATE_SESSION operation nfsd: clean up comments over nfs4_client definition svcrdma: Add Write chunk WRs to the RPC's Send WR chain svcrdma: Post WRs for Write chunks in svc_rdma_sendto() svcrdma: Post the Reply chunk and Send WR together svcrdma: Move write_info for Reply chunks into struct svc_rdma_send_ctxt svcrdma: Post Send WR chain svcrdma: Fix retry loop in svc_rdma_send() svcrdma: Prevent a UAF in svc_rdma_send() svcrdma: Fix SQ wake-ups svcrdma: Increase the per-transport rw_ctx count ...
2 parents f153fbe + 9b350d3 commit a01c9fe

Some content is hidden

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

44 files changed

+1763
-753
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8172,6 +8172,7 @@ F: include/uapi/scsi/fc/
81728172
FILE LOCKING (flock() and fcntl()/lockf())
81738173
M: Jeff Layton <[email protected]>
81748174
M: Chuck Lever <[email protected]>
8175+
R: Alexander Aring <[email protected]>
81758176
81768177
S: Maintained
81778178
F: fs/fcntl.c

fs/lockd/svc.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -710,16 +710,13 @@ static const struct svc_version *nlmsvc_version[] = {
710710
#endif
711711
};
712712

713-
static struct svc_stat nlmsvc_stats;
714-
715713
#define NLM_NRVERS ARRAY_SIZE(nlmsvc_version)
716714
static struct svc_program nlmsvc_program = {
717715
.pg_prog = NLM_PROGRAM, /* program number */
718716
.pg_nvers = NLM_NRVERS, /* number of entries in nlmsvc_version */
719717
.pg_vers = nlmsvc_version, /* version table */
720718
.pg_name = "lockd", /* service name */
721719
.pg_class = "nfsd", /* share authentication with nfsd */
722-
.pg_stats = &nlmsvc_stats, /* stats table */
723720
.pg_authenticate = &lockd_authenticate, /* export authentication */
724721
.pg_init_request = svc_generic_init_request,
725722
.pg_rpcbind_set = svc_generic_rpcbind_set,

fs/nfs/callback.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,15 +356,12 @@ static const struct svc_version *nfs4_callback_version[] = {
356356
[4] = &nfs4_callback_version4,
357357
};
358358

359-
static struct svc_stat nfs4_callback_stats;
360-
361359
static struct svc_program nfs4_callback_program = {
362360
.pg_prog = NFS4_CALLBACK, /* RPC service number */
363361
.pg_nvers = ARRAY_SIZE(nfs4_callback_version), /* Number of entries */
364362
.pg_vers = nfs4_callback_version, /* version table */
365363
.pg_name = "NFSv4 callback", /* service name */
366364
.pg_class = "nfs", /* authentication class */
367-
.pg_stats = &nfs4_callback_stats,
368365
.pg_authenticate = nfs_callback_authenticate,
369366
.pg_init_request = svc_generic_init_request,
370367
.pg_rpcbind_set = svc_generic_rpcbind_set,

fs/nfsd/blocklayout.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,10 +328,10 @@ nfsd4_scsi_proc_layoutcommit(struct inode *inode,
328328
}
329329

330330
static void
331-
nfsd4_scsi_fence_client(struct nfs4_layout_stateid *ls)
331+
nfsd4_scsi_fence_client(struct nfs4_layout_stateid *ls, struct nfsd_file *file)
332332
{
333333
struct nfs4_client *clp = ls->ls_stid.sc_client;
334-
struct block_device *bdev = ls->ls_file->nf_file->f_path.mnt->mnt_sb->s_bdev;
334+
struct block_device *bdev = file->nf_file->f_path.mnt->mnt_sb->s_bdev;
335335

336336
bdev->bd_disk->fops->pr_ops->pr_preempt(bdev, NFSD_MDS_PR_KEY,
337337
nfsd4_scsi_pr_key(clp), 0, true);

fs/nfsd/cache.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ enum {
8080

8181
int nfsd_drc_slab_create(void);
8282
void nfsd_drc_slab_free(void);
83-
int nfsd_net_reply_cache_init(struct nfsd_net *nn);
84-
void nfsd_net_reply_cache_destroy(struct nfsd_net *nn);
8583
int nfsd_reply_cache_init(struct nfsd_net *);
8684
void nfsd_reply_cache_shutdown(struct nfsd_net *);
8785
int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start,

fs/nfsd/filecache.c

Lines changed: 34 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,10 @@ static DEFINE_PER_CPU(unsigned long, nfsd_file_total_age);
6161
static DEFINE_PER_CPU(unsigned long, nfsd_file_evictions);
6262

6363
struct nfsd_fcache_disposal {
64-
struct work_struct work;
6564
spinlock_t lock;
6665
struct list_head freeme;
6766
};
6867

69-
static struct workqueue_struct *nfsd_filecache_wq __read_mostly;
70-
7168
static struct kmem_cache *nfsd_file_slab;
7269
static struct kmem_cache *nfsd_file_mark_slab;
7370
static struct list_lru nfsd_file_lru;
@@ -283,7 +280,7 @@ nfsd_file_free(struct nfsd_file *nf)
283280
nfsd_file_mark_put(nf->nf_mark);
284281
if (nf->nf_file) {
285282
nfsd_file_check_write_error(nf);
286-
filp_close(nf->nf_file, NULL);
283+
nfsd_filp_close(nf->nf_file);
287284
}
288285

289286
/*
@@ -421,7 +418,37 @@ nfsd_file_dispose_list_delayed(struct list_head *dispose)
421418
spin_lock(&l->lock);
422419
list_move_tail(&nf->nf_lru, &l->freeme);
423420
spin_unlock(&l->lock);
424-
queue_work(nfsd_filecache_wq, &l->work);
421+
svc_wake_up(nn->nfsd_serv);
422+
}
423+
}
424+
425+
/**
426+
* nfsd_file_net_dispose - deal with nfsd_files waiting to be disposed.
427+
* @nn: nfsd_net in which to find files to be disposed.
428+
*
429+
* When files held open for nfsv3 are removed from the filecache, whether
430+
* due to memory pressure or garbage collection, they are queued to
431+
* a per-net-ns queue. This function completes the disposal, either
432+
* directly or by waking another nfsd thread to help with the work.
433+
*/
434+
void nfsd_file_net_dispose(struct nfsd_net *nn)
435+
{
436+
struct nfsd_fcache_disposal *l = nn->fcache_disposal;
437+
438+
if (!list_empty(&l->freeme)) {
439+
LIST_HEAD(dispose);
440+
int i;
441+
442+
spin_lock(&l->lock);
443+
for (i = 0; i < 8 && !list_empty(&l->freeme); i++)
444+
list_move(l->freeme.next, &dispose);
445+
spin_unlock(&l->lock);
446+
if (!list_empty(&l->freeme))
447+
/* Wake up another thread to share the work
448+
* *before* doing any actual disposing.
449+
*/
450+
svc_wake_up(nn->nfsd_serv);
451+
nfsd_file_dispose_list(&dispose);
425452
}
426453
}
427454

@@ -631,28 +658,6 @@ nfsd_file_close_inode_sync(struct inode *inode)
631658
list_del_init(&nf->nf_lru);
632659
nfsd_file_free(nf);
633660
}
634-
flush_delayed_fput();
635-
}
636-
637-
/**
638-
* nfsd_file_delayed_close - close unused nfsd_files
639-
* @work: dummy
640-
*
641-
* Scrape the freeme list for this nfsd_net, and then dispose of them
642-
* all.
643-
*/
644-
static void
645-
nfsd_file_delayed_close(struct work_struct *work)
646-
{
647-
LIST_HEAD(head);
648-
struct nfsd_fcache_disposal *l = container_of(work,
649-
struct nfsd_fcache_disposal, work);
650-
651-
spin_lock(&l->lock);
652-
list_splice_init(&l->freeme, &head);
653-
spin_unlock(&l->lock);
654-
655-
nfsd_file_dispose_list(&head);
656661
}
657662

658663
static int
@@ -717,25 +722,18 @@ nfsd_file_cache_init(void)
717722
return ret;
718723

719724
ret = -ENOMEM;
720-
nfsd_filecache_wq = alloc_workqueue("nfsd_filecache", WQ_UNBOUND, 0);
721-
if (!nfsd_filecache_wq)
722-
goto out;
723-
724-
nfsd_file_slab = kmem_cache_create("nfsd_file",
725-
sizeof(struct nfsd_file), 0, 0, NULL);
725+
nfsd_file_slab = KMEM_CACHE(nfsd_file, 0);
726726
if (!nfsd_file_slab) {
727727
pr_err("nfsd: unable to create nfsd_file_slab\n");
728728
goto out_err;
729729
}
730730

731-
nfsd_file_mark_slab = kmem_cache_create("nfsd_file_mark",
732-
sizeof(struct nfsd_file_mark), 0, 0, NULL);
731+
nfsd_file_mark_slab = KMEM_CACHE(nfsd_file_mark, 0);
733732
if (!nfsd_file_mark_slab) {
734733
pr_err("nfsd: unable to create nfsd_file_mark_slab\n");
735734
goto out_err;
736735
}
737736

738-
739737
ret = list_lru_init(&nfsd_file_lru);
740738
if (ret) {
741739
pr_err("nfsd: failed to init nfsd_file_lru: %d\n", ret);
@@ -785,8 +783,6 @@ nfsd_file_cache_init(void)
785783
nfsd_file_slab = NULL;
786784
kmem_cache_destroy(nfsd_file_mark_slab);
787785
nfsd_file_mark_slab = NULL;
788-
destroy_workqueue(nfsd_filecache_wq);
789-
nfsd_filecache_wq = NULL;
790786
rhltable_destroy(&nfsd_file_rhltable);
791787
goto out;
792788
}
@@ -832,7 +828,6 @@ nfsd_alloc_fcache_disposal(void)
832828
l = kmalloc(sizeof(*l), GFP_KERNEL);
833829
if (!l)
834830
return NULL;
835-
INIT_WORK(&l->work, nfsd_file_delayed_close);
836831
spin_lock_init(&l->lock);
837832
INIT_LIST_HEAD(&l->freeme);
838833
return l;
@@ -841,7 +836,6 @@ nfsd_alloc_fcache_disposal(void)
841836
static void
842837
nfsd_free_fcache_disposal(struct nfsd_fcache_disposal *l)
843838
{
844-
cancel_work_sync(&l->work);
845839
nfsd_file_dispose_list(&l->freeme);
846840
kfree(l);
847841
}
@@ -910,8 +904,6 @@ nfsd_file_cache_shutdown(void)
910904
fsnotify_wait_marks_destroyed();
911905
kmem_cache_destroy(nfsd_file_mark_slab);
912906
nfsd_file_mark_slab = NULL;
913-
destroy_workqueue(nfsd_filecache_wq);
914-
nfsd_filecache_wq = NULL;
915907
rhltable_destroy(&nfsd_file_rhltable);
916908

917909
for_each_possible_cpu(i) {

fs/nfsd/filecache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ void nfsd_file_cache_shutdown_net(struct net *net);
5656
void nfsd_file_put(struct nfsd_file *nf);
5757
struct nfsd_file *nfsd_file_get(struct nfsd_file *nf);
5858
void nfsd_file_close_inode_sync(struct inode *inode);
59+
void nfsd_file_net_dispose(struct nfsd_net *nn);
5960
bool nfsd_file_is_cached(struct inode *inode);
6061
__be32 nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp,
6162
unsigned int may_flags, struct nfsd_file **nfp);

fs/nfsd/netns.h

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
#include <net/net_namespace.h>
1212
#include <net/netns/generic.h>
1313
#include <linux/filelock.h>
14+
#include <linux/nfs4.h>
1415
#include <linux/percpu_counter.h>
1516
#include <linux/siphash.h>
17+
#include <linux/sunrpc/stats.h>
1618

1719
/* Hash tables for nfs4_clientid state */
1820
#define CLIENT_HASH_BITS 4
@@ -26,10 +28,22 @@ struct nfsd4_client_tracking_ops;
2628

2729
enum {
2830
/* cache misses due only to checksum comparison failures */
29-
NFSD_NET_PAYLOAD_MISSES,
31+
NFSD_STATS_PAYLOAD_MISSES,
3032
/* amount of memory (in bytes) currently consumed by the DRC */
31-
NFSD_NET_DRC_MEM_USAGE,
32-
NFSD_NET_COUNTERS_NUM
33+
NFSD_STATS_DRC_MEM_USAGE,
34+
NFSD_STATS_RC_HITS, /* repcache hits */
35+
NFSD_STATS_RC_MISSES, /* repcache misses */
36+
NFSD_STATS_RC_NOCACHE, /* uncached reqs */
37+
NFSD_STATS_FH_STALE, /* FH stale error */
38+
NFSD_STATS_IO_READ, /* bytes returned to read requests */
39+
NFSD_STATS_IO_WRITE, /* bytes passed in write requests */
40+
#ifdef CONFIG_NFSD_V4
41+
NFSD_STATS_FIRST_NFS4_OP, /* count of individual nfsv4 operations */
42+
NFSD_STATS_LAST_NFS4_OP = NFSD_STATS_FIRST_NFS4_OP + LAST_NFS4_OP,
43+
#define NFSD_STATS_NFS4_OP(op) (NFSD_STATS_FIRST_NFS4_OP + (op))
44+
NFSD_STATS_WDELEG_GETATTR, /* count of getattr conflict with wdeleg */
45+
#endif
46+
NFSD_STATS_COUNTERS_NUM
3347
};
3448

3549
/*
@@ -164,7 +178,10 @@ struct nfsd_net {
164178
atomic_t num_drc_entries;
165179

166180
/* Per-netns stats counters */
167-
struct percpu_counter counter[NFSD_NET_COUNTERS_NUM];
181+
struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM];
182+
183+
/* sunrpc svc stats */
184+
struct svc_stat nfsd_svcstats;
168185

169186
/* longest hash chain seen */
170187
unsigned int longest_chain;
@@ -192,6 +209,10 @@ struct nfsd_net {
192209
atomic_t nfsd_courtesy_clients;
193210
struct shrinker *nfsd_client_shrinker;
194211
struct work_struct nfsd_shrinker_work;
212+
213+
/* last time an admin-revoke happened for NFSv4.0 */
214+
time64_t nfs40_last_revoke;
215+
195216
};
196217

197218
/* Simple check to find out if a given net was properly initialized */

fs/nfsd/nfs3proc.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,15 @@ nfsd3_proc_setattr(struct svc_rqst *rqstp)
7171
struct nfsd_attrs attrs = {
7272
.na_iattr = &argp->attrs,
7373
};
74+
const struct timespec64 *guardtime = NULL;
7475

7576
dprintk("nfsd: SETATTR(3) %s\n",
7677
SVCFH_fmt(&argp->fh));
7778

7879
fh_copy(&resp->fh, &argp->fh);
79-
resp->status = nfsd_setattr(rqstp, &resp->fh, &attrs,
80-
argp->check_guard, argp->guardtime);
80+
if (argp->check_guard)
81+
guardtime = &argp->guardtime;
82+
resp->status = nfsd_setattr(rqstp, &resp->fh, &attrs, guardtime);
8183
return rpc_success;
8284
}
8385

fs/nfsd/nfs3xdr.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,17 +295,14 @@ svcxdr_decode_sattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
295295
static bool
296296
svcxdr_decode_sattrguard3(struct xdr_stream *xdr, struct nfsd3_sattrargs *args)
297297
{
298-
__be32 *p;
299298
u32 check;
300299

301300
if (xdr_stream_decode_bool(xdr, &check) < 0)
302301
return false;
303302
if (check) {
304-
p = xdr_inline_decode(xdr, XDR_UNIT * 2);
305-
if (!p)
303+
if (!svcxdr_decode_nfstime3(xdr, &args->guardtime))
306304
return false;
307305
args->check_guard = 1;
308-
args->guardtime = be32_to_cpup(p);
309306
} else
310307
args->check_guard = 0;
311308

0 commit comments

Comments
 (0)