Skip to content

Commit 8b16da6

Browse files
committed
Merge tag 'nfsd-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull nfsd updates from Chuck Lever: "This release completes the SunRPC thread scheduler work that was begun in v6.6. The scheduler can now find an svc thread to wake in constant time and without a list walk. Thanks again to Neil Brown for this overhaul. Lorenzo Bianconi contributed infrastructure for a netlink-based NFSD control plane. The long-term plan is to provide the same functionality as found in /proc/fs/nfsd, plus some interesting additions, and then migrate the NFSD user space utilities to netlink. A long series to overhaul NFSD's NFSv4 operation encoding was applied in this release. The goals are to bring this family of encoding functions in line with the matching NFSv4 decoding functions and with the NFSv2 and NFSv3 XDR functions, preparing the way for better memory safety and maintainability. A further improvement to NFSD's write delegation support was contributed by Dai Ngo. This adds a CB_GETATTR callback, enabling the server to retrieve cached size and mtime data from clients holding write delegations. If the server can retrieve this information, it does not have to recall the delegation in some cases. The usual panoply of bug fixes and minor improvements round out this release. As always I am grateful to all contributors, reviewers, and testers" * tag 'nfsd-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (127 commits) svcrdma: Fix tracepoint printk format svcrdma: Drop connection after an RDMA Read error NFSD: clean up alloc_init_deleg() NFSD: Fix frame size warning in svc_export_parse() NFSD: Rewrite synopsis of nfsd_percpu_counters_init() nfsd: Clean up errors in nfs3proc.c nfsd: Clean up errors in nfs4state.c NFSD: Clean up errors in stats.c NFSD: simplify error paths in nfsd_svc() NFSD: Clean up nfsd4_encode_seek() NFSD: Clean up nfsd4_encode_offset_status() NFSD: Clean up nfsd4_encode_copy_notify() NFSD: Clean up nfsd4_encode_copy() NFSD: Clean up nfsd4_encode_test_stateid() NFSD: Clean up nfsd4_encode_exchange_id() NFSD: Clean up nfsd4_do_encode_secinfo() NFSD: Clean up nfsd4_encode_access() NFSD: Clean up nfsd4_encode_readdir() NFSD: Clean up nfsd4_encode_entry4() NFSD: Add an nfsd4_encode_nfs_cookie4() helper ...
2 parents 14ab6d4 + 3fd2ca5 commit 8b16da6

Some content is hidden

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

61 files changed

+3530
-1743
lines changed

Documentation/filesystems/nfs/exporting.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,10 @@ following flags are defined:
241241
all of an inode's dirty data on last close. Exports that behave this
242242
way should set EXPORT_OP_FLUSH_ON_CLOSE so that NFSD knows to skip
243243
waiting for writeback when closing such files.
244+
245+
EXPORT_OP_ASYNC_LOCK - Indicates a capable filesystem to do async lock
246+
requests from lockd. Only set EXPORT_OP_ASYNC_LOCK if the filesystem has
247+
it's own ->lock() functionality as core posix_lock_file() implementation
248+
has no async lock request handling yet. For more information about how to
249+
indicate an async lock request from a ->lock() file_operations struct, see
250+
fs/locks.c and comment for the function vfs_lock_file().

Documentation/netlink/specs/nfsd.yaml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
2+
3+
name: nfsd
4+
protocol: genetlink
5+
uapi-header: linux/nfsd_netlink.h
6+
7+
doc: NFSD configuration over generic netlink.
8+
9+
attribute-sets:
10+
-
11+
name: rpc-status
12+
attributes:
13+
-
14+
name: xid
15+
type: u32
16+
byte-order: big-endian
17+
-
18+
name: flags
19+
type: u32
20+
-
21+
name: prog
22+
type: u32
23+
-
24+
name: version
25+
type: u8
26+
-
27+
name: proc
28+
type: u32
29+
-
30+
name: service_time
31+
type: s64
32+
-
33+
name: pad
34+
type: pad
35+
-
36+
name: saddr4
37+
type: u32
38+
byte-order: big-endian
39+
display-hint: ipv4
40+
-
41+
name: daddr4
42+
type: u32
43+
byte-order: big-endian
44+
display-hint: ipv4
45+
-
46+
name: saddr6
47+
type: binary
48+
display-hint: ipv6
49+
-
50+
name: daddr6
51+
type: binary
52+
display-hint: ipv6
53+
-
54+
name: sport
55+
type: u16
56+
byte-order: big-endian
57+
-
58+
name: dport
59+
type: u16
60+
byte-order: big-endian
61+
-
62+
name: compound-ops
63+
type: u32
64+
multi-attr: true
65+
66+
operations:
67+
list:
68+
-
69+
name: rpc-status-get
70+
doc: dump pending nfsd rpc
71+
attribute-set: rpc-status
72+
dump:
73+
pre: nfsd-nl-rpc-status-get-start
74+
post: nfsd-nl-rpc-status-get-done
75+
reply:
76+
attributes:
77+
- xid
78+
- flags
79+
- prog
80+
- version
81+
- proc
82+
- service_time
83+
- saddr4
84+
- daddr4
85+
- saddr6
86+
- daddr6
87+
- sport
88+
- dport
89+
- compound-ops

