diff options
Diffstat (limited to 'fs/ocfs2/inode.c')
-rw-r--r-- | fs/ocfs2/inode.c | 113 |
1 files changed, 52 insertions, 61 deletions
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 07cc8bb68b6d..abb0a95cc717 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -376,6 +376,10 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
376 | 376 | ||
377 | OCFS2_I(inode)->ip_last_used_slot = 0; | 377 | OCFS2_I(inode)->ip_last_used_slot = 0; |
378 | OCFS2_I(inode)->ip_last_used_group = 0; | 378 | OCFS2_I(inode)->ip_last_used_group = 0; |
379 | |||
380 | if (S_ISDIR(inode->i_mode)) | ||
381 | ocfs2_resv_set_type(&OCFS2_I(inode)->ip_la_data_resv, | ||
382 | OCFS2_RESV_FLAG_DIR); | ||
379 | mlog_exit_void(); | 383 | mlog_exit_void(); |
380 | } | 384 | } |
381 | 385 | ||
@@ -539,7 +543,6 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
539 | struct buffer_head *fe_bh) | 543 | struct buffer_head *fe_bh) |
540 | { | 544 | { |
541 | int status = 0; | 545 | int status = 0; |
542 | struct ocfs2_truncate_context *tc = NULL; | ||
543 | struct ocfs2_dinode *fe; | 546 | struct ocfs2_dinode *fe; |
544 | handle_t *handle = NULL; | 547 | handle_t *handle = NULL; |
545 | 548 | ||
@@ -558,6 +561,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
558 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | 561 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
559 | if (IS_ERR(handle)) { | 562 | if (IS_ERR(handle)) { |
560 | status = PTR_ERR(handle); | 563 | status = PTR_ERR(handle); |
564 | handle = NULL; | ||
561 | mlog_errno(status); | 565 | mlog_errno(status); |
562 | goto out; | 566 | goto out; |
563 | } | 567 | } |
@@ -581,13 +585,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
581 | ocfs2_commit_trans(osb, handle); | 585 | ocfs2_commit_trans(osb, handle); |
582 | handle = NULL; | 586 | handle = NULL; |
583 | 587 | ||
584 | status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc); | 588 | status = ocfs2_commit_truncate(osb, inode, fe_bh); |
585 | if (status < 0) { | ||
586 | mlog_errno(status); | ||
587 | goto out; | ||
588 | } | ||
589 | |||
590 | status = ocfs2_commit_truncate(osb, inode, fe_bh, tc); | ||
591 | if (status < 0) { | 589 | if (status < 0) { |
592 | mlog_errno(status); | 590 | mlog_errno(status); |
593 | goto out; | 591 | goto out; |
@@ -639,11 +637,13 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
639 | goto bail_unlock; | 637 | goto bail_unlock; |
640 | } | 638 | } |
641 | 639 | ||
642 | status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode, | 640 | if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { |
643 | orphan_dir_bh); | 641 | status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode, |
644 | if (status < 0) { | 642 | orphan_dir_bh); |
645 | mlog_errno(status); | 643 | if (status < 0) { |
646 | goto bail_commit; | 644 | mlog_errno(status); |
645 | goto bail_commit; | ||
646 | } | ||
647 | } | 647 | } |
648 | 648 | ||
649 | /* set the inodes dtime */ | 649 | /* set the inodes dtime */ |
@@ -656,12 +656,7 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
656 | 656 | ||
657 | di->i_dtime = cpu_to_le64(CURRENT_TIME.tv_sec); | 657 | di->i_dtime = cpu_to_le64(CURRENT_TIME.tv_sec); |
658 | di->i_flags &= cpu_to_le32(~(OCFS2_VALID_FL | OCFS2_ORPHANED_FL)); | 658 | di->i_flags &= cpu_to_le32(~(OCFS2_VALID_FL | OCFS2_ORPHANED_FL)); |
659 | 659 | ocfs2_journal_dirty(handle, di_bh); | |
660 | status = ocfs2_journal_dirty(handle, di_bh); | ||
661 | if (status < 0) { | ||
662 | mlog_errno(status); | ||
663 | goto bail_commit; | ||
664 | } | ||
665 | 660 | ||
666 | ocfs2_remove_from_cache(INODE_CACHE(inode), di_bh); | 661 | ocfs2_remove_from_cache(INODE_CACHE(inode), di_bh); |
667 | dquot_free_inode(inode); | 662 | dquot_free_inode(inode); |
@@ -722,38 +717,39 @@ static void ocfs2_signal_wipe_completion(struct ocfs2_super *osb, | |||
722 | static int ocfs2_wipe_inode(struct inode *inode, | 717 | static int ocfs2_wipe_inode(struct inode *inode, |
723 | struct buffer_head *di_bh) | 718 | struct buffer_head *di_bh) |
724 | { | 719 | { |
725 | int status, orphaned_slot; | 720 | int status, orphaned_slot = -1; |
726 | struct inode *orphan_dir_inode = NULL; | 721 | struct inode *orphan_dir_inode = NULL; |
727 | struct buffer_head *orphan_dir_bh = NULL; | 722 | struct buffer_head *orphan_dir_bh = NULL; |
728 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 723 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
729 | struct ocfs2_dinode *di; | 724 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; |
730 | 725 | ||
731 | di = (struct ocfs2_dinode *) di_bh->b_data; | 726 | if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { |
732 | orphaned_slot = le16_to_cpu(di->i_orphaned_slot); | 727 | orphaned_slot = le16_to_cpu(di->i_orphaned_slot); |
733 | 728 | ||
734 | status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot); | 729 | status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot); |
735 | if (status) | 730 | if (status) |
736 | return status; | 731 | return status; |
737 | 732 | ||
738 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | 733 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, |
739 | ORPHAN_DIR_SYSTEM_INODE, | 734 | ORPHAN_DIR_SYSTEM_INODE, |
740 | orphaned_slot); | 735 | orphaned_slot); |
741 | if (!orphan_dir_inode) { | 736 | if (!orphan_dir_inode) { |
742 | status = -EEXIST; | 737 | status = -EEXIST; |
743 | mlog_errno(status); | 738 | mlog_errno(status); |
744 | goto bail; | 739 | goto bail; |
745 | } | 740 | } |
746 | 741 | ||
747 | /* Lock the orphan dir. The lock will be held for the entire | 742 | /* Lock the orphan dir. The lock will be held for the entire |
748 | * delete_inode operation. We do this now to avoid races with | 743 | * delete_inode operation. We do this now to avoid races with |
749 | * recovery completion on other nodes. */ | 744 | * recovery completion on other nodes. */ |
750 | mutex_lock(&orphan_dir_inode->i_mutex); | 745 | mutex_lock(&orphan_dir_inode->i_mutex); |
751 | status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); | 746 | status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); |
752 | if (status < 0) { | 747 | if (status < 0) { |
753 | mutex_unlock(&orphan_dir_inode->i_mutex); | 748 | mutex_unlock(&orphan_dir_inode->i_mutex); |
754 | 749 | ||
755 | mlog_errno(status); | 750 | mlog_errno(status); |
756 | goto bail; | 751 | goto bail; |
752 | } | ||
757 | } | 753 | } |
758 | 754 | ||
759 | /* we do this while holding the orphan dir lock because we | 755 | /* we do this while holding the orphan dir lock because we |
@@ -794,6 +790,9 @@ static int ocfs2_wipe_inode(struct inode *inode, | |||
794 | mlog_errno(status); | 790 | mlog_errno(status); |
795 | 791 | ||
796 | bail_unlock_dir: | 792 | bail_unlock_dir: |
793 | if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR) | ||
794 | return status; | ||
795 | |||
797 | ocfs2_inode_unlock(orphan_dir_inode, 1); | 796 | ocfs2_inode_unlock(orphan_dir_inode, 1); |
798 | mutex_unlock(&orphan_dir_inode->i_mutex); | 797 | mutex_unlock(&orphan_dir_inode->i_mutex); |
799 | brelse(orphan_dir_bh); | 798 | brelse(orphan_dir_bh); |
@@ -889,7 +888,8 @@ static int ocfs2_query_inode_wipe(struct inode *inode, | |||
889 | 888 | ||
890 | /* Do some basic inode verification... */ | 889 | /* Do some basic inode verification... */ |
891 | di = (struct ocfs2_dinode *) di_bh->b_data; | 890 | di = (struct ocfs2_dinode *) di_bh->b_data; |
892 | if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) { | 891 | if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL)) && |
892 | !(oi->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { | ||
893 | /* | 893 | /* |
894 | * Inodes in the orphan dir must have ORPHANED_FL. The only | 894 | * Inodes in the orphan dir must have ORPHANED_FL. The only |
895 | * inodes that come back out of the orphan dir are reflink | 895 | * inodes that come back out of the orphan dir are reflink |
@@ -972,7 +972,7 @@ static void ocfs2_cleanup_delete_inode(struct inode *inode, | |||
972 | void ocfs2_delete_inode(struct inode *inode) | 972 | void ocfs2_delete_inode(struct inode *inode) |
973 | { | 973 | { |
974 | int wipe, status; | 974 | int wipe, status; |
975 | sigset_t blocked, oldset; | 975 | sigset_t oldset; |
976 | struct buffer_head *di_bh = NULL; | 976 | struct buffer_head *di_bh = NULL; |
977 | 977 | ||
978 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); | 978 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); |
@@ -999,13 +999,7 @@ void ocfs2_delete_inode(struct inode *inode) | |||
999 | * messaging paths may return us -ERESTARTSYS. Which would | 999 | * messaging paths may return us -ERESTARTSYS. Which would |
1000 | * cause us to exit early, resulting in inodes being orphaned | 1000 | * cause us to exit early, resulting in inodes being orphaned |
1001 | * forever. */ | 1001 | * forever. */ |
1002 | sigfillset(&blocked); | 1002 | ocfs2_block_signals(&oldset); |
1003 | status = sigprocmask(SIG_BLOCK, &blocked, &oldset); | ||
1004 | if (status < 0) { | ||
1005 | mlog_errno(status); | ||
1006 | ocfs2_cleanup_delete_inode(inode, 1); | ||
1007 | goto bail; | ||
1008 | } | ||
1009 | 1003 | ||
1010 | /* | 1004 | /* |
1011 | * Synchronize us against ocfs2_get_dentry. We take this in | 1005 | * Synchronize us against ocfs2_get_dentry. We take this in |
@@ -1079,9 +1073,7 @@ bail_unlock_nfs_sync: | |||
1079 | ocfs2_nfs_sync_unlock(OCFS2_SB(inode->i_sb), 0); | 1073 | ocfs2_nfs_sync_unlock(OCFS2_SB(inode->i_sb), 0); |
1080 | 1074 | ||
1081 | bail_unblock: | 1075 | bail_unblock: |
1082 | status = sigprocmask(SIG_SETMASK, &oldset, NULL); | 1076 | ocfs2_unblock_signals(&oldset); |
1083 | if (status < 0) | ||
1084 | mlog_errno(status); | ||
1085 | bail: | 1077 | bail: |
1086 | clear_inode(inode); | 1078 | clear_inode(inode); |
1087 | mlog_exit_void(); | 1079 | mlog_exit_void(); |
@@ -1115,6 +1107,10 @@ void ocfs2_clear_inode(struct inode *inode) | |||
1115 | ocfs2_mark_lockres_freeing(&oi->ip_inode_lockres); | 1107 | ocfs2_mark_lockres_freeing(&oi->ip_inode_lockres); |
1116 | ocfs2_mark_lockres_freeing(&oi->ip_open_lockres); | 1108 | ocfs2_mark_lockres_freeing(&oi->ip_open_lockres); |
1117 | 1109 | ||
1110 | ocfs2_resv_discard(&OCFS2_SB(inode->i_sb)->osb_la_resmap, | ||
1111 | &oi->ip_la_data_resv); | ||
1112 | ocfs2_resv_init_once(&oi->ip_la_data_resv); | ||
1113 | |||
1118 | /* We very well may get a clear_inode before all an inodes | 1114 | /* We very well may get a clear_inode before all an inodes |
1119 | * metadata has hit disk. Of course, we can't drop any cluster | 1115 | * metadata has hit disk. Of course, we can't drop any cluster |
1120 | * locks until the journal has finished with it. The only | 1116 | * locks until the journal has finished with it. The only |
@@ -1290,13 +1286,8 @@ int ocfs2_mark_inode_dirty(handle_t *handle, | |||
1290 | fe->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec); | 1286 | fe->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec); |
1291 | fe->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); | 1287 | fe->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); |
1292 | 1288 | ||
1293 | status = ocfs2_journal_dirty(handle, bh); | 1289 | ocfs2_journal_dirty(handle, bh); |
1294 | if (status < 0) | ||
1295 | mlog_errno(status); | ||
1296 | |||
1297 | status = 0; | ||
1298 | leave: | 1290 | leave: |
1299 | |||
1300 | mlog_exit(status); | 1291 | mlog_exit(status); |
1301 | return status; | 1292 | return status; |
1302 | } | 1293 | } |