Skip to content

Commit 061ae2e

Browse files
Fred IsamanTrond Myklebust
authored andcommitted
NFS: create completion structure to pass into page_init functions
Factors out the code that will need to change when directio starts using these code paths. This will allow directio to use the generic pagein and flush routines Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
1 parent 6c75dc0 commit 061ae2e

File tree

8 files changed

+93
-51
lines changed

8 files changed

+93
-51
lines changed

fs/nfs/internal.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,10 @@ extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *,
300300
extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh);
301301
#endif
302302

303+
struct nfs_pgio_completion_ops;
303304
/* read.c */
304-
extern void nfs_async_read_error(struct list_head *head);
305305
extern struct nfs_read_header *nfs_readhdr_alloc(void);
306306
extern void nfs_readhdr_free(struct nfs_pgio_header *hdr);
307-
extern void nfs_read_completion(struct nfs_pgio_header *hdr);
308307
extern struct nfs_read_data *nfs_readdata_alloc(struct nfs_pgio_header *hdr,
309308
unsigned int pagecount);
310309
extern int nfs_initiate_read(struct rpc_clnt *clnt,
@@ -314,21 +313,21 @@ extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
314313
extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
315314
struct nfs_pgio_header *hdr);
316315
extern void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio,
317-
struct inode *inode);
316+
struct inode *inode,
317+
const struct nfs_pgio_completion_ops *compl_ops);
318318
extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
319319
extern void nfs_readdata_release(struct nfs_read_data *rdata);
320320

321321
/* write.c */
322-
extern void nfs_async_write_error(struct list_head *head);
323322
extern struct nfs_write_header *nfs_writehdr_alloc(void);
324323
extern void nfs_writehdr_free(struct nfs_pgio_header *hdr);
325324
extern struct nfs_write_data *nfs_writedata_alloc(struct nfs_pgio_header *hdr,
326325
unsigned int pagecount);
327-
extern void nfs_write_completion(struct nfs_pgio_header *hdr);
328326
extern int nfs_generic_flush(struct nfs_pageio_descriptor *desc,
329327
struct nfs_pgio_header *hdr);
330328
extern void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio,
331-
struct inode *inode, int ioflags);
329+
struct inode *inode, int ioflags,
330+
const struct nfs_pgio_completion_ops *compl_ops);
332331
extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
333332
extern void nfs_writedata_release(struct nfs_write_data *wdata);
334333
extern void nfs_commit_free(struct nfs_commit_data *p);

fs/nfs/pagelist.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
4949
hdr->io_start = req_offset(hdr->req);
5050
hdr->good_bytes = desc->pg_count;
5151
hdr->release = release;
52+
hdr->completion_ops = desc->pg_completion_ops;
5253
}
5354

5455
void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos)
@@ -240,6 +241,7 @@ EXPORT_SYMBOL_GPL(nfs_generic_pg_test);
240241
void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
241242
struct inode *inode,
242243
const struct nfs_pageio_ops *pg_ops,
244+
const struct nfs_pgio_completion_ops *compl_ops,
243245
size_t bsize,
244246
int io_flags)
245247
{
@@ -252,6 +254,7 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
252254
desc->pg_recoalesce = 0;
253255
desc->pg_inode = inode;
254256
desc->pg_ops = pg_ops;
257+
desc->pg_completion_ops = compl_ops;
255258
desc->pg_ioflags = io_flags;
256259
desc->pg_error = 0;
257260
desc->pg_lseg = NULL;

fs/nfs/pnfs.c

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,26 +1113,31 @@ pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *
11131113
EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_write);
11141114

11151115
bool
1116-
pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode)
1116+
pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode,
1117+
const struct nfs_pgio_completion_ops *compl_ops)
11171118
{
11181119
struct nfs_server *server = NFS_SERVER(inode);
11191120
struct pnfs_layoutdriver_type *ld = server->pnfs_curr_ld;
11201121

11211122
if (ld == NULL)
11221123
return false;
1123-
nfs_pageio_init(pgio, inode, ld->pg_read_ops, server->rsize, 0);
1124+
nfs_pageio_init(pgio, inode, ld->pg_read_ops, compl_ops,
1125+
server->rsize, 0);
11241126
return true;
11251127
}
11261128

11271129
bool
1128-
pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *inode, int ioflags)
1130+
pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *inode,
1131+
int ioflags,
1132+
const struct nfs_pgio_completion_ops *compl_ops)
11291133
{
11301134
struct nfs_server *server = NFS_SERVER(inode);
11311135
struct pnfs_layoutdriver_type *ld = server->pnfs_curr_ld;
11321136

11331137
if (ld == NULL)
11341138
return false;
1135-
nfs_pageio_init(pgio, inode, ld->pg_write_ops, server->wsize, ioflags);
1139+
nfs_pageio_init(pgio, inode, ld->pg_write_ops, compl_ops,
1140+
server->wsize, ioflags);
11361141
return true;
11371142
}
11381143

