Skip to content

Commit f1517df

Browse files
committed
Merge tag 'nfsd-4.16' of git://linux-nfs.org/~bfields/linux
Pull nfsd update from Bruce Fields: "A fairly small update this time around. Some cleanup, RDMA fixes, overlayfs fixes, and a fix for an NFSv4 state bug. The bigger deal for nfsd this time around was Jeff Layton's already-merged i_version patches" * tag 'nfsd-4.16' of git://linux-nfs.org/~bfields/linux: svcrdma: Fix Read chunk round-up NFSD: hide unused svcxdr_dupstr() nfsd: store stat times in fill_pre_wcc() instead of inode times nfsd: encode stat->mtime for getattr instead of inode->i_mtime nfsd: return RESOURCE not GARBAGE_ARGS on too many ops nfsd4: don't set lock stateid's sc_type to CLOSED nfsd: Detect unhashed stids in nfsd4_verify_open_stid() sunrpc: remove dead code in svc_sock_setbufsize svcrdma: Post Receives in the Receive completion handler nfsd4: permit layoutget of executable-only files lockd: convert nlm_rqst.a_count from atomic_t to refcount_t lockd: convert nlm_lockowner.count from atomic_t to refcount_t lockd: convert nsm_handle.sm_count from atomic_t to refcount_t
2 parents 9d21874 + 175e031 commit f1517df

File tree

14 files changed

+73
-97
lines changed

14 files changed

+73
-97
lines changed

fs/locks.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,9 +1554,9 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
15541554
EXPORT_SYMBOL(__break_lease);
15551555

15561556
/**
1557-
* lease_get_mtime - get the last modified time of an inode
1557+
* lease_get_mtime - update modified time of an inode with exclusive lease
15581558
* @inode: the inode
1559-
* @time: pointer to a timespec which will contain the last modified time
1559+
* @time: pointer to a timespec which contains the last modified time
15601560
*
15611561
* This is to force NFS clients to flush their caches for files with
15621562
* exclusive leases. The justification is that if someone has an
@@ -1580,8 +1580,6 @@ void lease_get_mtime(struct inode *inode, struct timespec *time)
15801580

15811581
if (has_lease)
15821582
*time = current_time(inode);
1583-
else
1584-
*time = inode->i_mtime;
15851583
}
15861584

15871585
EXPORT_SYMBOL(lease_get_mtime);

fs/nfsd/nfs3xdr.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,34 @@ encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
250250
return encode_post_op_attr(rqstp, p, fhp);
251251
}
252252

253+
/*
254+
* Fill in the pre_op attr for the wcc data
255+
*/
256+
void fill_pre_wcc(struct svc_fh *fhp)
257+
{
258+
struct inode *inode;
259+
struct kstat stat;
260+
__be32 err;
261+
262+
if (fhp->fh_pre_saved)
263+
return;
264+
265+
inode = d_inode(fhp->fh_dentry);
266+
err = fh_getattr(fhp, &stat);
267+
if (err) {
268+
/* Grab the times from inode anyway */
269+
stat.mtime = inode->i_mtime;
270+
stat.ctime = inode->i_ctime;
271+
stat.size = inode->i_size;
272+
}
273+
274+
fhp->fh_pre_mtime = stat.mtime;
275+
fhp->fh_pre_ctime = stat.ctime;
276+
fhp->fh_pre_size = stat.size;
277+
fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
278+
fhp->fh_pre_saved = true;
279+
}
280+
253281
/*
254282
* Fill in the post_op attr for the wcc data
255283
*/
@@ -261,7 +289,8 @@ void fill_post_wcc(struct svc_fh *fhp)
261289
printk("nfsd: inode locked twice during operation.\n");
262290

