aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLi Dongyang <lidongyang@novell.com>2010-04-22 04:11:19 -0400
committerMark Fasheh <mfasheh@suse.com>2010-04-23 14:03:49 -0400
commitd4cd1871cff68e188dadcf6d1280762522b643eb (patch)
treecf3a6426342378956f4d797066ec060eb3939083 /fs
parentd5a30458a90597915977f06e79406b664a41b8ac (diff)
ocfs2: add OCFS2_INODE_SKIP_ORPHAN_DIR flag and honor it in the inode wipe code
Currently in the error path of ocfs2_symlink and ocfs2_mknod, we just call iput with the inode we failed with, but the inode wipe code will complain because we don't add the inode to orphan dir. One solution would be to lock the orphan dir during the entire transaction, but that's too heavy for a rare error path. Instead, we add a flag, OCFS2_INODE_SKIP_ORPHAN_DIR which tells the inode wipe code that it won't find this inode in the orphan dir. [ Merge fixes and comment style cleanups -Mark ] Signed-off-by: Li Dongyang <lidongyang@novell.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/inode.c65
-rw-r--r--fs/ocfs2/inode.h2
-rw-r--r--fs/ocfs2/namei.c1
3 files changed, 39 insertions, 29 deletions
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 07cc8bb68b6d..26399202be7d 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -639,11 +639,13 @@ static int ocfs2_remove_inode(struct inode *inode,
639 goto bail_unlock; 639 goto bail_unlock;
640 } 640 }
641 641
642 status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode, 642 if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
643 orphan_dir_bh); 643 status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
644 if (status < 0) { 644 orphan_dir_bh);
645 mlog_errno(status); 645 if (status < 0) {
646 goto bail_commit; 646 mlog_errno(status);
647 goto bail_commit;
648 }
647 } 649 }
648 650
649 /* set the inodes dtime */ 651 /* set the inodes dtime */
@@ -726,34 +728,35 @@ static int ocfs2_wipe_inode(struct inode *inode,
726 struct inode *orphan_dir_inode = NULL; 728 struct inode *orphan_dir_inode = NULL;
727 struct buffer_head *orphan_dir_bh = NULL; 729 struct buffer_head *orphan_dir_bh = NULL;
728 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 730 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
729 struct ocfs2_dinode *di; 731 struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
730 732
731 di = (struct ocfs2_dinode *) di_bh->b_data; 733 if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
732 orphaned_slot = le16_to_cpu(di->i_orphaned_slot); 734 orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
733 735
734 status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot); 736 status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
735 if (status) 737 if (status)
736 return status; 738 return status;
737 739
738 orphan_dir_inode = ocfs2_get_system_file_inode(osb, 740 orphan_dir_inode = ocfs2_get_system_file_inode(osb,
739 ORPHAN_DIR_SYSTEM_INODE, 741 ORPHAN_DIR_SYSTEM_INODE,
740 orphaned_slot); 742 orphaned_slot);
741 if (!orphan_dir_inode) { 743 if (!orphan_dir_inode) {
742 status = -EEXIST; 744 status = -EEXIST;
743 mlog_errno(status); 745 mlog_errno(status);
744 goto bail; 746 goto bail;
745 } 747 }
746 748
747 /* Lock the orphan dir. The lock will be held for the entire 749 /* Lock the orphan dir. The lock will be held for the entire
748 * delete_inode operation. We do this now to avoid races with 750 * delete_inode operation. We do this now to avoid races with
749 * recovery completion on other nodes. */ 751 * recovery completion on other nodes. */
750 mutex_lock(&orphan_dir_inode->i_mutex); 752 mutex_lock(&orphan_dir_inode->i_mutex);
751 status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); 753 status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
752 if (status < 0) { 754 if (status < 0) {
753 mutex_unlock(&orphan_dir_inode->i_mutex); 755 mutex_unlock(&orphan_dir_inode->i_mutex);
754 756
755 mlog_errno(status); 757 mlog_errno(status);
756 goto bail; 758 goto bail;
759 }
757 } 760 }
758 761
759 /* we do this while holding the orphan dir lock because we 762 /* we do this while holding the orphan dir lock because we
@@ -794,6 +797,9 @@ static int ocfs2_wipe_inode(struct inode *inode,
794 mlog_errno(status); 797 mlog_errno(status);
795 798
796bail_unlock_dir: 799bail_unlock_dir:
800 if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)
801 return status;
802
797 ocfs2_inode_unlock(orphan_dir_inode, 1); 803 ocfs2_inode_unlock(orphan_dir_inode, 1);
798 mutex_unlock(&orphan_dir_inode->i_mutex); 804 mutex_unlock(&orphan_dir_inode->i_mutex);
799 brelse(orphan_dir_bh); 805 brelse(orphan_dir_bh);
@@ -889,7 +895,8 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
889 895
890 /* Do some basic inode verification... */ 896 /* Do some basic inode verification... */
891 di = (struct ocfs2_dinode *) di_bh->b_data; 897 di = (struct ocfs2_dinode *) di_bh->b_data;
892 if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) { 898 if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL)) &&
899 !(oi->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
893 /* 900 /*
894 * Inodes in the orphan dir must have ORPHANED_FL. The only 901 * Inodes in the orphan dir must have ORPHANED_FL. The only
895 * inodes that come back out of the orphan dir are reflink 902 * inodes that come back out of the orphan dir are reflink
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index ba4fe07b293c..0b28e1921a39 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -100,6 +100,8 @@ struct ocfs2_inode_info
100#define OCFS2_INODE_MAYBE_ORPHANED 0x00000020 100#define OCFS2_INODE_MAYBE_ORPHANED 0x00000020
101/* Does someone have the file open O_DIRECT */ 101/* Does someone have the file open O_DIRECT */
102#define OCFS2_INODE_OPEN_DIRECT 0x00000040 102#define OCFS2_INODE_OPEN_DIRECT 0x00000040
103/* Tell the inode wipe code it's not in orphan dir */
104#define OCFS2_INODE_SKIP_ORPHAN_DIR 0x00000080
103 105
104static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode) 106static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode)
105{ 107{
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index b1eb50ae4097..ae315c9c768f 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1976,6 +1976,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
1976 } 1976 }
1977 1977
1978 le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL); 1978 le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL);
1979 OCFS2_I(inode)->ip_flags &= ~OCFS2_INODE_SKIP_ORPHAN_DIR;
1979 1980
1980 /* Record which orphan dir our inode now resides 1981 /* Record which orphan dir our inode now resides
1981 * in. delete_inode will use this to determine which orphan 1982 * in. delete_inode will use this to determine which orphan