Skip to content

Commit 7dd4b80

Browse files
committed
Merge tag 'nfsd-6.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull nfsd fixes from Chuck Lever: - Fix a race when creating NFSv4 files - Revert the use of relaxed bitops * tag 'nfsd-6.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: NFSD: Use set_bit(RQ_DROPME) Revert "SUNRPC: Use RMW bitops in single-threaded hot paths" nfsd: fix handling of cached open files in nfsd4_open codepath
2 parents 092f623 + 5304930 commit 7dd4b80

File tree

12 files changed

+59
-89
lines changed

12 files changed

+59
-89
lines changed

fs/nfsd/filecache.c

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,8 +1071,8 @@ nfsd_file_is_cached(struct inode *inode)
10711071

10721072
static __be32
10731073
nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
1074-
unsigned int may_flags, struct nfsd_file **pnf,
1075-
bool open, bool want_gc)
1074+
unsigned int may_flags, struct file *file,
1075+
struct nfsd_file **pnf, bool want_gc)
10761076
{
10771077
struct nfsd_file_lookup_key key = {
10781078
.type = NFSD_FILE_KEY_FULL,
@@ -1147,8 +1147,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
11471147
status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags));
11481148
out:
11491149
if (status == nfs_ok) {
1150-
if (open)
1151-
this_cpu_inc(nfsd_file_acquisitions);
1150+
this_cpu_inc(nfsd_file_acquisitions);
11521151
*pnf = nf;
11531152
} else {
11541153
if (refcount_dec_and_test(&nf->nf_ref))
@@ -1158,20 +1157,23 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
11581157

11591158
out_status:
11601159
put_cred(key.cred);
1161-
if (open)
1162-
trace_nfsd_file_acquire(rqstp, key.inode, may_flags, nf, status);
1160+
trace_nfsd_file_acquire(rqstp, key.inode, may_flags, nf, status);
11631161
return status;
11641162

11651163
open_file:
11661164
trace_nfsd_file_alloc(nf);
11671165
nf->nf_mark = nfsd_file_mark_find_or_create(nf, key.inode);
11681166
if (nf->nf_mark) {
1169-
if (open) {
1167+
if (file) {
1168+
get_file(file);
1169+
nf->nf_file = file;
1170+
status = nfs_ok;
1171+
trace_nfsd_file_opened(nf, status);
1172+
} else {
11701173
status = nfsd_open_verified(rqstp, fhp, may_flags,
11711174
&nf->nf_file);
11721175
trace_nfsd_file_open(nf, status);
1173-
} else
1174-
status = nfs_ok;
1176+
}
11751177
} else
11761178
status = nfserr_jukebox;
11771179
/*
@@ -1207,7 +1209,7 @@ __be32
12071209
nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp,
12081210
unsigned int may_flags, struct nfsd_file **pnf)
12091211
{
1210-
return nfsd_file_do_acquire(rqstp, fhp, may_flags, pnf, true, true);
1212+
return nfsd_file_do_acquire(rqstp, fhp, may_flags, NULL, pnf, true);
12111213
}
12121214

12131215
/**
@@ -1228,28 +1230,30 @@ __be32
12281230
nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
12291231
unsigned int may_flags, struct nfsd_file **pnf)
12301232
{
1231-
return nfsd_file_do_acquire(rqstp, fhp, may_flags, pnf, true, false);
1233+
return nfsd_file_do_acquire(rqstp, fhp, may_flags, NULL, pnf, false);
12321234
}
12331235

12341236
/**
1235-
* nfsd_file_create - Get a struct nfsd_file, do not open
1237+
* nfsd_file_acquire_opened - Get a struct nfsd_file using existing open file
12361238
* @rqstp: the RPC transaction being executed
12371239
* @fhp: the NFS filehandle of the file just created
12381240
* @may_flags: NFSD_MAY_ settings for the file
1241+
* @file: cached, already-open file (may be NULL)
12391242
* @pnf: OUT: new or found "struct nfsd_file" object
12401243
*
1241-
* The nfsd_file_object returned by this API is reference-counted
1242-
* but not garbage-collected. The object is released immediately
1243-
* one RCU grace period after the final nfsd_file_put().
1244+
* Acquire a nfsd_file object that is not GC'ed. If one doesn't already exist,
1245+
* and @file is non-NULL, use it to instantiate a new nfsd_file instead of
1246+
* opening a new one.
12441247
*
12451248
* Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in
12461249
* network byte order is returned.
12471250
*/
12481251
__be32
1249-
nfsd_file_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1250-
unsigned int may_flags, struct nfsd_file **pnf)
1252+
nfsd_file_acquire_opened(struct svc_rqst *rqstp, struct svc_fh *fhp,
1253+
unsigned int may_flags, struct file *file,
1254+
struct nfsd_file **pnf)
12511255
{
1252-
return nfsd_file_do_acquire(rqstp, fhp, may_flags, pnf, false, false);
1256+
return nfsd_file_do_acquire(rqstp, fhp, may_flags, file, pnf, false);
12531257
}
12541258

