Skip to content

Commit 00bfa30

Browse files
amschuma-ntaptrondmypd
authored andcommitted
NFS: Create a common pgio_alloc and pgio_release function
These functions are identical for the read and write paths so they can be combined. Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
1 parent f79d06f commit 00bfa30

File tree

5 files changed

+74
-106
lines changed

5 files changed

+74
-106
lines changed

fs/nfs/internal.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,15 @@ extern void nfs_destroy_writepagecache(void);
231231

232232
extern int __init nfs_init_directcache(void);
233233
extern void nfs_destroy_directcache(void);
234-
extern bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount);
235234
extern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
236235
struct nfs_pgio_header *hdr,
237236
void (*release)(struct nfs_pgio_header *hdr));
238237
void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos);
239238
int nfs_iocounter_wait(struct nfs_io_counter *c);
240239

240+
struct nfs_pgio_data *nfs_pgio_data_alloc(struct nfs_pgio_header *, unsigned int);
241+
void nfs_pgio_data_release(struct nfs_pgio_data *);
242+
241243
static inline void nfs_iocounter_init(struct nfs_io_counter *c)
242244
{
243245
c->flags = 0;
@@ -407,7 +409,6 @@ extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
407409
extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
408410
struct nfs_pgio_header *hdr);
409411
extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
410-
extern void nfs_readdata_release(struct nfs_pgio_data *rdata);
411412

412413
/* super.c */
413414
void nfs_clone_super(struct super_block *, struct nfs_mount_info *);
@@ -429,7 +430,6 @@ extern void nfs_writehdr_free(struct nfs_pgio_header *hdr);
429430
extern int nfs_generic_flush(struct nfs_pageio_descriptor *desc,
430431
struct nfs_pgio_header *hdr);
431432
extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
432-
extern void nfs_writedata_release(struct nfs_pgio_data *wdata);
433433
extern void nfs_commit_free(struct nfs_commit_data *p);
434434
extern int nfs_initiate_write(struct rpc_clnt *clnt,
435435
struct nfs_pgio_data *data,

fs/nfs/pagelist.c

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
static struct kmem_cache *nfs_page_cachep;
2828

29-
bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount)
29+
static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount)
3030
{
3131
p->npages = pagecount;
3232
if (pagecount <= ARRAY_SIZE(p->page_array))
@@ -295,6 +295,66 @@ bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *pr
295295
}
296296
EXPORT_SYMBOL_GPL(nfs_generic_pg_test);
297297

