Skip to content

Commit c065c42

Browse files
committed
Merge tag 'nfsd-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull nfsd updates from Chuck Lever: "Highlights: - Update NFSv2 and NFSv3 XDR encoding functions - Add batch Receive posting to the server's RPC/RDMA transport (take 2) - Reduce page allocator traffic in svcrdma" * tag 'nfsd-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (70 commits) NFSD: Use DEFINE_SPINLOCK() for spinlock sunrpc: Remove unused function ip_map_lookup NFSv4.2: fix copy stateid copying for the async copy UAPI: nfsfh.h: Replace one-element array with flexible-array member svcrdma: Clean up dto_q critical section in svc_rdma_recvfrom() svcrdma: Remove svc_rdma_recv_ctxt::rc_pages and ::rc_arg svcrdma: Remove sc_read_complete_q svcrdma: Single-stage RDMA Read SUNRPC: Move svc_xprt_received() call sites SUNRPC: Export svc_xprt_received() svcrdma: Retain the page backing rq_res.head[0].iov_base svcrdma: Remove unused sc_pages field svcrdma: Normalize Send page handling svcrdma: Add a "deferred close" helper svcrdma: Maintain a Receive water mark svcrdma: Use svc_rdma_refresh_recvs() in wc_receive svcrdma: Add a batch Receive posting mechanism svcrdma: Remove stale comment for svc_rdma_wc_receive() svcrdma: Provide an explanatory comment in CMA event handler svcrdma: RPCDBG_FACILITY is no longer used ...
2 parents b5b3097 + b73ac68 commit c065c42

40 files changed

Lines changed: 1599 additions & 1185 deletions

fs/nfs_common/nfsacl.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,77 @@ int nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
136136
}
137137
EXPORT_SYMBOL_GPL(nfsacl_encode);
138138

