Skip to content

Commit b3d8e42

Browse files
committed
Merge tag 'nfsd-5.7' of git://git.linux-nfs.org/projects/cel/cel-2.6
Pull nfsd updates from Chuck Lever: - Fix EXCHANGE_ID response when NFSD runs in a container - A battery of new static trace points - Socket transports now use bio_vec to send Replies - NFS/RDMA now supports filesystems with no .splice_read method - Favor memcpy() over DMA mapping for small RPC/RDMA Replies - Add pre-requisites for supporting multiple Write chunks - Numerous minor fixes and clean-ups [ Chuck is filling in for Bruce this time while he and his family settle into a new house ] * tag 'nfsd-5.7' of git://git.linux-nfs.org/projects/cel/cel-2.6: (39 commits) svcrdma: Fix leak of transport addresses SUNRPC: Fix a potential buffer overflow in 'svc_print_xprts()' SUNRPC/cache: don't allow invalid entries to be flushed nfsd: fsnotify on rmdir under nfsd/clients/ nfsd4: kill warnings on testing stateids with mismatched clientids nfsd: remove read permission bit for ctl sysctl NFSD: Fix NFS server build errors sunrpc: Add tracing for cache events SUNRPC/cache: Allow garbage collection of invalid cache entries nfsd: export upcalls must not return ESTALE when mountd is down nfsd: Add tracepoints for update of the expkey and export cache entries nfsd: Add tracepoints for exp_find_key() and exp_get_by_name() nfsd: Add tracing to nfsd_set_fh_dentry() nfsd: Don't add locks to closed or closing open stateids SUNRPC: Teach server to use xprt_sock_sendmsg for socket sends SUNRPC: Refactor xs_sendpages() svcrdma: Avoid DMA mapping small RPC Replies svcrdma: Fix double sync of transport header buffer svcrdma: Refactor chunk list encoders SUNRPC: Add encoders for list item discriminators ...
2 parents bdabb68 + 1a33d8a commit b3d8e42

40 files changed

+1411
-913
lines changed

fs/nfs/dns_resolve.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,13 @@ static int nfs_dns_upcall(struct cache_detail *cd,
152152
struct cache_head *ch)
153153
{
154154
struct nfs_dns_ent *key = container_of(ch, struct nfs_dns_ent, h);
155-
int ret;
156155

157-
ret = nfs_cache_upcall(cd, key->hostname);
158-
if (ret)
159-
ret = sunrpc_cache_pipe_upcall(cd, ch);
160-
return ret;
156+
if (test_and_set_bit(CACHE_PENDING, &ch->flags))
157+
return 0;
158+
if (!nfs_cache_upcall(cd, key->hostname))
159+
return 0;
160+
clear_bit(CACHE_PENDING, &ch->flags);
161+
return sunrpc_cache_pipe_upcall_timeout(cd, ch);
161162
}
162163

163164
static int nfs_dns_match(struct cache_head *ca,

fs/nfsd/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ config NFSD_FLEXFILELAYOUT
136136

137137
config NFSD_V4_2_INTER_SSC
138138
bool "NFSv4.2 inter server to server COPY"
139-
depends on NFSD_V4 && NFS_V4_1 && NFS_V4_2
139+
depends on NFSD_V4 && NFS_V4_1 && NFS_V4_2 && NFS_FS=y
140140
help
141141
This option enables support for NFSv4.2 inter server to
142142
server copy where the destination server calls the NFSv4.2

fs/nfsd/export.c

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "netns.h"
2424
#include "pnfs.h"
2525
#include "filecache.h"
26+
#include "trace.h"
2627

2728
#define NFSDDBG_FACILITY NFSDDBG_EXPORT
2829

@@ -50,6 +51,11 @@ static void expkey_put(struct kref *ref)
5051
kfree_rcu(key, ek_rcu);
5152
}
5253

54+
static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
55+
{
56+
return sunrpc_cache_pipe_upcall(cd, h);
57+
}
58+
5359
static void expkey_request(struct cache_detail *cd,
5460
struct cache_head *h,
5561
char **bpp, int *blen)
@@ -140,7 +146,9 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
140146
if (len == 0) {
141147
set_bit(CACHE_NEGATIVE, &key.h.flags);
142148
ek = svc_expkey_update(cd, &key, ek);
143-
if (!ek)
149+
if (ek)
150+
trace_nfsd_expkey_update(ek, NULL);
151+
else
144152
err = -ENOMEM;
145153
} else {
146154
err = kern_path(buf, 0, &key.ek_path);
@@ -150,7 +158,9 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
150158
dprintk("Found the path %s\n", buf);
151159

152160
ek = svc_expkey_update(cd, &key, ek);
153-
if (!ek)
161+
if (ek)
162+
trace_nfsd_expkey_update(ek, buf);
163+
else
154164
err = -ENOMEM;
155165
path_put(&key.ek_path);
156166
}
@@ -249,6 +259,7 @@ static const struct cache_detail svc_expkey_cache_template = {
249259
.hash_size = EXPKEY_HASHMAX,
250260
.name = "nfsd.fh",
251261
.cache_put = expkey_put,
262+
.cache_upcall = expkey_upcall,
252263
.cache_request = expkey_request,
253264
.cache_parse = expkey_parse,
254265
.cache_show = expkey_show,
@@ -330,6 +341,11 @@ static void svc_export_put(struct kref *ref)
330341
kfree_rcu(exp, ex_rcu);
331342
}
332343

