diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 185 |
1 files changed, 41 insertions, 144 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index bc8c8c7f9039..34bdf5909687 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -146,51 +146,6 @@ xfs_inobp_check( | |||
146 | #endif | 146 | #endif |
147 | 147 | ||
148 | /* | 148 | /* |
149 | * called from bwrite on xfs inode buffers | ||
150 | */ | ||
151 | void | ||
152 | xfs_inobp_bwcheck(xfs_buf_t *bp) | ||
153 | { | ||
154 | xfs_mount_t *mp; | ||
155 | int i; | ||
156 | int j; | ||
157 | xfs_dinode_t *dip; | ||
158 | |||
159 | ASSERT(XFS_BUF_FSPRIVATE3(bp, void *) != NULL); | ||
160 | |||
161 | mp = XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *); | ||
162 | |||
163 | |||
164 | j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog; | ||
165 | |||
166 | for (i = 0; i < j; i++) { | ||
167 | dip = (xfs_dinode_t *) xfs_buf_offset(bp, | ||
168 | i * mp->m_sb.sb_inodesize); | ||
169 | if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) { | ||
170 | cmn_err(CE_WARN, | ||
171 | "Bad magic # 0x%x in XFS inode buffer 0x%Lx, starting blockno %Ld, offset 0x%x", | ||
172 | INT_GET(dip->di_core.di_magic, ARCH_CONVERT), | ||
173 | (__uint64_t)(__psunsigned_t) bp, | ||
174 | (__int64_t) XFS_BUF_ADDR(bp), | ||
175 | xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize)); | ||
176 | xfs_fs_cmn_err(CE_WARN, mp, | ||
177 | "corrupt, unmount and run xfs_repair"); | ||
178 | } | ||
179 | if (!dip->di_next_unlinked) { | ||
180 | cmn_err(CE_WARN, | ||
181 | "Bad next_unlinked field (0) in XFS inode buffer 0x%p, starting blockno %Ld, offset 0x%x", | ||
182 | (__uint64_t)(__psunsigned_t) bp, | ||
183 | (__int64_t) XFS_BUF_ADDR(bp), | ||
184 | xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize)); | ||
185 | xfs_fs_cmn_err(CE_WARN, mp, | ||
186 | "corrupt, unmount and run xfs_repair"); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | return; | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * This routine is called to map an inode number within a file | 149 | * This routine is called to map an inode number within a file |
195 | * system to the buffer containing the on-disk version of the | 150 | * system to the buffer containing the on-disk version of the |
196 | * inode. It returns a pointer to the buffer containing the | 151 | * inode. It returns a pointer to the buffer containing the |
@@ -203,7 +158,7 @@ xfs_inobp_bwcheck(xfs_buf_t *bp) | |||
203 | * Use xfs_imap() to determine the size and location of the | 158 | * Use xfs_imap() to determine the size and location of the |
204 | * buffer to read from disk. | 159 | * buffer to read from disk. |
205 | */ | 160 | */ |
206 | int | 161 | STATIC int |
207 | xfs_inotobp( | 162 | xfs_inotobp( |
208 | xfs_mount_t *mp, | 163 | xfs_mount_t *mp, |
209 | xfs_trans_t *tp, | 164 | xfs_trans_t *tp, |
@@ -1247,26 +1202,32 @@ xfs_ialloc( | |||
1247 | case S_IFREG: | 1202 | case S_IFREG: |
1248 | case S_IFDIR: | 1203 | case S_IFDIR: |
1249 | if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) { | 1204 | if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) { |
1250 | if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { | 1205 | uint di_flags = 0; |
1251 | if ((mode & S_IFMT) == S_IFDIR) { | 1206 | |
1252 | ip->i_d.di_flags |= XFS_DIFLAG_RTINHERIT; | 1207 | if ((mode & S_IFMT) == S_IFDIR) { |
1253 | } else { | 1208 | if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) |
1254 | ip->i_d.di_flags |= XFS_DIFLAG_REALTIME; | 1209 | di_flags |= XFS_DIFLAG_RTINHERIT; |
1210 | } else { | ||
1211 | if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { | ||
1212 | di_flags |= XFS_DIFLAG_REALTIME; | ||
1255 | ip->i_iocore.io_flags |= XFS_IOCORE_RT; | 1213 | ip->i_iocore.io_flags |= XFS_IOCORE_RT; |
1256 | } | 1214 | } |
1257 | } | 1215 | } |
1258 | if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) && | 1216 | if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) && |
1259 | xfs_inherit_noatime) | 1217 | xfs_inherit_noatime) |
1260 | ip->i_d.di_flags |= XFS_DIFLAG_NOATIME; | 1218 | di_flags |= XFS_DIFLAG_NOATIME; |
1261 | if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) && | 1219 | if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) && |
1262 | xfs_inherit_nodump) | 1220 | xfs_inherit_nodump) |
1263 | ip->i_d.di_flags |= XFS_DIFLAG_NODUMP; | 1221 | di_flags |= XFS_DIFLAG_NODUMP; |
1264 | if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) && | 1222 | if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) && |
1265 | xfs_inherit_sync) | 1223 | xfs_inherit_sync) |
1266 | ip->i_d.di_flags |= XFS_DIFLAG_SYNC; | 1224 | di_flags |= XFS_DIFLAG_SYNC; |
1267 | if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) && | 1225 | if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) && |
1268 | xfs_inherit_nosymlinks) | 1226 | xfs_inherit_nosymlinks) |
1269 | ip->i_d.di_flags |= XFS_DIFLAG_NOSYMLINKS; | 1227 | di_flags |= XFS_DIFLAG_NOSYMLINKS; |
1228 | if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | ||
1229 | di_flags |= XFS_DIFLAG_PROJINHERIT; | ||
1230 | ip->i_d.di_flags |= di_flags; | ||
1270 | } | 1231 | } |
1271 | /* FALLTHROUGH */ | 1232 | /* FALLTHROUGH */ |
1272 | case S_IFLNK: | 1233 | case S_IFLNK: |
@@ -2156,7 +2117,7 @@ static __inline__ int xfs_inode_clean(xfs_inode_t *ip) | |||
2156 | (ip->i_update_core == 0)); | 2117 | (ip->i_update_core == 0)); |
2157 | } | 2118 | } |
2158 | 2119 | ||
2159 | void | 2120 | STATIC void |
2160 | xfs_ifree_cluster( | 2121 | xfs_ifree_cluster( |
2161 | xfs_inode_t *free_ip, | 2122 | xfs_inode_t *free_ip, |
2162 | xfs_trans_t *tp, | 2123 | xfs_trans_t *tp, |
@@ -2875,7 +2836,7 @@ xfs_iunpin( | |||
2875 | * be subsequently pinned once someone is waiting for it to be | 2836 | * be subsequently pinned once someone is waiting for it to be |
2876 | * unpinned. | 2837 | * unpinned. |
2877 | */ | 2838 | */ |
2878 | void | 2839 | STATIC void |
2879 | xfs_iunpin_wait( | 2840 | xfs_iunpin_wait( |
2880 | xfs_inode_t *ip) | 2841 | xfs_inode_t *ip) |
2881 | { | 2842 | { |
@@ -3601,107 +3562,43 @@ corrupt_out: | |||
3601 | 3562 | ||
3602 | 3563 | ||
3603 | /* | 3564 | /* |
3604 | * Flush all inactive inodes in mp. Return true if no user references | 3565 | * Flush all inactive inodes in mp. |
3605 | * were found, false otherwise. | ||
3606 | */ | 3566 | */ |
3607 | int | 3567 | void |
3608 | xfs_iflush_all( | 3568 | xfs_iflush_all( |
3609 | xfs_mount_t *mp, | 3569 | xfs_mount_t *mp) |
3610 | int flag) | ||
3611 | { | 3570 | { |
3612 | int busy; | ||
3613 | int done; | ||
3614 | int purged; | ||
3615 | xfs_inode_t *ip; | 3571 | xfs_inode_t *ip; |
3616 | vmap_t vmap; | ||
3617 | vnode_t *vp; | 3572 | vnode_t *vp; |
3618 | 3573 | ||
3619 | busy = done = 0; | 3574 | again: |
3620 | while (!done) { | 3575 | XFS_MOUNT_ILOCK(mp); |
3621 | purged = 0; | 3576 | ip = mp->m_inodes; |
3622 | XFS_MOUNT_ILOCK(mp); | 3577 | if (ip == NULL) |
3623 | ip = mp->m_inodes; | 3578 | goto out; |
3624 | if (ip == NULL) { | ||
3625 | break; | ||
3626 | } | ||
3627 | do { | ||
3628 | /* Make sure we skip markers inserted by sync */ | ||
3629 | if (ip->i_mount == NULL) { | ||
3630 | ip = ip->i_mnext; | ||
3631 | continue; | ||
3632 | } | ||
3633 | |||
3634 | /* | ||
3635 | * It's up to our caller to purge the root | ||
3636 | * and quota vnodes later. | ||
3637 | */ | ||
3638 | vp = XFS_ITOV_NULL(ip); | ||
3639 | |||
3640 | if (!vp) { | ||
3641 | XFS_MOUNT_IUNLOCK(mp); | ||
3642 | xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC); | ||
3643 | purged = 1; | ||
3644 | break; | ||
3645 | } | ||
3646 | 3579 | ||
3647 | if (vn_count(vp) != 0) { | 3580 | do { |
3648 | if (vn_count(vp) == 1 && | 3581 | /* Make sure we skip markers inserted by sync */ |
3649 | (ip == mp->m_rootip || | 3582 | if (ip->i_mount == NULL) { |
3650 | (mp->m_quotainfo && | 3583 | ip = ip->i_mnext; |
3651 | (ip->i_ino == mp->m_sb.sb_uquotino || | 3584 | continue; |
3652 | ip->i_ino == mp->m_sb.sb_gquotino)))) { | 3585 | } |
3653 | 3586 | ||
3654 | ip = ip->i_mnext; | 3587 | vp = XFS_ITOV_NULL(ip); |
3655 | continue; | 3588 | if (!vp) { |
3656 | } | ||
3657 | if (!(flag & XFS_FLUSH_ALL)) { | ||
3658 | busy = 1; | ||
3659 | done = 1; | ||
3660 | break; | ||
3661 | } | ||
3662 | /* | ||
3663 | * Ignore busy inodes but continue flushing | ||
3664 | * others. | ||
3665 | */ | ||
3666 | ip = ip->i_mnext; | ||
3667 | continue; | ||
3668 | } | ||
3669 | /* | ||
3670 | * Sample vp mapping while holding mp locked on MP | ||
3671 | * systems, so we don't purge a reclaimed or | ||
3672 | * nonexistent vnode. We break from the loop | ||
3673 | * since we know that we modify | ||
3674 | * it by pulling ourselves from it in xfs_reclaim() | ||
3675 | * called via vn_purge() below. Set ip to the next | ||
3676 | * entry in the list anyway so we'll know below | ||
3677 | * whether we reached the end or not. | ||
3678 | */ | ||
3679 | VMAP(vp, vmap); | ||
3680 | XFS_MOUNT_IUNLOCK(mp); | 3589 | XFS_MOUNT_IUNLOCK(mp); |
3590 | xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC); | ||
3591 | goto again; | ||
3592 | } | ||
3681 | 3593 | ||
3682 | vn_purge(vp, &vmap); | 3594 | ASSERT(vn_count(vp) == 0); |
3683 | 3595 | ||
3684 | purged = 1; | 3596 | ip = ip->i_mnext; |
3685 | break; | 3597 | } while (ip != mp->m_inodes); |
3686 | } while (ip != mp->m_inodes); | 3598 | out: |
3687 | /* | ||
3688 | * We need to distinguish between when we exit the loop | ||
3689 | * after a purge and when we simply hit the end of the | ||
3690 | * list. We can't use the (ip == mp->m_inodes) test, | ||
3691 | * because when we purge an inode at the start of the list | ||
3692 | * the next inode on the list becomes mp->m_inodes. That | ||
3693 | * would cause such a test to bail out early. The purged | ||
3694 | * variable tells us how we got out of the loop. | ||
3695 | */ | ||
3696 | if (!purged) { | ||
3697 | done = 1; | ||
3698 | } | ||
3699 | } | ||
3700 | XFS_MOUNT_IUNLOCK(mp); | 3599 | XFS_MOUNT_IUNLOCK(mp); |
3701 | return !busy; | ||
3702 | } | 3600 | } |
3703 | 3601 | ||
3704 | |||
3705 | /* | 3602 | /* |
3706 | * xfs_iaccess: check accessibility of inode for mode. | 3603 | * xfs_iaccess: check accessibility of inode for mode. |
3707 | */ | 3604 | */ |