diff options
Diffstat (limited to 'fs/f2fs/dir.c')
-rw-r--r-- | fs/f2fs/dir.c | 105 |
1 files changed, 48 insertions, 57 deletions
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 2851ae6948a1..cd3342d4a3a7 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
@@ -249,9 +249,6 @@ ino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr) | |||
249 | void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, | 249 | void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, |
250 | struct page *page, struct inode *inode) | 250 | struct page *page, struct inode *inode) |
251 | { | 251 | { |
252 | struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); | ||
253 | |||
254 | mutex_lock_op(sbi, DENTRY_OPS); | ||
255 | lock_page(page); | 252 | lock_page(page); |
256 | wait_on_page_writeback(page); | 253 | wait_on_page_writeback(page); |
257 | de->ino = cpu_to_le32(inode->i_ino); | 254 | de->ino = cpu_to_le32(inode->i_ino); |
@@ -265,7 +262,6 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, | |||
265 | F2FS_I(inode)->i_pino = dir->i_ino; | 262 | F2FS_I(inode)->i_pino = dir->i_ino; |
266 | 263 | ||
267 | f2fs_put_page(page, 1); | 264 | f2fs_put_page(page, 1); |
268 | mutex_unlock_op(sbi, DENTRY_OPS); | ||
269 | } | 265 | } |
270 | 266 | ||
271 | void init_dent_inode(const struct qstr *name, struct page *ipage) | 267 | void init_dent_inode(const struct qstr *name, struct page *ipage) |
@@ -284,6 +280,43 @@ void init_dent_inode(const struct qstr *name, struct page *ipage) | |||
284 | set_page_dirty(ipage); | 280 | set_page_dirty(ipage); |
285 | } | 281 | } |
286 | 282 | ||
283 | static int make_empty_dir(struct inode *inode, struct inode *parent) | ||
284 | { | ||
285 | struct page *dentry_page; | ||
286 | struct f2fs_dentry_block *dentry_blk; | ||
287 | struct f2fs_dir_entry *de; | ||
288 | void *kaddr; | ||
289 | |||
290 | dentry_page = get_new_data_page(inode, 0, true); | ||
291 | if (IS_ERR(dentry_page)) | ||
292 | return PTR_ERR(dentry_page); | ||
293 | |||
294 | kaddr = kmap_atomic(dentry_page); | ||
295 | dentry_blk = (struct f2fs_dentry_block *)kaddr; | ||
296 | |||
297 | de = &dentry_blk->dentry[0]; | ||
298 | de->name_len = cpu_to_le16(1); | ||
299 | de->hash_code = 0; | ||
300 | de->ino = cpu_to_le32(inode->i_ino); | ||
301 | memcpy(dentry_blk->filename[0], ".", 1); | ||
302 | set_de_type(de, inode); | ||
303 | |||
304 | de = &dentry_blk->dentry[1]; | ||
305 | de->hash_code = 0; | ||
306 | de->name_len = cpu_to_le16(2); | ||
307 | de->ino = cpu_to_le32(parent->i_ino); | ||
308 | memcpy(dentry_blk->filename[1], "..", 2); | ||
309 | set_de_type(de, inode); | ||
310 | |||
311 | test_and_set_bit_le(0, &dentry_blk->dentry_bitmap); | ||
312 | test_and_set_bit_le(1, &dentry_blk->dentry_bitmap); | ||
313 | kunmap_atomic(kaddr); | ||
314 | |||
315 | set_page_dirty(dentry_page); | ||
316 | f2fs_put_page(dentry_page, 1); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
287 | static int init_inode_metadata(struct inode *inode, | 320 | static int init_inode_metadata(struct inode *inode, |
288 | struct inode *dir, const struct qstr *name) | 321 | struct inode *dir, const struct qstr *name) |
289 | { | 322 | { |
@@ -294,7 +327,7 @@ static int init_inode_metadata(struct inode *inode, | |||
294 | return err; | 327 | return err; |
295 | 328 | ||
296 | if (S_ISDIR(inode->i_mode)) { | 329 | if (S_ISDIR(inode->i_mode)) { |
297 | err = f2fs_make_empty(inode, dir); | 330 | err = make_empty_dir(inode, dir); |
298 | if (err) { | 331 | if (err) { |
299 | remove_inode_page(inode); | 332 | remove_inode_page(inode); |
300 | return err; | 333 | return err; |
@@ -317,7 +350,7 @@ static int init_inode_metadata(struct inode *inode, | |||
317 | } | 350 | } |
318 | if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) { | 351 | if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) { |
319 | inc_nlink(inode); | 352 | inc_nlink(inode); |
320 | f2fs_write_inode(inode, NULL); | 353 | update_inode_page(inode); |
321 | } | 354 | } |
322 | return 0; | 355 | return 0; |
323 | } | 356 | } |
@@ -341,7 +374,7 @@ static void update_parent_metadata(struct inode *dir, struct inode *inode, | |||
341 | } | 374 | } |
342 | 375 | ||
343 | if (need_dir_update) | 376 | if (need_dir_update) |
344 | f2fs_write_inode(dir, NULL); | 377 | update_inode_page(dir); |
345 | else | 378 | else |
346 | mark_inode_dirty(dir); | 379 | mark_inode_dirty(dir); |
347 | 380 | ||
@@ -373,6 +406,10 @@ next: | |||
373 | goto next; | 406 | goto next; |
374 | } | 407 | } |
375 | 408 | ||
409 | /* | ||
410 | * Caller should grab and release a mutex by calling mutex_lock_op() and | ||
411 | * mutex_unlock_op(). | ||
412 | */ | ||
376 | int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *inode) | 413 | int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *inode) |
377 | { | 414 | { |
378 | unsigned int bit_pos; | 415 | unsigned int bit_pos; |
@@ -382,7 +419,6 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *in | |||
382 | f2fs_hash_t dentry_hash; | 419 | f2fs_hash_t dentry_hash; |
383 | struct f2fs_dir_entry *de; | 420 | struct f2fs_dir_entry *de; |
384 | unsigned int nbucket, nblock; | 421 | unsigned int nbucket, nblock; |
385 | struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); | ||
386 | size_t namelen = name->len; | 422 | size_t namelen = name->len; |
387 | struct page *dentry_page = NULL; | 423 | struct page *dentry_page = NULL; |
388 | struct f2fs_dentry_block *dentry_blk = NULL; | 424 | struct f2fs_dentry_block *dentry_blk = NULL; |
@@ -412,12 +448,9 @@ start: | |||
412 | bidx = dir_block_index(level, (le32_to_cpu(dentry_hash) % nbucket)); | 448 | bidx = dir_block_index(level, (le32_to_cpu(dentry_hash) % nbucket)); |
413 | 449 | ||
414 | for (block = bidx; block <= (bidx + nblock - 1); block++) { | 450 | for (block = bidx; block <= (bidx + nblock - 1); block++) { |
415 | mutex_lock_op(sbi, DENTRY_OPS); | ||
416 | dentry_page = get_new_data_page(dir, block, true); | 451 | dentry_page = get_new_data_page(dir, block, true); |
417 | if (IS_ERR(dentry_page)) { | 452 | if (IS_ERR(dentry_page)) |
418 | mutex_unlock_op(sbi, DENTRY_OPS); | ||
419 | return PTR_ERR(dentry_page); | 453 | return PTR_ERR(dentry_page); |
420 | } | ||
421 | 454 | ||
422 | dentry_blk = kmap(dentry_page); | 455 | dentry_blk = kmap(dentry_page); |
423 | bit_pos = room_for_filename(dentry_blk, slots); | 456 | bit_pos = room_for_filename(dentry_blk, slots); |
@@ -426,7 +459,6 @@ start: | |||
426 | 459 | ||
427 | kunmap(dentry_page); | 460 | kunmap(dentry_page); |
428 | f2fs_put_page(dentry_page, 1); | 461 | f2fs_put_page(dentry_page, 1); |
429 | mutex_unlock_op(sbi, DENTRY_OPS); | ||
430 | } | 462 | } |
431 | 463 | ||
432 | /* Move to next level to find the empty slot for new dentry */ | 464 | /* Move to next level to find the empty slot for new dentry */ |
@@ -456,7 +488,6 @@ add_dentry: | |||
456 | fail: | 488 | fail: |
457 | kunmap(dentry_page); | 489 | kunmap(dentry_page); |
458 | f2fs_put_page(dentry_page, 1); | 490 | f2fs_put_page(dentry_page, 1); |
459 | mutex_unlock_op(sbi, DENTRY_OPS); | ||
460 | return err; | 491 | return err; |
461 | } | 492 | } |
462 | 493 | ||
@@ -476,8 +507,6 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, | |||
476 | void *kaddr = page_address(page); | 507 | void *kaddr = page_address(page); |
477 | int i; | 508 | int i; |
478 | 509 | ||
479 | mutex_lock_op(sbi, DENTRY_OPS); | ||
480 | |||
481 | lock_page(page); | 510 | lock_page(page); |
482 | wait_on_page_writeback(page); | 511 | wait_on_page_writeback(page); |
483 | 512 | ||
@@ -497,7 +526,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, | |||
497 | 526 | ||
498 | if (inode && S_ISDIR(inode->i_mode)) { | 527 | if (inode && S_ISDIR(inode->i_mode)) { |
499 | drop_nlink(dir); | 528 | drop_nlink(dir); |
500 | f2fs_write_inode(dir, NULL); | 529 | update_inode_page(dir); |
501 | } else { | 530 | } else { |
502 | mark_inode_dirty(dir); | 531 | mark_inode_dirty(dir); |
503 | } | 532 | } |
@@ -509,7 +538,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, | |||
509 | drop_nlink(inode); | 538 | drop_nlink(inode); |
510 | i_size_write(inode, 0); | 539 | i_size_write(inode, 0); |
511 | } | 540 | } |
512 | f2fs_write_inode(inode, NULL); | 541 | update_inode_page(inode); |
542 | |||
513 | if (inode->i_nlink == 0) | 543 | if (inode->i_nlink == 0) |
514 | add_orphan_inode(sbi, inode->i_ino); | 544 | add_orphan_inode(sbi, inode->i_ino); |
515 | } | 545 | } |
@@ -522,45 +552,6 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, | |||
522 | inode_dec_dirty_dents(dir); | 552 | inode_dec_dirty_dents(dir); |
523 | } | 553 | } |
524 | f2fs_put_page(page, 1); | 554 | f2fs_put_page(page, 1); |
525 | |||
526 | mutex_unlock_op(sbi, DENTRY_OPS); | ||
527 | } | ||
528 | |||
529 | int f2fs_make_empty(struct inode *inode, struct inode *parent) | ||
530 | { | ||
531 | struct page *dentry_page; | ||
532 | struct f2fs_dentry_block *dentry_blk; | ||
533 | struct f2fs_dir_entry *de; | ||
534 | void *kaddr; | ||
535 | |||
536 | dentry_page = get_new_data_page(inode, 0, true); | ||
537 | if (IS_ERR(dentry_page)) | ||
538 | return PTR_ERR(dentry_page); | ||
539 | |||
540 | kaddr = kmap_atomic(dentry_page); | ||
541 | dentry_blk = (struct f2fs_dentry_block *)kaddr; | ||
542 | |||
543 | de = &dentry_blk->dentry[0]; | ||
544 | de->name_len = cpu_to_le16(1); | ||
545 | de->hash_code = f2fs_dentry_hash(".", 1); | ||
546 | de->ino = cpu_to_le32(inode->i_ino); | ||
547 | memcpy(dentry_blk->filename[0], ".", 1); | ||
548 | set_de_type(de, inode); | ||
549 | |||
550 | de = &dentry_blk->dentry[1]; | ||
551 | de->hash_code = f2fs_dentry_hash("..", 2); | ||
552 | de->name_len = cpu_to_le16(2); | ||
553 | de->ino = cpu_to_le32(parent->i_ino); | ||
554 | memcpy(dentry_blk->filename[1], "..", 2); | ||
555 | set_de_type(de, inode); | ||
556 | |||
557 | test_and_set_bit_le(0, &dentry_blk->dentry_bitmap); | ||
558 | test_and_set_bit_le(1, &dentry_blk->dentry_bitmap); | ||
559 | kunmap_atomic(kaddr); | ||
560 | |||
561 | set_page_dirty(dentry_page); | ||
562 | f2fs_put_page(dentry_page, 1); | ||
563 | return 0; | ||
564 | } | 555 | } |
565 | 556 | ||
566 | bool f2fs_empty_dir(struct inode *dir) | 557 | bool f2fs_empty_dir(struct inode *dir) |