Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm...
[linux-3.10.git] / fs / jffs2 / file.c
index 5edc2bf..1506673 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
@@ -9,8 +10,9 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/time.h>
 #include <linux/pagemap.h>
@@ -27,13 +29,20 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
                        struct page **pagep, void **fsdata);
 static int jffs2_readpage (struct file *filp, struct page *pg);
 
-int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
+int jffs2_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = filp->f_mapping->host;
        struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+       int ret;
 
+       ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+       if (ret)
+               return ret;
+
+       mutex_lock(&inode->i_mutex);
        /* Trigger GC to flush any pending writes for this inode */
        jffs2_flush_wbuf_gc(c, inode->i_ino);
+       mutex_unlock(&inode->i_mutex);
 
        return 0;
 }
@@ -56,7 +65,7 @@ const struct file_operations jffs2_file_operations =
 
 const struct inode_operations jffs2_file_inode_operations =
 {
-       .permission =   jffs2_permission,
+       .get_acl =      jffs2_get_acl,
        .setattr =      jffs2_setattr,
        .setxattr =     jffs2_setxattr,
        .getxattr =     jffs2_getxattr,
@@ -78,7 +87,8 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)
        unsigned char *pg_buf;
        int ret;
 
-       D2(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT));
+       jffs2_dbg(2, "%s(): ino #%lu, page at offset 0x%lx\n",
+                 __func__, inode->i_ino, pg->index << PAGE_CACHE_SHIFT);
 
        BUG_ON(!PageLocked(pg));
 
@@ -98,8 +108,8 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)
        flush_dcache_page(pg);
        kunmap(pg);
 
-       D2(printk(KERN_DEBUG "readpage finished\n"));
-       return 0;
+       jffs2_dbg(2, "readpage finished\n");
+       return ret;
 }
 
 int jffs2_do_readpage_unlock(struct inode *inode, struct page *pg)
@@ -128,33 +138,39 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
        struct page *pg;
        struct inode *inode = mapping->host;
        struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+       struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+       struct jffs2_raw_inode ri;
+       uint32_t alloc_len = 0;
        pgoff_t index = pos >> PAGE_CACHE_SHIFT;
        uint32_t pageofs = index << PAGE_CACHE_SHIFT;
        int ret = 0;
 
+       jffs2_dbg(1, "%s()\n", __func__);
+
+       if (pageofs > inode->i_size) {
+               ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
+                                         ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
+               if (ret)
+                       return ret;
+       }
+
+       mutex_lock(&f->sem);
        pg = grab_cache_page_write_begin(mapping, index, flags);
-       if (!pg)
+       if (!pg) {
+               if (alloc_len)
+                       jffs2_complete_reservation(c);
+               mutex_unlock(&f->sem);
                return -ENOMEM;
+       }
        *pagep = pg;
 
-       D1(printk(KERN_DEBUG "jffs2_write_begin()\n"));
-
-       if (pageofs > inode->i_size) {
+       if (alloc_len) {
                /* Make new hole frag from old EOF to new page */
-               struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-               struct jffs2_raw_inode ri;
                struct jffs2_full_dnode *fn;
-               uint32_t alloc_len;
-
-               D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
-                         (unsigned int)inode->i_size, pageofs));
 
-               ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
-                                         ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
-               if (ret)
-                       goto out_page;
+               jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
+                         (unsigned int)inode->i_size, pageofs);
 
-               mutex_lock(&f->sem);
                memset(&ri, 0, sizeof(ri));
 
                ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -165,8 +181,8 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
                ri.ino = cpu_to_je32(f->inocache->ino);
                ri.version = cpu_to_je32(++f->highest_version);
                ri.mode = cpu_to_jemode(inode->i_mode);
-               ri.uid = cpu_to_je16(inode->i_uid);
-               ri.gid = cpu_to_je16(inode->i_gid);
+               ri.uid = cpu_to_je16(i_uid_read(inode));
+               ri.gid = cpu_to_je16(i_gid_read(inode));
                ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
                ri.atime = ri.ctime = ri.mtime = cpu_to_je32(get_seconds());
                ri.offset = cpu_to_je32(inode->i_size);
