fs: introduce write_begin, write_end, and perform_write aops
[linux-2.6.git] / fs / libfs.c
index 5294de1..f2b32d3 100644 (file)
@@ -351,6 +351,26 @@ int simple_prepare_write(struct file *file, struct page *page,
        return 0;
 }
 
+int simple_write_begin(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned flags,
+                       struct page **pagep, void **fsdata)
+{
+       struct page *page;
+       pgoff_t index;
+       unsigned from;
+
+       index = pos >> PAGE_CACHE_SHIFT;
+       from = pos & (PAGE_CACHE_SIZE - 1);
+
+       page = __grab_cache_page(mapping, index);
+       if (!page)
+               return -ENOMEM;
+
+       *pagep = page;
+
+       return simple_prepare_write(file, page, from, from+len);
+}
+
 int simple_commit_write(struct file *file, struct page *page,
                        unsigned from, unsigned to)
 {
@@ -369,6 +389,28 @@ int simple_commit_write(struct file *file, struct page *page,
        return 0;
 }
 
+int simple_write_end(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned copied,
+                       struct page *page, void *fsdata)
+{
+       unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+
+       /* zero the stale part of the page if we did a short copy */
+       if (copied < len) {
+               void *kaddr = kmap_atomic(page, KM_USER0);
+               memset(kaddr + from + copied, 0, len - copied);
+               flush_dcache_page(page);
+               kunmap_atomic(kaddr, KM_USER0);
+       }
+
+       simple_commit_write(file, page, from, from+copied);
+
+       unlock_page(page);
+       page_cache_release(page);
+
+       return copied;
+}
+
 /*
  * the inodes created here are not hashed. If you use iunique to generate
  * unique inode values later for this filesystem, then you must take care
@@ -642,6 +684,8 @@ EXPORT_SYMBOL(dcache_dir_open);
 EXPORT_SYMBOL(dcache_readdir);
 EXPORT_SYMBOL(generic_read_dir);
 EXPORT_SYMBOL(get_sb_pseudo);
+EXPORT_SYMBOL(simple_write_begin);
+EXPORT_SYMBOL(simple_write_end);
 EXPORT_SYMBOL(simple_commit_write);
 EXPORT_SYMBOL(simple_dir_inode_operations);
 EXPORT_SYMBOL(simple_dir_operations);