diff options
Diffstat (limited to 'fs/f2fs/dir.c')
-rw-r--r-- | fs/f2fs/dir.c | 85 |
1 files changed, 45 insertions, 40 deletions
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 7db6e58622d9..fc1dacf55b3a 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
@@ -264,15 +264,10 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, | |||
264 | f2fs_put_page(page, 1); | 264 | f2fs_put_page(page, 1); |
265 | } | 265 | } |
266 | 266 | ||
267 | void init_dent_inode(const struct qstr *name, struct page *ipage) | 267 | static void init_dent_inode(const struct qstr *name, struct page *ipage) |
268 | { | 268 | { |
269 | struct f2fs_node *rn; | 269 | struct f2fs_node *rn; |
270 | 270 | ||
271 | if (IS_ERR(ipage)) | ||
272 | return; | ||
273 | |||
274 | wait_on_page_writeback(ipage); | ||
275 | |||
276 | /* copy name info. to this inode page */ | 271 | /* copy name info. to this inode page */ |
277 | rn = (struct f2fs_node *)page_address(ipage); | 272 | rn = (struct f2fs_node *)page_address(ipage); |
278 | rn->i.i_namelen = cpu_to_le32(name->len); | 273 | rn->i.i_namelen = cpu_to_le32(name->len); |
@@ -280,14 +275,15 @@ void init_dent_inode(const struct qstr *name, struct page *ipage) | |||
280 | set_page_dirty(ipage); | 275 | set_page_dirty(ipage); |
281 | } | 276 | } |
282 | 277 | ||
283 | static int make_empty_dir(struct inode *inode, struct inode *parent) | 278 | static int make_empty_dir(struct inode *inode, |
279 | struct inode *parent, struct page *page) | ||
284 | { | 280 | { |
285 | struct page *dentry_page; | 281 | struct page *dentry_page; |
286 | struct f2fs_dentry_block *dentry_blk; | 282 | struct f2fs_dentry_block *dentry_blk; |
287 | struct f2fs_dir_entry *de; | 283 | struct f2fs_dir_entry *de; |
288 | void *kaddr; | 284 | void *kaddr; |
289 | 285 | ||
290 | dentry_page = get_new_data_page(inode, NULL, 0, true); | 286 | dentry_page = get_new_data_page(inode, page, 0, true); |
291 | if (IS_ERR(dentry_page)) | 287 | if (IS_ERR(dentry_page)) |
292 | return PTR_ERR(dentry_page); | 288 | return PTR_ERR(dentry_page); |
293 | 289 | ||
@@ -317,42 +313,47 @@ static int make_empty_dir(struct inode *inode, struct inode *parent) | |||
317 | return 0; | 313 | return 0; |
318 | } | 314 | } |
319 | 315 | ||
320 | static int init_inode_metadata(struct inode *inode, | 316 | static struct page *init_inode_metadata(struct inode *inode, |
321 | struct inode *dir, const struct qstr *name) | 317 | struct inode *dir, const struct qstr *name) |
322 | { | 318 | { |
319 | struct page *page; | ||
320 | int err; | ||
321 | |||
323 | if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { | 322 | if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { |
324 | int err; | 323 | page = new_inode_page(inode, name); |
325 | err = new_inode_page(inode, name); | 324 | if (IS_ERR(page)) |
326 | if (err) | 325 | return page; |
327 | return err; | ||
328 | 326 | ||
329 | if (S_ISDIR(inode->i_mode)) { | 327 | if (S_ISDIR(inode->i_mode)) { |
330 | err = make_empty_dir(inode, dir); | 328 | err = make_empty_dir(inode, dir, page); |
331 | if (err) { | 329 | if (err) |
332 | remove_inode_page(inode); | 330 | goto error; |
333 | return err; | ||
334 | } | ||
335 | } | 331 | } |
336 | 332 | ||
337 | err = f2fs_init_acl(inode, dir); | 333 | err = f2fs_init_acl(inode, dir); |
338 | if (err) { | 334 | if (err) |
339 | remove_inode_page(inode); | 335 | goto error; |
340 | return err; | 336 | |
341 | } | 337 | wait_on_page_writeback(page); |
342 | } else { | 338 | } else { |
343 | struct page *ipage; | 339 | page = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino); |
344 | ipage = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino); | 340 | if (IS_ERR(page)) |
345 | if (IS_ERR(ipage)) | 341 | return page; |
346 | return PTR_ERR(ipage); | 342 | |
347 | set_cold_node(inode, ipage); | 343 | wait_on_page_writeback(page); |
348 | init_dent_inode(name, ipage); | 344 | set_cold_node(inode, page); |
349 | f2fs_put_page(ipage, 1); | ||
350 | } | 345 | } |
351 | if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) { | 346 | |
347 | init_dent_inode(name, page); | ||
348 | |||
349 | if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) | ||
352 | inc_nlink(inode); | 350 | inc_nlink(inode); |
353 | update_inode_page(inode); | 351 | return page; |
354 | } | 352 | |
355 | return 0; | 353 | error: |
354 | f2fs_put_page(page, 1); | ||
355 | remove_inode_page(inode); | ||
356 | return ERR_PTR(err); | ||
356 | } | 357 | } |
357 | 358 | ||
358 | static void update_parent_metadata(struct inode *dir, struct inode *inode, | 359 | static void update_parent_metadata(struct inode *dir, struct inode *inode, |
@@ -423,6 +424,7 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *in | |||
423 | struct page *dentry_page = NULL; | 424 | struct page *dentry_page = NULL; |
424 | struct f2fs_dentry_block *dentry_blk = NULL; | 425 | struct f2fs_dentry_block *dentry_blk = NULL; |
425 | int slots = GET_DENTRY_SLOTS(namelen); | 426 | int slots = GET_DENTRY_SLOTS(namelen); |
427 | struct page *page; | ||
426 | int err = 0; | 428 | int err = 0; |
427 | int i; | 429 | int i; |
428 | 430 | ||
@@ -465,12 +467,13 @@ start: | |||
465 | ++level; | 467 | ++level; |
466 | goto start; | 468 | goto start; |
467 | add_dentry: | 469 | add_dentry: |
468 | err = init_inode_metadata(inode, dir, name); | ||
469 | if (err) | ||
470 | goto fail; | ||
471 | |||
472 | wait_on_page_writeback(dentry_page); | 470 | wait_on_page_writeback(dentry_page); |
473 | 471 | ||
472 | page = init_inode_metadata(inode, dir, name); | ||
473 | if (IS_ERR(page)) { | ||
474 | err = PTR_ERR(page); | ||
475 | goto fail; | ||
476 | } | ||
474 | de = &dentry_blk->dentry[bit_pos]; | 477 | de = &dentry_blk->dentry[bit_pos]; |
475 | de->hash_code = dentry_hash; | 478 | de->hash_code = dentry_hash; |
476 | de->name_len = cpu_to_le16(namelen); | 479 | de->name_len = cpu_to_le16(namelen); |
@@ -481,10 +484,12 @@ add_dentry: | |||
481 | test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); | 484 | test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); |
482 | set_page_dirty(dentry_page); | 485 | set_page_dirty(dentry_page); |
483 | 486 | ||
484 | update_parent_metadata(dir, inode, current_depth); | 487 | /* we don't need to mark_inode_dirty now */ |
485 | |||
486 | /* update parent inode number before releasing dentry page */ | ||
487 | F2FS_I(inode)->i_pino = dir->i_ino; | 488 | F2FS_I(inode)->i_pino = dir->i_ino; |
489 | update_inode(inode, page); | ||
490 | f2fs_put_page(page, 1); | ||
491 | |||
492 | update_parent_metadata(dir, inode, current_depth); | ||
488 | fail: | 493 | fail: |
489 | kunmap(dentry_page); | 494 | kunmap(dentry_page); |
490 | f2fs_put_page(dentry_page, 1); | 495 | f2fs_put_page(dentry_page, 1); |