diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 4ef24a397684..478f4c74cc31 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -280,7 +280,7 @@ static int wait_on_page_writeback_range(struct address_space *mapping, | |||
280 | * it is otherwise livelockable. | 280 | * it is otherwise livelockable. |
281 | */ | 281 | */ |
282 | int sync_page_range(struct inode *inode, struct address_space *mapping, | 282 | int sync_page_range(struct inode *inode, struct address_space *mapping, |
283 | loff_t pos, size_t count) | 283 | loff_t pos, loff_t count) |
284 | { | 284 | { |
285 | pgoff_t start = pos >> PAGE_CACHE_SHIFT; | 285 | pgoff_t start = pos >> PAGE_CACHE_SHIFT; |
286 | pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT; | 286 | pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT; |
@@ -305,9 +305,8 @@ EXPORT_SYMBOL(sync_page_range); | |||
305 | * as it forces O_SYNC writers to different parts of the same file | 305 | * as it forces O_SYNC writers to different parts of the same file |
306 | * to be serialised right until io completion. | 306 | * to be serialised right until io completion. |
307 | */ | 307 | */ |
308 | static int sync_page_range_nolock(struct inode *inode, | 308 | int sync_page_range_nolock(struct inode *inode, struct address_space *mapping, |
309 | struct address_space *mapping, | 309 | loff_t pos, loff_t count) |
310 | loff_t pos, size_t count) | ||
311 | { | 310 | { |
312 | pgoff_t start = pos >> PAGE_CACHE_SHIFT; | 311 | pgoff_t start = pos >> PAGE_CACHE_SHIFT; |
313 | pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT; | 312 | pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT; |
@@ -322,6 +321,7 @@ static int sync_page_range_nolock(struct inode *inode, | |||
322 | ret = wait_on_page_writeback_range(mapping, start, end); | 321 | ret = wait_on_page_writeback_range(mapping, start, end); |
323 | return ret; | 322 | return ret; |
324 | } | 323 | } |
324 | EXPORT_SYMBOL(sync_page_range_nolock); | ||
325 | 325 | ||
326 | /** | 326 | /** |
327 | * filemap_fdatawait - walk the list of under-writeback pages of the given | 327 | * filemap_fdatawait - walk the list of under-writeback pages of the given |
@@ -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 | /* |