diff options
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 16 | ||||
| -rw-r--r-- | fs/xfs/xfs_iget.c | 18 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode.c | 34 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode.h | 1 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode_item.c | 5 |
5 files changed, 23 insertions, 51 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index b5afcfcdc7d5..264b1e7dacf7 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
| @@ -71,6 +71,22 @@ xfs_synchronize_atime( | |||
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | /* | 73 | /* |
| 74 | * If the linux inode exists, mark it dirty. | ||
| 75 | * Used when commiting a dirty inode into a transaction so that | ||
| 76 | * the inode will get written back by the linux code | ||
| 77 | */ | ||
| 78 | void | ||
| 79 | xfs_mark_inode_dirty_sync( | ||
| 80 | xfs_inode_t *ip) | ||
| 81 | { | ||
| 82 | bhv_vnode_t *vp; | ||
| 83 | |||
| 84 | vp = XFS_ITOV_NULL(ip); | ||
| 85 | if (vp) | ||
| 86 | mark_inode_dirty_sync(vn_to_inode(vp)); | ||
| 87 | } | ||
| 88 | |||
| 89 | /* | ||
| 74 | * Change the requested timestamp in the given inode. | 90 | * Change the requested timestamp in the given inode. |
| 75 | * We don't lock across timestamp updates, and we don't log them but | 91 | * We don't lock across timestamp updates, and we don't log them but |
| 76 | * we do record the fact that there is dirty information in core. | 92 | * we do record the fact that there is dirty information in core. |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index eecc33d3751f..f01b07687faf 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
| @@ -140,27 +140,9 @@ again: | |||
| 140 | return ENOENT; | 140 | return ENOENT; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | /* | ||
| 144 | * There may be transactions sitting in the | ||
| 145 | * incore log buffers or being flushed to disk | ||
| 146 | * at this time. We can't clear the | ||
| 147 | * XFS_IRECLAIMABLE flag until these | ||
| 148 | * transactions have hit the disk, otherwise we | ||
| 149 | * will void the guarantee the flag provides | ||
| 150 | * xfs_iunpin() | ||
| 151 | */ | ||
| 152 | if (xfs_ipincount(ip)) { | ||
| 153 | read_unlock(&pag->pag_ici_lock); | ||
| 154 | xfs_log_force(mp, 0, | ||
| 155 | XFS_LOG_FORCE|XFS_LOG_SYNC); | ||
| 156 | XFS_STATS_INC(xs_ig_frecycle); | ||
| 157 | goto again; | ||
| 158 | } | ||
| 159 | |||
| 160 | xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); | 143 | xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); |
| 161 | 144 | ||
| 162 | XFS_STATS_INC(xs_ig_found); | 145 | XFS_STATS_INC(xs_ig_found); |
| 163 | |||
| 164 | xfs_iflags_clear(ip, XFS_IRECLAIMABLE); | 146 | xfs_iflags_clear(ip, XFS_IRECLAIMABLE); |
| 165 | read_unlock(&pag->pag_ici_lock); | 147 | read_unlock(&pag->pag_ici_lock); |
| 166 | 148 | ||
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 597e0ed4d2b6..805cab7b2770 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
| @@ -2814,40 +2814,8 @@ xfs_iunpin( | |||
| 2814 | { | 2814 | { |
| 2815 | ASSERT(atomic_read(&ip->i_pincount) > 0); | 2815 | ASSERT(atomic_read(&ip->i_pincount) > 0); |
| 2816 | 2816 | ||
| 2817 | if (atomic_dec_and_lock(&ip->i_pincount, &ip->i_flags_lock)) { | 2817 | if (atomic_dec_and_test(&ip->i_pincount)) |
| 2818 | |||
| 2819 | /* | ||
| 2820 | * If the inode is currently being reclaimed, the link between | ||
| 2821 | * the bhv_vnode and the xfs_inode will be broken after the | ||
| 2822 | * XFS_IRECLAIM* flag is set. Hence, if these flags are not | ||
| 2823 | * set, then we can move forward and mark the linux inode dirty | ||
| 2824 | * knowing that it is still valid as it won't freed until after | ||
| 2825 | * the bhv_vnode<->xfs_inode link is broken in xfs_reclaim. The | ||
| 2826 | * i_flags_lock is used to synchronise the setting of the | ||
| 2827 | * XFS_IRECLAIM* flags and the breaking of the link, and so we | ||
| 2828 | * can execute atomically w.r.t to reclaim by holding this lock | ||
| 2829 | * here. | ||
| 2830 | * | ||
| 2831 | * However, we still need to issue the unpin wakeup call as the | ||
| 2832 | * inode reclaim may be blocked waiting for the inode to become | ||
| 2833 | * unpinned. | ||
| 2834 | */ | ||
| 2835 | |||
| 2836 | if (!__xfs_iflags_test(ip, XFS_IRECLAIM|XFS_IRECLAIMABLE)) { | ||
| 2837 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); | ||
| 2838 | struct inode *inode = NULL; | ||
| 2839 | |||
| 2840 | BUG_ON(vp == NULL); | ||
| 2841 | inode = vn_to_inode(vp); | ||
| 2842 | BUG_ON(inode->i_state & I_CLEAR); | ||
| 2843 | |||
| 2844 | /* make sync come back and flush this inode */ | ||
| 2845 | if (!(inode->i_state & (I_NEW|I_FREEING))) | ||
| 2846 | mark_inode_dirty_sync(inode); | ||
| 2847 | } | ||
| 2848 | spin_unlock(&ip->i_flags_lock); | ||
| 2849 | wake_up(&ip->i_ipin_wait); | 2818 | wake_up(&ip->i_ipin_wait); |
| 2850 | } | ||
| 2851 | } | 2819 | } |
| 2852 | 2820 | ||
| 2853 | /* | 2821 | /* |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index d8ed51e28cbb..bc869fd2f6ef 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
| @@ -532,6 +532,7 @@ xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); | |||
| 532 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); | 532 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); |
| 533 | 533 | ||
| 534 | void xfs_synchronize_atime(xfs_inode_t *); | 534 | void xfs_synchronize_atime(xfs_inode_t *); |
| 535 | void xfs_mark_inode_dirty_sync(xfs_inode_t *); | ||
| 535 | 536 | ||
| 536 | xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); | 537 | xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); |
| 537 | void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t, | 538 | void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t, |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index e365b137ee4f..034ca7202295 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
| @@ -274,6 +274,11 @@ xfs_inode_item_format( | |||
| 274 | */ | 274 | */ |
| 275 | xfs_synchronize_atime(ip); | 275 | xfs_synchronize_atime(ip); |
| 276 | 276 | ||
| 277 | /* | ||
| 278 | * make sure the linux inode is dirty | ||
| 279 | */ | ||
| 280 | xfs_mark_inode_dirty_sync(ip); | ||
| 281 | |||
| 277 | vecp->i_addr = (xfs_caddr_t)&ip->i_d; | 282 | vecp->i_addr = (xfs_caddr_t)&ip->i_d; |
| 278 | vecp->i_len = sizeof(xfs_dinode_core_t); | 283 | vecp->i_len = sizeof(xfs_dinode_core_t); |
| 279 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE); | 284 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE); |