12551259
/*

fs/nfsd/filecache.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ __be32 nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp,
6060
unsigned int may_flags, struct nfsd_file **nfp);
6161
__be32 nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
6262
unsigned int may_flags, struct nfsd_file **nfp);
63-
__be32 nfsd_file_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
64-
unsigned int may_flags, struct nfsd_file **nfp);
63+
__be32 nfsd_file_acquire_opened(struct svc_rqst *rqstp, struct svc_fh *fhp,
64+
unsigned int may_flags, struct file *file,
65+
struct nfsd_file **nfp);
6566
int nfsd_file_cache_stats_show(struct seq_file *m, void *v);
6667
#endif /* _FS_NFSD_FILECACHE_H */

fs/nfsd/nfs4proc.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
937937
* the client wants us to do more in this compound:
938938
*/
939939
if (!nfsd4_last_compound_op(rqstp))
940-
__clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
940+
clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
941941

942942
/* check stateid */
943943
status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
@@ -2607,12 +2607,11 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
26072607
cstate->minorversion = args->minorversion;
26082608
fh_init(current_fh, NFS4_FHSIZE);
26092609
fh_init(save_fh, NFS4_FHSIZE);
2610-
26112610
/*
26122611
* Don't use the deferral mechanism for NFSv4; compounds make it
26132612
* too hard to avoid non-idempotency problems.
26142613
*/
2615-
__clear_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
2614+
clear_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
26162615

26172616
/*
26182617
* According to RFC3010, this takes precedence over all other errors.
@@ -2734,7 +2733,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
27342733
out:
27352734
cstate->status = status;
27362735
/* Reset deferral mechanism for RPC deferrals */
2737-
__set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
2736+
set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
27382737
return rpc_success;
27392738
}
27402739

fs/nfsd/nfs4state.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5262,18 +5262,10 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
52625262
if (!fp->fi_fds[oflag]) {
52635263
spin_unlock(&fp->fi_lock);
52645264

5265-
if (!open->op_filp) {
5266-
status = nfsd_file_acquire(rqstp, cur_fh, access, &nf);
5267-
if (status != nfs_ok)
5268-
goto out_put_access;
5269-
} else {
5270-
status = nfsd_file_create(rqstp, cur_fh, access, &nf);
5271-
if (status != nfs_ok)
5272-
goto out_put_access;
5273-
nf->nf_file = open->op_filp;
5274-
open->op_filp = NULL;
5275-
trace_nfsd_file_create(rqstp, access, nf);
5276-
}
5265+
status = nfsd_file_acquire_opened(rqstp, cur_fh, access,
5266+
open->op_filp, &nf);
5267+
if (status != nfs_ok)
5268+
goto out_put_access;
52775269

52785270
spin_lock(&fp->fi_lock);
52795271
if (!fp->fi_fds[oflag]) {

fs/nfsd/nfs4xdr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2523,7 +2523,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
25232523
argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
25242524

25252525
if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack)
2526-
__clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags);
2526+
clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags);
25272527

25282528
return true;
25292529
}

fs/nfsd/nfsproc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ nfsd_proc_read(struct svc_rqst *rqstp)
211211
if (resp->status == nfs_ok)
212212
resp->status = fh_getattr(&resp->fh, &resp->stat);
213213
else if (resp->status == nfserr_jukebox)
214-
__set_bit(RQ_DROPME, &rqstp->rq_flags);
214+
set_bit(RQ_DROPME, &rqstp->rq_flags);
215215
return rpc_success;
216216
}
217217

@@ -246,7 +246,7 @@ nfsd_proc_write(struct svc_rqst *rqstp)
246246
if (resp->status == nfs_ok)
247247
resp->status = fh_getattr(&resp->fh, &resp->stat);
248248
else if (resp->status == nfserr_jukebox)
249-
__set_bit(RQ_DROPME, &rqstp->rq_flags);
249+
set_bit(RQ_DROPME, &rqstp->rq_flags);
250250
return rpc_success;
251251
}
252252

fs/nfsd/trace.h

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -981,43 +981,6 @@ TRACE_EVENT(nfsd_file_acquire,
981981
)
982982
);
983983

