diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-04 19:33:18 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-04 19:33:18 -0400 |
| commit | 7572e56314a7e2568f7196862222b45cfb9d6eda (patch) | |
| tree | 345bc292de14b24f28d5367f999bcf7500abedc3 | |
| parent | a66f6375bdeb64d7a56c532bda7c006358845820 (diff) | |
| parent | d577632e65ea01fb3b124b652d7bd2381251da3c (diff) | |
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2:
ocfs2: Avoid a gcc warning in ocfs2_wipe_inode().
ocfs2: Avoid direct write if we fall back to buffered I/O
ocfs2_dlmfs: Fix math error when reading LVB.
ocfs2: Update VFS inode's id info after reflink.
ocfs2: potential ERR_PTR dereference on error paths
ocfs2: Add directory entry later in ocfs2_symlink() and ocfs2_mknod()
ocfs2: use OCFS2_INODE_SKIP_ORPHAN_DIR in ocfs2_mknod error path
ocfs2: use OCFS2_INODE_SKIP_ORPHAN_DIR in ocfs2_symlink error path
ocfs2: add OCFS2_INODE_SKIP_ORPHAN_DIR flag and honor it in the inode wipe code
ocfs2: Reset status if we want to restart file extension.
ocfs2: Compute metaecc for superblocks during online resize.
ocfs2: Check the owner of a lockres inside the spinlock
ocfs2: one more warning fix in ocfs2_file_aio_write(), v2
ocfs2_dlmfs: User DLM_* when decoding file open flags.
| -rw-r--r-- | fs/ocfs2/buffer_head_io.c | 2 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmast.c | 5 | ||||
| -rw-r--r-- | fs/ocfs2/dlmfs/dlmfs.c | 14 | ||||
| -rw-r--r-- | fs/ocfs2/file.c | 32 | ||||
| -rw-r--r-- | fs/ocfs2/inode.c | 68 | ||||
| -rw-r--r-- | fs/ocfs2/inode.h | 2 | ||||
| -rw-r--r-- | fs/ocfs2/namei.c | 58 | ||||
| -rw-r--r-- | fs/ocfs2/refcounttree.c | 3 |
8 files changed, 110 insertions, 74 deletions
diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c index ecebb2276790..f9d5d3ffc75a 100644 --- a/fs/ocfs2/buffer_head_io.c +++ b/fs/ocfs2/buffer_head_io.c | |||
| @@ -406,6 +406,7 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb, | |||
| 406 | struct buffer_head *bh) | 406 | struct buffer_head *bh) |
| 407 | { | 407 | { |
| 408 | int ret = 0; | 408 | int ret = 0; |
| 409 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; | ||
| 409 | 410 | ||
| 410 | mlog_entry_void(); | 411 | mlog_entry_void(); |
| 411 | 412 | ||
| @@ -425,6 +426,7 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb, | |||
| 425 | 426 | ||
| 426 | get_bh(bh); /* for end_buffer_write_sync() */ | 427 | get_bh(bh); /* for end_buffer_write_sync() */ |
| 427 | bh->b_end_io = end_buffer_write_sync; | 428 | bh->b_end_io = end_buffer_write_sync; |
| 429 | ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &di->i_check); | ||
| 428 | submit_bh(WRITE, bh); | 430 | submit_bh(WRITE, bh); |
| 429 | 431 | ||
| 430 | wait_on_buffer(bh); | 432 | wait_on_buffer(bh); |
diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c index a795eb91f4ea..12d5eb78a11a 100644 --- a/fs/ocfs2/dlm/dlmast.c +++ b/fs/ocfs2/dlm/dlmast.c | |||
| @@ -184,9 +184,8 @@ static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, | |||
| 184 | BUG_ON(!lksb); | 184 | BUG_ON(!lksb); |
| 185 | 185 | ||
| 186 | /* only updates if this node masters the lockres */ | 186 | /* only updates if this node masters the lockres */ |
| 187 | spin_lock(&res->spinlock); | ||
| 187 | if (res->owner == dlm->node_num) { | 188 | if (res->owner == dlm->node_num) { |
| 188 | |||
| 189 | spin_lock(&res->spinlock); | ||
| 190 | /* check the lksb flags for the direction */ | 189 | /* check the lksb flags for the direction */ |
| 191 | if (lksb->flags & DLM_LKSB_GET_LVB) { | 190 | if (lksb->flags & DLM_LKSB_GET_LVB) { |
| 192 | mlog(0, "getting lvb from lockres for %s node\n", | 191 | mlog(0, "getting lvb from lockres for %s node\n", |
| @@ -201,8 +200,8 @@ static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, | |||
| 201 | * here. In the future we might want to clear it at the time | 200 | * here. In the future we might want to clear it at the time |
| 202 | * the put is actually done. | 201 | * the put is actually done. |
| 203 | */ | 202 | */ |
| 204 | spin_unlock(&res->spinlock); | ||
| 205 | } | 203 | } |
| 204 | spin_unlock(&res->spinlock); | ||
| 206 | 205 | ||
| 207 | /* reset any lvb flags on the lksb */ | 206 | /* reset any lvb flags on the lksb */ |
| 208 | lksb->flags &= ~(DLM_LKSB_PUT_LVB|DLM_LKSB_GET_LVB); | 207 | lksb->flags &= ~(DLM_LKSB_PUT_LVB|DLM_LKSB_GET_LVB); |
diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c index 1b0de157a08c..b83d6107a1f5 100644 --- a/fs/ocfs2/dlmfs/dlmfs.c +++ b/fs/ocfs2/dlmfs/dlmfs.c | |||
| @@ -112,20 +112,20 @@ MODULE_PARM_DESC(capabilities, DLMFS_CAPABILITIES); | |||
| 112 | * O_RDONLY -> PRMODE level | 112 | * O_RDONLY -> PRMODE level |
| 113 | * O_WRONLY -> EXMODE level | 113 | * O_WRONLY -> EXMODE level |
| 114 | * | 114 | * |
| 115 | * O_NONBLOCK -> LKM_NOQUEUE | 115 | * O_NONBLOCK -> NOQUEUE |
| 116 | */ | 116 | */ |
| 117 | static int dlmfs_decode_open_flags(int open_flags, | 117 | static int dlmfs_decode_open_flags(int open_flags, |
| 118 | int *level, | 118 | int *level, |
| 119 | int *flags) | 119 | int *flags) |
| 120 | { | 120 | { |
| 121 | if (open_flags & (O_WRONLY|O_RDWR)) | 121 | if (open_flags & (O_WRONLY|O_RDWR)) |
| 122 | *level = LKM_EXMODE; | 122 | *level = DLM_LOCK_EX; |
| 123 | else | 123 | else |
| 124 | *level = LKM_PRMODE; | 124 | *level = DLM_LOCK_PR; |
| 125 | 125 | ||
| 126 | *flags = 0; | 126 | *flags = 0; |
| 127 | if (open_flags & O_NONBLOCK) | 127 | if (open_flags & O_NONBLOCK) |
| 128 | *flags |= LKM_NOQUEUE; | 128 | *flags |= DLM_LKF_NOQUEUE; |
| 129 | 129 | ||
| 130 | return 0; | 130 | return 0; |
| 131 | } | 131 | } |
| @@ -166,7 +166,7 @@ static int dlmfs_file_open(struct inode *inode, | |||
| 166 | * to be able userspace to be able to distinguish a | 166 | * to be able userspace to be able to distinguish a |
| 167 | * valid lock request from one that simply couldn't be | 167 | * valid lock request from one that simply couldn't be |
| 168 | * granted. */ | 168 | * granted. */ |
| 169 | if (flags & LKM_NOQUEUE && status == -EAGAIN) | 169 | if (flags & DLM_LKF_NOQUEUE && status == -EAGAIN) |
| 170 | status = -ETXTBSY; | 170 | status = -ETXTBSY; |
| 171 | kfree(fp); | 171 | kfree(fp); |
| 172 | goto bail; | 172 | goto bail; |
| @@ -193,7 +193,7 @@ static int dlmfs_file_release(struct inode *inode, | |||
| 193 | status = 0; | 193 | status = 0; |
| 194 | if (fp) { | 194 | if (fp) { |
| 195 | level = fp->fp_lock_level; | 195 | level = fp->fp_lock_level; |
| 196 | if (level != LKM_IVMODE) | 196 | if (level != DLM_LOCK_IV) |
| 197 | user_dlm_cluster_unlock(&ip->ip_lockres, level); | 197 | user_dlm_cluster_unlock(&ip->ip_lockres, level); |
| 198 | 198 | ||
| 199 | kfree(fp); | 199 | kfree(fp); |
| @@ -262,7 +262,7 @@ static ssize_t dlmfs_file_read(struct file *filp, | |||
| 262 | if ((count + *ppos) > i_size_read(inode)) | 262 | if ((count + *ppos) > i_size_read(inode)) |
| 263 | readlen = i_size_read(inode) - *ppos; | 263 | readlen = i_size_read(inode) - *ppos; |
| 264 | else | 264 | else |
| 265 | readlen = count - *ppos; | 265 | readlen = count; |
| 266 | 266 | ||
| 267 | lvb_buf = kmalloc(readlen, GFP_NOFS); | 267 | lvb_buf = kmalloc(readlen, GFP_NOFS); |
| 268 | if (!lvb_buf) | 268 | if (!lvb_buf) |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 17947dc8341e..a5fbd9cea968 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -684,6 +684,7 @@ restarted_transaction: | |||
| 684 | if (why == RESTART_META) { | 684 | if (why == RESTART_META) { |
| 685 | mlog(0, "restarting function.\n"); | 685 | mlog(0, "restarting function.\n"); |
| 686 | restart_func = 1; | 686 | restart_func = 1; |
| 687 | status = 0; | ||
| 687 | } else { | 688 | } else { |
| 688 | BUG_ON(why != RESTART_TRANS); | 689 | BUG_ON(why != RESTART_TRANS); |
| 689 | 690 | ||
| @@ -1981,18 +1982,18 @@ relock: | |||
| 1981 | /* communicate with ocfs2_dio_end_io */ | 1982 | /* communicate with ocfs2_dio_end_io */ |
| 1982 | ocfs2_iocb_set_rw_locked(iocb, rw_level); | 1983 | ocfs2_iocb_set_rw_locked(iocb, rw_level); |
| 1983 | 1984 | ||
| 1984 | if (direct_io) { | 1985 | ret = generic_segment_checks(iov, &nr_segs, &ocount, |
| 1985 | ret = generic_segment_checks(iov, &nr_segs, &ocount, | 1986 | VERIFY_READ); |
| 1986 | VERIFY_READ); | 1987 | if (ret) |
| 1987 | if (ret) | 1988 | goto out_dio; |
| 1988 | goto out_dio; | ||
| 1989 | 1989 | ||
| 1990 | count = ocount; | 1990 | count = ocount; |
| 1991 | ret = generic_write_checks(file, ppos, &count, | 1991 | ret = generic_write_checks(file, ppos, &count, |
| 1992 | S_ISBLK(inode->i_mode)); | 1992 | S_ISBLK(inode->i_mode)); |
| 1993 | if (ret) | 1993 | if (ret) |
| 1994 | goto out_dio; | 1994 | goto out_dio; |
| 1995 | 1995 | ||
| 1996 | if (direct_io) { | ||
| 1996 | written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, | 1997 | written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, |
| 1997 | ppos, count, ocount); | 1998 | ppos, count, ocount); |
| 1998 | if (written < 0) { | 1999 | if (written < 0) { |
| @@ -2007,7 +2008,10 @@ relock: | |||
| 2007 | goto out_dio; | 2008 | goto out_dio; |
| 2008 | } | 2009 | } |
| 2009 | } else { | 2010 | } else { |
| 2010 | written = __generic_file_aio_write(iocb, iov, nr_segs, ppos); | 2011 | current->backing_dev_info = file->f_mapping->backing_dev_info; |
| 2012 | written = generic_file_buffered_write(iocb, iov, nr_segs, *ppos, | ||
| 2013 | ppos, count, 0); | ||
| 2014 | current->backing_dev_info = NULL; | ||
| 2011 | } | 2015 | } |
| 2012 | 2016 | ||
| 2013 | out_dio: | 2017 | out_dio: |
| @@ -2021,9 +2025,9 @@ out_dio: | |||
| 2021 | if (ret < 0) | 2025 | if (ret < 0) |
| 2022 | written = ret; | 2026 | written = ret; |
| 2023 | 2027 | ||
| 2024 | if (!ret && (old_size != i_size_read(inode) || | 2028 | if (!ret && ((old_size != i_size_read(inode)) || |
| 2025 | old_clusters != OCFS2_I(inode)->ip_clusters || | 2029 | (old_clusters != OCFS2_I(inode)->ip_clusters) || |
| 2026 | has_refcount)) { | 2030 | has_refcount)) { |
| 2027 | ret = jbd2_journal_force_commit(osb->journal->j_journal); | 2031 | ret = jbd2_journal_force_commit(osb->journal->j_journal); |
| 2028 | if (ret < 0) | 2032 | if (ret < 0) |
| 2029 | written = ret; | 2033 | written = ret; |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 07cc8bb68b6d..af189887201c 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
| @@ -558,6 +558,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
| 558 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | 558 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
| 559 | if (IS_ERR(handle)) { | 559 | if (IS_ERR(handle)) { |
| 560 | status = PTR_ERR(handle); | 560 | status = PTR_ERR(handle); |
| 561 | handle = NULL; | ||
| 561 | mlog_errno(status); | 562 | mlog_errno(status); |
| 562 | goto out; | 563 | goto out; |
| 563 | } | 564 | } |
| @@ -639,11 +640,13 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
| 639 | goto bail_unlock; | 640 | goto bail_unlock; |
| 640 | } | 641 | } |
| 641 | 642 | ||
| 642 | status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode, | 643 | if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { |
| 643 | orphan_dir_bh); | 644 | status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode, |
| 644 | if (status < 0) { | 645 | orphan_dir_bh); |
| 645 | mlog_errno(status); | 646 | if (status < 0) { |
| 646 | goto bail_commit; | 647 | mlog_errno(status); |
| 648 | goto bail_commit; | ||
| 649 | } | ||
| 647 | } | 650 | } |
| 648 | 651 | ||
| 649 | /* set the inodes dtime */ | 652 | /* set the inodes dtime */ |
| @@ -722,38 +725,39 @@ static void ocfs2_signal_wipe_completion(struct ocfs2_super *osb, | |||
| 722 | static int ocfs2_wipe_inode(struct inode *inode, | 725 | static int ocfs2_wipe_inode(struct inode *inode, |
| 723 | struct buffer_head *di_bh) | 726 | struct buffer_head *di_bh) |
| 724 | { | 727 | { |
| 725 | int status, orphaned_slot; | 728 | int status, orphaned_slot = -1; |
| 726 | struct inode *orphan_dir_inode = NULL; | 729 | struct inode *orphan_dir_inode = NULL; |
| 727 | struct buffer_head *orphan_dir_bh = NULL; | 730 | struct buffer_head *orphan_dir_bh = NULL; |
| 728 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 731 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 729 | struct ocfs2_dinode *di; | 732 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; |
| 730 | 733 | ||
| 731 | di = (struct ocfs2_dinode *) di_bh->b_data; | 734 | if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { |
| 732 | orphaned_slot = le16_to_cpu(di->i_orphaned_slot); | 735 | orphaned_slot = le16_to_cpu(di->i_orphaned_slot); |
| 733 | 736 | ||
| 734 | status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot); | 737 | status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot); |
| 735 | if (status) | 738 | if (status) |
| 736 | return status; | 739 | return status; |
| 737 | 740 | ||
| 738 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | 741 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, |
| 739 | ORPHAN_DIR_SYSTEM_INODE, | 742 | ORPHAN_DIR_SYSTEM_INODE, |
| 740 | orphaned_slot); | 743 | orphaned_slot); |
| 741 | if (!orphan_dir_inode) { | 744 | if (!orphan_dir_inode) { |
| 742 | status = -EEXIST; | 745 | status = -EEXIST; |
| 743 | mlog_errno(status); | 746 | mlog_errno(status); |
| 744 | goto bail; | 747 | goto bail; |
| 745 | } | 748 | } |
| 746 | 749 | ||
| 747 | /* Lock the orphan dir. The lock will be held for the entire | 750 | /* Lock the orphan dir. The lock will be held for the entire |
| 748 | * delete_inode operation. We do this now to avoid races with | 751 | * delete_inode operation. We do this now to avoid races with |
| 749 | * recovery completion on other nodes. */ | 752 | * recovery completion on other nodes. */ |
| 750 | mutex_lock(&orphan_dir_inode->i_mutex); | 753 | mutex_lock(&orphan_dir_inode->i_mutex); |
| 751 | status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); | 754 | status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); |
| 752 | if (status < 0) { | 755 | if (status < 0) { |
| 753 | mutex_unlock(&orphan_dir_inode->i_mutex); | 756 | mutex_unlock(&orphan_dir_inode->i_mutex); |
| 754 | 757 | ||
| 755 | mlog_errno(status); | 758 | mlog_errno(status); |
| 756 | goto bail; | 759 | goto bail; |
| 760 | } | ||
| 757 | } | 761 | } |
| 758 | 762 | ||
| 759 | /* we do this while holding the orphan dir lock because we | 763 | /* we do this while holding the orphan dir lock because we |
| @@ -794,6 +798,9 @@ static int ocfs2_wipe_inode(struct inode *inode, | |||
| 794 | mlog_errno(status); | 798 | mlog_errno(status); |
| 795 | 799 | ||
| 796 | bail_unlock_dir: | 800 | bail_unlock_dir: |
| 801 | if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR) | ||
| 802 | return status; | ||
| 803 | |||
| 797 | ocfs2_inode_unlock(orphan_dir_inode, 1); | 804 | ocfs2_inode_unlock(orphan_dir_inode, 1); |
| 798 | mutex_unlock(&orphan_dir_inode->i_mutex); | 805 | mutex_unlock(&orphan_dir_inode->i_mutex); |
| 799 | brelse(orphan_dir_bh); | 806 | brelse(orphan_dir_bh); |
| @@ -889,7 +896,8 @@ static int ocfs2_query_inode_wipe(struct inode *inode, | |||
| 889 | 896 | ||
| 890 | /* Do some basic inode verification... */ | 897 | /* Do some basic inode verification... */ |
| 891 | di = (struct ocfs2_dinode *) di_bh->b_data; | 898 | di = (struct ocfs2_dinode *) di_bh->b_data; |
| 892 | if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) { | 899 | if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL)) && |
| 900 | !(oi->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { | ||
| 893 | /* | 901 | /* |
| 894 | * Inodes in the orphan dir must have ORPHANED_FL. The only | 902 | * Inodes in the orphan dir must have ORPHANED_FL. The only |
| 895 | * inodes that come back out of the orphan dir are reflink | 903 | * 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 | ||
| 104 | static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode) | 106 | static 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..4cbb18f26c5f 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -408,23 +408,28 @@ static int ocfs2_mknod(struct inode *dir, | |||
| 408 | } | 408 | } |
| 409 | } | 409 | } |
| 410 | 410 | ||
| 411 | status = ocfs2_add_entry(handle, dentry, inode, | 411 | /* |
| 412 | OCFS2_I(inode)->ip_blkno, parent_fe_bh, | 412 | * Do this before adding the entry to the directory. We add |
| 413 | &lookup); | 413 | * also set d_op after success so that ->d_iput() will cleanup |
| 414 | if (status < 0) { | 414 | * the dentry lock even if ocfs2_add_entry() fails below. |
| 415 | */ | ||
| 416 | status = ocfs2_dentry_attach_lock(dentry, inode, | ||
| 417 | OCFS2_I(dir)->ip_blkno); | ||
| 418 | if (status) { | ||
| 415 | mlog_errno(status); | 419 | mlog_errno(status); |
| 416 | goto leave; | 420 | goto leave; |
| 417 | } | 421 | } |
| 422 | dentry->d_op = &ocfs2_dentry_ops; | ||
| 418 | 423 | ||
| 419 | status = ocfs2_dentry_attach_lock(dentry, inode, | 424 | status = ocfs2_add_entry(handle, dentry, inode, |
| 420 | OCFS2_I(dir)->ip_blkno); | 425 | OCFS2_I(inode)->ip_blkno, parent_fe_bh, |
| 421 | if (status) { | 426 | &lookup); |
| 427 | if (status < 0) { | ||
| 422 | mlog_errno(status); | 428 | mlog_errno(status); |
| 423 | goto leave; | 429 | goto leave; |
| 424 | } | 430 | } |
| 425 | 431 | ||
| 426 | insert_inode_hash(inode); | 432 | insert_inode_hash(inode); |
| 427 | dentry->d_op = &ocfs2_dentry_ops; | ||
| 428 | d_instantiate(dentry, inode); | 433 | d_instantiate(dentry, inode); |
| 429 | status = 0; | 434 | status = 0; |
| 430 | leave: | 435 | leave: |
| @@ -445,11 +450,6 @@ leave: | |||
| 445 | 450 | ||
| 446 | ocfs2_free_dir_lookup_result(&lookup); | 451 | ocfs2_free_dir_lookup_result(&lookup); |
| 447 | 452 | ||
| 448 | if ((status < 0) && inode) { | ||
| 449 | clear_nlink(inode); | ||
| 450 | iput(inode); | ||
| 451 | } | ||
| 452 | |||
| 453 | if (inode_ac) | 453 | if (inode_ac) |
| 454 | ocfs2_free_alloc_context(inode_ac); | 454 | ocfs2_free_alloc_context(inode_ac); |
| 455 | 455 | ||
| @@ -459,6 +459,17 @@ leave: | |||
| 459 | if (meta_ac) | 459 | if (meta_ac) |
| 460 | ocfs2_free_alloc_context(meta_ac); | 460 | ocfs2_free_alloc_context(meta_ac); |
| 461 | 461 | ||
| 462 | /* | ||
| 463 | * We should call iput after the i_mutex of the bitmap been | ||
| 464 | * unlocked in ocfs2_free_alloc_context, or the | ||
| 465 | * ocfs2_delete_inode will mutex_lock again. | ||
| 466 | */ | ||
| 467 | if ((status < 0) && inode) { | ||
| 468 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR; | ||
| 469 | clear_nlink(inode); | ||
| 470 | iput(inode); | ||
| 471 | } | ||
| 472 | |||
| 462 | mlog_exit(status); | 473 | mlog_exit(status); |
| 463 | 474 | ||
| 464 | return status; | 475 | return status; |
| @@ -1771,22 +1782,27 @@ static int ocfs2_symlink(struct inode *dir, | |||
| 1771 | } | 1782 | } |
| 1772 | } | 1783 | } |
| 1773 | 1784 | ||
| 1774 | status = ocfs2_add_entry(handle, dentry, inode, | 1785 | /* |
| 1775 | le64_to_cpu(fe->i_blkno), parent_fe_bh, | 1786 | * Do this before adding the entry to the directory. We add |
| 1776 | &lookup); | 1787 | * also set d_op after success so that ->d_iput() will cleanup |
| 1777 | if (status < 0) { | 1788 | * the dentry lock even if ocfs2_add_entry() fails below. |
| 1789 | */ | ||
| 1790 | status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); | ||
| 1791 | if (status) { | ||
| 1778 | mlog_errno(status); | 1792 | mlog_errno(status); |
| 1779 | goto bail; | 1793 | goto bail; |
| 1780 | } | 1794 | } |
| 1795 | dentry->d_op = &ocfs2_dentry_ops; | ||
| 1781 | 1796 | ||
| 1782 | status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); | 1797 | status = ocfs2_add_entry(handle, dentry, inode, |
| 1783 | if (status) { | 1798 | le64_to_cpu(fe->i_blkno), parent_fe_bh, |
| 1799 | &lookup); | ||
| 1800 | if (status < 0) { | ||
| 1784 | mlog_errno(status); | 1801 | mlog_errno(status); |
| 1785 | goto bail; | 1802 | goto bail; |
| 1786 | } | 1803 | } |
| 1787 | 1804 | ||
| 1788 | insert_inode_hash(inode); | 1805 | insert_inode_hash(inode); |
| 1789 | dentry->d_op = &ocfs2_dentry_ops; | ||
| 1790 | d_instantiate(dentry, inode); | 1806 | d_instantiate(dentry, inode); |
| 1791 | bail: | 1807 | bail: |
| 1792 | if (status < 0 && did_quota) | 1808 | if (status < 0 && did_quota) |
| @@ -1811,6 +1827,7 @@ bail: | |||
| 1811 | if (xattr_ac) | 1827 | if (xattr_ac) |
| 1812 | ocfs2_free_alloc_context(xattr_ac); | 1828 | ocfs2_free_alloc_context(xattr_ac); |
| 1813 | if ((status < 0) && inode) { | 1829 | if ((status < 0) && inode) { |
| 1830 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR; | ||
| 1814 | clear_nlink(inode); | 1831 | clear_nlink(inode); |
| 1815 | iput(inode); | 1832 | iput(inode); |
| 1816 | } | 1833 | } |
| @@ -1976,6 +1993,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, | |||
| 1976 | } | 1993 | } |
| 1977 | 1994 | ||
| 1978 | le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL); | 1995 | le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL); |
| 1996 | OCFS2_I(inode)->ip_flags &= ~OCFS2_INODE_SKIP_ORPHAN_DIR; | ||
| 1979 | 1997 | ||
| 1980 | /* Record which orphan dir our inode now resides | 1998 | /* Record which orphan dir our inode now resides |
| 1981 | * in. delete_inode will use this to determine which orphan | 1999 | * in. delete_inode will use this to determine which orphan |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index bd96f6c7877e..5cbcd0f008fc 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
| @@ -4083,6 +4083,9 @@ static int ocfs2_complete_reflink(struct inode *s_inode, | |||
| 4083 | di->i_attr = s_di->i_attr; | 4083 | di->i_attr = s_di->i_attr; |
| 4084 | 4084 | ||
| 4085 | if (preserve) { | 4085 | if (preserve) { |
| 4086 | t_inode->i_uid = s_inode->i_uid; | ||
| 4087 | t_inode->i_gid = s_inode->i_gid; | ||
| 4088 | t_inode->i_mode = s_inode->i_mode; | ||
| 4086 | di->i_uid = s_di->i_uid; | 4089 | di->i_uid = s_di->i_uid; |
| 4087 | di->i_gid = s_di->i_gid; | 4090 | di->i_gid = s_di->i_gid; |
| 4088 | di->i_mode = s_di->i_mode; | 4091 | di->i_mode = s_di->i_mode; |