344+
static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
345+
{
346+
return sunrpc_cache_pipe_upcall(cd, h);
347+
}
348+
333349
static void svc_export_request(struct cache_detail *cd,
334350
struct cache_head *h,
335351
char **bpp, int *blen)
@@ -643,15 +659,17 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
643659
}
644660

645661
expp = svc_export_lookup(&exp);
646-
if (expp)
647-
expp = svc_export_update(&exp, expp);
648-
else
649-
err = -ENOMEM;
650-
cache_flush();
651-
if (expp == NULL)
662+
if (!expp) {
652663
err = -ENOMEM;
653-
else
664+
goto out4;
665+
}
666+
expp = svc_export_update(&exp, expp);
667+
if (expp) {
668+
trace_nfsd_export_update(expp);
669+
cache_flush();
654670
exp_put(expp);
671+
} else
672+
err = -ENOMEM;
655673
out4:
656674
nfsd4_fslocs_free(&exp.ex_fslocs);
657675
kfree(exp.ex_uuid);
@@ -767,6 +785,7 @@ static const struct cache_detail svc_export_cache_template = {
767785
.hash_size = EXPORT_HASHMAX,
768786
.name = "nfsd.export",
769787
.cache_put = svc_export_put,
788+
.cache_upcall = svc_export_upcall,
770789
.cache_request = svc_export_request,
771790
.cache_parse = svc_export_parse,
772791
.cache_show = svc_export_show,
@@ -832,8 +851,10 @@ exp_find_key(struct cache_detail *cd, struct auth_domain *clp, int fsid_type,
832851
if (ek == NULL)
833852
return ERR_PTR(-ENOMEM);
834853
err = cache_check(cd, &ek->h, reqp);
835-
if (err)
854+
if (err) {
855+
trace_nfsd_exp_find_key(&key, err);
836856
return ERR_PTR(err);
857+
}
837858
return ek;
838859
}
839860

@@ -855,8 +876,10 @@ exp_get_by_name(struct cache_detail *cd, struct auth_domain *clp,
855876
if (exp == NULL)
856877
return ERR_PTR(-ENOMEM);
857878
err = cache_check(cd, &exp->h, reqp);
858-
if (err)
879+
if (err) {
880+
trace_nfsd_exp_get_by_name(&key, err);
859881
return ERR_PTR(err);
882+
}
860883
return exp;
861884
}
862885

fs/nfsd/filecache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ nfsd_file_find_locked(struct inode *inode, unsigned int may_flags,
890890
unsigned char need = may_flags & NFSD_FILE_MAY_MASK;
891891

892892
hlist_for_each_entry_rcu(nf, &nfsd_file_hashtbl[hashval].nfb_head,
893-
nf_node) {
893+
nf_node, lockdep_is_held(&nfsd_file_hashtbl[hashval].nfb_lock)) {
894894
if ((need & nf->nf_may) != need)
895895
continue;
896896
if (nf->nf_inode != inode)

fs/nfsd/netns.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ struct nfsd_net {
172172
unsigned int longest_chain_cachesize;
173173

174174
struct shrinker nfsd_reply_cache_shrinker;
175+
/* utsname taken from the the process that starts the server */
176+
char nfsd_name[UNX_MAXNODENAME+1];
175177
};
176178

177179
/* Simple check to find out if a given net was properly initialized */

fs/nfsd/nfs4idmap.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ idtoname_hash(struct ent *ent)
122122
return hash;
123123
}
124124

125+
static int
126+
idtoname_upcall(struct cache_detail *cd, struct cache_head *h)
127+
{
128+
return sunrpc_cache_pipe_upcall_timeout(cd, h);
129+
}
130+
125131
static void
126132
idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
127133
int *blen)
@@ -184,6 +190,7 @@ static const struct cache_detail idtoname_cache_template = {
184190
.hash_size = ENT_HASHMAX,
185191
.name = "nfs4.idtoname",
186192
.cache_put = ent_put,
193+
.cache_upcall = idtoname_upcall,
187194
.cache_request = idtoname_request,
188195
.cache_parse = idtoname_parse,
189196
.cache_show = idtoname_show,
@@ -295,6 +302,12 @@ nametoid_hash(struct ent *ent)
295302
return hash_str(ent->name, ENT_HASHBITS);
296303
}
297304

305+
static int
306+
nametoid_upcall(struct cache_detail *cd, struct cache_head *h)
307+
{
308+
return sunrpc_cache_pipe_upcall_timeout(cd, h);
309+
}
310+
298311
static void
299312
nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
300313
int *blen)
@@ -347,6 +360,7 @@ static const struct cache_detail nametoid_cache_template = {
347360
.hash_size = ENT_HASHMAX,
348361
.name = "nfs4.nametoid",
349362
.cache_put = ent_put,
363+
.cache_upcall = nametoid_upcall,
350364
.cache_request = nametoid_request,
351365
.cache_parse = nametoid_parse,
352366
.cache_show = nametoid_show,

fs/nfsd/nfs4state.c

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,8 @@ find_any_file(struct nfs4_file *f)
494494
{
495495
struct nfsd_file *ret;
496496

497+
if (!f)
498+
return NULL;
497499
spin_lock(&f->fi_lock);
498500
ret = __nfs4_get_fd(f, O_RDWR);
499501
if (!ret) {
@@ -1309,6 +1311,12 @@ static void nfs4_put_stateowner(struct nfs4_stateowner *sop)
13091311
nfs4_free_stateowner(sop);
13101312
}
13111313

1314+
static bool
1315+
nfs4_ol_stateid_unhashed(const struct nfs4_ol_stateid *stp)
1316+
{
1317+
return list_empty(&stp->st_perfile);
1318+
}
1319+
13121320
static bool unhash_ol_stateid(struct nfs4_ol_stateid *stp)
13131321
{
13141322
struct nfs4_file *fp = stp->st_stid.sc_file;
@@ -1379,9 +1387,11 @@ static bool unhash_lock_stateid(struct nfs4_ol_stateid *stp)
13791387
{
13801388
lockdep_assert_held(&stp->st_stid.sc_client->cl_lock);
13811389

1390+
if (!unhash_ol_stateid(stp))
1391+
return false;
13821392
list_del_init(&stp->st_locks);
13831393
nfs4_unhash_stid(&stp->st_stid);
1384-
return unhash_ol_stateid(stp);
1394+
return true;
13851395
}
13861396

13871397
static void release_lock_stateid(struct nfs4_ol_stateid *stp)
@@ -1446,13 +1456,12 @@ static void release_open_stateid_locks(struct nfs4_ol_stateid *open_stp,
14461456
static bool unhash_open_stateid(struct nfs4_ol_stateid *stp,
14471457
struct list_head *reaplist)
14481458
{
1449-
bool unhashed;
1450-
14511459
lockdep_assert_held(&stp->st_stid.sc_client->cl_lock);
14521460

1453-
unhashed = unhash_ol_stateid(stp);
1461+
if (!unhash_ol_stateid(stp))
1462+
return false;
14541463
release_open_stateid_locks(stp, reaplist);
1455-
return unhashed;
1464+
return true;
14561465
}
14571466

14581467
static void release_open_stateid(struct nfs4_ol_stateid *stp)
@@ -2636,7 +2645,7 @@ static const struct file_operations client_ctl_fops = {
26362645
static const struct tree_descr client_files[] = {
26372646
[0] = {"info", &client_info_fops, S_IRUSR},
26382647
[1] = {"states", &client_states_fops, S_IRUSR},
2639-
[2] = {"ctl", &client_ctl_fops, S_IRUSR|S_IWUSR},
2648+
[2] = {"ctl", &client_ctl_fops, S_IWUSR},
26402649
[3] = {""},
26412650
};
26422651

@@ -4343,7 +4352,8 @@ find_file_locked(struct knfsd_fh *fh, unsigned int hashval)
43434352
{
43444353
struct nfs4_file *fp;
43454354

4346-
hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash) {
4355+
hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash,
4356+
lockdep_is_held(&state_lock)) {
43474357
if (fh_match(&fp->fi_fhandle, fh)) {
43484358
if (refcount_inc_not_zero(&fp->fi_ref))
43494359
return fp;
@@ -5521,15 +5531,8 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
55215531
if (ZERO_STATEID(stateid) || ONE_STATEID(stateid) ||
55225532
CLOSE_STATEID(stateid))
55235533
return status;
5524-
/* Client debugging aid. */
5525-
if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid)) {
5526-
char addr_str[INET6_ADDRSTRLEN];
5527-
rpc_ntop((struct sockaddr *)&cl->cl_addr, addr_str,
5528-
sizeof(addr_str));
5529-
pr_warn_ratelimited("NFSD: client %s testing state ID "
5530-
"with incorrect client ID\n", addr_str);
5534+
if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid))
55315535
return status;
5532-
}
55335536
spin_lock(&cl->cl_lock);
55345537
s = find_stateid_locked(cl, stateid);
55355538
if (!s)
@@ -6393,21 +6396,21 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp,
63936396
}
63946397

63956398
static struct nfs4_ol_stateid *
6396-
find_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp)
6399+
find_lock_stateid(const struct nfs4_lockowner *lo,
6400+
const struct nfs4_ol_stateid *ost)
63976401
{
63986402
struct nfs4_ol_stateid *lst;
6399-
struct nfs4_client *clp = lo->lo_owner.so_client;
64006403

6401-
lockdep_assert_held(&clp->cl_lock);
6404+
lockdep_assert_held(&ost->st_stid.sc_client->cl_lock);
64026405

6403-
list_for_each_entry(lst, &lo->lo_owner.so_stateids, st_perstateowner) {
6404-
if (lst->st_stid.sc_type != NFS4_LOCK_STID)
6405-
continue;
6406-
if (lst->st_stid.sc_file == fp) {
6407-
refcount_inc(&lst->st_stid.sc_count);
6408-
return lst;
6406+
/* If ost is not hashed, ost->st_locks will not be valid */
6407+
if (!nfs4_ol_stateid_unhashed(ost))
6408+
list_for_each_entry(lst, &ost->st_locks, st_locks) {
6409+
if (lst->st_stateowner == &lo->lo_owner) {
6410+
refcount_inc(&lst->st_stid.sc_count);
6411+
return lst;
6412+
}
64096413
}
6410-
}
64116414
return NULL;
64126415
}
64136416

@@ -6423,11 +6426,11 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,
64236426
mutex_lock_nested(&stp->st_mutex, OPEN_STATEID_MUTEX);
64246427
retry:
64256428
spin_lock(&clp->cl_lock);
6426-
spin_lock(&fp->fi_lock);
6427-
retstp = find_lock_stateid(lo, fp);
6429+
if (nfs4_ol_stateid_unhashed(open_stp))
6430+
goto out_close;
6431+
retstp = find_lock_stateid(lo, open_stp);
64286432
if (retstp)
6429-
goto out_unlock;
6430-
6433+
goto out_found;
64316434
refcount_inc(&stp->st_stid.sc_count);
64326435
stp->st_stid.sc_type = NFS4_LOCK_STID;
64336436
stp->st_stateowner = nfs4_get_stateowner(&lo->lo_owner);
@@ -6436,22 +6439,26 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,
64366439
stp->st_access_bmap = 0;
64376440
stp->st_deny_bmap = open_stp->st_deny_bmap;
64386441
stp->st_openstp = open_stp;
6442+
spin_lock(&fp->fi_lock);
64396443
list_add(&stp->st_locks, &open_stp->st_locks);
64406444
list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
64416445
list_add(&stp->st_perfile, &fp->fi_stateids);
6442-
out_unlock:
64436446
spin_unlock(&fp->fi_lock);
64446447
spin_unlock(&clp->cl_lock);
6445-
if (retstp) {
6446-
if (nfsd4_lock_ol_stateid(retstp) != nfs_ok) {
6447-
nfs4_put_stid(&retstp->st_stid);
6448-
goto retry;
6449-
}
6450-
/* To keep mutex tracking happy */
6451-
mutex_unlock(&stp->st_mutex);
6452-
stp = retstp;
6453-
}
64546448
return stp;
6449+
out_found:
6450+
spin_unlock(&clp->cl_lock);
6451+
if (nfsd4_lock_ol_stateid(retstp) != nfs_ok) {
6452+
nfs4_put_stid(&retstp->st_stid);
6453+
goto retry;
6454+
}
6455+
/* To keep mutex tracking happy */
6456+
mutex_unlock(&stp->st_mutex);
6457+
return retstp;
6458+
out_close:
6459+
spin_unlock(&clp->cl_lock);
6460+
mutex_unlock(&stp->st_mutex);
6461+
return NULL;
64556462
}
64566463

64576464
static struct nfs4_ol_stateid *
@@ -6466,7 +6473,7 @@ find_or_create_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fi,
64666473

64676474
*new = false;
64686475
spin_lock(&clp->cl_lock);
6469-
lst = find_lock_stateid(lo, fi);
6476+
lst = find_lock_stateid(lo, ost);
64706477
spin_unlock(&clp->cl_lock);
64716478
if (lst != NULL) {
64726479
if (nfsd4_lock_ol_stateid(lst) == nfs_ok)

0 commit comments

Comments
 (0)