lockd: per-net NSM client creation and destruction helpers introduced
[pandora-kernel.git] / fs / udf / file.c
index 7f3f7ba..d1c6093 100644 (file)
 #include "udf_i.h"
 #include "udf_sb.h"
 
-static int udf_adinicb_readpage(struct file *file, struct page *page)
+static void __udf_adinicb_readpage(struct page *page)
 {
        struct inode *inode = page->mapping->host;
        char *kaddr;
        struct udf_inode_info *iinfo = UDF_I(inode);
 
-       BUG_ON(!PageLocked(page));
-
        kaddr = kmap(page);
-       memset(kaddr, 0, PAGE_CACHE_SIZE);
        memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size);
+       memset(kaddr + inode->i_size, 0, PAGE_CACHE_SIZE - inode->i_size);
        flush_dcache_page(page);
        SetPageUptodate(page);
        kunmap(page);
+}
+
+static int udf_adinicb_readpage(struct file *file, struct page *page)
+{
+       BUG_ON(!PageLocked(page));
+       __udf_adinicb_readpage(page);
        unlock_page(page);
 
        return 0;
@@ -77,6 +81,25 @@ static int udf_adinicb_writepage(struct page *page,
        return 0;
 }
 
+static int udf_adinicb_write_begin(struct file *file,
+                       struct address_space *mapping, loff_t pos,
+                       unsigned len, unsigned flags, struct page **pagep,
+                       void **fsdata)
+{
+       struct page *page;
+
+       if (WARN_ON_ONCE(pos >= PAGE_CACHE_SIZE))
+               return -EIO;
+       page = grab_cache_page_write_begin(mapping, 0, flags);
+       if (!page)
+               return -ENOMEM;
+       *pagep = page;
+
+       if (!PageUptodate(page) && len != PAGE_CACHE_SIZE)
+               __udf_adinicb_readpage(page);
+       return 0;
+}
+
 static int udf_adinicb_write_end(struct file *file,
                        struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned copied,
@@ -98,8 +121,8 @@ static int udf_adinicb_write_end(struct file *file,
 const struct address_space_operations udf_adinicb_aops = {
        .readpage       = udf_adinicb_readpage,
        .writepage      = udf_adinicb_writepage,
-       .write_begin = simple_write_begin,
-       .write_end = udf_adinicb_write_end,
+       .write_begin    = udf_adinicb_write_begin,
+       .write_end      = udf_adinicb_write_end,
 };
 
 static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,