aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/fsync.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/fsync.c')
-rw-r--r--fs/ext4/fsync.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index da3bed3e0c29..036f78f7a1ef 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -129,15 +129,30 @@ static int ext4_sync_parent(struct inode *inode)
129{ 129{
130 struct writeback_control wbc; 130 struct writeback_control wbc;
131 struct dentry *dentry = NULL; 131 struct dentry *dentry = NULL;
132 struct inode *next;
132 int ret = 0; 133 int ret = 0;
133 134
134 while (inode && ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) { 135 if (!ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY))
136 return 0;
137 inode = igrab(inode);
138 while (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) {
135 ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY); 139 ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY);
136 dentry = list_entry(inode->i_dentry.next, 140 dentry = NULL;
137 struct dentry, d_alias); 141 spin_lock(&inode->i_lock);
138 if (!dentry || !dentry->d_parent || !dentry->d_parent->d_inode) 142 if (!list_empty(&inode->i_dentry)) {
143 dentry = list_first_entry(&inode->i_dentry,
144 struct dentry, d_alias);
145 dget(dentry);
146 }
147 spin_unlock(&inode->i_lock);
148 if (!dentry)
139 break; 149 break;
140 inode = dentry->d_parent->d_inode; 150 next = igrab(dentry->d_parent->d_inode);
151 dput(dentry);
152 if (!next)
153 break;
154 iput(inode);
155 inode = next;
141 ret = sync_mapping_buffers(inode->i_mapping); 156 ret = sync_mapping_buffers(inode->i_mapping);
142 if (ret) 157 if (ret)
143 break; 158 break;
@@ -148,6 +163,7 @@ static int ext4_sync_parent(struct inode *inode)
148 if (ret) 163 if (ret)
149 break; 164 break;
150 } 165 }
166 iput(inode);
151 return ret; 167 return ret;
152} 168}
153 169