298+
static inline struct nfs_rw_header *NFS_RW_HEADER(struct nfs_pgio_header *hdr)
299+
{
300+
return container_of(hdr, struct nfs_rw_header, header);
301+
}
302+
303+
/**
304+
* nfs_pgio_data_alloc - Allocate pageio data
305+
* @hdr: The header making a request
306+
* @pagecount: Number of pages to create
307+
*/
308+
struct nfs_pgio_data *nfs_pgio_data_alloc(struct nfs_pgio_header *hdr,
309+
unsigned int pagecount)
310+
{
311+
struct nfs_pgio_data *data, *prealloc;
312+
313+
prealloc = &NFS_RW_HEADER(hdr)->rpc_data;
314+
if (prealloc->header == NULL)
315+
data = prealloc;
316+
else
317+
data = kzalloc(sizeof(*data), GFP_KERNEL);
318+
if (!data)
319+
goto out;
320+
321+
if (nfs_pgarray_set(&data->pages, pagecount)) {
322+
data->header = hdr;
323+
atomic_inc(&hdr->refcnt);
324+
} else {
325+
if (data != prealloc)
326+
kfree(data);
327+
data = NULL;
328+
}
329+
out:
330+
return data;
331+
}
332+
333+
/**
334+
* nfs_pgio_data_release - Properly free pageio data
335+
* @data: The data to release
336+
*/
337+
void nfs_pgio_data_release(struct nfs_pgio_data *data)
338+
{
339+
struct nfs_pgio_header *hdr = data->header;
340+
struct nfs_rw_header *pageio_header = NFS_RW_HEADER(hdr);
341+
342+
put_nfs_open_context(data->args.context);
343+
if (data->pages.pagevec != data->pages.page_array)
344+
kfree(data->pages.pagevec);
345+
if (data == &pageio_header->rpc_data) {
346+
data->header = NULL;
347+
data = NULL;
348+
}
349+
if (atomic_dec_and_test(&hdr->refcnt))
350+
hdr->completion_ops->completion(hdr);
351+
/* Note: we only free the rpc_task after callbacks are done.
352+
* See the comment in rpc_free_task() for why
353+
*/
354+
kfree(data);
355+
}
356+
EXPORT_SYMBOL_GPL(nfs_pgio_data_release);
357+
298358
/**
299359
* nfs_pageio_init - initialise a page io descriptor
300360
* @desc: pointer to descriptor

fs/nfs/pnfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,7 +1536,7 @@ pnfs_write_through_mds(struct nfs_pageio_descriptor *desc,
15361536
nfs_pageio_reset_write_mds(desc);
15371537
desc->pg_recoalesce = 1;
15381538
}
1539-
nfs_writedata_release(data);
1539+
nfs_pgio_data_release(data);
15401540
}
15411541

15421542
static enum pnfs_try_status
@@ -1691,7 +1691,7 @@ pnfs_read_through_mds(struct nfs_pageio_descriptor *desc,
16911691
nfs_pageio_reset_read_mds(desc);
16921692
desc->pg_recoalesce = 1;
16931693
}
1694-
nfs_readdata_release(data);
1694+
nfs_pgio_data_release(data);
16951695
}
16961696

16971697
/*

fs/nfs/read.c

Lines changed: 4 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -51,31 +51,6 @@ struct nfs_rw_header *nfs_readhdr_alloc(void)
5151
}
5252
EXPORT_SYMBOL_GPL(nfs_readhdr_alloc);
5353

54-
static struct nfs_pgio_data *nfs_readdata_alloc(struct nfs_pgio_header *hdr,
55-
unsigned int pagecount)
56-
{
57-
struct nfs_pgio_data *data, *prealloc;
58-
59-
prealloc = &container_of(hdr, struct nfs_rw_header, header)->rpc_data;
60-
if (prealloc->header == NULL)
61-
data = prealloc;
62-
else
63-
data = kzalloc(sizeof(*data), GFP_KERNEL);
64-
if (!data)
65-
goto out;
66-
67-
if (nfs_pgarray_set(&data->pages, pagecount)) {
68-
data->header = hdr;
69-
atomic_inc(&hdr->refcnt);
70-
} else {
71-
if (data != prealloc)
72-
kfree(data);
73-
data = NULL;
74-
}
75-
out:
76-
return data;
77-
}
78-
7954
void nfs_readhdr_free(struct nfs_pgio_header *hdr)
8055
{
8156
struct nfs_rw_header *rhdr = container_of(hdr, struct nfs_rw_header, header);
@@ -84,27 +59,6 @@ void nfs_readhdr_free(struct nfs_pgio_header *hdr)
8459
}
8560
EXPORT_SYMBOL_GPL(nfs_readhdr_free);
8661

87-
void nfs_readdata_release(struct nfs_pgio_data *rdata)
88-
{
89-
struct nfs_pgio_header *hdr = rdata->header;
90-
struct nfs_rw_header *read_header = container_of(hdr, struct nfs_rw_header, header);
91-
92-
put_nfs_open_context(rdata->args.context);
93-
if (rdata->pages.pagevec != rdata->pages.page_array)
94-
kfree(rdata->pages.pagevec);
95-
if (rdata == &read_header->rpc_data) {
96-
rdata->header = NULL;
97-
rdata = NULL;
98-
}
99-
if (atomic_dec_and_test(&hdr->refcnt))
100-
hdr->completion_ops->completion(hdr);
101-
/* Note: we only free the rpc_task after callbacks are done.
102-
* See the comment in rpc_free_task() for why
103-
*/
104-
kfree(rdata);
105-
}
106-
EXPORT_SYMBOL_GPL(nfs_readdata_release);
107-
10862
static
10963
int nfs_return_empty_page(struct page *page)
11064
{
@@ -327,7 +281,7 @@ static void nfs_pagein_error(struct nfs_pageio_descriptor *desc,
327281
struct nfs_pgio_data *data = list_first_entry(&hdr->rpc_list,
328282
struct nfs_pgio_data, list);
329283
list_del(&data->list);
330-
nfs_readdata_release(data);
284+
nfs_pgio_data_release(data);
331285
}
332286
desc->pg_completion_ops->error_cleanup(&desc->pg_list);
333287
}
@@ -359,7 +313,7 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc,
359313
do {
360314
size_t len = min(nbytes,rsize);
361315

362-
data = nfs_readdata_alloc(hdr, 1);
316+
data = nfs_pgio_data_alloc(hdr, 1);
363317
if (!data) {
364318
nfs_pagein_error(desc, hdr);
365319
return -ENOMEM;
@@ -385,7 +339,7 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc,
385339
struct nfs_pgio_data *data;
386340
struct list_head *head = &desc->pg_list;
387341

388-
data = nfs_readdata_alloc(hdr, nfs_page_array_len(desc->pg_base,
342+
data = nfs_pgio_data_alloc(hdr, nfs_page_array_len(desc->pg_base,
389343
desc->pg_count));
390344
if (!data) {
391345
nfs_pagein_error(desc, hdr);
@@ -515,7 +469,7 @@ static void nfs_readpage_result_common(struct rpc_task *task, void *calldata)
515469

516470
static void nfs_readpage_release_common(void *calldata)
517471
{
518-
nfs_readdata_release(calldata);
472+
nfs_pgio_data_release(calldata);
519473
}
520474

521475
void nfs_read_prepare(struct rpc_task *task, void *calldata)

fs/nfs/write.c

Lines changed: 4 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -87,59 +87,13 @@ struct nfs_rw_header *nfs_writehdr_alloc(void)
8787
}
8888
EXPORT_SYMBOL_GPL(nfs_writehdr_alloc);
8989

90-
static struct nfs_pgio_data *nfs_writedata_alloc(struct nfs_pgio_header *hdr,
91-
unsigned int pagecount)
92-
{
93-
struct nfs_pgio_data *data, *prealloc;
94-
95-
prealloc = &container_of(hdr, struct nfs_rw_header, header)->rpc_data;
96-
if (prealloc->header == NULL)
97-
data = prealloc;
98-
else
99-
data = kzalloc(sizeof(*data), GFP_KERNEL);
100-
if (!data)
101-
goto out;
102-
103-
if (nfs_pgarray_set(&data->pages, pagecount)) {
104-
data->header = hdr;
105-
atomic_inc(&hdr->refcnt);
106-
} else {
107-
if (data != prealloc)
108-
kfree(data);
109-
data = NULL;
110-
}
111-
out:
112-
return data;
113-
}
114-
11590
void nfs_writehdr_free(struct nfs_pgio_header *hdr)
11691
{
11792
struct nfs_rw_header *whdr = container_of(hdr, struct nfs_rw_header, header);
11893
mempool_free(whdr, nfs_wdata_mempool);
11994
}
12095
EXPORT_SYMBOL_GPL(nfs_writehdr_free);
12196

122-
void nfs_writedata_release(struct nfs_pgio_data *wdata)
123-
{
124-
struct nfs_pgio_header *hdr = wdata->header;
125-
struct nfs_rw_header *write_header = container_of(hdr, struct nfs_rw_header, header);
126-
127-
put_nfs_open_context(wdata->args.context);
128-
if (wdata->pages.pagevec != wdata->pages.page_array)
129-
kfree(wdata->pages.pagevec);
130-
if (wdata == &write_header->rpc_data) {
131-
wdata->header = NULL;
132-
wdata = NULL;
133-
}
134-
if (atomic_dec_and_test(&hdr->refcnt))
135-
hdr->completion_ops->completion(hdr);
136-
/* Note: we only free the rpc_task after callbacks are done.
137-
* See the comment in rpc_free_task() for why
138-
*/
139-
kfree(wdata);
140-
}
141-
EXPORT_SYMBOL_GPL(nfs_writedata_release);
142-
14397
static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
14498
{
14599
ctx->error = error;
@@ -1146,7 +1100,7 @@ static void nfs_flush_error(struct nfs_pageio_descriptor *desc,
11461100
struct nfs_pgio_data *data = list_first_entry(&hdr->rpc_list,
11471101
struct nfs_pgio_data, list);
11481102
list_del(&data->list);
1149-
nfs_writedata_release(data);
1103+
nfs_pgio_data_release(data);
11501104
}
11511105
desc->pg_completion_ops->error_cleanup(&desc->pg_list);
11521106
}
@@ -1179,7 +1133,7 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc,
11791133
do {
11801134
size_t len = min(nbytes, wsize);
11811135

1182-
data = nfs_writedata_alloc(hdr, 1);
1136+
data = nfs_pgio_data_alloc(hdr, 1);
11831137
if (!data) {
11841138
nfs_flush_error(desc, hdr);
11851139
return -ENOMEM;
@@ -1214,7 +1168,7 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc,
12141168
struct list_head *head = &desc->pg_list;
12151169
struct nfs_commit_info cinfo;
12161170

1217-
data = nfs_writedata_alloc(hdr, nfs_page_array_len(desc->pg_base,
1171+
data = nfs_pgio_data_alloc(hdr, nfs_page_array_len(desc->pg_base,
12181172
desc->pg_count));
12191173
if (!data) {
12201174
nfs_flush_error(desc, hdr);
@@ -1348,7 +1302,7 @@ static void nfs_writeback_release_common(void *calldata)
13481302
set_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags);
13491303
spin_unlock(&hdr->lock);
13501304
}
1351-
nfs_writedata_release(data);
1305+
nfs_pgio_data_release(data);
13521306
}
13531307

13541308
static const struct rpc_call_ops nfs_write_common_ops = {

0 commit comments

Comments
 (0)