aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2007-10-16 04:25:01 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:42:55 -0400
commitafddba49d18f346e5cc2938b6ed7c512db18ca68 (patch)
tree4726e3d3b0e9e8e5b5d3b2b0cccb36446bbdf3ca /include
parent637aff46f94a754207c80c8c64bf1b74f24b967d (diff)
fs: introduce write_begin, write_end, and perform_write aops
These are intended to replace prepare_write and commit_write with more flexible alternatives that are also able to avoid the buffered write deadlock problems efficiently (which prepare_write is unable to do). [mark.fasheh@oracle.com: API design contributions, code review and fixes] [akpm@linux-foundation.org: various fixes] [dmonakhov@sw.ru: new aop block_write_begin fix] Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com> Signed-off-by: Dmitriy Monakhov <dmonakhov@openvz.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/buffer_head.h10
-rw-r--r--include/linux/fs.h30
-rw-r--r--include/linux/pagemap.h2
3 files changed, 41 insertions, 1 deletions
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 35cadad84b14..a562ecfb1a14 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -203,6 +203,16 @@ void block_invalidatepage(struct page *page, unsigned long offset);
203int block_write_full_page(struct page *page, get_block_t *get_block, 203int block_write_full_page(struct page *page, get_block_t *get_block,
204 struct writeback_control *wbc); 204 struct writeback_control *wbc);
205int block_read_full_page(struct page*, get_block_t*); 205int block_read_full_page(struct page*, get_block_t*);
206int block_write_begin(struct file *, struct address_space *,
207 loff_t, unsigned, unsigned,
208 struct page **, void **, get_block_t*);
209int block_write_end(struct file *, struct address_space *,
210 loff_t, unsigned, unsigned,
211 struct page *, void *);
212int generic_write_end(struct file *, struct address_space *,
213 loff_t, unsigned, unsigned,
214 struct page *, void *);
215void page_zero_new_buffers(struct page *page, unsigned from, unsigned to);
206int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*); 216int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
207int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*, 217int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*,
208 loff_t *); 218 loff_t *);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 86ce27c72554..e9344e6f877d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -394,6 +394,8 @@ enum positive_aop_returns {
394 AOP_TRUNCATED_PAGE = 0x80001, 394 AOP_TRUNCATED_PAGE = 0x80001,
395}; 395};
396 396
397#define AOP_FLAG_UNINTERRUPTIBLE 0x0001 /* will not do a short write */
398
397/* 399/*
398 * oh the beauties of C type declarations. 400 * oh the beauties of C type declarations.
399 */ 401 */
@@ -413,7 +415,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page,
413size_t iov_iter_copy_from_user(struct page *page, 415size_t iov_iter_copy_from_user(struct page *page,
414 struct iov_iter *i, unsigned long offset, size_t bytes); 416 struct iov_iter *i, unsigned long offset, size_t bytes);
415void iov_iter_advance(struct iov_iter *i, size_t bytes); 417void iov_iter_advance(struct iov_iter *i, size_t bytes);
416int iov_iter_fault_in_readable(struct iov_iter *i); 418int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes);
417size_t iov_iter_single_seg_count(struct iov_iter *i); 419size_t iov_iter_single_seg_count(struct iov_iter *i);
418 420
419static inline void iov_iter_init(struct iov_iter *i, 421static inline void iov_iter_init(struct iov_iter *i,
@@ -454,6 +456,14 @@ struct address_space_operations {
454 */ 456 */
455 int (*prepare_write)(struct file *, struct page *, unsigned, unsigned); 457 int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
456 int (*commit_write)(struct file *, struct page *, unsigned, unsigned); 458 int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
459
460 int (*write_begin)(struct file *, struct address_space *mapping,
461 loff_t pos, unsigned len, unsigned flags,
462 struct page **pagep, void **fsdata);
463 int (*write_end)(struct file *, struct address_space *mapping,
464 loff_t pos, unsigned len, unsigned copied,
465 struct page *page, void *fsdata);
466
457 /* Unfortunately this kludge is needed for FIBMAP. Don't use it */ 467 /* Unfortunately this kludge is needed for FIBMAP. Don't use it */
458 sector_t (*bmap)(struct address_space *, sector_t); 468 sector_t (*bmap)(struct address_space *, sector_t);
459 void (*invalidatepage) (struct page *, unsigned long); 469 void (*invalidatepage) (struct page *, unsigned long);
@@ -468,6 +478,18 @@ struct address_space_operations {
468 int (*launder_page) (struct page *); 478 int (*launder_page) (struct page *);
469}; 479};
470 480
481/*
482 * pagecache_write_begin/pagecache_write_end must be used by general code
483 * to write into the pagecache.
484 */
485int pagecache_write_begin(struct file *, struct address_space *mapping,
486 loff_t pos, unsigned len, unsigned flags,
487 struct page **pagep, void **fsdata);
488
489int pagecache_write_end(struct file *, struct address_space *mapping,
490 loff_t pos, unsigned len, unsigned copied,
491 struct page *page, void *fsdata);
492
471struct backing_dev_info; 493struct backing_dev_info;
472struct address_space { 494struct address_space {
473 struct inode *host; /* owner: inode, block_device */ 495 struct inode *host; /* owner: inode, block_device */
@@ -1866,6 +1888,12 @@ extern int simple_prepare_write(struct file *file, struct page *page,
1866 unsigned offset, unsigned to); 1888 unsigned offset, unsigned to);
1867extern int simple_commit_write(struct file *file, struct page *page, 1889extern int simple_commit_write(struct file *file, struct page *page,
1868 unsigned offset, unsigned to); 1890 unsigned offset, unsigned to);
1891extern int simple_write_begin(struct file *file, struct address_space *mapping,
1892 loff_t pos, unsigned len, unsigned flags,
1893 struct page **pagep, void **fsdata);
1894extern int simple_write_end(struct file *file, struct address_space *mapping,
1895 loff_t pos, unsigned len, unsigned copied,
1896 struct page *page, void *fsdata);
1869 1897
1870extern struct dentry *simple_lookup(struct inode *, struct dentry *, struct nameidata *); 1898extern struct dentry *simple_lookup(struct inode *, struct dentry *, struct nameidata *);
1871extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *); 1899extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *);
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 8f1e390fd71b..db8a410ae9e1 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -96,6 +96,8 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
96unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, 96unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
97 int tag, unsigned int nr_pages, struct page **pages); 97 int tag, unsigned int nr_pages, struct page **pages);
98 98
99struct page *__grab_cache_page(struct address_space *mapping, pgoff_t index);
100
99/* 101/*
100 * Returns locked page at given index in given cache, creating it if needed. 102 * Returns locked page at given index in given cache, creating it if needed.
101 */ 103 */