diff options
Diffstat (limited to 'fs/nfs/pagelist.c')
-rw-r--r-- | fs/nfs/pagelist.c | 71 |
1 files changed, 66 insertions, 5 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 7017eb0e0bc8..528128545d66 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -225,14 +225,26 @@ out: | |||
225 | /** | 225 | /** |
226 | * nfs_pageio_init - initialise a page io descriptor | 226 | * nfs_pageio_init - initialise a page io descriptor |
227 | * @desc: pointer to descriptor | 227 | * @desc: pointer to descriptor |
228 | * @iosize: io block size | 228 | * @inode: pointer to inode |
229 | * @doio: pointer to io function | ||
230 | * @bsize: io block size | ||
231 | * @io_flags: extra parameters for the io function | ||
229 | */ | 232 | */ |
230 | void nfs_pageio_init(struct nfs_pageio_descriptor *desc, unsigned int bsize) | 233 | void nfs_pageio_init(struct nfs_pageio_descriptor *desc, |
234 | struct inode *inode, | ||
235 | int (*doio)(struct inode *, struct list_head *, size_t, int), | ||
236 | unsigned int bsize, | ||
237 | int io_flags) | ||
231 | { | 238 | { |
232 | INIT_LIST_HEAD(&desc->pg_list); | 239 | INIT_LIST_HEAD(&desc->pg_list); |
240 | desc->pg_bytes_written = 0; | ||
233 | desc->pg_count = 0; | 241 | desc->pg_count = 0; |
234 | desc->pg_bsize = bsize; | 242 | desc->pg_bsize = bsize; |
235 | desc->pg_base = 0; | 243 | desc->pg_base = 0; |
244 | desc->pg_inode = inode; | ||
245 | desc->pg_doio = doio; | ||
246 | desc->pg_ioflags = io_flags; | ||
247 | desc->pg_error = 0; | ||
236 | } | 248 | } |
237 | 249 | ||
238 | /** | 250 | /** |
@@ -265,15 +277,15 @@ static int nfs_can_coalesce_requests(struct nfs_page *prev, | |||
265 | } | 277 | } |
266 | 278 | ||
267 | /** | 279 | /** |
268 | * nfs_pageio_add_request - Attempt to coalesce a request into a page list. | 280 | * nfs_pageio_do_add_request - Attempt to coalesce a request into a page list. |
269 | * @desc: destination io descriptor | 281 | * @desc: destination io descriptor |
270 | * @req: request | 282 | * @req: request |
271 | * | 283 | * |
272 | * Returns true if the request 'req' was successfully coalesced into the | 284 | * Returns true if the request 'req' was successfully coalesced into the |
273 | * existing list of pages 'desc'. | 285 | * existing list of pages 'desc'. |
274 | */ | 286 | */ |
275 | static int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, | 287 | static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, |
276 | struct nfs_page *req) | 288 | struct nfs_page *req) |
277 | { | 289 | { |
278 | size_t newlen = req->wb_bytes; | 290 | size_t newlen = req->wb_bytes; |
279 | 291 | ||
@@ -301,6 +313,46 @@ static int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, | |||
301 | return 1; | 313 | return 1; |
302 | } | 314 | } |
303 | 315 | ||
316 | /* | ||
317 | * Helper for nfs_pageio_add_request and nfs_pageio_complete | ||
318 | */ | ||
319 | static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) | ||
320 | { | ||
321 | if (!list_empty(&desc->pg_list)) { | ||
322 | int error = desc->pg_doio(desc->pg_inode, | ||
323 | &desc->pg_list, | ||
324 | desc->pg_count, | ||
325 | desc->pg_ioflags); | ||
326 | if (error < 0) | ||
327 | desc->pg_error = error; | ||
328 | else | ||
329 | desc->pg_bytes_written += desc->pg_count; | ||
330 | } | ||
331 | if (list_empty(&desc->pg_list)) { | ||
332 | desc->pg_count = 0; | ||
333 | desc->pg_base = 0; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | /** | ||
338 | * nfs_pageio_add_request - Attempt to coalesce a request into a page list. | ||
339 | * @desc: destination io descriptor | ||
340 | * @req: request | ||
341 | * | ||
342 | * Returns true if the request 'req' was successfully coalesced into the | ||
343 | * existing list of pages 'desc'. | ||
344 | */ | ||
345 | static int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, | ||
346 | struct nfs_page *req) | ||
347 | { | ||
348 | while (!nfs_pageio_do_add_request(desc, req)) { | ||
349 | nfs_pageio_doio(desc); | ||
350 | if (desc->pg_error < 0) | ||
351 | return 0; | ||
352 | } | ||
353 | return 1; | ||
354 | } | ||
355 | |||
304 | /** | 356 | /** |
305 | * nfs_pageio_add_list - Split coalesced requests out from a list. | 357 | * nfs_pageio_add_list - Split coalesced requests out from a list. |
306 | * @desc: destination io descriptor | 358 | * @desc: destination io descriptor |
@@ -320,6 +372,15 @@ void nfs_pageio_add_list(struct nfs_pageio_descriptor *desc, | |||
320 | } | 372 | } |
321 | } | 373 | } |
322 | 374 | ||
375 | /** | ||
376 | * nfs_pageio_complete - Complete I/O on an nfs_pageio_descriptor | ||
377 | * @desc: pointer to io descriptor | ||
378 | */ | ||
379 | void nfs_pageio_complete(struct nfs_pageio_descriptor *desc) | ||
380 | { | ||
381 | nfs_pageio_doio(desc); | ||
382 | } | ||
383 | |||
323 | #define NFS_SCAN_MAXENTRIES 16 | 384 | #define NFS_SCAN_MAXENTRIES 16 |
324 | /** | 385 | /** |
325 | * nfs_scan_dirty - Scan the radix tree for dirty requests | 386 | * nfs_scan_dirty - Scan the radix tree for dirty requests |