fs/lockd/svc.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include <linux/uio.h>
2525
#include <linux/smp.h>
2626
#include <linux/mutex.h>
27-
#include <linux/kthread.h>
2827
#include <linux/freezer.h>
2928
#include <linux/inetdevice.h>
3029

@@ -135,11 +134,11 @@ lockd(void *vrqstp)
135134
* The main request loop. We don't terminate until the last
136135
* NFS mount or NFS daemon has gone away.
137136
*/
138-
while (!kthread_should_stop()) {
137+
while (!svc_thread_should_stop(rqstp)) {
139138
/* update sv_maxconn if it has changed */
140139
rqstp->rq_server->sv_maxconn = nlm_max_connections;
141140

142-
nlmsvc_retry_blocked();
141+
nlmsvc_retry_blocked(rqstp);
143142
svc_recv(rqstp);
144143
}
145144
if (nlmsvc_ops)
@@ -373,7 +372,9 @@ static void lockd_put(void)
373372
unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
374373
#endif
375374

375+
svc_get(nlmsvc_serv);
376376
svc_set_num_threads(nlmsvc_serv, NULL, 0);
377+
svc_put(nlmsvc_serv);
377378
timer_delete_sync(&nlmsvc_retry);
378379
nlmsvc_serv = NULL;
379380
dprintk("lockd_down: service destroyed\n");

fs/lockd/svclock.c

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include <linux/sunrpc/svc_xprt.h>
3131
#include <linux/lockd/nlm.h>
3232
#include <linux/lockd/lockd.h>
33-
#include <linux/kthread.h>
3433
#include <linux/exportfs.h>
3534

3635
#define NLMDBG_FACILITY NLMDBG_SVCLOCK
@@ -481,9 +480,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
481480
struct nlm_host *host, struct nlm_lock *lock, int wait,
482481
struct nlm_cookie *cookie, int reclaim)
483482
{
484-
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
485483
struct inode *inode = nlmsvc_file_inode(file);
486-
#endif
487484
struct nlm_block *block = NULL;
488485
int error;
489486
int mode;
@@ -497,7 +494,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
497494
(long long)lock->fl.fl_end,
498495
wait);
499496

500-
if (nlmsvc_file_file(file)->f_op->lock) {
497+
if (!exportfs_lock_op_is_async(inode->i_sb->s_export_op)) {
501498
async_block = wait;
502499
wait = 0;
503500
}
@@ -543,6 +540,25 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
543540
goto out;
544541
}
545542

