Merge branch 'work.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[sfrench/cifs-2.6.git] / fs / open.c
index 53bc0573c0eca56633388b8126ad887c089996d2..94bef26ff1b616a23544da9e0d9232ef97aca034 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -852,8 +852,17 @@ static int do_dentry_open(struct file *f,
         * XXX: Huge page cache doesn't support writing yet. Drop all page
         * cache for this file before processing writes.
         */
-       if ((f->f_mode & FMODE_WRITE) && filemap_nr_thps(inode->i_mapping))
-               truncate_pagecache(inode, 0);
+       if (f->f_mode & FMODE_WRITE) {
+               /*
+                * Paired with smp_mb() in collapse_file() to ensure nr_thps
+                * is up to date and the update to i_writecount by
+                * get_write_access() is visible. Ensures subsequent insertion
+                * of THPs into the page cache will fail.
+                */
+               smp_mb();
+               if (filemap_nr_thps(inode->i_mapping))
+                       truncate_pagecache(inode, 0);
+       }
 
        return 0;
 
@@ -1164,7 +1173,7 @@ struct file *filp_open(const char *filename, int flags, umode_t mode)
 }
 EXPORT_SYMBOL(filp_open);
 
-struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
+struct file *file_open_root(const struct path *root,
                            const char *filename, int flags, umode_t mode)
 {
        struct open_flags op;
@@ -1172,7 +1181,7 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
        int err = build_open_flags(&how, &op);
        if (err)
                return ERR_PTR(err);
-       return do_file_open_root(dentry, mnt, filename, &op);
+       return do_file_open_root(root, filename, &op);
 }
 EXPORT_SYMBOL(file_open_root);