aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c76
1 files changed, 51 insertions, 25 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 5287be18633b..55f0975a9b15 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -153,14 +153,8 @@ int sync_blockdev(struct block_device *bdev)
153{ 153{
154 int ret = 0; 154 int ret = 0;
155 155
156 if (bdev) { 156 if (bdev)
157 int err; 157 ret = filemap_write_and_wait(bdev->bd_inode->i_mapping);
158
159 ret = filemap_fdatawrite(bdev->bd_inode->i_mapping);
160 err = filemap_fdatawait(bdev->bd_inode->i_mapping);
161 if (!ret)
162 ret = err;
163 }
164 return ret; 158 return ret;
165} 159}
166EXPORT_SYMBOL(sync_blockdev); 160EXPORT_SYMBOL(sync_blockdev);
@@ -1768,7 +1762,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
1768 * handle that here by just cleaning them. 1762 * handle that here by just cleaning them.
1769 */ 1763 */
1770 1764
1771 block = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); 1765 block = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
1772 head = page_buffers(page); 1766 head = page_buffers(page);
1773 bh = head; 1767 bh = head;
1774 1768
@@ -2160,11 +2154,12 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
2160 * truncates. Uses prepare/commit_write to allow the filesystem to 2154 * truncates. Uses prepare/commit_write to allow the filesystem to
2161 * deal with the hole. 2155 * deal with the hole.
2162 */ 2156 */
2163int generic_cont_expand(struct inode *inode, loff_t size) 2157static int __generic_cont_expand(struct inode *inode, loff_t size,
2158 pgoff_t index, unsigned int offset)
2164{ 2159{
2165 struct address_space *mapping = inode->i_mapping; 2160 struct address_space *mapping = inode->i_mapping;
2166 struct page *page; 2161 struct page *page;
2167 unsigned long index, offset, limit; 2162 unsigned long limit;
2168 int err; 2163 int err;
2169 2164
2170 err = -EFBIG; 2165 err = -EFBIG;
@@ -2176,24 +2171,24 @@ int generic_cont_expand(struct inode *inode, loff_t size)
2176 if (size > inode->i_sb->s_maxbytes) 2171 if (size > inode->i_sb->s_maxbytes)
2177 goto out; 2172 goto out;
2178 2173
2179 offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */
2180
2181 /* ugh. in prepare/commit_write, if from==to==start of block, we
2182 ** skip the prepare. make sure we never send an offset for the start
2183 ** of a block
2184 */
2185 if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) {
2186 offset++;
2187 }
2188 index = size >> PAGE_CACHE_SHIFT;
2189 err = -ENOMEM; 2174 err = -ENOMEM;
2190 page = grab_cache_page(mapping, index); 2175 page = grab_cache_page(mapping, index);
2191 if (!page) 2176 if (!page)
2192 goto out; 2177 goto out;
2193 err = mapping->a_ops->prepare_write(NULL, page, offset, offset); 2178 err = mapping->a_ops->prepare_write(NULL, page, offset, offset);
2194 if (!err) { 2179 if (err) {
2195 err = mapping->a_ops->commit_write(NULL, page, offset, offset); 2180 /*
2181 * ->prepare_write() may have instantiated a few blocks
2182 * outside i_size. Trim these off again.
2183 */
2184 unlock_page(page);
2185 page_cache_release(page);
2186 vmtruncate(inode, inode->i_size);
2187 goto out;
2196 } 2188 }
2189
2190 err = mapping->a_ops->commit_write(NULL, page, offset, offset);
2191
2197 unlock_page(page); 2192 unlock_page(page);
2198 page_cache_release(page); 2193 page_cache_release(page);
2199 if (err > 0) 2194 if (err > 0)
@@ -2202,6 +2197,36 @@ out:
2202 return err; 2197 return err;
2203} 2198}
2204 2199
2200int generic_cont_expand(struct inode *inode, loff_t size)
2201{
2202 pgoff_t index;
2203 unsigned int offset;
2204
2205 offset = (size & (PAGE_CACHE_SIZE - 1)); /* Within page */
2206
2207 /* ugh. in prepare/commit_write, if from==to==start of block, we
2208 ** skip the prepare. make sure we never send an offset for the start
2209 ** of a block
2210 */
2211 if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) {
2212 /* caller must handle this extra byte. */
2213 offset++;
2214 }
2215 index = size >> PAGE_CACHE_SHIFT;
2216
2217 return __generic_cont_expand(inode, size, index, offset);
2218}
2219
2220int generic_cont_expand_simple(struct inode *inode, loff_t size)
2221{
2222 loff_t pos = size - 1;
2223 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
2224 unsigned int offset = (pos & (PAGE_CACHE_SIZE - 1)) + 1;
2225
2226 /* prepare/commit_write can handle even if from==to==start of block. */
2227 return __generic_cont_expand(inode, size, index, offset);
2228}
2229
2205/* 2230/*
2206 * For moronic filesystems that do not allow holes in file. 2231 * For moronic filesystems that do not allow holes in file.
2207 * We may have to extend the file. 2232 * We may have to extend the file.
@@ -2610,7 +2635,7 @@ int block_truncate_page(struct address_space *mapping,
2610 pgoff_t index = from >> PAGE_CACHE_SHIFT; 2635 pgoff_t index = from >> PAGE_CACHE_SHIFT;
2611 unsigned offset = from & (PAGE_CACHE_SIZE-1); 2636 unsigned offset = from & (PAGE_CACHE_SIZE-1);
2612 unsigned blocksize; 2637 unsigned blocksize;
2613 pgoff_t iblock; 2638 sector_t iblock;
2614 unsigned length, pos; 2639 unsigned length, pos;
2615 struct inode *inode = mapping->host; 2640 struct inode *inode = mapping->host;
2616 struct page *page; 2641 struct page *page;
@@ -2626,7 +2651,7 @@ int block_truncate_page(struct address_space *mapping,
2626 return 0; 2651 return 0;
2627 2652
2628 length = blocksize - length; 2653 length = blocksize - length;
2629 iblock = index << (PAGE_CACHE_SHIFT - inode->i_blkbits); 2654 iblock = (sector_t)index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
2630 2655
2631 page = grab_cache_page(mapping, index); 2656 page = grab_cache_page(mapping, index);
2632 err = -ENOMEM; 2657 err = -ENOMEM;
@@ -3145,6 +3170,7 @@ EXPORT_SYMBOL(fsync_bdev);
3145EXPORT_SYMBOL(generic_block_bmap); 3170EXPORT_SYMBOL(generic_block_bmap);
3146EXPORT_SYMBOL(generic_commit_write); 3171EXPORT_SYMBOL(generic_commit_write);
3147EXPORT_SYMBOL(generic_cont_expand); 3172EXPORT_SYMBOL(generic_cont_expand);
3173EXPORT_SYMBOL(generic_cont_expand_simple);
3148EXPORT_SYMBOL(init_buffer); 3174EXPORT_SYMBOL(init_buffer);
3149EXPORT_SYMBOL(invalidate_bdev); 3175EXPORT_SYMBOL(invalidate_bdev);
3150EXPORT_SYMBOL(ll_rw_block); 3176EXPORT_SYMBOL(ll_rw_block);