543+
spin_lock(&nlm_blocked_lock);
544+
/*
545+
* If this is a lock request for an already pending
546+
* lock request we return nlm_lck_blocked without calling
547+
* vfs_lock_file() again. Otherwise we have two pending
548+
* requests on the underlaying ->lock() implementation but
549+
* only one nlm_block to being granted by lm_grant().
550+
*/
551+
if (exportfs_lock_op_is_async(inode->i_sb->s_export_op) &&
552+
!list_empty(&block->b_list)) {
553+
spin_unlock(&nlm_blocked_lock);
554+
ret = nlm_lck_blocked;
555+
goto out;
556+
}
557+
558+
/* Append to list of blocked */
559+
nlmsvc_insert_block_locked(block, NLM_NEVER);
560+
spin_unlock(&nlm_blocked_lock);
561+
546562
if (!wait)
547563
lock->fl.fl_flags &= ~FL_SLEEP;
548564
mode = lock_to_openmode(&lock->fl);
@@ -552,16 +568,12 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
552568
dprintk("lockd: vfs_lock_file returned %d\n", error);
553569
switch (error) {
554570
case 0:
571+
nlmsvc_remove_block(block);
555572
ret = nlm_granted;
556573
goto out;
557574
case -EAGAIN:
558-
/*
559-
* If this is a blocking request for an
560-
* already pending lock request then we need
561-
* to put it back on lockd's block list
562-
*/
563-
if (wait)
564-
break;
575+
if (!wait)
576+
nlmsvc_remove_block(block);
565577
ret = async_block ? nlm_lck_blocked : nlm_lck_denied;
566578
goto out;
567579
case FILE_LOCK_DEFERRED:
@@ -572,17 +584,16 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
572584
ret = nlmsvc_defer_lock_rqst(rqstp, block);
573585
goto out;
574586
case -EDEADLK:
587+
nlmsvc_remove_block(block);
575588
ret = nlm_deadlock;
576589
goto out;
577590
default: /* includes ENOLCK */
591+
nlmsvc_remove_block(block);
578592
ret = nlm_lck_denied_nolocks;
579593
goto out;
580594
}
581595

582596
ret = nlm_lck_blocked;
583-
584-
/* Append to list of blocked */
585-
nlmsvc_insert_block(block, NLM_NEVER);
586597
out:
587598
mutex_unlock(&file->f_mutex);
588599
nlmsvc_release_block(block);
@@ -1020,13 +1031,13 @@ retry_deferred_block(struct nlm_block *block)
10201031
* be retransmitted.
10211032
*/
10221033
void
1023-
nlmsvc_retry_blocked(void)
1034+
nlmsvc_retry_blocked(struct svc_rqst *rqstp)
10241035
{
10251036
unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
10261037
struct nlm_block *block;
10271038

10281039
spin_lock(&nlm_blocked_lock);
1029-
while (!list_empty(&nlm_blocked) && !kthread_should_stop()) {
1040+
while (!list_empty(&nlm_blocked) && !svc_thread_should_stop(rqstp)) {
10301041
block = list_entry(nlm_blocked.next, struct nlm_block, b_list);
10311042

10321043
if (block->b_when == NLM_NEVER)

fs/locks.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,11 +2264,13 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
22642264
* To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX
22652265
* locks, the ->lock() interface may return asynchronously, before the lock has
22662266
* been granted or denied by the underlying filesystem, if (and only if)
2267-
* lm_grant is set. Callers expecting ->lock() to return asynchronously
2268-
* will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if)
2269-
* the request is for a blocking lock. When ->lock() does return asynchronously,
2270-
* it must return FILE_LOCK_DEFERRED, and call ->lm_grant() when the lock
2271-
* request completes.
2267+
* lm_grant is set. Additionally EXPORT_OP_ASYNC_LOCK in export_operations
2268+
* flags need to be set.
2269+
*
2270+
* Callers expecting ->lock() to return asynchronously will only use F_SETLK,
2271+
* not F_SETLKW; they will set FL_SLEEP if (and only if) the request is for a
2272+
* blocking lock. When ->lock() does return asynchronously, it must return
2273+
* FILE_LOCK_DEFERRED, and call ->lm_grant() when the lock request completes.
22722274
* If the request is for non-blocking lock the file system should return
22732275
* FILE_LOCK_DEFERRED then try to get the lock and call the callback routine
22742276
* with the result. If the request timed out the callback routine will return a

fs/nfs/callback.c

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -78,53 +78,14 @@ nfs4_callback_svc(void *vrqstp)
7878

7979
set_freezable();
8080

81-
while (!kthread_freezable_should_stop(NULL))
81+
while (!svc_thread_should_stop(rqstp))
8282
svc_recv(rqstp);
8383

8484
svc_exit_thread(rqstp);
8585
return 0;
8686
}
8787

8888
#if defined(CONFIG_NFS_V4_1)
89-
/*
90-
* The callback service for NFSv4.1 callbacks
91-
*/
92-
static int
93-
nfs41_callback_svc(void *vrqstp)
94-
{
95-
struct svc_rqst *rqstp = vrqstp;
96-
struct svc_serv *serv = rqstp->rq_server;
97-
struct rpc_rqst *req;
98-
int error;
99-
DEFINE_WAIT(wq);
100-
101-
set_freezable();
102-
103-
while (!kthread_freezable_should_stop(NULL)) {
104-
prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_IDLE);
105-
spin_lock_bh(&serv->sv_cb_lock);
106-
if (!list_empty(&serv->sv_cb_list)) {
107-
req = list_first_entry(&serv->sv_cb_list,
108-
struct rpc_rqst, rq_bc_list);
109-
list_del(&req->rq_bc_list);
110-
spin_unlock_bh(&serv->sv_cb_lock);
111-
finish_wait(&serv->sv_cb_waitq, &wq);
112-
dprintk("Invoking bc_svc_process()\n");
113-
error = bc_svc_process(serv, req, rqstp);
114-
dprintk("bc_svc_process() returned w/ error code= %d\n",
115-
error);
116-
} else {
117-
spin_unlock_bh(&serv->sv_cb_lock);
118-
if (!kthread_should_stop())
119-
schedule();
120-
finish_wait(&serv->sv_cb_waitq, &wq);
121-
}
122-
}
123-
124-
svc_exit_thread(rqstp);
125-
return 0;
126-
}
127-
12889
static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
12990
struct svc_serv *serv)
13091
{
@@ -237,10 +198,7 @@ static struct svc_serv *nfs_callback_create_svc(int minorversion)
237198
cb_info->users);
238199