@@ -1162,13 +1167,15 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
11621167
}
11631168
EXPORT_SYMBOL_GPL(pnfs_generic_pg_test);
11641169

1165-
static int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head)
1170+
static int pnfs_write_done_resend_to_mds(struct inode *inode,
1171+
struct list_head *head,
1172+
const struct nfs_pgio_completion_ops *compl_ops)
11661173
{
11671174
struct nfs_pageio_descriptor pgio;
11681175
LIST_HEAD(failed);
11691176

11701177
/* Resend all requests through the MDS */
1171-
nfs_pageio_init_write_mds(&pgio, inode, FLUSH_STABLE);
1178+
nfs_pageio_init_write_mds(&pgio, inode, FLUSH_STABLE, compl_ops);
11721179
while (!list_empty(head)) {
11731180
struct nfs_page *req = nfs_list_entry(head->next);
11741181

@@ -1201,7 +1208,8 @@ static void pnfs_ld_handle_write_error(struct nfs_write_data *data)
12011208
}
12021209
if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
12031210
data->task.tk_status = pnfs_write_done_resend_to_mds(hdr->inode,
1204-
&hdr->pages);
1211+
&hdr->pages,
1212+
hdr->completion_ops);
12051213
}
12061214

12071215
/*
@@ -1292,7 +1300,7 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
12921300

12931301
whdr = nfs_writehdr_alloc();
12941302
if (!whdr) {
1295-
nfs_async_write_error(&desc->pg_list);
1303+
desc->pg_completion_ops->error_cleanup(&hdr->pages);
12961304
put_lseg(desc->pg_lseg);
12971305
desc->pg_lseg = NULL;
12981306
return -ENOMEM;
@@ -1309,18 +1317,20 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
13091317
} else
13101318
pnfs_do_multiple_writes(desc, &hdr->rpc_list, desc->pg_ioflags);
13111319
if (atomic_dec_and_test(&hdr->refcnt))
1312-
nfs_write_completion(hdr);
1320+
hdr->completion_ops->completion(hdr);
13131321
return ret;
13141322
}
13151323
EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages);
13161324

1317-
static int pnfs_read_done_resend_to_mds(struct inode *inode, struct list_head *head)
1325+
static int pnfs_read_done_resend_to_mds(struct inode *inode,
1326+
struct list_head *head,
1327+
const struct nfs_pgio_completion_ops *compl_ops)
13181328
{
13191329
struct nfs_pageio_descriptor pgio;
13201330
LIST_HEAD(failed);
13211331

13221332
/* Resend all requests through the MDS */
1323-
nfs_pageio_init_read_mds(&pgio, inode);
1333+
nfs_pageio_init_read_mds(&pgio, inode, compl_ops);
13241334
while (!list_empty(head)) {
13251335
struct nfs_page *req = nfs_list_entry(head->next);
13261336

@@ -1349,7 +1359,8 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
13491359
}
13501360
if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
13511361
data->task.tk_status = pnfs_read_done_resend_to_mds(hdr->inode,
1352-
&hdr->pages);
1362+
&hdr->pages,
1363+
hdr->completion_ops);
13531364
}
13541365

