Commit d4cd1871cff68e188dadcf6d1280762522b643eb

Authored by Li Dongyang
Committed by Mark Fasheh
1 parent d5a30458a9

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>

Showing 3 changed files with 39 additions and 29 deletions Side-by-side Diff

... ... @@ -639,11 +639,13 @@
639 639 goto bail_unlock;
640 640 }
641 641  
642   - status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
643   - orphan_dir_bh);
644   - if (status < 0) {
645   - mlog_errno(status);
646   - goto bail_commit;
  642 + if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
  643 + status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
  644 + orphan_dir_bh);
  645 + if (status < 0) {
  646 + mlog_errno(status);
  647 + goto bail_commit;
  648 + }
647 649 }
648 650  
649 651 /* set the inodes dtime */
650 652  
651 653  
652 654  
653 655  
654 656  
... ... @@ -726,34 +728,35 @@
726 728 struct inode *orphan_dir_inode = NULL;
727 729 struct buffer_head *orphan_dir_bh = NULL;
728 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;
732   - orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
  733 + if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
  734 + orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
733 735  
734   - status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
735   - if (status)
736   - return status;
  736 + status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
  737 + if (status)
  738 + return status;
737 739  
738   - orphan_dir_inode = ocfs2_get_system_file_inode(osb,
739   - ORPHAN_DIR_SYSTEM_INODE,
740   - orphaned_slot);
741   - if (!orphan_dir_inode) {
742   - status = -EEXIST;
743   - mlog_errno(status);
744   - goto bail;
745   - }
  740 + orphan_dir_inode = ocfs2_get_system_file_inode(osb,
  741 + ORPHAN_DIR_SYSTEM_INODE,
  742 + orphaned_slot);
  743 + if (!orphan_dir_inode) {
  744 + status = -EEXIST;
  745 + mlog_errno(status);
  746 + goto bail;
  747 + }
746 748  
747   - /* Lock the orphan dir. The lock will be held for the entire
748   - * delete_inode operation. We do this now to avoid races with
749   - * recovery completion on other nodes. */
750   - mutex_lock(&orphan_dir_inode->i_mutex);
751   - status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
752   - if (status < 0) {
753   - mutex_unlock(&orphan_dir_inode->i_mutex);
  749 + /* Lock the orphan dir. The lock will be held for the entire
  750 + * delete_inode operation. We do this now to avoid races with
  751 + * recovery completion on other nodes. */
  752 + mutex_lock(&orphan_dir_inode->i_mutex);
  753 + status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
  754 + if (status < 0) {
  755 + mutex_unlock(&orphan_dir_inode->i_mutex);
754 756  
755   - mlog_errno(status);
756   - goto bail;
  757 + mlog_errno(status);
  758 + goto bail;
  759 + }
757 760 }
758 761  
759 762 /* we do this while holding the orphan dir lock because we
... ... @@ -794,6 +797,9 @@
794 797 mlog_errno(status);
795 798  
796 799 bail_unlock_dir:
  800 + if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)
  801 + return status;
  802 +
797 803 ocfs2_inode_unlock(orphan_dir_inode, 1);
798 804 mutex_unlock(&orphan_dir_inode->i_mutex);
799 805 brelse(orphan_dir_bh);
... ... @@ -889,7 +895,8 @@
889 895  
890 896 /* Do some basic inode verification... */
891 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 901 * Inodes in the orphan dir must have ORPHANED_FL. The only
895 902 * inodes that come back out of the orphan dir are reflink
... ... @@ -100,6 +100,8 @@
100 100 #define OCFS2_INODE_MAYBE_ORPHANED 0x00000020
101 101 /* Does someone have the file open O_DIRECT */
102 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  
104 106 static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode)
105 107 {
... ... @@ -1976,6 +1976,7 @@
1976 1976 }
1977 1977  
1978 1978 le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL);
  1979 + OCFS2_I(inode)->ip_flags &= ~OCFS2_INODE_SKIP_ORPHAN_DIR;
1979 1980  
1980 1981 /* Record which orphan dir our inode now resides
1981 1982 * in. delete_inode will use this to determine which orphan