984-
TRACE_EVENT(nfsd_file_create,
985-
TP_PROTO(
986-
const struct svc_rqst *rqstp,
987-
unsigned int may_flags,
988-
const struct nfsd_file *nf
989-
),
990-
991-
TP_ARGS(rqstp, may_flags, nf),
992-
993-
TP_STRUCT__entry(
994-
__field(const void *, nf_inode)
995-
__field(const void *, nf_file)
996-
__field(unsigned long, may_flags)
997-
__field(unsigned long, nf_flags)
998-
__field(unsigned long, nf_may)
999-
__field(unsigned int, nf_ref)
1000-
__field(u32, xid)
1001-
),
1002-
1003-
TP_fast_assign(
1004-
__entry->nf_inode = nf->nf_inode;
1005-
__entry->nf_file = nf->nf_file;
1006-
__entry->may_flags = may_flags;
1007-
__entry->nf_flags = nf->nf_flags;
1008-
__entry->nf_may = nf->nf_may;
1009-
__entry->nf_ref = refcount_read(&nf->nf_ref);
1010-
__entry->xid = be32_to_cpu(rqstp->rq_xid);
1011-
),
1012-
1013-
TP_printk("xid=0x%x inode=%p may_flags=%s ref=%u nf_flags=%s nf_may=%s nf_file=%p",
1014-
__entry->xid, __entry->nf_inode,
1015-
show_nfsd_may_flags(__entry->may_flags),
1016-
__entry->nf_ref, show_nf_flags(__entry->nf_flags),
1017-
show_nfsd_may_flags(__entry->nf_may), __entry->nf_file
1018-
)
1019-
);
1020-
1021984
TRACE_EVENT(nfsd_file_insert_err,
1022985
TP_PROTO(
1023986
const struct svc_rqst *rqstp,
@@ -1079,8 +1042,8 @@ TRACE_EVENT(nfsd_file_cons_err,
10791042
)
10801043
);
10811044

1082-
TRACE_EVENT(nfsd_file_open,
1083-
TP_PROTO(struct nfsd_file *nf, __be32 status),
1045+
DECLARE_EVENT_CLASS(nfsd_file_open_class,
1046+
TP_PROTO(const struct nfsd_file *nf, __be32 status),
10841047
TP_ARGS(nf, status),
10851048
TP_STRUCT__entry(
10861049
__field(void *, nf_inode) /* cannot be dereferenced */
@@ -1104,6 +1067,17 @@ TRACE_EVENT(nfsd_file_open,
11041067
__entry->nf_file)
11051068
)
11061069

1070+
#define DEFINE_NFSD_FILE_OPEN_EVENT(name) \
1071+
DEFINE_EVENT(nfsd_file_open_class, name, \
1072+
TP_PROTO( \
1073+
const struct nfsd_file *nf, \
1074+
__be32 status \
1075+
), \
1076+
TP_ARGS(nf, status))
1077+
1078+
DEFINE_NFSD_FILE_OPEN_EVENT(nfsd_file_open);
1079+
DEFINE_NFSD_FILE_OPEN_EVENT(nfsd_file_opened);
1080+
11071081
TRACE_EVENT(nfsd_file_is_cached,
11081082
TP_PROTO(
11091083
const struct inode *inode,

net/sunrpc/auth_gss/svcauth_gss.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct g
923923
* rejecting the server-computed MIC in this somewhat rare case,
924924
* do not use splice with the GSS integrity service.
925925
*/
926-
__clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
926+
clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
927927

928928
/* Did we already verify the signature on the original pass through? */
929929
if (rqstp->rq_deferred)
@@ -990,7 +990,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs
990990
int pad, remaining_len, offset;
991991
u32 rseqno;
992992

993-
__clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
993+
clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
994994

995995
priv_len = svc_getnl(&buf->head[0]);
996996
if (rqstp->rq_deferred) {

net/sunrpc/svc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,10 +1243,10 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
12431243
goto err_short_len;
12441244

12451245
/* Will be turned off by GSS integrity and privacy services */
1246-
__set_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
1246+
set_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
12471247
/* Will be turned off only when NFSv4 Sessions are used */
1248-
__set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
1249-
__clear_bit(RQ_DROPME, &rqstp->rq_flags);
1248+
set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
1249+
clear_bit(RQ_DROPME, &rqstp->rq_flags);
12501250

12511251
svc_putu32(resv, rqstp->rq_xid);
12521252

net/sunrpc/svc_xprt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,7 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req)
12381238
trace_svc_defer(rqstp);
12391239
svc_xprt_get(rqstp->rq_xprt);
12401240
dr->xprt = rqstp->rq_xprt;
1241-
__set_bit(RQ_DROPME, &rqstp->rq_flags);
1241+
set_bit(RQ_DROPME, &rqstp->rq_flags);
12421242

12431243
dr->handle.revisit = svc_revisit;
12441244
return &dr->handle;

0 commit comments

Comments
 (0)