Skip to content

Commit f35d170

Browse files
committed
Merge tag 'nfsd-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull nfsd updates from Chuck Lever: "I'm thrilled to announce that the Linux in-kernel NFS server now offers NFSv4 write delegations. A write delegation enables a client to cache data and metadata for a single file more aggressively, reducing network round trips and server workload. Many thanks to Dai Ngo for contributing this facility, and to Jeff Layton and Neil Brown for reviewing and testing it. This release also sees the removal of all support for DES- and triple-DES-based Kerberos encryption types in the kernel's SunRPC implementation. These encryption types have been deprecated by the Internet community for years and are considered insecure. This change affects both the in-kernel NFS client and server. The server's UDP and TCP socket transports have now fully adopted David Howells' new bio_vec iterator so that no more than one sendmsg() call is needed to transmit each RPC message. In particular, this helps kTLS optimize record boundaries when sending RPC-with-TLS replies, and it takes the server a baby step closer to handling file I/O via folios. We've begun work on overhauling the SunRPC thread scheduler to remove a costly linked-list walk when looking for an idle RPC service thread to wake. The pre-requisites are included in this release. Thanks to Neil Brown for his ongoing work on this improvement" * tag 'nfsd-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (56 commits) Documentation: Add missing documentation for EXPORT_OP flags SUNRPC: Remove unused declaration rpc_modcount() SUNRPC: Remove unused declarations NFSD: da_addr_body field missing in some GETDEVICEINFO replies SUNRPC: Remove return value of svc_pool_wake_idle_thread() SUNRPC: make rqst_should_sleep() idempotent() SUNRPC: Clean up svc_set_num_threads SUNRPC: Count ingress RPC messages per svc_pool SUNRPC: Deduplicate thread wake-up code SUNRPC: Move trace_svc_xprt_enqueue SUNRPC: Add enum svc_auth_status SUNRPC: change svc_xprt::xpt_flags bits to enum SUNRPC: change svc_rqst::rq_flags bits to enum SUNRPC: change svc_pool::sp_flags bits to enum SUNRPC: change cache_head.flags bits to enum SUNRPC: remove timeout arg from svc_recv() SUNRPC: change svc_recv() to return void. SUNRPC: call svc_process() from svc_recv(). nfsd: separate nfsd_last_thread() from nfsd_put() nfsd: Simplify code around svc_exit_thread() call in nfsd() ...
2 parents 8ae5d29 + b38a602 commit f35d170

Some content is hidden

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

54 files changed

+969
-1799
lines changed

Documentation/filesystems/nfs/exporting.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,29 @@ following flags are defined:
215215
This flag causes nfsd to close any open files for this inode _before_
216216
calling into the vfs to do an unlink or a rename that would replace
217217
an existing file.
218+
219+
EXPORT_OP_REMOTE_FS - Backing storage for this filesystem is remote
220+
PF_LOCAL_THROTTLE exists for loopback NFSD, where a thread needs to
221+
write to one bdi (the final bdi) in order to free up writes queued
222+
to another bdi (the client bdi). Such threads get a private balance
223+
of dirty pages so that dirty pages for the client bdi do not imact
224+
the daemon writing to the final bdi. For filesystems whose durable
225+
storage is not local (such as exported NFS filesystems), this
226+
constraint has negative consequences. EXPORT_OP_REMOTE_FS enables
227+
an export to disable writeback throttling.
228+
229+
EXPORT_OP_NOATOMIC_ATTR - Filesystem does not update attributes atomically
230+
EXPORT_OP_NOATOMIC_ATTR indicates that the exported filesystem
231+
cannot provide the semantics required by the "atomic" boolean in
232+
NFSv4's change_info4. This boolean indicates to a client whether the
233+
returned before and after change attributes were obtained atomically
234+
with the respect to the requested metadata operation (UNLINK,
235+
OPEN/CREATE, MKDIR, etc).
236+
237+
EXPORT_OP_FLUSH_ON_CLOSE - Filesystem flushes file data on close(2)
238+
On most filesystems, inodes can remain under writeback after the
239+
file is closed. NFSD relies on client activity or local flusher
240+
threads to handle writeback. Certain filesystems, such as NFS, flush
241+
all of an inode's dirty data on last close. Exports that behave this
242+
way should set EXPORT_OP_FLUSH_ON_CLOSE so that NFSD knows to skip
243+
waiting for writeback when closing such files.

