Skip to content

Commit 0b233b7

Browse files
committed
Merge branch 'for-3.19' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields: "A comparatively quieter cycle for nfsd this time, but still with two larger changes: - RPC server scalability improvements from Jeff Layton (using RCU instead of a spinlock to find idle threads). - server-side NFSv4.2 ALLOCATE/DEALLOCATE support from Anna Schumaker, enabling fallocate on new clients" * 'for-3.19' of git://linux-nfs.org/~bfields/linux: (32 commits) nfsd4: fix xdr4 count of server in fs_location4 nfsd4: fix xdr4 inclusion of escaped char sunrpc/cache: convert to use string_escape_str() sunrpc: only call test_bit once in svc_xprt_received fs: nfsd: Fix signedness bug in compare_blob sunrpc: add some tracepoints around enqueue and dequeue of svc_xprt sunrpc: convert to lockless lookup of queued server threads sunrpc: fix potential races in pool_stats collection sunrpc: add a rcu_head to svc_rqst and use kfree_rcu to free it sunrpc: require svc_create callers to pass in meaningful shutdown routine sunrpc: have svc_wake_up only deal with pool 0 sunrpc: convert sp_task_pending flag to use atomic bitops sunrpc: move rq_cachetype field to better optimize space sunrpc: move rq_splice_ok flag into rq_flags sunrpc: move rq_dropme flag into rq_flags sunrpc: move rq_usedeferral flag to rq_flags sunrpc: move rq_local field to rq_flags sunrpc: add a generic rq_flags field to svc_rqst and move rq_secure to it nfsd: minor off by one checks in __write_versions() sunrpc: release svc_pool_map reference when serv allocation fails ...
2 parents 6f51ee7 + bf7491f commit 0b233b7

File tree

27 files changed

+525
-269
lines changed

27 files changed

+525
-269
lines changed

drivers/staging/android/ashmem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
446446
loff_t start = range->pgstart * PAGE_SIZE;
447447
loff_t end = (range->pgend + 1) * PAGE_SIZE;
448448

449-
do_fallocate(range->asma->file,
449+
vfs_fallocate(range->asma->file,
450450
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
451451
start, end - start);
452452
range->purged = ASHMEM_WAS_PURGED;

fs/ioctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ int ioctl_preallocate(struct file *filp, void __user *argp)
443443
return -EINVAL;
444444
}
445445

446-
return do_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
446+
return vfs_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
447447
}
448448

449449
static int file_ioctl(struct file *filp, unsigned int cmd,

fs/lockd/mon.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ int nsm_monitor(const struct nlm_host *host)
214214
if (unlikely(res.status != 0))
215215
status = -EIO;
216216
if (unlikely(status < 0)) {
217-
printk(KERN_NOTICE "lockd: cannot monitor %s\n", nsm->sm_name);
217+
pr_notice_ratelimited("lockd: cannot monitor %s\n", nsm->sm_name);
218218
return status;
219219
}
220220

fs/lockd/svc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ static struct svc_serv *lockd_create_svc(void)
350350
printk(KERN_WARNING
351351
"lockd_up: no pid, %d users??\n", nlmsvc_users);
352352

353-
serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
353+
serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, svc_rpcb_cleanup);
354354
if (!serv) {
355355
printk(KERN_WARNING "lockd_up: create service failed\n");
356356
return ERR_PTR(-ENOMEM);

fs/nfsd/nfs4proc.c

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3434
*/
3535
#include <linux/file.h>
36+
#include <linux/falloc.h>
3637
#include <linux/slab.h>
3738

3839
#include "idmap.h"
@@ -772,7 +773,7 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
772773
* the client wants us to do more in this compound:
773774
*/
774775
if (!nfsd4_last_compound_op(rqstp))
775-
rqstp->rq_splice_ok = false;
776+
clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
776777

777778
/* check stateid */
778779
if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
@@ -1013,6 +1014,44 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
10131014
return status;
10141015
}
10151016

