aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2010-06-04 05:29:57 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2010-08-09 16:47:32 -0400
commit6e1db88d536adcbbfe562b2d4b7d6425784fff12 (patch)
tree8cfcb5a6190722db6249b2e4978f39247975abcf
parentf4e420dc423148fba637af1ab618fa8896dfb2d6 (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>
-rw-r--r--fs/buffer.c69
-rw-r--r--fs/ext2/dir.c3
-rw-r--r--fs/ext3/inode.c3
-rw-r--r--fs/ext4/inode.c11
-rw-r--r--fs/minix/inode.c3
-rw-r--r--fs/nilfs2/dir.c3
-rw-r--r--fs/reiserfs/inode.c3
-rw-r--r--fs/sysv/itree.c3
-rw-r--r--fs/ufs/inode.c3
-rw-r--r--include/linux/buffer_head.h2
10 files changed, 39 insertions, 64 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}
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,6 +1952,15 @@ static int __block_commit_write(struct inode *inode, struct page *page,
1948 return 0; 1952 return 0;
1949} 1953}
1950 1954
1955int __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}
1962EXPORT_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
1995out: 1989 *pagep = page;
1996 return status; 1990 return status;
1997} 1991}
1998EXPORT_SYMBOL(block_write_begin_newtrunc); 1992EXPORT_SYMBOL(block_write_begin_newtrunc);
@@ -2379,17 +2373,6 @@ out:
2379} 2373}
2380EXPORT_SYMBOL(cont_write_begin); 2374EXPORT_SYMBOL(cont_write_begin);
2381 2375
2382int 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}
2391EXPORT_SYMBOL(block_prepare_write);
2392
2393int block_commit_write(struct page *page, unsigned from, unsigned to) 2376int 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;
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 6b946bae11cf..764109886ec0 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -450,8 +450,7 @@ ino_t ext2_inode_by_name(struct inode *dir, struct qstr *child)
450 450
451static int ext2_prepare_chunk(struct page *page, loff_t pos, unsigned len) 451static int ext2_prepare_chunk(struct page *page, loff_t pos, unsigned len)
452{ 452{
453 return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, 453 return __block_write_begin(page, pos, len, ext2_get_block);
454 &page, NULL, ext2_get_block);
455} 454}
456 455
457/* Releases the page */ 456/* Releases the page */
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index a66f3fe33672..5c6f07eefa4a 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1196,8 +1196,7 @@ retry:
1196 ret = PTR_ERR(handle); 1196 ret = PTR_ERR(handle);
1197 goto out; 1197 goto out;
1198 } 1198 }
1199 ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 1199 ret = __block_write_begin(page, pos, len, ext3_get_block);
1200 ext3_get_block);
1201 if (ret) 1200 if (ret)
1202 goto write_begin_failed; 1201 goto write_begin_failed;
1203 1202
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index d6a7701018a6..3da3c9646e5e 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1578,11 +1578,9 @@ retry:
1578 *pagep = page; 1578 *pagep = page;
1579 1579
1580 if (ext4_should_dioread_nolock(inode)) 1580 if (ext4_should_dioread_nolock(inode))
1581 ret = block_write_begin(file, mapping, pos, len, flags, pagep, 1581 ret = __block_write_begin(page, pos, len, ext4_get_block_write);
1582 fsdata, ext4_get_block_write);
1583 else 1582 else
1584 ret = block_write_begin(file, mapping, pos, len, flags, pagep, 1583 ret = __block_write_begin(page, pos, len, ext4_get_block);
1585 fsdata, ext4_get_block);
1586 1584
1587 if (!ret && ext4_should_journal_data(inode)) { 1585 if (!ret && ext4_should_journal_data(inode)) {
1588 ret = walk_page_buffers(handle, page_buffers(page), 1586 ret = walk_page_buffers(handle, page_buffers(page),
@@ -1593,7 +1591,7 @@ retry:
1593 unlock_page(page); 1591 unlock_page(page);
1594 page_cache_release(page); 1592 page_cache_release(page);
1595 /* 1593 /*
1596 * block_write_begin may have instantiated a few blocks 1594 * __block_write_begin may have instantiated a few blocks
1597 * outside i_size. Trim these off again. Don't need 1595 * outside i_size. Trim these off again. Don't need
1598 * i_size_read because we hold i_mutex. 1596 * i_size_read because we hold i_mutex.
1599 * 1597 *
@@ -3185,8 +3183,7 @@ retry:
3185 } 3183 }
3186 *pagep = page; 3184 *pagep = page;
3187 3185
3188 ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 3186 ret = __block_write_begin(page, pos, len, ext4_da_get_block_prep);
3189 ext4_da_get_block_prep);
3190 if (ret < 0) { 3187 if (ret < 0) {
3191 unlock_page(page); 3188 unlock_page(page);
3192 ext4_journal_stop(handle); 3189 ext4_journal_stop(handle);
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index f4abe45229bb..6b29e73f0ca6 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -359,8 +359,7 @@ static int minix_readpage(struct file *file, struct page *page)
359 359
360int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len) 360int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len)
361{ 361{
362 return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, 362 return __block_write_begin(page, pos, len, minix_get_block);
363 &page, NULL, minix_get_block);
364} 363}
365 364
366static int minix_write_begin(struct file *file, struct address_space *mapping, 365static int minix_write_begin(struct file *file, struct address_space *mapping,
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index fc2bcfa599a3..d14e3b94d81f 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -83,8 +83,7 @@ static unsigned nilfs_last_byte(struct inode *inode, unsigned long page_nr)
83static int nilfs_prepare_chunk(struct page *page, unsigned from, unsigned to) 83static int nilfs_prepare_chunk(struct page *page, unsigned from, unsigned to)
84{ 84{
85 loff_t pos = page_offset(page) + from; 85 loff_t pos = page_offset(page) + from;
86 return block_write_begin_newtrunc(NULL, page->mapping, pos, to - from, 86 return __block_write_begin(page, pos, to - from, nilfs_get_block);
87 0, &page, NULL, nilfs_get_block);
88} 87}
89 88
90static void nilfs_commit_chunk(struct page *page, 89static void nilfs_commit_chunk(struct page *page,
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 4c1fb548ab64..045729f5674a 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2585,8 +2585,7 @@ static int reiserfs_write_begin(struct file *file,
2585 old_ref = th->t_refcount; 2585 old_ref = th->t_refcount;
2586 th->t_refcount++; 2586 th->t_refcount++;
2587 } 2587 }
2588 ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 2588 ret = __block_write_begin(page, pos, len, reiserfs_get_block);
2589 reiserfs_get_block);
2590 if (ret && reiserfs_transaction_running(inode->i_sb)) { 2589 if (ret && reiserfs_transaction_running(inode->i_sb)) {
2591 struct reiserfs_transaction_handle *th = current->journal_info; 2590 struct reiserfs_transaction_handle *th = current->journal_info;
2592 /* this gets a little ugly. If reiserfs_get_block returned an 2591 /* this gets a little ugly. If reiserfs_get_block returned an
diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c
index 4068f485cfd6..82a005c3d7eb 100644
--- a/fs/sysv/itree.c
+++ b/fs/sysv/itree.c
@@ -461,8 +461,7 @@ static int sysv_readpage(struct file *file, struct page *page)
461 461
462int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len) 462int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len)
463{ 463{
464 return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, 464 return __block_write_begin(page, pos, len, get_block);
465 &page, NULL, get_block);
466} 465}
467 466
468static int sysv_write_begin(struct file *file, struct address_space *mapping, 467static int sysv_write_begin(struct file *file, struct address_space *mapping,
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index a9555b1ffd28..45ce32391f8f 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -560,8 +560,7 @@ static int ufs_readpage(struct file *file, struct page *page)
560 560
561int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len) 561int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len)
562{ 562{
563 return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, 563 return __block_write_begin(page, pos, len, ufs_getfrag_block);
564 &page, NULL, ufs_getfrag_block);
565} 564}
566 565
567static int ufs_write_begin(struct file *file, struct address_space *mapping, 566static int ufs_write_begin(struct file *file, struct address_space *mapping,
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 7638647f0424..accc9f81bb63 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -209,6 +209,8 @@ int block_write_begin_newtrunc(struct file *, struct address_space *,
209int block_write_begin(struct file *, struct address_space *, 209int block_write_begin(struct file *, struct address_space *,
210 loff_t, unsigned, unsigned, 210 loff_t, unsigned, unsigned,
211 struct page **, void **, get_block_t*); 211 struct page **, void **, get_block_t*);
212int __block_write_begin(struct page *page, loff_t pos, unsigned len,
213 get_block_t *get_block);
212int block_write_end(struct file *, struct address_space *, 214int block_write_end(struct file *, struct address_space *,
213 loff_t, unsigned, unsigned, 215 loff_t, unsigned, unsigned,
214 struct page *, void *); 216 struct page *, void *);