Merge branch 'work.iget' into work.misc
[sfrench/cifs-2.6.git] / fs / inode.c
index d123fe4b6f7d4a9b69be1453354814574192ae9f..691c00747e725918cdc98e1f1414a42047f1baee 100644 (file)
@@ -345,7 +345,7 @@ EXPORT_SYMBOL(inc_nlink);
 void address_space_init_once(struct address_space *mapping)
 {
        memset(mapping, 0, sizeof(*mapping));
-       INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC);
+       INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC | __GFP_ACCOUNT);
        spin_lock_init(&mapping->tree_lock);
        init_rwsem(&mapping->i_mmap_rwsem);
        INIT_LIST_HEAD(&mapping->private_list);
@@ -365,6 +365,7 @@ void inode_init_once(struct inode *inode)
        INIT_HLIST_NODE(&inode->i_hash);
        INIT_LIST_HEAD(&inode->i_devices);
        INIT_LIST_HEAD(&inode->i_io_list);
+       INIT_LIST_HEAD(&inode->i_wb_list);
        INIT_LIST_HEAD(&inode->i_lru);
        address_space_init_once(&inode->i_data);
        i_size_ordered_init(inode);
@@ -507,6 +508,7 @@ void clear_inode(struct inode *inode)
        BUG_ON(!list_empty(&inode->i_data.private_list));
        BUG_ON(!(inode->i_state & I_FREEING));
        BUG_ON(inode->i_state & I_CLEAR);
+       BUG_ON(!list_empty(&inode->i_wb_list));
        /* don't need i_lock here, no concurrent mods to i_state */
        inode->i_state = I_FREEING | I_CLEAR;
 }
@@ -1644,6 +1646,13 @@ bool atime_needs_update(const struct path *path, struct inode *inode)
 
        if (inode->i_flags & S_NOATIME)
                return false;
+
+       /* Atime updates will likely cause i_uid and i_gid to be written
+        * back improprely if their true value is unknown to the vfs.
+        */
+       if (HAS_UNMAPPED_ID(inode))
+               return false;
+
        if (IS_NOATIME(inode))
                return false;
        if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))
@@ -1747,7 +1756,6 @@ int dentry_needs_remove_privs(struct dentry *dentry)
                mask |= ATTR_KILL_PRIV;
        return mask;
 }
-EXPORT_SYMBOL(dentry_needs_remove_privs);
 
 static int __remove_privs(struct dentry *dentry, int kill)
 {
@@ -1767,8 +1775,8 @@ static int __remove_privs(struct dentry *dentry, int kill)
  */
 int file_remove_privs(struct file *file)
 {
-       struct dentry *dentry = file->f_path.dentry;
-       struct inode *inode = d_inode(dentry);
+       struct dentry *dentry = file_dentry(file);
+       struct inode *inode = file_inode(file);
        int kill;
        int error = 0;
 
@@ -1776,7 +1784,7 @@ int file_remove_privs(struct file *file)
        if (IS_NOSEC(inode))
                return 0;
 
-       kill = file_needs_remove_privs(file);
+       kill = dentry_needs_remove_privs(dentry);
        if (kill < 0)
                return kill;
        if (kill)