fs/exportfs/expfs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ static int export_encode_fh(struct inode *inode, struct fid *fid,
386386
* @inode: the object to encode
387387
* @fid: where to store the file handle fragment
388388
* @max_len: maximum length to store there
389+
* @parent: parent directory inode, if wanted
389390
* @flags: properties of the requested file handle
390391
*
391392
* Returns an enum fid_type or a negative errno.

fs/lockd/mon.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
276276
{
277277
struct nsm_handle *new;
278278

279+
if (!hostname)
280+
return NULL;
281+
279282
new = kzalloc(sizeof(*new) + hostname_len + 1, GFP_KERNEL);
280283
if (unlikely(new == NULL))
281284
return NULL;

fs/lockd/svc.c

Lines changed: 10 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545

4646
#define NLMDBG_FACILITY NLMDBG_SVC
4747
#define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE)
48-
#define ALLOWED_SIGS (sigmask(SIGKILL))
4948

5049
static struct svc_program nlmsvc_program;
5150

@@ -57,6 +56,12 @@ static unsigned int nlmsvc_users;
5756
static struct svc_serv *nlmsvc_serv;
5857
unsigned long nlmsvc_timeout;
5958

59+
static void nlmsvc_request_retry(struct timer_list *tl)
60+
{
61+
svc_wake_up(nlmsvc_serv);
62+
}
63+
DEFINE_TIMER(nlmsvc_retry, nlmsvc_request_retry);
64+
6065
unsigned int lockd_net_id;
6166

6267
/*
@@ -111,70 +116,32 @@ static void set_grace_period(struct net *net)
111116
schedule_delayed_work(&ln->grace_period_end, grace_period);
112117
}
113118

114-
static void restart_grace(void)
115-
{
116-
if (nlmsvc_ops) {
117-
struct net *net = &init_net;
118-
struct lockd_net *ln = net_generic(net, lockd_net_id);
119-
120-
cancel_delayed_work_sync(&ln->grace_period_end);
121-
locks_end_grace(&ln->lockd_manager);
122-
nlmsvc_invalidate_all();
123-
set_grace_period(net);
124-
}
125-
}
126-
127119
/*
128120
* This is the lockd kernel thread
129121
*/
130122
static int
131123
lockd(void *vrqstp)
132124
{
133-
int err = 0;
134125
struct svc_rqst *rqstp = vrqstp;
135126
struct net *net = &init_net;
136127
struct lockd_net *ln = net_generic(net, lockd_net_id);
137128

138129
/* try_to_freeze() is called from svc_recv() */
139130
set_freezable();
140131

141-
/* Allow SIGKILL to tell lockd to drop all of its locks */
142-
allow_signal(SIGKILL);
143-
144132
dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n");
145133

146134
/*
147135
* The main request loop. We don't terminate until the last
148136
* NFS mount or NFS daemon has gone away.
149137
*/
150138
while (!kthread_should_stop()) {
151-
long timeout = MAX_SCHEDULE_TIMEOUT;
152-
RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
153-
154139
/* update sv_maxconn if it has changed */
155140
rqstp->rq_server->sv_maxconn = nlm_max_connections;
156141

157-
if (signalled()) {
158-
flush_signals(current);
159-
restart_grace();
160-
continue;
161-
}
162-
163-
timeout = nlmsvc_retry_blocked();
164-
165-
/*
166-
* Find a socket with data available and call its
167-
* recvfrom routine.
168-
*/
169-
err = svc_recv(rqstp, timeout);
170-
if (err == -EAGAIN || err == -EINTR)
171-
continue;
172-
dprintk("lockd: request from %s\n",
173-
svc_print_addr(rqstp, buf, sizeof(buf)));
174-
175-
svc_process(rqstp);
142+
nlmsvc_retry_blocked();
143+
svc_recv(rqstp);
176144
}
177-
flush_signals(current);
178145
if (nlmsvc_ops)
179146
nlmsvc_invalidate_all();
180147
nlm_shutdown_hosts();
@@ -407,6 +374,7 @@ static void lockd_put(void)
407374
#endif
408375

409376
svc_set_num_threads(nlmsvc_serv, NULL, 0);
377+
timer_delete_sync(&nlmsvc_retry);
410378
nlmsvc_serv = NULL;
411379
dprintk("lockd_down: service destroyed\n");
412380
}
@@ -538,7 +506,7 @@ static inline int is_callback(u32 proc)
538506
}
539507

540508

541-
static int lockd_authenticate(struct svc_rqst *rqstp)
509+
static enum svc_auth_status lockd_authenticate(struct svc_rqst *rqstp)
542510
{
543511
rqstp->rq_client = NULL;
544512
switch (rqstp->rq_authop->flavour) {

fs/lockd/svclock.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,14 @@ static void nlmsvc_insert_block(struct nlm_block *block, unsigned long when)
131131
static inline void
132132
nlmsvc_remove_block(struct nlm_block *block)
133133
{
134+
spin_lock(&nlm_blocked_lock);
134135
if (!list_empty(&block->b_list)) {
135-
spin_lock(&nlm_blocked_lock);
136136
list_del_init(&block->b_list);
137137
spin_unlock(&nlm_blocked_lock);
138138
nlmsvc_release_block(block);
139+
return;
139140
}
141+
spin_unlock(&nlm_blocked_lock);
140142
}
141143

142144
/*
@@ -152,6 +154,7 @@ nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock)
152154
file, lock->fl.fl_pid,
153155
(long long)lock->fl.fl_start,
154156
(long long)lock->fl.fl_end, lock->fl.fl_type);
157+
spin_lock(&nlm_blocked_lock);
155158
list_for_each_entry(block, &nlm_blocked, b_list) {
156159
fl = &block->b_call->a_args.lock.fl;
157160
dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n",
@@ -161,9 +164,11 @@ nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock)
161164
nlmdbg_cookie2a(&block->b_call->a_args.cookie));
162165
if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) {
163166
kref_get(&block->b_count);
167+
spin_unlock(&nlm_blocked_lock);
164168
return block;
165169
}
166170
}
171+
spin_unlock(&nlm_blocked_lock);
167172

168173
return NULL;
169174
}
@@ -185,16 +190,19 @@ nlmsvc_find_block(struct nlm_cookie *cookie)
185190
{
186191
struct nlm_block *block;
187192

193+
spin_lock(&nlm_blocked_lock);
188194
list_for_each_entry(block, &nlm_blocked, b_list) {
189195
if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie))
190196
goto found;
191197
}
198+
spin_unlock(&nlm_blocked_lock);
192199

193200
return NULL;
194201

195202
found:
196203
dprintk("nlmsvc_find_block(%s): block=%p\n", nlmdbg_cookie2a(cookie), block);
197204
kref_get(&block->b_count);
205+
spin_unlock(&nlm_blocked_lock);
198206
return block;
199207
}
200208

@@ -317,6 +325,7 @@ void nlmsvc_traverse_blocks(struct nlm_host *host,
317325

318326
restart:
319327
mutex_lock(&file->f_mutex);
328+
spin_lock(&nlm_blocked_lock);
320329
list_for_each_entry_safe(block, next, &file->f_blocks, b_flist) {
321330
if (!match(block->b_host, host))
322331
continue;
@@ -325,11 +334,13 @@ void nlmsvc_traverse_blocks(struct nlm_host *host,
325334
if (list_empty(&block->b_list))
326335
continue;
327336
kref_get(&block->b_count);
337+
spin_unlock(&nlm_blocked_lock);
328338
mutex_unlock(&file->f_mutex);
329339
nlmsvc_unlink_block(block);
330340
nlmsvc_release_block(block);
331341
goto restart;
332342
}
343+
spin_unlock(&nlm_blocked_lock);
333344
mutex_unlock(&file->f_mutex);
334345
}
335346

@@ -1008,7 +1019,7 @@ retry_deferred_block(struct nlm_block *block)
10081019
* picks up locks that can be granted, or grant notifications that must
10091020
* be retransmitted.
10101021
*/
1011-
unsigned long
1022+
void
10121023
nlmsvc_retry_blocked(void)
10131024
{
10141025
unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
@@ -1038,5 +1049,6 @@ nlmsvc_retry_blocked(void)
10381049
}
10391050
spin_unlock(&nlm_blocked_lock);
10401051

1041-
return timeout;
1052+
if (timeout < MAX_SCHEDULE_TIMEOUT)
1053+
mod_timer(&nlmsvc_retry, jiffies + timeout);
10421054
}

fs/locks.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,13 +1744,6 @@ generic_add_lease(struct file *filp, int arg, struct file_lock **flp, void **pri
17441744
if (is_deleg && !inode_trylock(inode))
17451745
return -EAGAIN;
17461746

1747-
if (is_deleg && arg == F_WRLCK) {
1748-
/* Write delegations are not currently supported: */
1749-
inode_unlock(inode);
1750-
WARN_ON_ONCE(1);
1751-
return -EINVAL;
1752-
}
1753-
17541747
percpu_down_read(&file_rwsem);
17551748
spin_lock(&ctx->flc_lock);
17561749
time_out_leases(inode, &dispose);

fs/nfs/callback.c

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,23 +74,12 @@ static int nfs4_callback_up_net(struct svc_serv *serv, struct net *net)
7474
static int
7575
nfs4_callback_svc(void *vrqstp)
7676
{
77-
int err;
7877
struct svc_rqst *rqstp = vrqstp;
7978

8079
set_freezable();
8180

82-
while (!kthread_freezable_should_stop(NULL)) {
83-
84-
if (signal_pending(current))
85-
flush_signals(current);
86-
/*
87-
* Listen for a request on the socket
88-
*/
89-
err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT);
90-
if (err == -EAGAIN || err == -EINTR)
91-
continue;
92-
svc_process(rqstp);
93-
}
81+
while (!kthread_freezable_should_stop(NULL))
82+
svc_recv(rqstp);
9483

9584
svc_exit_thread(rqstp);
9685
return 0;
@@ -112,11 +101,7 @@ nfs41_callback_svc(void *vrqstp)
112101
set_freezable();
113102

114103
while (!kthread_freezable_should_stop(NULL)) {
115-
116-
if (signal_pending(current))
117-
flush_signals(current);
118-
119-
prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
104+
prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_IDLE);
120105
spin_lock_bh(&serv->sv_cb_lock);
121106
if (!list_empty(&serv->sv_cb_list)) {
122107
req = list_first_entry(&serv->sv_cb_list,
@@ -387,7 +372,7 @@ check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp)
387372
* All other checking done after NFS decoding where the nfs_client can be
388373
* found in nfs4_callback_compound
389374
*/
390-
static int nfs_callback_authenticate(struct svc_rqst *rqstp)
375+
static enum svc_auth_status nfs_callback_authenticate(struct svc_rqst *rqstp)
391376
{
392377
rqstp->rq_auth_stat = rpc_autherr_badcred;
393378

fs/nfsd/blocklayoutxdr.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ nfsd4_block_encode_getdeviceinfo(struct xdr_stream *xdr,
8383
int len = sizeof(__be32), ret, i;
8484
__be32 *p;
8585

86+
/*
87+
* See paragraph 5 of RFC 8881 S18.40.3.
88+
*/
89+
if (!gdp->gd_maxcount) {
90+
if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
91+
return nfserr_resource;
92+
return nfs_ok;
93+
}
94+
8695
p = xdr_reserve_space(xdr, len + sizeof(__be32));
8796
if (!p)
8897
return nfserr_resource;

fs/nfsd/cache.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
* typical sockaddr_storage. This is for space reasons, since sockaddr_storage
2020
* is much larger than a sockaddr_in6.
2121
*/
22-
struct svc_cacherep {
22+
struct nfsd_cacherep {
2323
struct {
2424
/* Keep often-read xid, csum in the same cache line: */
2525
__be32 k_xid;
@@ -84,8 +84,10 @@ int nfsd_net_reply_cache_init(struct nfsd_net *nn);
8484
void nfsd_net_reply_cache_destroy(struct nfsd_net *nn);
8585
int nfsd_reply_cache_init(struct nfsd_net *);
8686
void nfsd_reply_cache_shutdown(struct nfsd_net *);
87-
int nfsd_cache_lookup(struct svc_rqst *);
88-
void nfsd_cache_update(struct svc_rqst *, int, __be32 *);
87+
int nfsd_cache_lookup(struct svc_rqst *rqstp,
88+
struct nfsd_cacherep **cacherep);
89+
void nfsd_cache_update(struct svc_rqst *rqstp, struct nfsd_cacherep *rp,
90+
int cachetype, __be32 *statp);
8991
int nfsd_reply_cache_stats_show(struct seq_file *m, void *v);
9092

9193
#endif /* NFSCACHE_H */

fs/nfsd/flexfilelayoutxdr.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ nfsd4_ff_encode_getdeviceinfo(struct xdr_stream *xdr,
8585
int addr_len;
8686
__be32 *p;
8787

88+
/*
89+
* See paragraph 5 of RFC 8881 S18.40.3.
90+
*/
91+
if (!gdp->gd_maxcount) {
92+
if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
93+
return nfserr_resource;
94+
return nfs_ok;
95+
}
96+
8897
/* len + padding for two strings */
8998
addr_len = 16 + da->netaddr.netid_len + da->netaddr.addr_len;
9099
ver_len = 20;

0 commit comments

Comments
 (0)