diff options
author | Christoph Hellwig <hch@lst.de> | 2010-06-04 05:29:57 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-08-09 16:47:32 -0400 |
commit | 6e1db88d536adcbbfe562b2d4b7d6425784fff12 (patch) | |
tree | 8cfcb5a6190722db6249b2e4978f39247975abcf /fs/buffer.c | |
parent | f4e420dc423148fba637af1ab618fa8896dfb2d6 (diff) |
introduce __block_write_begin
Split up the block_write_begin implementation - __block_write_begin is a new
trivial wrapper for block_prepare_write that always takes an already
allocated page and can be either called from block_write_begin or filesystem
code that already has a page allocated. Remove the handling of already
allocated pages from block_write_begin after switching all callers that
do it to __block_write_begin.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/buffer.c')
-rw-r--r-- | fs/buffer.c | 69 |
1 files changed, 26 insertions, 43 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index 14529ec759b9..c319c49da511 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 | } |
1834 | EXPORT_SYMBOL(page_zero_new_buffers); | 1834 | EXPORT_SYMBOL(page_zero_new_buffers); |
1835 | 1835 | ||
1836 | static int __block_prepare_write(struct inode *inode, struct page *page, | 1836 | int 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 | } |
1918 | EXPORT_SYMBOL(block_prepare_write); | ||
1915 | 1919 | ||
1916 | static int __block_commit_write(struct inode *inode, struct page *page, | 1920 | static int __block_commit_write(struct inode *inode, struct page *page, |
1917 | unsigned from, unsigned to) | 1921 | unsigned from, unsigned to) |
@@ -1948,6 +1952,15 @@ static int __block_commit_write(struct inode *inode, struct page *page, | |||
1948 | return 0; | 1952 | return 0; |
1949 | } | 1953 | } |
1950 | 1954 | ||
1955 | int __block_write_begin(struct page *page, loff_t pos, unsigned len, | ||
1956 | get_block_t *get_block) | ||
1957 | { | ||
1958 | unsigned start = pos & (PAGE_CACHE_SIZE - 1); | ||
1959 | |||
1960 | return block_prepare_write(page, start, start + len, get_block); | ||
1961 | } | ||
1962 | EXPORT_SYMBOL(__block_write_begin); | ||
1963 | |||
1951 | /* | 1964 | /* |
1952 | * Filesystems implementing the new truncate sequence should use the | 1965 | * Filesystems implementing the new truncate sequence should use the |
1953 | * _newtrunc postfix variant which won't incorrectly call vmtruncate. | 1966 | * _newtrunc postfix variant which won't incorrectly call vmtruncate. |
@@ -1958,41 +1971,22 @@ int block_write_begin_newtrunc(struct file *file, struct address_space *mapping, | |||
1958 | struct page **pagep, void **fsdata, | 1971 | struct page **pagep, void **fsdata, |
1959 | get_block_t *get_block) | 1972 | get_block_t *get_block) |
1960 | { | 1973 | { |
1961 | struct inode *inode = mapping->host; | 1974 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; |
1962 | int status = 0; | ||
1963 | struct page *page; | 1975 | struct page *page; |
1964 | pgoff_t index; | 1976 | int status; |
1965 | unsigned start, end; | ||
1966 | int ownpage = 0; | ||
1967 | 1977 | ||
1968 | index = pos >> PAGE_CACHE_SHIFT; | 1978 | page = grab_cache_page_write_begin(mapping, index, flags); |
1969 | start = pos & (PAGE_CACHE_SIZE - 1); | 1979 | if (!page) |
1970 | end = start + len; | 1980 | return -ENOMEM; |
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 | 1981 | ||
1984 | status = __block_prepare_write(inode, page, start, end, get_block); | 1982 | status = __block_write_begin(page, pos, len, get_block); |
1985 | if (unlikely(status)) { | 1983 | if (unlikely(status)) { |
1986 | ClearPageUptodate(page); | 1984 | unlock_page(page); |
1987 | 1985 | page_cache_release(page); | |
1988 | if (ownpage) { | 1986 | page = NULL; |
1989 | unlock_page(page); | ||
1990 | page_cache_release(page); | ||
1991 | *pagep = NULL; | ||
1992 | } | ||
1993 | } | 1987 | } |
1994 | 1988 | ||
1995 | out: | 1989 | *pagep = page; |
1996 | return status; | 1990 | return status; |
1997 | } | 1991 | } |
1998 | EXPORT_SYMBOL(block_write_begin_newtrunc); | 1992 | EXPORT_SYMBOL(block_write_begin_newtrunc); |
@@ -2379,17 +2373,6 @@ out: | |||
2379 | } | 2373 | } |
2380 | EXPORT_SYMBOL(cont_write_begin); | 2374 | EXPORT_SYMBOL(cont_write_begin); |
2381 | 2375 | ||
2382 | int block_prepare_write(struct page *page, unsigned from, unsigned to, | ||
2383 | get_block_t *get_block) | ||
2384 | { | ||
2385 | struct inode *inode = page->mapping->host; | ||
2386 | int err = __block_prepare_write(inode, page, from, to, get_block); | ||
2387 | if (err) | ||
2388 | ClearPageUptodate(page); | ||
2389 | return err; | ||
2390 | } | ||
2391 | EXPORT_SYMBOL(block_prepare_write); | ||
2392 | |||
2393 | int block_commit_write(struct page *page, unsigned from, unsigned to) | 2376 | int block_commit_write(struct page *page, unsigned from, unsigned to) |
2394 | { | 2377 | { |
2395 | struct inode *inode = page->mapping->host; | 2378 | struct inode *inode = page->mapping->host; |