239200
threadfn = nfs4_callback_svc;
240-
#if defined(CONFIG_NFS_V4_1)
241-
if (minorversion)
242-
threadfn = nfs41_callback_svc;
243-
#else
201+
#if !defined(CONFIG_NFS_V4_1)
244202
if (minorversion)
245203
return ERR_PTR(-ENOTSUPP);
246204
#endif

fs/nfsd/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ nfsd-y += trace.o
1212

1313
nfsd-y += nfssvc.o nfsctl.o nfsfh.o vfs.o \
1414
export.o auth.o lockd.o nfscache.o \
15-
stats.o filecache.o nfs3proc.o nfs3xdr.o
15+
stats.o filecache.o nfs3proc.o nfs3xdr.o \
16+
netlink.o
1617
nfsd-$(CONFIG_NFSD_V2) += nfsproc.o nfsxdr.o
1718
nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o
1819
nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o

fs/nfsd/blocklayoutxdr.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616

1717
__be32
1818
nfsd4_block_encode_layoutget(struct xdr_stream *xdr,
19-
struct nfsd4_layoutget *lgp)
19+
const struct nfsd4_layoutget *lgp)
2020
{
21-
struct pnfs_block_extent *b = lgp->lg_content;
21+
const struct pnfs_block_extent *b = lgp->lg_content;
2222
int len = sizeof(__be32) + 5 * sizeof(__be64) + sizeof(__be32);
2323
__be32 *p;
2424

@@ -77,7 +77,7 @@ nfsd4_block_encode_volume(struct xdr_stream *xdr, struct pnfs_block_volume *b)
7777

7878
__be32
7979
nfsd4_block_encode_getdeviceinfo(struct xdr_stream *xdr,
80-
struct nfsd4_getdeviceinfo *gdp)
80+
const struct nfsd4_getdeviceinfo *gdp)
8181
{
8282
struct pnfs_block_deviceaddr *dev = gdp->gd_device;
8383
int len = sizeof(__be32), ret, i;

fs/nfsd/blocklayoutxdr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ struct pnfs_block_deviceaddr {
5151
};
5252

5353
__be32 nfsd4_block_encode_getdeviceinfo(struct xdr_stream *xdr,
54-
struct nfsd4_getdeviceinfo *gdp);
54+
const struct nfsd4_getdeviceinfo *gdp);
5555
__be32 nfsd4_block_encode_layoutget(struct xdr_stream *xdr,
56-
struct nfsd4_layoutget *lgp);
56+
const struct nfsd4_layoutget *lgp);
5757
int nfsd4_block_decode_layoutupdate(__be32 *p, u32 len, struct iomap **iomapp,
5858
u32 block_size);
5959
int nfsd4_scsi_decode_layoutupdate(__be32 *p, u32 len, struct iomap **iomapp,

0 commit comments

Comments
 (0)