1017+
static __be32
1018+
nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1019+
struct nfsd4_fallocate *fallocate, int flags)
1020+
{
1021+
__be32 status = nfserr_notsupp;
1022+
struct file *file;
1023+
1024+
status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
1025+
&fallocate->falloc_stateid,
1026+
WR_STATE, &file);
1027+
if (status != nfs_ok) {
1028+
dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n");
1029+
return status;
1030+
}
1031+
1032+
status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, file,
1033+
fallocate->falloc_offset,
1034+
fallocate->falloc_length,
1035+
flags);
1036+
fput(file);
1037+
return status;
1038+
}
1039+
1040+
static __be32
1041+
nfsd4_allocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1042+
struct nfsd4_fallocate *fallocate)
1043+
{
1044+
return nfsd4_fallocate(rqstp, cstate, fallocate, 0);
1045+
}
1046+
1047+
static __be32
1048+
nfsd4_deallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1049+
struct nfsd4_fallocate *fallocate)
1050+
{
1051+
return nfsd4_fallocate(rqstp, cstate, fallocate,
1052+
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE);
1053+
}
1054+
10161055
static __be32
10171056
nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
10181057
struct nfsd4_seek *seek)
@@ -1331,7 +1370,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
13311370
* Don't use the deferral mechanism for NFSv4; compounds make it
13321371
* too hard to avoid non-idempotency problems.
13331372
*/
1334-
rqstp->rq_usedeferral = false;
1373+
clear_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
13351374

13361375
/*
13371376
* According to RFC3010, this takes precedence over all other errors.
@@ -1447,7 +1486,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
14471486
BUG_ON(cstate->replay_owner);
14481487
out:
14491488
/* Reset deferral mechanism for RPC deferrals */
1450-
rqstp->rq_usedeferral = true;
1489+
set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
14511490
dprintk("nfsv4 compound returned %d\n", ntohl(status));
14521491
return status;
14531492
}
@@ -1929,6 +1968,18 @@ static struct nfsd4_operation nfsd4_ops[] = {
19291968
},
19301969

19311970
/* NFSv4.2 operations */
1971+
[OP_ALLOCATE] = {
1972+
.op_func = (nfsd4op_func)nfsd4_allocate,
1973+
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1974+
.op_name = "OP_ALLOCATE",
1975+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
1976+
},
1977+
[OP_DEALLOCATE] = {
1978+
.op_func = (nfsd4op_func)nfsd4_deallocate,
1979+
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1980+
.op_name = "OP_DEALLOCATE",
1981+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
1982+
},
19321983
[OP_SEEK] = {
19331984
.op_func = (nfsd4op_func)nfsd4_seek,
19341985
.op_name = "OP_SEEK",

fs/nfsd/nfs4state.c

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,11 @@ opaque_hashval(const void *ptr, int nbytes)
275275
return x;
276276
}
277277

278-
static void nfsd4_free_file(struct nfs4_file *f)
278+
static void nfsd4_free_file_rcu(struct rcu_head *rcu)
279279
{
280-
kmem_cache_free(file_slab, f);
280+
struct nfs4_file *fp = container_of(rcu, struct nfs4_file, fi_rcu);
281+
282+
kmem_cache_free(file_slab, fp);
281283
}
282284

283285
static inline void
@@ -286,9 +288,10 @@ put_nfs4_file(struct nfs4_file *fi)
286288
might_lock(&state_lock);
287289

288290
if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) {
289-
hlist_del(&fi->fi_hash);
291+
hlist_del_rcu(&fi->fi_hash);
290292
spin_unlock(&state_lock);
291-
nfsd4_free_file(fi);
293+
WARN_ON_ONCE(!list_empty(&fi->fi_delegations));
294+
call_rcu(&fi->fi_rcu, nfsd4_free_file_rcu);
292295
}
293296
}
294297

@@ -1440,7 +1443,7 @@ static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, stru
14401443
list_add(&new->se_perclnt, &clp->cl_sessions);
14411444
spin_unlock(&clp->cl_lock);
14421445

