aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c180
1 files changed, 36 insertions, 144 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index d54812b198e9..50efa339e051 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1833,9 +1833,10 @@ void page_zero_new_buffers(struct page *page, unsigned from, unsigned to)
1833} 1833}
1834EXPORT_SYMBOL(page_zero_new_buffers); 1834EXPORT_SYMBOL(page_zero_new_buffers);
1835 1835
1836static int __block_prepare_write(struct inode *inode, struct page *page, 1836int block_prepare_write(struct page *page, unsigned from, unsigned to,
1837 unsigned from, unsigned to, get_block_t *get_block) 1837 get_block_t *get_block)
1838{ 1838{
1839 struct inode *inode = page->mapping->host;
1839 unsigned block_start, block_end; 1840 unsigned block_start, block_end;
1840 sector_t block; 1841 sector_t block;
1841 int err = 0; 1842 int err = 0;
@@ -1908,10 +1909,13 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
1908 if (!buffer_uptodate(*wait_bh)) 1909 if (!buffer_uptodate(*wait_bh))
1909 err = -EIO; 1910 err = -EIO;
1910 } 1911 }
1911 if (unlikely(err)) 1912 if (unlikely(err)) {
1912 page_zero_new_buffers(page, from, to); 1913 page_zero_new_buffers(page, from, to);
1914 ClearPageUptodate(page);
1915 }
1913 return err; 1916 return err;
1914} 1917}
1918EXPORT_SYMBOL(block_prepare_write);
1915 1919
1916static int __block_commit_write(struct inode *inode, struct page *page, 1920static int __block_commit_write(struct inode *inode, struct page *page,
1917 unsigned from, unsigned to) 1921 unsigned from, unsigned to)
@@ -1948,90 +1952,41 @@ static int __block_commit_write(struct inode *inode, struct page *page,
1948 return 0; 1952 return 0;
1949} 1953}
1950 1954
1951/* 1955int __block_write_begin(struct page *page, loff_t pos, unsigned len,
1952 * Filesystems implementing the new truncate sequence should use the 1956 get_block_t *get_block)
1953 * _newtrunc postfix variant which won't incorrectly call vmtruncate.
1954 * The filesystem needs to handle block truncation upon failure.
1955 */
1956int block_write_begin_newtrunc(struct file *file, struct address_space *mapping,
1957 loff_t pos, unsigned len, unsigned flags,
1958 struct page **pagep, void **fsdata,
1959 get_block_t *get_block)
1960{ 1957{
1961 struct inode *inode = mapping->host; 1958 unsigned start = pos & (PAGE_CACHE_SIZE - 1);
1962 int status = 0;
1963 struct page *page;
1964 pgoff_t index;
1965 unsigned start, end;
1966 int ownpage = 0;
1967
1968 index = pos >> PAGE_CACHE_SHIFT;
1969 start = pos & (PAGE_CACHE_SIZE - 1);
1970 end = start + len;
1971
1972 page = *pagep;
1973 if (page == NULL) {
1974 ownpage = 1;
1975 page = grab_cache_page_write_begin(mapping, index, flags);
1976 if (!page) {
1977 status = -ENOMEM;
1978 goto out;
1979 }
1980 *pagep = page;
1981 } else
1982 BUG_ON(!PageLocked(page));
1983
1984 status = __block_prepare_write(inode, page, start, end, get_block);
1985 if (unlikely(status)) {
1986 ClearPageUptodate(page);
1987 1959
1988 if (ownpage) { 1960 return block_prepare_write(page, start, start + len, get_block);
1989 unlock_page(page);
1990 page_cache_release(page);
1991 *pagep = NULL;
1992 }
1993 }
1994
1995out:
1996 return status;
1997} 1961}
1998EXPORT_SYMBOL(block_write_begin_newtrunc); 1962EXPORT_SYMBOL(__block_write_begin);
1999 1963
2000/* 1964/*
2001 * block_write_begin takes care of the basic task of block allocation and 1965 * block_write_begin takes care of the basic task of block allocation and
2002 * bringing partial write blocks uptodate first. 1966 * bringing partial write blocks uptodate first.
2003 * 1967 *
2004 * If *pagep is not NULL, then block_write_begin uses the locked page 1968 * The filesystem needs to handle block truncation upon failure.
2005 * at *pagep rather than allocating its own. In this case, the page will
2006 * not be unlocked or deallocated on failure.
2007 */ 1969 */
2008int block_write_begin(struct file *file, struct address_space *mapping, 1970int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len,
2009 loff_t pos, unsigned len, unsigned flags, 1971 unsigned flags, struct page **pagep, get_block_t *get_block)
2010 struct page **pagep, void **fsdata,
2011 get_block_t *get_block)
2012{ 1972{
2013 int ret; 1973 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
1974 struct page *page;
1975 int status;
2014 1976
2015 ret = block_write_begin_newtrunc(file, mapping, pos, len, flags, 1977 page = grab_cache_page_write_begin(mapping, index, flags);
2016 pagep, fsdata, get_block); 1978 if (!page)
1979 return -ENOMEM;
2017 1980
2018 /* 1981 status = __block_write_begin(page, pos, len, get_block);
2019 * prepare_write() may have instantiated a few blocks 1982 if (unlikely(status)) {
2020 * outside i_size. Trim these off again. Don't need 1983 unlock_page(page);
2021 * i_size_read because we hold i_mutex. 1984 page_cache_release(page);
2022 * 1985 page = NULL;
2023 * Filesystems which pass down their own page also cannot
2024 * call into vmtruncate here because it would lead to lock
2025 * inversion problems (*pagep is locked). This is a further
2026 * example of where the old truncate sequence is inadequate.
2027 */
2028 if (unlikely(ret) && *pagep == NULL) {
2029 loff_t isize = mapping->host->i_size;
2030 if (pos + len > isize)
2031 vmtruncate(mapping->host, isize);
2032 } 1986 }
2033 1987
2034 return ret; 1988 *pagep = page;
1989 return status;
2035} 1990}
2036EXPORT_SYMBOL(block_write_begin); 1991EXPORT_SYMBOL(block_write_begin);
2037 1992
@@ -2351,7 +2306,7 @@ out:
2351 * For moronic filesystems that do not allow holes in file. 2306 * For moronic filesystems that do not allow holes in file.
2352 * We may have to extend the file. 2307 * We may have to extend the file.
2353 */ 2308 */
2354int cont_write_begin_newtrunc(struct file *file, struct address_space *mapping, 2309int cont_write_begin(struct file *file, struct address_space *mapping,
2355 loff_t pos, unsigned len, unsigned flags, 2310 loff_t pos, unsigned len, unsigned flags,
2356 struct page **pagep, void **fsdata, 2311 struct page **pagep, void **fsdata,
2357 get_block_t *get_block, loff_t *bytes) 2312 get_block_t *get_block, loff_t *bytes)
@@ -2363,7 +2318,7 @@ int cont_write_begin_newtrunc(struct file *file, struct address_space *mapping,
2363 2318
2364 err = cont_expand_zero(file, mapping, pos, bytes); 2319 err = cont_expand_zero(file, mapping, pos, bytes);
2365 if (err) 2320 if (err)
2366 goto out; 2321 return err;
2367 2322
2368 zerofrom = *bytes & ~PAGE_CACHE_MASK; 2323 zerofrom = *bytes & ~PAGE_CACHE_MASK;
2369 if (pos+len > *bytes && zerofrom & (blocksize-1)) { 2324 if (pos+len > *bytes && zerofrom & (blocksize-1)) {
@@ -2371,44 +2326,10 @@ int cont_write_begin_newtrunc(struct file *file, struct address_space *mapping,
2371 (*bytes)++; 2326 (*bytes)++;
2372 } 2327 }
2373 2328
2374 *pagep = NULL; 2329 return block_write_begin(mapping, pos, len, flags, pagep, get_block);
2375 err = block_write_begin_newtrunc(file, mapping, pos, len,
2376 flags, pagep, fsdata, get_block);
2377out:
2378 return err;
2379}
2380EXPORT_SYMBOL(cont_write_begin_newtrunc);
2381
2382int cont_write_begin(struct file *file, struct address_space *mapping,
2383 loff_t pos, unsigned len, unsigned flags,
2384 struct page **pagep, void **fsdata,
2385 get_block_t *get_block, loff_t *bytes)
2386{
2387 int ret;
2388
2389 ret = cont_write_begin_newtrunc(file, mapping, pos, len, flags,
2390 pagep, fsdata, get_block, bytes);
2391 if (unlikely(ret)) {
2392 loff_t isize = mapping->host->i_size;
2393 if (pos + len > isize)
2394 vmtruncate(mapping->host, isize);
2395 }
2396
2397 return ret;
2398} 2330}
2399EXPORT_SYMBOL(cont_write_begin); 2331EXPORT_SYMBOL(cont_write_begin);
2400 2332
2401int block_prepare_write(struct page *page, unsigned from, unsigned to,
2402 get_block_t *get_block)
2403{
2404 struct inode *inode = page->mapping->host;
2405 int err = __block_prepare_write(inode, page, from, to, get_block);
2406 if (err)
2407 ClearPageUptodate(page);
2408 return err;
2409}
2410EXPORT_SYMBOL(block_prepare_write);
2411
2412int block_commit_write(struct page *page, unsigned from, unsigned to) 2333int block_commit_write(struct page *page, unsigned from, unsigned to)
2413{ 2334{
2414 struct inode *inode = page->mapping->host; 2335 struct inode *inode = page->mapping->host;
@@ -2510,11 +2431,11 @@ static void attach_nobh_buffers(struct page *page, struct buffer_head *head)
2510} 2431}
2511 2432
2512/* 2433/*
2513 * Filesystems implementing the new truncate sequence should use the 2434 * On entry, the page is fully not uptodate.
2514 * _newtrunc postfix variant which won't incorrectly call vmtruncate. 2435 * On exit the page is fully uptodate in the areas outside (from,to)
2515 * The filesystem needs to handle block truncation upon failure. 2436 * The filesystem needs to handle block truncation upon failure.
2516 */ 2437 */
2517int nobh_write_begin_newtrunc(struct file *file, struct address_space *mapping, 2438int nobh_write_begin(struct address_space *mapping,
2518 loff_t pos, unsigned len, unsigned flags, 2439 loff_t pos, unsigned len, unsigned flags,
2519 struct page **pagep, void **fsdata, 2440 struct page **pagep, void **fsdata,
2520 get_block_t *get_block) 2441 get_block_t *get_block)
@@ -2547,8 +2468,8 @@ int nobh_write_begin_newtrunc(struct file *file, struct address_space *mapping,
2547 unlock_page(page); 2468 unlock_page(page);
2548 page_cache_release(page); 2469 page_cache_release(page);
2549 *pagep = NULL; 2470 *pagep = NULL;
2550 return block_write_begin_newtrunc(file, mapping, pos, len, 2471 return block_write_begin(mapping, pos, len, flags, pagep,
2551 flags, pagep, fsdata, get_block); 2472 get_block);
2552 } 2473 }
2553 2474
2554 if (PageMappedToDisk(page)) 2475 if (PageMappedToDisk(page))
@@ -2654,35 +2575,6 @@ out_release:
2654 2575
2655 return ret; 2576 return ret;
2656} 2577}
2657EXPORT_SYMBOL(nobh_write_begin_newtrunc);
2658
2659/*
2660 * On entry, the page is fully not uptodate.
2661 * On exit the page is fully uptodate in the areas outside (from,to)
2662 */
2663int nobh_write_begin(struct file *file, struct address_space *mapping,
2664 loff_t pos, unsigned len, unsigned flags,
2665 struct page **pagep, void **fsdata,
2666 get_block_t *get_block)
2667{
2668 int ret;
2669
2670 ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags,
2671 pagep, fsdata, get_block);
2672
2673 /*
2674 * prepare_write() may have instantiated a few blocks
2675 * outside i_size. Trim these off again. Don't need
2676 * i_size_read because we hold i_mutex.
2677 */
2678 if (unlikely(ret)) {
2679 loff_t isize = mapping->host->i_size;
2680 if (pos + len > isize)
2681 vmtruncate(mapping->host, isize);
2682 }
2683
2684 return ret;
2685}
2686EXPORT_SYMBOL(nobh_write_begin); 2578EXPORT_SYMBOL(nobh_write_begin);
2687 2579
2688int nobh_write_end(struct file *file, struct address_space *mapping, 2580int nobh_write_end(struct file *file, struct address_space *mapping,