diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2006-01-08 04:02:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-08 23:13:47 -0500 |
commit | 28fd129827b00e12829d48a5290f46277600619b (patch) | |
tree | 38e50e1b88965fec41ea5b36aa557fb5c2b1ca73 /mm/filemap.c | |
parent | 05eb0b51fb46430050d5873458612f53e0234f2e (diff) |
[PATCH] Fix and add EXPORT_SYMBOL(filemap_write_and_wait)
This patch add EXPORT_SYMBOL(filemap_write_and_wait) and use it.
See mm/filemap.c:
And changes the filemap_write_and_wait() and filemap_write_and_wait_range().
Current filemap_write_and_wait() doesn't wait if filemap_fdatawrite()
returns error. However, even if filemap_fdatawrite() returned an
error, it may have submitted the partially data pages to the device.
(e.g. in the case of -ENOSPC)
<quotation>
Andrew Morton writes,
If filemap_fdatawrite() returns an error, this might be due to some
I/O problem: dead disk, unplugged cable, etc. Given the generally
crappy quality of the kernel's handling of such exceptions, there's a
good chance that the filemap_fdatawait() will get stuck in D state
forever.
</quotation>
So, this patch doesn't wait if filemap_fdatawrite() returns the -EIO.
Trond, could you please review the nfs part? Especially I'm not sure,
nfs must use the "filemap_fdatawrite(inode->i_mapping) == 0", or not.
Acked-by: Trond Myklebust <trond.myklebust@fys.uio.no>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 8fdf36508023..478f4c74cc31 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -343,30 +343,44 @@ EXPORT_SYMBOL(filemap_fdatawait); | |||
343 | 343 | ||
344 | int filemap_write_and_wait(struct address_space *mapping) | 344 | int filemap_write_and_wait(struct address_space *mapping) |
345 | { | 345 | { |
346 | int retval = 0; | 346 | int err = 0; |
347 | 347 | ||
348 | if (mapping->nrpages) { | 348 | if (mapping->nrpages) { |
349 | retval = filemap_fdatawrite(mapping); | 349 | err = filemap_fdatawrite(mapping); |
350 | if (retval == 0) | 350 | /* |
351 | retval = filemap_fdatawait(mapping); | 351 | * Even if the above returned error, the pages may be |
352 | * written partially (e.g. -ENOSPC), so we wait for it. | ||
353 | * But the -EIO is special case, it may indicate the worst | ||
354 | * thing (e.g. bug) happened, so we avoid waiting for it. | ||
355 | */ | ||
356 | if (err != -EIO) { | ||
357 | int err2 = filemap_fdatawait(mapping); | ||
358 | if (!err) | ||
359 | err = err2; | ||
360 | } | ||
352 | } | 361 | } |
353 | return retval; | 362 | return err; |
354 | } | 363 | } |
364 | EXPORT_SYMBOL(filemap_write_and_wait); | ||
355 | 365 | ||
356 | int filemap_write_and_wait_range(struct address_space *mapping, | 366 | int filemap_write_and_wait_range(struct address_space *mapping, |
357 | loff_t lstart, loff_t lend) | 367 | loff_t lstart, loff_t lend) |
358 | { | 368 | { |
359 | int retval = 0; | 369 | int err = 0; |
360 | 370 | ||
361 | if (mapping->nrpages) { | 371 | if (mapping->nrpages) { |
362 | retval = __filemap_fdatawrite_range(mapping, lstart, lend, | 372 | err = __filemap_fdatawrite_range(mapping, lstart, lend, |
363 | WB_SYNC_ALL); | 373 | WB_SYNC_ALL); |
364 | if (retval == 0) | 374 | /* See comment of filemap_write_and_wait() */ |
365 | retval = wait_on_page_writeback_range(mapping, | 375 | if (err != -EIO) { |
366 | lstart >> PAGE_CACHE_SHIFT, | 376 | int err2 = wait_on_page_writeback_range(mapping, |
367 | lend >> PAGE_CACHE_SHIFT); | 377 | lstart >> PAGE_CACHE_SHIFT, |
378 | lend >> PAGE_CACHE_SHIFT); | ||
379 | if (!err) | ||
380 | err = err2; | ||
381 | } | ||
368 | } | 382 | } |
369 | return retval; | 383 | return err; |
370 | } | 384 | } |
371 | 385 | ||
372 | /* | 386 | /* |