1443-
if (cses->flags & SESSION4_BACK_CHAN) {
1446+
{
14441447
struct sockaddr *sa = svc_addr(rqstp);
14451448
/*
14461449
* This is a little silly; with sessions there's no real
@@ -1711,15 +1714,14 @@ static int copy_cred(struct svc_cred *target, struct svc_cred *source)
17111714
return 0;
17121715
}
17131716

1714-
static long long
1717+
static int
17151718
compare_blob(const struct xdr_netobj *o1, const struct xdr_netobj *o2)
17161719
{
1717-
long long res;
1718-
1719-
res = o1->len - o2->len;
1720-
if (res)
1721-
return res;
1722-
return (long long)memcmp(o1->data, o2->data, o1->len);
1720+
if (o1->len < o2->len)
1721+
return -1;
1722+
if (o1->len > o2->len)
1723+
return 1;
1724+
return memcmp(o1->data, o2->data, o1->len);
17231725
}
17241726

17251727
static int same_name(const char *n1, const char *n2)
@@ -1907,7 +1909,7 @@ add_clp_to_name_tree(struct nfs4_client *new_clp, struct rb_root *root)
19071909
static struct nfs4_client *
19081910
find_clp_in_name_tree(struct xdr_netobj *name, struct rb_root *root)
19091911
{
1910-
long long cmp;
1912+
int cmp;
19111913
struct rb_node *node = root->rb_node;
19121914
struct nfs4_client *clp;
19131915

@@ -3057,10 +3059,9 @@ static struct nfs4_file *nfsd4_alloc_file(void)
30573059
}
30583060

30593061
/* OPEN Share state helper functions */
3060-
static void nfsd4_init_file(struct nfs4_file *fp, struct knfsd_fh *fh)
3062+
static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval,
3063+
struct nfs4_file *fp)
30613064
{
3062-
unsigned int hashval = file_hashval(fh);
3063-
30643065
lockdep_assert_held(&state_lock);
30653066

30663067
atomic_set(&fp->fi_ref, 1);
@@ -3073,7 +3074,7 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct knfsd_fh *fh)
30733074
fp->fi_share_deny = 0;
30743075
memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
30753076
memset(fp->fi_access, 0, sizeof(fp->fi_access));
3076-
hlist_add_head(&fp->fi_hash, &file_hashtbl[hashval]);
3077+
hlist_add_head_rcu(&fp->fi_hash, &file_hashtbl[hashval]);
30773078
}
30783079

30793080
void
@@ -3294,17 +3295,14 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net)
32943295

32953296
/* search file_hashtbl[] for file */
32963297
static struct nfs4_file *
3297-
find_file_locked(struct knfsd_fh *fh)
3298+
find_file_locked(struct knfsd_fh *fh, unsigned int hashval)
32983299
{
3299-
unsigned int hashval = file_hashval(fh);
33003300
struct nfs4_file *fp;
33013301

3302-
lockdep_assert_held(&state_lock);
3303-
3304-
hlist_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
3302+
hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash) {
33053303
if (nfsd_fh_match(&fp->fi_fhandle, fh)) {
3306-
get_nfs4_file(fp);
3307-
return fp;
3304+
if (atomic_inc_not_zero(&fp->fi_ref))
3305+
return fp;
33083306
}
33093307
}
33103308
return NULL;
@@ -3314,22 +3312,30 @@ static struct nfs4_file *
33143312
find_file(struct knfsd_fh *fh)
33153313
{
33163314
struct nfs4_file *fp;
3315+
unsigned int hashval = file_hashval(fh);
33173316

3318-
spin_lock(&state_lock);
3319-
fp = find_file_locked(fh);
3320-
spin_unlock(&state_lock);
3317+
rcu_read_lock();
3318+
fp = find_file_locked(fh, hashval);
3319+
rcu_read_unlock();
33213320
return fp;
33223321
}
33233322

33243323
static struct nfs4_file *
33253324
find_or_add_file(struct nfs4_file *new, struct knfsd_fh *fh)
33263325
{
33273326
struct nfs4_file *fp;
3327+
unsigned int hashval = file_hashval(fh);
3328+
3329+
rcu_read_lock();
3330+
fp = find_file_locked(fh, hashval);
3331+
rcu_read_unlock();
3332+
if (fp)
3333+
return fp;
33283334

33293335
spin_lock(&state_lock);
3330-
fp = find_file_locked(fh);
3331-
if (fp == NULL) {
3332-
nfsd4_init_file(new, fh);
3336+
fp = find_file_locked(fh, hashval);
3337+
if (likely(fp == NULL)) {
3338+
nfsd4_init_file(fh, hashval, new);
33333339
fp = new;
33343340
}
33353341
spin_unlock(&state_lock);
@@ -4127,7 +4133,7 @@ void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
41274133
nfs4_put_stateowner(so);
41284134
}
41294135
if (open->op_file)
4130-
nfsd4_free_file(open->op_file);
4136+
kmem_cache_free(file_slab, open->op_file);
41314137
if (open->op_stp)
41324138
nfs4_put_stid(&open->op_stp->st_stid);
41334139
}