139+
/**
140+
* nfs_stream_encode_acl - Encode an NFSv3 ACL
141+
*
142+
* @xdr: an xdr_stream positioned to receive an encoded ACL
143+
* @inode: inode of file whose ACL this is
144+
* @acl: posix_acl to encode
145+
* @encode_entries: whether to encode ACEs as well
146+
* @typeflag: ACL type: NFS_ACL_DEFAULT or zero
147+
*
148+
* Return values:
149+
* %false: The ACL could not be encoded
150+
* %true: @xdr is advanced to the next available position
151+
*/
152+
bool nfs_stream_encode_acl(struct xdr_stream *xdr, struct inode *inode,
153+
struct posix_acl *acl, int encode_entries,
154+
int typeflag)
155+
{
156+
const size_t elem_size = XDR_UNIT * 3;
157+
u32 entries = (acl && acl->a_count) ? max_t(int, acl->a_count, 4) : 0;
158+
struct nfsacl_encode_desc nfsacl_desc = {
159+
.desc = {
160+
.elem_size = elem_size,
161+
.array_len = encode_entries ? entries : 0,
162+
.xcode = xdr_nfsace_encode,
163+
},
164+
.acl = acl,
165+
.typeflag = typeflag,
166+
.uid = inode->i_uid,
167+
.gid = inode->i_gid,
168+
};
169+
struct nfsacl_simple_acl aclbuf;
170+
unsigned int base;
171+
int err;
172+
173+
if (entries > NFS_ACL_MAX_ENTRIES)
174+
return false;
175+
if (xdr_stream_encode_u32(xdr, entries) < 0)
176+
return false;
177+
178+
if (encode_entries && acl && acl->a_count == 3) {
179+
struct posix_acl *acl2 = &aclbuf.acl;
180+
181+
/* Avoid the use of posix_acl_alloc(). nfsacl_encode() is
182+
* invoked in contexts where a memory allocation failure is
183+
* fatal. Fortunately this fake ACL is small enough to
184+
* construct on the stack. */
185+
posix_acl_init(acl2, 4);
186+
187+
/* Insert entries in canonical order: other orders seem
188+
to confuse Solaris VxFS. */
189+
acl2->a_entries[0] = acl->a_entries[0]; /* ACL_USER_OBJ */
190+
acl2->a_entries[1] = acl->a_entries[1]; /* ACL_GROUP_OBJ */
191+
acl2->a_entries[2] = acl->a_entries[1]; /* ACL_MASK */
192+
acl2->a_entries[2].e_tag = ACL_MASK;
193+
acl2->a_entries[3] = acl->a_entries[2]; /* ACL_OTHER */
194+
nfsacl_desc.acl = acl2;
195+
}
196+
197+
base = xdr_stream_pos(xdr);
198+
if (!xdr_reserve_space(xdr, XDR_UNIT +
199+
elem_size * nfsacl_desc.desc.array_len))
200+
return false;
201+
err = xdr_encode_array2(xdr->buf, base, &nfsacl_desc.desc);
202+
if (err)
203+
return false;
204+
205+
return true;
206+
}
207+
EXPORT_SYMBOL_GPL(nfs_stream_encode_acl);
208+
209+
139210
struct nfsacl_decode_desc {
140211
struct xdr_array2_desc desc;
141212
unsigned int count;

fs/nfsd/Kconfig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ config NFSD_BLOCKLAYOUT
9999
help
100100
This option enables support for the exporting pNFS block layouts
101101
in the kernel's NFS server. The pNFS block layout enables NFS
102-
clients to directly perform I/O to block devices accesible to both
102+
clients to directly perform I/O to block devices accessible to both
103103
the server and the clients. See RFC 5663 for more details.
104104

105105
If unsure, say N.
@@ -113,7 +113,7 @@ config NFSD_SCSILAYOUT
113113
help
114114
This option enables support for the exporting pNFS SCSI layouts
115115
in the kernel's NFS server. The pNFS SCSI layout enables NFS
116-
clients to directly perform I/O to SCSI devices accesible to both
116+
clients to directly perform I/O to SCSI devices accessible to both
117117
the server and the clients. See draft-ietf-nfsv4-scsi-layout for
118118
more details.
119119

@@ -127,7 +127,7 @@ config NFSD_FLEXFILELAYOUT
127127
This option enables support for the exporting pNFS Flex File
128128
layouts in the kernel's NFS server. The pNFS Flex File layout
129129
enables NFS clients to directly perform I/O to NFSv3 devices
130-
accesible to both the server and the clients. See
130+
accessible to both the server and the clients. See
131131
draft-ietf-nfsv4-flex-files for more details.
132132

133133
Warning, this server implements the bare minimum functionality

fs/nfsd/netns.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ struct nfsd_net {
5151
bool grace_ended;
5252
time64_t boot_time;
5353

54-
/* internal mount of the "nfsd" pseudofilesystem: */
55-
struct vfsmount *nfsd_mnt;
56-
5754
struct dentry *nfsd_client_dir;
5855

5956
/*
@@ -130,6 +127,9 @@ struct nfsd_net {
130127
wait_queue_head_t ntf_wq;
131128
atomic_t ntf_refcnt;
132129

130+
/* Allow umount to wait for nfsd state cleanup */
131+
struct completion nfsd_shutdown_complete;
132+
133133
/*
134134
* clientid and stateid data for construction of net unique COPY
135135
* stateids.

fs/nfsd/nfs2acl.c

Lines changed: 31 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -242,79 +242,61 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)
242242
/* GETACL */
243243
static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p)
244244
{
245+
struct xdr_stream *xdr = &rqstp->rq_res_stream;
245246
struct nfsd3_getaclres *resp = rqstp->rq_resp;
246247
struct dentry *dentry = resp->fh.fh_dentry;
247248
struct inode *inode;
248-
struct kvec *head = rqstp->rq_res.head;
249-
unsigned int base;
250-
int n;
251249
int w;
252250

253-
*p++ = resp->status;
254-
if (resp->status != nfs_ok)
255-
return xdr_ressize_check(rqstp, p);
251+
if (!svcxdr_encode_stat(xdr, resp->status))
252+
return 0;
256253

257-
/*
258-
* Since this is version 2, the check for nfserr in
259-
* nfsd_dispatch actually ensures the following cannot happen.
260-
* However, it seems fragile to depend on that.
261-
*/
262254
if (dentry == NULL || d_really_is_negative(dentry))
263-
return 0;
255+
return 1;
264256
inode = d_inode(dentry);
265257

266-
p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat);
267-
*p++ = htonl(resp->mask);
268-
if (!xdr_ressize_check(rqstp, p))
258+
if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat))
259+
return 0;
260+
if (xdr_stream_encode_u32(xdr, resp->mask) < 0)
269261
return 0;
270-
base = (char *)p - (char *)head->iov_base;
271262

272263
rqstp->rq_res.page_len = w = nfsacl_size(
273264
(resp->mask & NFS_ACL) ? resp->acl_access : NULL,
274265
(resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
275266
while (w > 0) {
276267
if (!*(rqstp->rq_next_page++))
277-
return 0;
268+
return 1;
278269
w -= PAGE_SIZE;
279270
}
280271

281-
n = nfsacl_encode(&rqstp->rq_res, base, inode,
282-
resp->acl_access,
283-
resp->mask & NFS_ACL, 0);
284-
if (n > 0)
285-
n = nfsacl_encode(&rqstp->rq_res, base + n, inode,
286-
resp->acl_default,
287-
resp->mask & NFS_DFACL,
288-
NFS_ACL_DEFAULT);
289-
return (n > 0);
290-
}
291-
292-
static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p)
293-
{
294-
struct nfsd_attrstat *resp = rqstp->rq_resp;
295-
296-
*p++ = resp->status;
297-
if (resp->status != nfs_ok)
298-
goto out;
272+
if (!nfs_stream_encode_acl(xdr, inode, resp->acl_access,
273+
resp->mask & NFS_ACL, 0))
274+
return 0;
275+
if (!nfs_stream_encode_acl(xdr, inode, resp->acl_default,
276+
resp->mask & NFS_DFACL, NFS_ACL_DEFAULT))
277+
return 0;
299278

300-
p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat);
301-
out:
302-
return xdr_ressize_check(rqstp, p);
279+
return 1;
303280
}
304281

305282
/* ACCESS */
306283
static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, __be32 *p)
307284
{
285+
struct xdr_stream *xdr = &rqstp->rq_res_stream;
308286
struct nfsd3_accessres *resp = rqstp->rq_resp;
309287

310-
*p++ = resp->status;
311-
if (resp->status != nfs_ok)
312-
goto out;
288+
if (!svcxdr_encode_stat(xdr, resp->status))
289+
return 0;
290+
switch (resp->status) {
291+
case nfs_ok:
292+
if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat))
293+
return 0;
294+
if (xdr_stream_encode_u32(xdr, resp->access) < 0)
295+
return 0;
296+
break;
297+
}
313298

314-
p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat);
315-
*p++ = htonl(resp->access);
316-
out:
317-
return xdr_ressize_check(rqstp, p);
299+
return 1;
318300
}
319301

320302
/*
@@ -329,13 +311,6 @@ static void nfsaclsvc_release_getacl(struct svc_rqst *rqstp)
329311
posix_acl_release(resp->acl_default);
330312
}
331313

332-
static void nfsaclsvc_release_attrstat(struct svc_rqst *rqstp)
333-
{
334-
struct nfsd_attrstat *resp = rqstp->rq_resp;
335-
336-
fh_put(&resp->fh);
337-
}
338-
339314
static void nfsaclsvc_release_access(struct svc_rqst *rqstp)
340315
{
341316
struct nfsd3_accessres *resp = rqstp->rq_resp;
@@ -375,8 +350,8 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
375350
[ACLPROC2_SETACL] = {
376351
.pc_func = nfsacld_proc_setacl,
377352
.pc_decode = nfsaclsvc_decode_setaclargs,
378-
.pc_encode = nfsaclsvc_encode_attrstatres,
379-
.pc_release = nfsaclsvc_release_attrstat,
353+
.pc_encode = nfssvc_encode_attrstatres,
354+
.pc_release = nfssvc_release_attrstat,
380355
.pc_argsize = sizeof(struct nfsd3_setaclargs),
381356
.pc_ressize = sizeof(struct nfsd_attrstat),
382357
.pc_cachetype = RC_NOCACHE,
@@ -386,8 +361,8 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
386361
[ACLPROC2_GETATTR] = {
387362
.pc_func = nfsacld_proc_getattr,
388363
.pc_decode = nfssvc_decode_fhandleargs,
389-
.pc_encode = nfsaclsvc_encode_attrstatres,
390-
.pc_release = nfsaclsvc_release_attrstat,
364+
.pc_encode = nfssvc_encode_attrstatres,
365+
.pc_release = nfssvc_release_attrstat,
391366
.pc_argsize = sizeof(struct nfsd_fhandle),
392367
.pc_ressize = sizeof(struct nfsd_attrstat),
393368
.pc_cachetype = RC_NOCACHE,

fs/nfsd/nfs3acl.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -168,22 +168,25 @@ static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p)
168168
/* GETACL */
169169
static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p)
170170
{
171+
struct xdr_stream *xdr = &rqstp->rq_res_stream;
171172
struct nfsd3_getaclres *resp = rqstp->rq_resp;
172173
struct dentry *dentry = resp->fh.fh_dentry;
174+
struct kvec *head = rqstp->rq_res.head;
175+
struct inode *inode = d_inode(dentry);
176+
unsigned int base;
177+
int n;
178+
int w;
173179

174-
*p++ = resp->status;
175-
p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh);
176-
if (resp->status == 0 && dentry && d_really_is_positive(dentry)) {
177-
struct inode *inode = d_inode(dentry);
178-
struct kvec *head = rqstp->rq_res.head;
179-
unsigned int base;
180-
int n;
181-
int w;
182-
183-
*p++ = htonl(resp->mask);
184-
if (!xdr_ressize_check(rqstp, p))
180+
if (!svcxdr_encode_nfsstat3(xdr, resp->status))
181+
return 0;
182+
switch (resp->status) {
183+
case nfs_ok:
184+
if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
185+
return 0;
186+
if (xdr_stream_encode_u32(xdr, resp->mask) < 0)
185187
return 0;
186-
base = (char *)p - (char *)head->iov_base;
188+
189+
base = (char *)xdr->p - (char *)head->iov_base;
187190

188191
rqstp->rq_res.page_len = w = nfsacl_size(
189192
(resp->mask & NFS_ACL) ? resp->acl_access : NULL,
@@ -204,21 +207,23 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p)
204207
NFS_ACL_DEFAULT);
205208
if (n <= 0)
206209
return 0;
207-
} else
208-
if (!xdr_ressize_check(rqstp, p))
210+
break;
211+
default:
212+
if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
209213
return 0;
214+
}
210215

211216
return 1;
212217
}
213218

214219
/* SETACL */
215220
static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, __be32 *p)
216221
{
222+
struct xdr_stream *xdr = &rqstp->rq_res_stream;
217223
struct nfsd3_attrstat *resp = rqstp->rq_resp;
218224

219-
*p++ = resp->status;
220-
p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh);
221-
return xdr_ressize_check(rqstp, p);
225+
return svcxdr_encode_nfsstat3(xdr, resp->status) &&
226+
svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh);
222227
}
223228

224229
/*

0 commit comments

Comments
 (0)