263291
err = fh_getattr(fhp, &fhp->fh_post_attr);
264-
fhp->fh_post_change = nfsd4_change_attribute(d_inode(fhp->fh_dentry));
292+
fhp->fh_post_change = nfsd4_change_attribute(&fhp->fh_post_attr,
293+
d_inode(fhp->fh_dentry));
265294
if (err) {
266295
fhp->fh_post_saved = false;
267296
/* Grab the ctime anyway - set_change_info might use it */

fs/nfsd/nfs4proc.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,14 +1363,14 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
13631363
const struct nfsd4_layout_ops *ops;
13641364
struct nfs4_layout_stateid *ls;
13651365
__be32 nfserr;
1366-
int accmode;
1366+
int accmode = NFSD_MAY_READ_IF_EXEC;
13671367

13681368
switch (lgp->lg_seg.iomode) {
13691369
case IOMODE_READ:
1370-
accmode = NFSD_MAY_READ;
1370+
accmode |= NFSD_MAY_READ;
13711371
break;
13721372
case IOMODE_RW:
1373-
accmode = NFSD_MAY_READ | NFSD_MAY_WRITE;
1373+
accmode |= NFSD_MAY_READ | NFSD_MAY_WRITE;
13741374
break;
13751375
default:
13761376
dprintk("%s: invalid iomode %d\n",
@@ -1703,6 +1703,9 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
17031703
status = nfserr_minor_vers_mismatch;
17041704
if (nfsd_minorversion(args->minorversion, NFSD_TEST) <= 0)
17051705
goto out;
1706+
status = nfserr_resource;
1707+
if (args->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
1708+
goto out;
17061709

17071710
status = nfs41_check_op_ordering(args);
17081711
if (status) {

fs/nfsd/nfs4state.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3590,6 +3590,7 @@ nfsd4_verify_open_stid(struct nfs4_stid *s)
35903590
switch (s->sc_type) {
35913591
default:
35923592
break;
3593+
case 0:
35933594
case NFS4_CLOSED_STID:
35943595
case NFS4_CLOSED_DELEG_STID:
35953596
ret = nfserr_bad_stateid;
@@ -5182,7 +5183,6 @@ nfsd4_free_lock_stateid(stateid_t *stateid, struct nfs4_stid *s)
51825183
lockowner(stp->st_stateowner)))
51835184
goto out;
51845185

5185-
stp->st_stid.sc_type = NFS4_CLOSED_STID;
51865186
release_lock_stateid(stp);
51875187
ret = nfs_ok;
51885188

@@ -6078,10 +6078,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
60786078
* If this is a new, never-before-used stateid, and we are
60796079
* returning an error, then just go ahead and release it.
60806080
*/
6081-
if (status && new) {
6082-
lock_stp->st_stid.sc_type = NFS4_CLOSED_STID;
6081+
if (status && new)
60836082
release_lock_stateid(lock_stp);
6084-
}
60856083

60866084
mutex_unlock(&lock_stp->st_mutex);
60876085

fs/nfsd/nfs4xdr.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,8 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
455455
}
456456

457457
label->len = 0;
458-
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
459-
if (bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
458+
if (IS_ENABLED(CONFIG_NFSD_V4_SECURITY_LABEL) &&
459+
bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
460460
READ_BUF(4);
461461
len += 4;
462462
dummy32 = be32_to_cpup(p++); /* lfs: we don't use it */
@@ -476,7 +476,6 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
476476
if (!label->data)
477477
return nfserr_jukebox;
478478
}
479-
#endif
480479
if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
481480
if (!umask)
482481
goto xdr_error;
@@ -1918,8 +1917,13 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
19181917

19191918
if (argp->taglen > NFSD4_MAX_TAGLEN)
19201919
goto xdr_error;
1921-
if (argp->opcnt > 100)
1922-
goto xdr_error;
1920+
/*
1921+
* NFS4ERR_RESOURCE is a more helpful error than GARBAGE_ARGS
1922+
* here, so we return success at the xdr level so that
1923+
* nfsd4_proc can handle this is an NFS-level error.
1924+
*/
1925+
if (argp->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
1926+
return 0;
19231927

19241928
if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
19251929
argp->ops = kzalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
@@ -1991,7 +1995,7 @@ static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode,
19911995
*p++ = cpu_to_be32(convert_to_wallclock(exp->cd->flush_time));
19921996
*p++ = 0;
19931997
} else if (IS_I_VERSION(inode)) {
1994-
p = xdr_encode_hyper(p, nfsd4_change_attribute(inode));
1998+
p = xdr_encode_hyper(p, nfsd4_change_attribute(stat, inode));
19951999
} else {
19962000
*p++ = cpu_to_be32(stat->ctime.tv_sec);
19972001
*p++ = cpu_to_be32(stat->ctime.tv_nsec);

fs/nfsd/nfsfh.h

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -253,36 +253,20 @@ fh_clear_wcc(struct svc_fh *fhp)
253253
* By using both ctime and the i_version counter we guarantee that as
254254
* long as time doesn't go backwards we never reuse an old value.
255255
*/
256-
static inline u64 nfsd4_change_attribute(struct inode *inode)
256+
static inline u64 nfsd4_change_attribute(struct kstat *stat,
257+
struct inode *inode)
257258
{
258259
u64 chattr;
259260

260-
chattr = inode->i_ctime.tv_sec;
261+
chattr = stat->ctime.tv_sec;
261262
chattr <<= 30;
262-
chattr += inode->i_ctime.tv_nsec;
263+
chattr += stat->ctime.tv_nsec;
263264
chattr += inode_query_iversion(inode);
264265
return chattr;
265266
}
266267

267-
/*
268-
* Fill in the pre_op attr for the wcc data
269-
*/
270-
static inline void
271-
fill_pre_wcc(struct svc_fh *fhp)
272-
{
273-
struct inode *inode;
274-
275-
inode = d_inode(fhp->fh_dentry);
276-
if (!fhp->fh_pre_saved) {
277-
fhp->fh_pre_mtime = inode->i_mtime;
278-
fhp->fh_pre_ctime = inode->i_ctime;
279-
fhp->fh_pre_size = inode->i_size;
280-
fhp->fh_pre_change = nfsd4_change_attribute(inode);
281-
fhp->fh_pre_saved = true;
282-
}
283-
}
284-
285-
extern void fill_post_wcc(struct svc_fh *);
268+
extern void fill_pre_wcc(struct svc_fh *fhp);
269+
extern void fill_post_wcc(struct svc_fh *fhp);
286270
#else
287271
#define fh_clear_wcc(ignored)
288272
#define fill_pre_wcc(ignored)

fs/nfsd/nfsxdr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
188188
*p++ = htonl((u32) stat->ino);
189189
*p++ = htonl((u32) stat->atime.tv_sec);
190190
*p++ = htonl(stat->atime.tv_nsec ? stat->atime.tv_nsec / 1000 : 0);
191+
time = stat->mtime;
191192
lease_get_mtime(d_inode(dentry), &time);
192193
*p++ = htonl((u32) time.tv_sec);
193194
*p++ = htonl(time.tv_nsec ? time.tv_nsec / 1000 : 0);

include/linux/sunrpc/svc_rdma.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,6 @@ extern void svc_rdma_wc_reg(struct ib_cq *, struct ib_wc *);
185185
extern void svc_rdma_wc_read(struct ib_cq *, struct ib_wc *);
186186
extern void svc_rdma_wc_inv(struct ib_cq *, struct ib_wc *);
187187
extern int svc_rdma_send(struct svcxprt_rdma *, struct ib_send_wr *);
188-
extern int svc_rdma_post_recv(struct svcxprt_rdma *, gfp_t);
189-
extern int svc_rdma_repost_recv(struct svcxprt_rdma *, gfp_t);
190188
extern int svc_rdma_create_listen(struct svc_serv *, int, struct sockaddr *);
191189
extern struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *);
192190
extern void svc_rdma_put_context(struct svc_rdma_op_ctxt *, int);

net/sunrpc/svcsock.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -384,25 +384,11 @@ static int svc_partial_recvfrom(struct svc_rqst *rqstp,
384384
static void svc_sock_setbufsize(struct socket *sock, unsigned int snd,
385385
unsigned int rcv)
386386
{
387-
#if 0
388-
mm_segment_t oldfs;
389-
oldfs = get_fs(); set_fs(KERNEL_DS);
390-
sock_setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
391-
(char*)&snd, sizeof(snd));
392-
sock_setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
393-
(char*)&rcv, sizeof(rcv));
394-
#else
395-
/* sock_setsockopt limits use to sysctl_?mem_max,
396-
* which isn't acceptable. Until that is made conditional
397-
* on not having CAP_SYS_RESOURCE or similar, we go direct...
398-
* DaveM said I could!
399-
*/
400387
lock_sock(sock->sk);
401388
sock->sk->sk_sndbuf = snd * 2;
402389
sock->sk->sk_rcvbuf = rcv * 2;
403390
sock->sk->sk_write_space(sock->sk);
404391
release_sock(sock->sk);
405-
#endif
406392
}
407393

408394
static int svc_sock_secure_port(struct svc_rqst *rqstp)

net/sunrpc/xprtrdma/svc_rdma_backchannel.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp,
9595
out_notfound:
9696
dprintk("svcrdma: unrecognized bc reply: xprt=%p, xid=%08x\n",
9797
xprt, be32_to_cpu(xid));
98-
9998
goto out_unlock;
10099
}
101100

@@ -129,10 +128,6 @@ static int svc_rdma_bc_sendto(struct svcxprt_rdma *rdma,
129128
if (ret < 0)
130129
goto out_err;
131130

132-
ret = svc_rdma_repost_recv(rdma, GFP_NOIO);
133-
if (ret)
134-
goto out_err;
135-
136131
/* Bump page refcnt so Send completion doesn't release
137132
* the rq_buffer before all retransmits are complete.
138133
*/

net/sunrpc/xprtrdma/svc_rdma_recvfrom.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -400,10 +400,6 @@ static void svc_rdma_send_error(struct svcxprt_rdma *xprt,
400400
struct page *page;
401401
int ret;
402402

403-
ret = svc_rdma_repost_recv(xprt, GFP_KERNEL);
404-
if (ret)
405-
return;
406-
407403
page = alloc_page(GFP_KERNEL);
408404
if (!page)
409405
return;
@@ -554,8 +550,6 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
554550
ret = svc_rdma_handle_bc_reply(xprt->xpt_bc_xprt, p,
555551
&rqstp->rq_arg);
556552
svc_rdma_put_context(ctxt, 0);
557-
if (ret)
558-
goto repost;
559553
return ret;
560554
}
561555

@@ -590,6 +584,5 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
590584

591585
out_drop:
592586
svc_rdma_put_context(ctxt, 1);
593-
repost:
594-
return svc_rdma_repost_recv(rdma_xprt, GFP_KERNEL);
587+
return 0;
595588
}

net/sunrpc/xprtrdma/svc_rdma_rw.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -727,12 +727,16 @@ static int svc_rdma_build_normal_read_chunk(struct svc_rqst *rqstp,
727727
head->arg.head[0].iov_len - info->ri_position;
728728
head->arg.head[0].iov_len = info->ri_position;
729729

730-
/* Read chunk may need XDR roundup (see RFC 5666, s. 3.7).
730+
/* Read chunk may need XDR roundup (see RFC 8166, s. 3.4.5.2).
731731
*
732-
* NFSv2/3 write decoders need the length of the tail to
733-
* contain the size of the roundup padding.
732+
* If the client already rounded up the chunk length, the
733+
* length does not change. Otherwise, the length of the page
734+
* list is increased to include XDR round-up.
735+
*
736+
* Currently these chunks always start at page offset 0,
737+
* thus the rounded-up length never crosses a page boundary.
734738
*/
735-
head->arg.tail[0].iov_len += 4 - (info->ri_chunklen & 3);
739+
info->ri_chunklen = XDR_QUADLEN(info->ri_chunklen) << 2;
736740

737741
head->arg.page_len = info->ri_chunklen;
738742
head->arg.len += info->ri_chunklen;

net/sunrpc/xprtrdma/svc_rdma_sendto.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -674,9 +674,6 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
674674
svc_rdma_xdr_encode_reply_chunk(rdma_resp, rp_ch, ret);
675675
}
676676

677-
ret = svc_rdma_post_recv(rdma, GFP_KERNEL);
678-
if (ret)
679-
goto err1;
680677
ret = svc_rdma_send_reply_msg(rdma, rdma_argp, rdma_resp, rqstp,
681678
wr_lst, rp_ch);
682679
if (ret < 0)
@@ -687,9 +684,6 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
687684
if (ret != -E2BIG && ret != -EINVAL)
688685
goto err1;
689686

690-
ret = svc_rdma_post_recv(rdma, GFP_KERNEL);
691-
if (ret)
692-
goto err1;
693687
ret = svc_rdma_send_error_msg(rdma, rdma_resp, rqstp);
694688
if (ret < 0)
695689
goto err0;

0 commit comments

Comments
 (0)