@@ -181,7 +197,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
                if (IS_ERR(fn)) {
                        ret = PTR_ERR(fn);
                        jffs2_complete_reservation(c);
-                       mutex_unlock(&f->sem);
                        goto out_page;
                }
                ret = jffs2_add_full_dnode_to_inode(c, f, fn);
@@ -191,16 +206,15 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
                        f->metadata = NULL;
                }
                if (ret) {
-                       D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in write_begin, returned %d\n", ret));
+                       jffs2_dbg(1, "Eep. add_full_dnode_to_inode() failed in write_begin, returned %d\n",
+                                 ret);
                        jffs2_mark_node_obsolete(c, fn->raw);
                        jffs2_free_full_dnode(fn);
                        jffs2_complete_reservation(c);
-                       mutex_unlock(&f->sem);
                        goto out_page;
                }
                jffs2_complete_reservation(c);
                inode->i_size = pageofs;
-               mutex_unlock(&f->sem);
        }
 
        /*
@@ -209,18 +223,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
         * case of a short-copy.
         */
        if (!PageUptodate(pg)) {
-               mutex_lock(&f->sem);
                ret = jffs2_do_readpage_nolock(inode, pg);
-               mutex_unlock(&f->sem);
                if (ret)
                        goto out_page;
        }
-       D1(printk(KERN_DEBUG "end write_begin(). pg->flags %lx\n", pg->flags));
+       mutex_unlock(&f->sem);
+       jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
        return ret;
 
 out_page:
        unlock_page(pg);
        page_cache_release(pg);
+       mutex_unlock(&f->sem);
        return ret;
 }
 
@@ -241,8 +255,9 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,
        int ret = 0;
        uint32_t writtenlen = 0;
 
-       D1(printk(KERN_DEBUG "jffs2_write_end(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n",
-                 inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
+       jffs2_dbg(1, "%s(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n",
+                 __func__, inode->i_ino, pg->index << PAGE_CACHE_SHIFT,
+                 start, end, pg->flags);
 
        /* We need to avoid deadlock with page_cache_read() in
           jffs2_garbage_collect_pass(). So the page must be
@@ -261,7 +276,8 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,
        ri = jffs2_alloc_raw_inode();
 
        if (!ri) {
-               D1(printk(KERN_DEBUG "jffs2_write_end(): Allocation of raw inode failed\n"));
+               jffs2_dbg(1, "%s(): Allocation of raw inode failed\n",
+                         __func__);
                unlock_page(pg);
                page_cache_release(pg);
                return -ENOMEM;
@@ -270,8 +286,8 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,
        /* Set the fields that the generic jffs2_write_inode_range() code can't find */
        ri->ino = cpu_to_je32(inode->i_ino);
        ri->mode = cpu_to_jemode(inode->i_mode);
-       ri->uid = cpu_to_je16(inode->i_uid);
-       ri->gid = cpu_to_je16(inode->i_gid);
+       ri->uid = cpu_to_je16(i_uid_read(inode));
+       ri->gid = cpu_to_je16(i_gid_read(inode));
        ri->isize = cpu_to_je32((uint32_t)inode->i_size);
        ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds());
 
@@ -308,13 +324,14 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,
                /* generic_file_write has written more to the page cache than we've
                   actually written to the medium. Mark the page !Uptodate so that
                   it gets reread */
-               D1(printk(KERN_DEBUG "jffs2_write_end(): Not all bytes written. Marking page !uptodate\n"));
+               jffs2_dbg(1, "%s(): Not all bytes written. Marking page !uptodate\n",
+                       __func__);
                SetPageError(pg);
                ClearPageUptodate(pg);
        }
 
-       D1(printk(KERN_DEBUG "jffs2_write_end() returning %d\n",
-                                       writtenlen > 0 ? writtenlen : ret));
+       jffs2_dbg(1, "%s() returning %d\n",
+                 __func__, writtenlen > 0 ? writtenlen : ret);
        unlock_page(pg);
        page_cache_release(pg);
        return writtenlen > 0 ? writtenlen : ret;