aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r--fs/ext4/namei.c131
1 files changed, 76 insertions, 55 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 1cb84f78909e..3520ab8a6639 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -67,6 +67,7 @@ static struct buffer_head *ext4_append(handle_t *handle,
67 return ERR_PTR(err); 67 return ERR_PTR(err);
68 inode->i_size += inode->i_sb->s_blocksize; 68 inode->i_size += inode->i_sb->s_blocksize;
69 EXT4_I(inode)->i_disksize = inode->i_size; 69 EXT4_I(inode)->i_disksize = inode->i_size;
70 BUFFER_TRACE(bh, "get_write_access");
70 err = ext4_journal_get_write_access(handle, bh); 71 err = ext4_journal_get_write_access(handle, bh);
71 if (err) { 72 if (err) {
72 brelse(bh); 73 brelse(bh);
@@ -1778,6 +1779,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
1778 1779
1779 blocksize = dir->i_sb->s_blocksize; 1780 blocksize = dir->i_sb->s_blocksize;
1780 dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino)); 1781 dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino));
1782 BUFFER_TRACE(bh, "get_write_access");
1781 retval = ext4_journal_get_write_access(handle, bh); 1783 retval = ext4_journal_get_write_access(handle, bh);
1782 if (retval) { 1784 if (retval) {
1783 ext4_std_error(dir->i_sb, retval); 1785 ext4_std_error(dir->i_sb, retval);
@@ -2510,8 +2512,7 @@ static int empty_dir(struct inode *inode)
2510 ext4_rec_len_from_disk(de1->rec_len, sb->s_blocksize); 2512 ext4_rec_len_from_disk(de1->rec_len, sb->s_blocksize);
2511 de = ext4_next_entry(de1, sb->s_blocksize); 2513 de = ext4_next_entry(de1, sb->s_blocksize);
2512 while (offset < inode->i_size) { 2514 while (offset < inode->i_size) {
2513 if (!bh || 2515 if ((void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
2514 (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
2515 unsigned int lblock; 2516 unsigned int lblock;
2516 err = 0; 2517 err = 0;
2517 brelse(bh); 2518 brelse(bh);
@@ -2539,26 +2540,37 @@ static int empty_dir(struct inode *inode)
2539 return 1; 2540 return 1;
2540} 2541}
2541 2542
2542/* ext4_orphan_add() links an unlinked or truncated inode into a list of 2543/*
2544 * ext4_orphan_add() links an unlinked or truncated inode into a list of
2543 * such inodes, starting at the superblock, in case we crash before the 2545 * such inodes, starting at the superblock, in case we crash before the
2544 * file is closed/deleted, or in case the inode truncate spans multiple 2546 * file is closed/deleted, or in case the inode truncate spans multiple
2545 * transactions and the last transaction is not recovered after a crash. 2547 * transactions and the last transaction is not recovered after a crash.
2546 * 2548 *
2547 * At filesystem recovery time, we walk this list deleting unlinked 2549 * At filesystem recovery time, we walk this list deleting unlinked
2548 * inodes and truncating linked inodes in ext4_orphan_cleanup(). 2550 * inodes and truncating linked inodes in ext4_orphan_cleanup().
2551 *
2552 * Orphan list manipulation functions must be called under i_mutex unless
2553 * we are just creating the inode or deleting it.
2549 */ 2554 */
2550int ext4_orphan_add(handle_t *handle, struct inode *inode) 2555int ext4_orphan_add(handle_t *handle, struct inode *inode)
2551{ 2556{
2552 struct super_block *sb = inode->i_sb; 2557 struct super_block *sb = inode->i_sb;
2558 struct ext4_sb_info *sbi = EXT4_SB(sb);
2553 struct ext4_iloc iloc; 2559 struct ext4_iloc iloc;
2554 int err = 0, rc; 2560 int err = 0, rc;
2561 bool dirty = false;
2555 2562
2556 if (!EXT4_SB(sb)->s_journal) 2563 if (!sbi->s_journal)
2557 return 0; 2564 return 0;
2558 2565
2559 mutex_lock(&EXT4_SB(sb)->s_orphan_lock); 2566 WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) &&
2567 !mutex_is_locked(&inode->i_mutex));
2568 /*
2569 * Exit early if inode already is on orphan list. This is a big speedup
2570 * since we don't have to contend on the global s_orphan_lock.
2571 */
2560 if (!list_empty(&EXT4_I(inode)->i_orphan)) 2572 if (!list_empty(&EXT4_I(inode)->i_orphan))
2561 goto out_unlock; 2573 return 0;
2562 2574
2563 /* 2575 /*
2564 * Orphan handling is only valid for files with data blocks 2576 * Orphan handling is only valid for files with data blocks
@@ -2569,48 +2581,51 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
2569 J_ASSERT((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || 2581 J_ASSERT((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
2570 S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); 2582 S_ISLNK(inode->i_mode)) || inode->i_nlink == 0);
2571 2583
2572 BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access"); 2584 BUFFER_TRACE(sbi->s_sbh, "get_write_access");
2573 err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh); 2585 err = ext4_journal_get_write_access(handle, sbi->s_sbh);
2574 if (err) 2586 if (err)
2575 goto out_unlock; 2587 goto out;
2576 2588
2577 err = ext4_reserve_inode_write(handle, inode, &iloc); 2589 err = ext4_reserve_inode_write(handle, inode, &iloc);
2578 if (err) 2590 if (err)
2579 goto out_unlock; 2591 goto out;
2592
2593 mutex_lock(&sbi->s_orphan_lock);
2580 /* 2594 /*
2581 * Due to previous errors inode may be already a part of on-disk 2595 * Due to previous errors inode may be already a part of on-disk
2582 * orphan list. If so skip on-disk list modification. 2596 * orphan list. If so skip on-disk list modification.
2583 */ 2597 */
2584 if (NEXT_ORPHAN(inode) && NEXT_ORPHAN(inode) <= 2598 if (!NEXT_ORPHAN(inode) || NEXT_ORPHAN(inode) >
2585 (le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) 2599 (le32_to_cpu(sbi->s_es->s_inodes_count))) {
2586 goto mem_insert; 2600 /* Insert this inode at the head of the on-disk orphan list */
2587 2601 NEXT_ORPHAN(inode) = le32_to_cpu(sbi->s_es->s_last_orphan);
2588 /* Insert this inode at the head of the on-disk orphan list... */ 2602 sbi->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
2589 NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan); 2603 dirty = true;
2590 EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino); 2604 }
2591 err = ext4_handle_dirty_super(handle, sb); 2605 list_add(&EXT4_I(inode)->i_orphan, &sbi->s_orphan);
2592 rc = ext4_mark_iloc_dirty(handle, inode, &iloc); 2606 mutex_unlock(&sbi->s_orphan_lock);
2593 if (!err) 2607
2594 err = rc; 2608 if (dirty) {
2595 2609 err = ext4_handle_dirty_super(handle, sb);
2596 /* Only add to the head of the in-memory list if all the 2610 rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
2597 * previous operations succeeded. If the orphan_add is going to 2611 if (!err)
2598 * fail (possibly taking the journal offline), we can't risk 2612 err = rc;
2599 * leaving the inode on the orphan list: stray orphan-list 2613 if (err) {
2600 * entries can cause panics at unmount time. 2614 /*
2601 * 2615 * We have to remove inode from in-memory list if
2602 * This is safe: on error we're going to ignore the orphan list 2616 * addition to on disk orphan list failed. Stray orphan
2603 * anyway on the next recovery. */ 2617 * list entries can cause panics at unmount time.
2604mem_insert: 2618 */
2605 if (!err) 2619 mutex_lock(&sbi->s_orphan_lock);
2606 list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); 2620 list_del(&EXT4_I(inode)->i_orphan);
2607 2621 mutex_unlock(&sbi->s_orphan_lock);
2622 }
2623 }
2608 jbd_debug(4, "superblock will point to %lu\n", inode->i_ino); 2624 jbd_debug(4, "superblock will point to %lu\n", inode->i_ino);
2609 jbd_debug(4, "orphan inode %lu will point to %d\n", 2625 jbd_debug(4, "orphan inode %lu will point to %d\n",
2610 inode->i_ino, NEXT_ORPHAN(inode)); 2626 inode->i_ino, NEXT_ORPHAN(inode));
2611out_unlock: 2627out:
2612 mutex_unlock(&EXT4_SB(sb)->s_orphan_lock); 2628 ext4_std_error(sb, err);
2613 ext4_std_error(inode->i_sb, err);
2614 return err; 2629 return err;
2615} 2630}
2616 2631
@@ -2622,45 +2637,51 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
2622{ 2637{
2623 struct list_head *prev; 2638 struct list_head *prev;
2624 struct ext4_inode_info *ei = EXT4_I(inode); 2639 struct ext4_inode_info *ei = EXT4_I(inode);
2625 struct ext4_sb_info *sbi; 2640 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
2626 __u32 ino_next; 2641 __u32 ino_next;
2627 struct ext4_iloc iloc; 2642 struct ext4_iloc iloc;
2628 int err = 0; 2643 int err = 0;
2629 2644
2630 if ((!EXT4_SB(inode->i_sb)->s_journal) && 2645 if (!sbi->s_journal && !(sbi->s_mount_state & EXT4_ORPHAN_FS))
2631 !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS))
2632 return 0; 2646 return 0;
2633 2647
2634 mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); 2648 WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) &&
2649 !mutex_is_locked(&inode->i_mutex));
2650 /* Do this quick check before taking global s_orphan_lock. */
2635 if (list_empty(&ei->i_orphan)) 2651 if (list_empty(&ei->i_orphan))
2636 goto out; 2652 return 0;
2637 2653
2638 ino_next = NEXT_ORPHAN(inode); 2654 if (handle) {
2639 prev = ei->i_orphan.prev; 2655 /* Grab inode buffer early before taking global s_orphan_lock */
2640 sbi = EXT4_SB(inode->i_sb); 2656 err = ext4_reserve_inode_write(handle, inode, &iloc);
2657 }
2641 2658
2659 mutex_lock(&sbi->s_orphan_lock);
2642 jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino); 2660 jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
2643 2661
2662 prev = ei->i_orphan.prev;
2644 list_del_init(&ei->i_orphan); 2663 list_del_init(&ei->i_orphan);
2645 2664
2646 /* If we're on an error path, we may not have a valid 2665 /* If we're on an error path, we may not have a valid
2647 * transaction handle with which to update the orphan list on 2666 * transaction handle with which to update the orphan list on
2648 * disk, but we still need to remove the inode from the linked 2667 * disk, but we still need to remove the inode from the linked
2649 * list in memory. */ 2668 * list in memory. */
2650 if (!handle) 2669 if (!handle || err) {
2651 goto out; 2670 mutex_unlock(&sbi->s_orphan_lock);
2652
2653 err = ext4_reserve_inode_write(handle, inode, &iloc);
2654 if (err)
2655 goto out_err; 2671 goto out_err;
2672 }
2656 2673
2674 ino_next = NEXT_ORPHAN(inode);
2657 if (prev == &sbi->s_orphan) { 2675 if (prev == &sbi->s_orphan) {
2658 jbd_debug(4, "superblock will point to %u\n", ino_next); 2676 jbd_debug(4, "superblock will point to %u\n", ino_next);
2659 BUFFER_TRACE(sbi->s_sbh, "get_write_access"); 2677 BUFFER_TRACE(sbi->s_sbh, "get_write_access");
2660 err = ext4_journal_get_write_access(handle, sbi->s_sbh); 2678 err = ext4_journal_get_write_access(handle, sbi->s_sbh);
2661 if (err) 2679 if (err) {
2680 mutex_unlock(&sbi->s_orphan_lock);
2662 goto out_brelse; 2681 goto out_brelse;
2682 }
2663 sbi->s_es->s_last_orphan = cpu_to_le32(ino_next); 2683 sbi->s_es->s_last_orphan = cpu_to_le32(ino_next);
2684 mutex_unlock(&sbi->s_orphan_lock);
2664 err = ext4_handle_dirty_super(handle, inode->i_sb); 2685 err = ext4_handle_dirty_super(handle, inode->i_sb);
2665 } else { 2686 } else {
2666 struct ext4_iloc iloc2; 2687 struct ext4_iloc iloc2;
@@ -2670,20 +2691,20 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
2670 jbd_debug(4, "orphan inode %lu will point to %u\n", 2691 jbd_debug(4, "orphan inode %lu will point to %u\n",
2671 i_prev->i_ino, ino_next); 2692 i_prev->i_ino, ino_next);
2672 err = ext4_reserve_inode_write(handle, i_prev, &iloc2); 2693 err = ext4_reserve_inode_write(handle, i_prev, &iloc2);
2673 if (err) 2694 if (err) {
2695 mutex_unlock(&sbi->s_orphan_lock);
2674 goto out_brelse; 2696 goto out_brelse;
2697 }
2675 NEXT_ORPHAN(i_prev) = ino_next; 2698 NEXT_ORPHAN(i_prev) = ino_next;
2676 err = ext4_mark_iloc_dirty(handle, i_prev, &iloc2); 2699 err = ext4_mark_iloc_dirty(handle, i_prev, &iloc2);
2700 mutex_unlock(&sbi->s_orphan_lock);
2677 } 2701 }
2678 if (err) 2702 if (err)
2679 goto out_brelse; 2703 goto out_brelse;
2680 NEXT_ORPHAN(inode) = 0; 2704 NEXT_ORPHAN(inode) = 0;
2681 err = ext4_mark_iloc_dirty(handle, inode, &iloc); 2705 err = ext4_mark_iloc_dirty(handle, inode, &iloc);
2682
2683out_err: 2706out_err:
2684 ext4_std_error(inode->i_sb, err); 2707 ext4_std_error(inode->i_sb, err);
2685out:
2686 mutex_unlock(&EXT4_SB(inode->i_sb)->s_orphan_lock);
2687 return err; 2708 return err;
2688 2709
2689out_brelse: 2710out_brelse: