Skip to content

Commit 7b207cc

Browse files
neilbrownchucklever
authored andcommitted
svc: don't hold reference for poolstats, only mutex.
A future patch will remove refcounting on svc_serv as it is of little use. It is currently used to keep the svc around while the pool_stats file is open. Change this to get the pointer, protected by the mutex, only in seq_start, and the release the mutex in seq_stop. This means that if the nfsd server is stopped and restarted while the pool_stats file it open, then some pool stats info could be from the first instance and some from the second. This might appear odd, but is unlikely to be a problem in practice. Signed-off-by: NeilBrown <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 05a4b58 commit 7b207cc

File tree

5 files changed

+36
-34
lines changed

5 files changed

+36
-34
lines changed

fs/nfsd/netns.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ struct nfsd_net {
123123
u32 clientid_counter;
124124
u32 clverifier_counter;
125125

126-
struct svc_serv *nfsd_serv;
126+
struct svc_info nfsd_info;
127+
#define nfsd_serv nfsd_info.serv
128+
127129
/* When a listening socket is added to nfsd, keep_active is set
128130
* and this justifies a reference on nfsd_serv. This stops
129131
* nfsd_serv from being freed. When the number of threads is

fs/nfsd/nfsctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ static const struct file_operations pool_stats_operations = {
183183
.open = nfsd_pool_stats_open,
184184
.read = seq_read,
185185
.llseek = seq_lseek,
186-
.release = nfsd_pool_stats_release,
186+
.release = seq_release,
187187
};
188188

189189
DEFINE_SHOW_ATTRIBUTE(nfsd_reply_cache_stats);

fs/nfsd/nfssvc.c

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,7 @@ int nfsd_create_serv(struct net *net)
684684
return error;
685685
}
686686
spin_lock(&nfsd_notifier_lock);
687+
nn->nfsd_info.mutex = &nfsd_mutex;
687688
nn->nfsd_serv = serv;
688689
spin_unlock(&nfsd_notifier_lock);
689690

@@ -1082,28 +1083,7 @@ bool nfssvc_encode_voidres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
10821083

10831084
int nfsd_pool_stats_open(struct inode *inode, struct file *file)
10841085
{
1085-
int ret;
10861086
struct nfsd_net *nn = net_generic(inode->i_sb->s_fs_info, nfsd_net_id);
10871087

1088-
mutex_lock(&nfsd_mutex);
1089-
if (nn->nfsd_serv == NULL) {
1090-
mutex_unlock(&nfsd_mutex);
1091-
return -ENODEV;
1092-
}
1093-
svc_get(nn->nfsd_serv);
1094-
ret = svc_pool_stats_open(nn->nfsd_serv, file);
1095-
mutex_unlock(&nfsd_mutex);
1096-
return ret;
1097-
}
1098-
1099-
int nfsd_pool_stats_release(struct inode *inode, struct file *file)
1100-
{
1101-
struct seq_file *seq = file->private_data;
1102-
struct svc_serv *serv = seq->private;
1103-
int ret = seq_release(inode, file);
1104-
1105-
mutex_lock(&nfsd_mutex);
1106-
svc_put(serv);
1107-
mutex_unlock(&nfsd_mutex);
1108-
return ret;
1088+
return svc_pool_stats_open(&nn->nfsd_info, file);
11091089
}

include/linux/sunrpc/svc.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ struct svc_serv {
9797
#endif /* CONFIG_SUNRPC_BACKCHANNEL */
9898
};
9999

100+
/* This is used by pool_stats to find and lock an svc */
101+
struct svc_info {
102+
struct svc_serv *serv;
103+
struct mutex *mutex;
104+
};
105+
100106
/**
101107
* svc_get() - increment reference count on a SUNRPC serv
102108
* @serv: the svc_serv to have count incremented
@@ -431,7 +437,7 @@ void svc_exit_thread(struct svc_rqst *);
431437
struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
432438
int (*threadfn)(void *data));
433439
int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
434-
int svc_pool_stats_open(struct svc_serv *serv, struct file *file);
440+
int svc_pool_stats_open(struct svc_info *si, struct file *file);
435441
void svc_process(struct svc_rqst *rqstp);
436442
void svc_process_bc(struct rpc_rqst *req, struct svc_rqst *rqstp);
437443
int svc_register(const struct svc_serv *, struct net *, const int,

net/sunrpc/svc_xprt.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,29 +1362,36 @@ int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen)
13621362
}
13631363
EXPORT_SYMBOL_GPL(svc_xprt_names);
13641364

1365-
13661365
/*----------------------------------------------------------------------------*/
13671366

13681367
static void *svc_pool_stats_start(struct seq_file *m, loff_t *pos)
13691368
{
13701369
unsigned int pidx = (unsigned int)*pos;
1371-
struct svc_serv *serv = m->private;
1370+
struct svc_info *si = m->private;
13721371

13731372
dprintk("svc_pool_stats_start, *pidx=%u\n", pidx);
13741373

1374+
mutex_lock(si->mutex);
1375+
13751376
if (!pidx)
13761377
return SEQ_START_TOKEN;
1377-
return (pidx > serv->sv_nrpools ? NULL : &serv->sv_pools[pidx-1]);
1378+
if (!si->serv)
1379+
return NULL;
1380+
return pidx > si->serv->sv_nrpools ? NULL
1381+
: &si->serv->sv_pools[pidx - 1];
13781382
}
13791383

13801384
static void *svc_pool_stats_next(struct seq_file *m, void *p, loff_t *pos)
13811385
{
13821386
struct svc_pool *pool = p;
1383-
struct svc_serv *serv = m->private;
1387+
struct svc_info *si = m->private;
1388+
struct svc_serv *serv = si->serv;
13841389

13851390
dprintk("svc_pool_stats_next, *pos=%llu\n", *pos);
13861391

1387-
if (p == SEQ_START_TOKEN) {
1392+
if (!serv) {
1393+
pool = NULL;
1394+
} else if (p == SEQ_START_TOKEN) {
13881395
pool = &serv->sv_pools[0];
13891396
} else {
13901397
unsigned int pidx = (pool - &serv->sv_pools[0]);
@@ -1399,6 +1406,9 @@ static void *svc_pool_stats_next(struct seq_file *m, void *p, loff_t *pos)
13991406

14001407
static void svc_pool_stats_stop(struct seq_file *m, void *p)
14011408
{
1409+
struct svc_info *si = m->private;
1410+
1411+
mutex_unlock(si->mutex);
14021412
}
14031413

14041414
static int svc_pool_stats_show(struct seq_file *m, void *p)
@@ -1426,14 +1436,18 @@ static const struct seq_operations svc_pool_stats_seq_ops = {
14261436
.show = svc_pool_stats_show,
14271437
};
14281438

1429-
int svc_pool_stats_open(struct svc_serv *serv, struct file *file)
1439+
int svc_pool_stats_open(struct svc_info *info, struct file *file)
14301440
{
1441+
struct seq_file *seq;
14311442
int err;
14321443

14331444
err = seq_open(file, &svc_pool_stats_seq_ops);
1434-
if (!err)
1435-
((struct seq_file *) file->private_data)->private = serv;
1436-
return err;
1445+
if (err)
1446+
return err;
1447+
seq = file->private_data;
1448+
seq->private = info;
1449+
1450+
return 0;
14371451
}
14381452
EXPORT_SYMBOL(svc_pool_stats_open);
14391453

0 commit comments

Comments
 (0)