diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-09-25 14:55:53 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-09-30 18:34:55 -0400 |
commit | 44c16156512f33c81e382a1e1df9524e26a7026a (patch) | |
tree | b06e5aba8d4a5419c1a11a6d0da00450c8e2d766 /fs | |
parent | 7cd8558baa4e4588a80ecb31cb30784195763cdd (diff) |
f2fs: call f2fs_unlock_op after error was handled
This patch relocates f2fs_unlock_op in every directory operations to be called
after any error was processed.
Otherwise, the checkpoint can be entered with valid node ids without its
dentry when -ENOSPC is occurred.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/f2fs/f2fs.h | 1 | ||||
-rw-r--r-- | fs/f2fs/inode.c | 23 | ||||
-rw-r--r-- | fs/f2fs/namei.c | 32 |
3 files changed, 35 insertions, 21 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 94cfdc4d0c00..a397f7ac9945 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -1194,6 +1194,7 @@ void update_inode(struct inode *, struct page *); | |||
1194 | void update_inode_page(struct inode *); | 1194 | void update_inode_page(struct inode *); |
1195 | int f2fs_write_inode(struct inode *, struct writeback_control *); | 1195 | int f2fs_write_inode(struct inode *, struct writeback_control *); |
1196 | void f2fs_evict_inode(struct inode *); | 1196 | void f2fs_evict_inode(struct inode *); |
1197 | void handle_failed_inode(struct inode *); | ||
1197 | 1198 | ||
1198 | /* | 1199 | /* |
1199 | * namei.c | 1200 | * namei.c |
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index ff95547cfc3d..63923eef1ffe 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c | |||
@@ -306,3 +306,26 @@ no_delete: | |||
306 | out_clear: | 306 | out_clear: |
307 | clear_inode(inode); | 307 | clear_inode(inode); |
308 | } | 308 | } |
309 | |||
310 | /* caller should call f2fs_lock_op() */ | ||
311 | void handle_failed_inode(struct inode *inode) | ||
312 | { | ||
313 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | ||
314 | |||
315 | clear_nlink(inode); | ||
316 | make_bad_inode(inode); | ||
317 | unlock_new_inode(inode); | ||
318 | |||
319 | i_size_write(inode, 0); | ||
320 | if (F2FS_HAS_BLOCKS(inode)) | ||
321 | f2fs_truncate(inode); | ||
322 | |||
323 | remove_inode_page(inode); | ||
324 | stat_dec_inline_inode(inode); | ||
325 | |||
326 | alloc_nid_failed(sbi, inode->i_ino); | ||
327 | f2fs_unlock_op(sbi); | ||
328 | |||
329 | /* iput will drop the inode object */ | ||
330 | iput(inode); | ||
331 | } | ||
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index ba0779d4cfd7..0d2526e5aa11 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -123,9 +123,9 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
123 | 123 | ||
124 | f2fs_lock_op(sbi); | 124 | f2fs_lock_op(sbi); |
125 | err = f2fs_add_link(dentry, inode); | 125 | err = f2fs_add_link(dentry, inode); |
126 | f2fs_unlock_op(sbi); | ||
127 | if (err) | 126 | if (err) |
128 | goto out; | 127 | goto out; |
128 | f2fs_unlock_op(sbi); | ||
129 | 129 | ||
130 | alloc_nid_done(sbi, ino); | 130 | alloc_nid_done(sbi, ino); |
131 | 131 | ||
@@ -133,9 +133,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
133 | unlock_new_inode(inode); | 133 | unlock_new_inode(inode); |
134 | return 0; | 134 | return 0; |
135 | out: | 135 | out: |
136 | clear_nlink(inode); | 136 | handle_failed_inode(inode); |
137 | iget_failed(inode); | ||
138 | alloc_nid_failed(sbi, ino); | ||
139 | return err; | 137 | return err; |
140 | } | 138 | } |
141 | 139 | ||
@@ -154,15 +152,16 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, | |||
154 | set_inode_flag(F2FS_I(inode), FI_INC_LINK); | 152 | set_inode_flag(F2FS_I(inode), FI_INC_LINK); |
155 | f2fs_lock_op(sbi); | 153 | f2fs_lock_op(sbi); |
156 | err = f2fs_add_link(dentry, inode); | 154 | err = f2fs_add_link(dentry, inode); |
157 | f2fs_unlock_op(sbi); | ||
158 | if (err) | 155 | if (err) |
159 | goto out; | 156 | goto out; |
157 | f2fs_unlock_op(sbi); | ||
160 | 158 | ||
161 | d_instantiate(dentry, inode); | 159 | d_instantiate(dentry, inode); |
162 | return 0; | 160 | return 0; |
163 | out: | 161 | out: |
164 | clear_inode_flag(F2FS_I(inode), FI_INC_LINK); | 162 | clear_inode_flag(F2FS_I(inode), FI_INC_LINK); |
165 | iput(inode); | 163 | iput(inode); |
164 | f2fs_unlock_op(sbi); | ||
166 | return err; | 165 | return err; |
167 | } | 166 | } |
168 | 167 | ||
@@ -253,9 +252,9 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, | |||
253 | 252 | ||
254 | f2fs_lock_op(sbi); | 253 | f2fs_lock_op(sbi); |
255 | err = f2fs_add_link(dentry, inode); | 254 | err = f2fs_add_link(dentry, inode); |
256 | f2fs_unlock_op(sbi); | ||
257 | if (err) | 255 | if (err) |
258 | goto out; | 256 | goto out; |
257 | f2fs_unlock_op(sbi); | ||
259 | 258 | ||
260 | err = page_symlink(inode, symname, symlen); | 259 | err = page_symlink(inode, symname, symlen); |
261 | alloc_nid_done(sbi, inode->i_ino); | 260 | alloc_nid_done(sbi, inode->i_ino); |
@@ -264,9 +263,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, | |||
264 | unlock_new_inode(inode); | 263 | unlock_new_inode(inode); |
265 | return err; | 264 | return err; |
266 | out: | 265 | out: |
267 | clear_nlink(inode); | 266 | handle_failed_inode(inode); |
268 | iget_failed(inode); | ||
269 | alloc_nid_failed(sbi, inode->i_ino); | ||
270 | return err; | 267 | return err; |
271 | } | 268 | } |
272 | 269 | ||
@@ -290,9 +287,9 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
290 | set_inode_flag(F2FS_I(inode), FI_INC_LINK); | 287 | set_inode_flag(F2FS_I(inode), FI_INC_LINK); |
291 | f2fs_lock_op(sbi); | 288 | f2fs_lock_op(sbi); |
292 | err = f2fs_add_link(dentry, inode); | 289 | err = f2fs_add_link(dentry, inode); |
293 | f2fs_unlock_op(sbi); | ||
294 | if (err) | 290 | if (err) |
295 | goto out_fail; | 291 | goto out_fail; |
292 | f2fs_unlock_op(sbi); | ||
296 | 293 | ||
297 | alloc_nid_done(sbi, inode->i_ino); | 294 | alloc_nid_done(sbi, inode->i_ino); |
298 | 295 | ||
@@ -303,9 +300,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
303 | 300 | ||
304 | out_fail: | 301 | out_fail: |
305 | clear_inode_flag(F2FS_I(inode), FI_INC_LINK); | 302 | clear_inode_flag(F2FS_I(inode), FI_INC_LINK); |
306 | clear_nlink(inode); | 303 | handle_failed_inode(inode); |
307 | iget_failed(inode); | ||
308 | alloc_nid_failed(sbi, inode->i_ino); | ||
309 | return err; | 304 | return err; |
310 | } | 305 | } |
311 | 306 | ||
@@ -338,18 +333,16 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, | |||
338 | 333 | ||
339 | f2fs_lock_op(sbi); | 334 | f2fs_lock_op(sbi); |
340 | err = f2fs_add_link(dentry, inode); | 335 | err = f2fs_add_link(dentry, inode); |
341 | f2fs_unlock_op(sbi); | ||
342 | if (err) | 336 | if (err) |
343 | goto out; | 337 | goto out; |
338 | f2fs_unlock_op(sbi); | ||
344 | 339 | ||
345 | alloc_nid_done(sbi, inode->i_ino); | 340 | alloc_nid_done(sbi, inode->i_ino); |
346 | d_instantiate(dentry, inode); | 341 | d_instantiate(dentry, inode); |
347 | unlock_new_inode(inode); | 342 | unlock_new_inode(inode); |
348 | return 0; | 343 | return 0; |
349 | out: | 344 | out: |
350 | clear_nlink(inode); | 345 | handle_failed_inode(inode); |
351 | iget_failed(inode); | ||
352 | alloc_nid_failed(sbi, inode->i_ino); | ||
353 | return err; | 346 | return err; |
354 | } | 347 | } |
355 | 348 | ||
@@ -677,10 +670,7 @@ static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
677 | release_out: | 670 | release_out: |
678 | release_orphan_inode(sbi); | 671 | release_orphan_inode(sbi); |
679 | out: | 672 | out: |
680 | f2fs_unlock_op(sbi); | 673 | handle_failed_inode(inode); |
681 | clear_nlink(inode); | ||
682 | iget_failed(inode); | ||
683 | alloc_nid_failed(sbi, inode->i_ino); | ||
684 | return err; | 674 | return err; |
685 | } | 675 | } |
686 | 676 | ||