fs/nfsd/nfs4xdr.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,23 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
15131513
DECODE_TAIL;
15141514
}
15151515

1516+
static __be32
1517+
nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
1518+
struct nfsd4_fallocate *fallocate)
1519+
{
1520+
DECODE_HEAD;
1521+
1522+
status = nfsd4_decode_stateid(argp, &fallocate->falloc_stateid);
1523+
if (status)
1524+
return status;
1525+
1526+
READ_BUF(16);
1527+
p = xdr_decode_hyper(p, &fallocate->falloc_offset);
1528+
xdr_decode_hyper(p, &fallocate->falloc_length);
1529+
1530+
DECODE_TAIL;
1531+
}
1532+
15161533
static __be32
15171534
nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
15181535
{
@@ -1604,10 +1621,10 @@ static nfsd4_dec nfsd4_dec_ops[] = {
16041621
[OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete,
16051622

16061623
/* new operations for NFSv4.2 */
1607-
[OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp,
1624+
[OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate,
16081625
[OP_COPY] = (nfsd4_dec)nfsd4_decode_notsupp,
16091626
[OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp,
1610-
[OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp,
1627+
[OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate,
16111628
[OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp,
16121629
[OP_LAYOUTERROR] = (nfsd4_dec)nfsd4_decode_notsupp,
16131630
[OP_LAYOUTSTATS] = (nfsd4_dec)nfsd4_decode_notsupp,
@@ -1714,7 +1731,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
17141731
argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
17151732

17161733
if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack)
1717-
argp->rqstp->rq_splice_ok = false;
1734+
clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags);
17181735

17191736
DECODE_TAIL;
17201737
}
@@ -1795,9 +1812,12 @@ static __be32 nfsd4_encode_components_esc(struct xdr_stream *xdr, char sep,
17951812
}
17961813
else
17971814
end++;
1815+
if (found_esc)
1816+
end = next;
1817+
17981818
str = end;
17991819
}
1800-
pathlen = htonl(xdr->buf->len - pathlen_offset);
1820+
pathlen = htonl(count);
18011821
write_bytes_to_xdr_buf(xdr->buf, pathlen_offset, &pathlen, 4);
18021822
return 0;
18031823
}
@@ -3236,10 +3256,10 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
32363256

32373257
p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */
32383258
if (!p) {
3239-
WARN_ON_ONCE(resp->rqstp->rq_splice_ok);
3259+
WARN_ON_ONCE(test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags));
32403260
return nfserr_resource;
32413261
}
3242-
if (resp->xdr.buf->page_len && resp->rqstp->rq_splice_ok) {
3262+
if (resp->xdr.buf->page_len && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) {
32433263
WARN_ON_ONCE(1);
32443264
return nfserr_resource;
32453265
}
@@ -3256,7 +3276,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
32563276
goto err_truncate;
32573277
}
32583278

3259-
if (file->f_op->splice_read && resp->rqstp->rq_splice_ok)
3279+
if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
32603280
err = nfsd4_encode_splice_read(resp, read, file, maxcount);
32613281
else
32623282
err = nfsd4_encode_readv(resp, read, file, maxcount);

fs/nfsd/nfscache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
490490
/* From the hall of fame of impractical attacks:
491491
* Is this a user who tries to snoop on the cache? */
492492
rtn = RC_DOIT;
493-
if (!rqstp->rq_secure && rp->c_secure)
493+
if (!test_bit(RQ_SECURE, &rqstp->rq_flags) && rp->c_secure)
494494
goto out;
495495

496496
/* Compose RPC reply header */
@@ -579,7 +579,7 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
579579
spin_lock(&b->cache_lock);
580580
drc_mem_usage += bufsize;
581581
lru_put_end(b, rp);
582-
rp->c_secure = rqstp->rq_secure;
582+
rp->c_secure = test_bit(RQ_SECURE, &rqstp->rq_flags);
583583
rp->c_type = cachetype;
584584
rp->c_state = RC_DONE;
585585
spin_unlock(&b->cache_lock);

0 commit comments

Comments
 (0)