13551366
/*
@@ -1443,7 +1454,7 @@ pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
14431454

14441455
rhdr = nfs_readhdr_alloc();
14451456
if (!rhdr) {
1446-
nfs_async_read_error(&desc->pg_list);
1457+
desc->pg_completion_ops->error_cleanup(&desc->pg_list);
14471458
ret = -ENOMEM;
14481459
put_lseg(desc->pg_lseg);
14491460
desc->pg_lseg = NULL;
@@ -1461,7 +1472,7 @@ pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
14611472
} else
14621473
pnfs_do_multiple_reads(desc, &hdr->rpc_list);
14631474
if (atomic_dec_and_test(&hdr->refcnt))
1464-
nfs_read_completion(hdr);
1475+
hdr->completion_ops->completion(hdr);
14651476
return ret;
14661477
}
14671478
EXPORT_SYMBOL_GPL(pnfs_generic_pg_readpages);

fs/nfs/pnfs.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,10 @@ extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
168168
void get_layout_hdr(struct pnfs_layout_hdr *lo);
169169
void put_lseg(struct pnfs_layout_segment *lseg);
170170

171-
bool pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *);
172-
bool pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *, int);
171+
bool pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *,
172+
const struct nfs_pgio_completion_ops *);
173+
bool pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *,
174+
int, const struct nfs_pgio_completion_ops *);
173175

174176
void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, u32);
175177
void unset_pnfs_layoutdriver(struct nfs_server *);

fs/nfs/read.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
static const struct nfs_pageio_ops nfs_pageio_read_ops;
3333
static const struct rpc_call_ops nfs_read_common_ops;
34+
static const struct nfs_pgio_completion_ops nfs_async_read_completion_ops;
3435

3536
static struct kmem_cache *nfs_rdata_cachep;
3637

@@ -95,7 +96,7 @@ void nfs_readdata_release(struct nfs_read_data *rdata)
9596
else
9697
rdata->header = NULL;
9798
if (atomic_dec_and_test(&hdr->refcnt))
98-
nfs_read_completion(hdr);
99+
hdr->completion_ops->completion(hdr);
99100
}
100101

101102
static
@@ -108,9 +109,10 @@ int nfs_return_empty_page(struct page *page)
108109
}
109110

110111
void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio,
111-
struct inode *inode)
112+
struct inode *inode,
113+
const struct nfs_pgio_completion_ops *compl_ops)
112114
{
113-
nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops,
115+
nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops, compl_ops,
114116
NFS_SERVER(inode)->rsize, 0);
115117
}
116118

@@ -122,10 +124,11 @@ void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio)
122124
EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds);
123125

124126
static void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
125-
struct inode *inode)
127+
struct inode *inode,
128+
const struct nfs_pgio_completion_ops *compl_ops)
126129
{
127-
if (!pnfs_pageio_init_read(pgio, inode))
128-
nfs_pageio_init_read_mds(pgio, inode);
130+
if (!pnfs_pageio_init_read(pgio, inode, compl_ops))
131+
nfs_pageio_init_read_mds(pgio, inode, compl_ops);
129132
}
130133

131134
int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
@@ -146,7 +149,7 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
146149
if (len < PAGE_CACHE_SIZE)
147150
zero_user_segment(page, len, PAGE_CACHE_SIZE);
148151

149-
nfs_pageio_init_read(&pgio, inode);
152+
nfs_pageio_init_read(&pgio, inode, &nfs_async_read_completion_ops);
150153
nfs_pageio_add_request(&pgio, new);
151154
nfs_pageio_complete(&pgio);
152155
return 0;
@@ -170,7 +173,7 @@ static void nfs_readpage_release(struct nfs_page *req)
170173
}
171174

172175
/* Note io was page aligned */
173-
void nfs_read_completion(struct nfs_pgio_header *hdr)
176+
static void nfs_read_completion(struct nfs_pgio_header *hdr)
174177
{
175178
unsigned long bytes = 0;
176179

@@ -300,7 +303,7 @@ nfs_do_multiple_reads(struct list_head *head,
300303
return ret;
301304
}
302305

303-
void
306+
static void
304307
nfs_async_read_error(struct list_head *head)
305308
{
306309
struct nfs_page *req;
@@ -312,6 +315,11 @@ nfs_async_read_error(struct list_head *head)
312315
}
313316
}
314317

318+
static const struct nfs_pgio_completion_ops nfs_async_read_completion_ops = {
319+
.error_cleanup = nfs_async_read_error,
320+
.completion = nfs_read_completion,
321+
};
322+
315323
/*
316324
* Generate multiple requests to fill a single page.
317325
*
@@ -362,7 +370,7 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc,
362370
list_del(&data->list);
363371
nfs_readdata_release(data);
364372
}
365-
nfs_async_read_error(&hdr->pages);
373+
desc->pg_completion_ops->error_cleanup(&hdr->pages);
366374
return -ENOMEM;
367375
}
368376

@@ -378,7 +386,7 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc,
378386
data = nfs_readdata_alloc(hdr, nfs_page_array_len(desc->pg_base,
379387
desc->pg_count));
380388
if (!data) {
381-
nfs_async_read_error(head);
389+
desc->pg_completion_ops->error_cleanup(head);
382390
ret = -ENOMEM;
383391
goto out;
384392
}
@@ -414,7 +422,7 @@ static int nfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
414422

415423
rhdr = nfs_readhdr_alloc();
416424
if (!rhdr) {
417-
nfs_async_read_error(&desc->pg_list);
425+
desc->pg_completion_ops->error_cleanup(&desc->pg_list);
418426
return -ENOMEM;
419427
}
420428
hdr = &rhdr->header;
@@ -427,7 +435,7 @@ static int nfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
427435
else
428436
set_bit(NFS_IOHDR_REDO, &hdr->flags);
429437
if (atomic_dec_and_test(&hdr->refcnt))
430-
nfs_read_completion(hdr);
438+
hdr->completion_ops->completion(hdr);
431439
return ret;
432440
}
433441

@@ -652,7 +660,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
652660
if (ret == 0)
653661
goto read_complete; /* all pages were read */
654662

655-
nfs_pageio_init_read(&pgio, inode);
663+
nfs_pageio_init_read(&pgio, inode, &nfs_async_read_completion_ops);
656664

657665
ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc);
658666

0 commit comments

Comments
 (0)