jfs: fix a couple races
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / jfs / inode.c
index 4692bf3ca8cbcbaff9db883759b77d3d725cbc0d..77554b61d1247b2346c4c337d874281504e66f1c 100644 (file)
@@ -125,7 +125,7 @@ int jfs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
        int wait = wbc->sync_mode == WB_SYNC_ALL;
 
-       if (test_cflag(COMMIT_Nolink, inode))
+       if (inode->i_nlink == 0)
                return 0;
        /*
         * If COMMIT_DIRTY is not set, the inode isn't really dirty.
@@ -300,6 +300,16 @@ static int jfs_readpages(struct file *file, struct address_space *mapping,
        return mpage_readpages(mapping, pages, nr_pages, jfs_get_block);
 }
 
+static void jfs_write_failed(struct address_space *mapping, loff_t to)
+{
+       struct inode *inode = mapping->host;
+
+       if (to > inode->i_size) {
+               truncate_pagecache(inode, to, inode->i_size);
+               jfs_truncate(inode);
+       }
+}
+
 static int jfs_write_begin(struct file *file, struct address_space *mapping,
                                loff_t pos, unsigned len, unsigned flags,
                                struct page **pagep, void **fsdata)
@@ -308,11 +318,8 @@ static int jfs_write_begin(struct file *file, struct address_space *mapping,
 
        ret = nobh_write_begin(mapping, pos, len, flags, pagep, fsdata,
                                jfs_get_block);
-       if (unlikely(ret)) {
-               loff_t isize = mapping->host->i_size;
-               if (pos + len > isize)
-                       vmtruncate(mapping->host, isize);
-       }
+       if (unlikely(ret))
+               jfs_write_failed(mapping, pos + len);
 
        return ret;
 }
@@ -326,6 +333,7 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb,
        const struct iovec *iov, loff_t offset, unsigned long nr_segs)
 {
        struct file *file = iocb->ki_filp;
+       struct address_space *mapping = file->f_mapping;
        struct inode *inode = file->f_mapping->host;
        ssize_t ret;
 
@@ -341,7 +349,7 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb,
                loff_t end = offset + iov_length(iov, nr_segs);
 
                if (end > isize)
-                       vmtruncate(inode, isize);
+                       jfs_write_failed(mapping, end);
        }
 
        return ret;