diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-04-11 18:45:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-04-11 18:45:47 -0400 |
commit | a97b52022a73ec12e43f0b2c7d4bd1f40f89c81d (patch) | |
tree | 1a35544915a5704fa59c63b43e9f46e20be1e296 /fs/ext4/fsync.c | |
parent | 18770c7c3a0ccd60017ac76b5d2e7d1f71376b94 (diff) | |
parent | c8205636029fc869278c55b7336053b3e7ae3ef4 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: fix data corruption regression by reverting commit 6de9843dab3f
ext4: Allow indirect-block file to grow the file size to max file size
ext4: allow an active handle to be started when freezing
ext4: sync the directory inode in ext4_sync_parent()
ext4: init timer earlier to avoid a kernel panic in __save_error_info
jbd2: fix potential memory leak on transaction commit
ext4: fix a double free in ext4_register_li_request
ext4: fix credits computing for indirect mapped files
ext4: remove unnecessary [cm]time update of quota file
jbd2: move bdget out of critical section
Diffstat (limited to 'fs/ext4/fsync.c')
-rw-r--r-- | fs/ext4/fsync.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 4673bc05274f..e9473cbe80df 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c | |||
@@ -125,9 +125,11 @@ extern int ext4_flush_completed_IO(struct inode *inode) | |||
125 | * the parent directory's parent as well, and so on recursively, if | 125 | * the parent directory's parent as well, and so on recursively, if |
126 | * they are also freshly created. | 126 | * they are also freshly created. |
127 | */ | 127 | */ |
128 | static void ext4_sync_parent(struct inode *inode) | 128 | static int ext4_sync_parent(struct inode *inode) |
129 | { | 129 | { |
130 | struct writeback_control wbc; | ||
130 | struct dentry *dentry = NULL; | 131 | struct dentry *dentry = NULL; |
132 | int ret = 0; | ||
131 | 133 | ||
132 | while (inode && ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) { | 134 | while (inode && ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) { |
133 | ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY); | 135 | ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY); |
@@ -136,8 +138,17 @@ static void ext4_sync_parent(struct inode *inode) | |||
136 | if (!dentry || !dentry->d_parent || !dentry->d_parent->d_inode) | 138 | if (!dentry || !dentry->d_parent || !dentry->d_parent->d_inode) |
137 | break; | 139 | break; |
138 | inode = dentry->d_parent->d_inode; | 140 | inode = dentry->d_parent->d_inode; |
139 | sync_mapping_buffers(inode->i_mapping); | 141 | ret = sync_mapping_buffers(inode->i_mapping); |
142 | if (ret) | ||
143 | break; | ||
144 | memset(&wbc, 0, sizeof(wbc)); | ||
145 | wbc.sync_mode = WB_SYNC_ALL; | ||
146 | wbc.nr_to_write = 0; /* only write out the inode */ | ||
147 | ret = sync_inode(inode, &wbc); | ||
148 | if (ret) | ||
149 | break; | ||
140 | } | 150 | } |
151 | return ret; | ||
141 | } | 152 | } |
142 | 153 | ||
143 | /* | 154 | /* |
@@ -176,7 +187,7 @@ int ext4_sync_file(struct file *file, int datasync) | |||
176 | if (!journal) { | 187 | if (!journal) { |
177 | ret = generic_file_fsync(file, datasync); | 188 | ret = generic_file_fsync(file, datasync); |
178 | if (!ret && !list_empty(&inode->i_dentry)) | 189 | if (!ret && !list_empty(&inode->i_dentry)) |
179 | ext4_sync_parent(inode); | 190 | ret = ext4_sync_parent(inode); |
180 | goto out; | 191 | goto out; |
181 | } | 192 | } |
182 | 193 | ||