ext4: avoid unnecessary stalls in ext4_evict_inode()
[sfrench/cifs-2.6.git] / fs / ext4 / inode.c
index 962f28a0e1762f442e4b2855b9c8db20d28f79ef..754c2190af3148cd60f1d0a8006918ef3198937a 100644 (file)
@@ -215,7 +215,8 @@ void ext4_evict_inode(struct inode *inode)
                 */
                if (inode->i_ino != EXT4_JOURNAL_INO &&
                    ext4_should_journal_data(inode) &&
-                   (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) {
+                   (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) &&
+                   inode->i_data.nrpages) {
                        journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
                        tid_t commit_tid = EXT4_I(inode)->i_datasync_tid;
 
@@ -5295,7 +5296,14 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
                        error = PTR_ERR(handle);
                        goto err_out;
                }
+
+               /* dquot_transfer() calls back ext4_get_inode_usage() which
+                * counts xattr inode references.
+                */
+               down_read(&EXT4_I(inode)->xattr_sem);
                error = dquot_transfer(inode, attr);
+               up_read(&EXT4_I(inode)->xattr_sem);
+
                if (error) {
                        ext4_journal_stop(handle);
                        return error;