diff options
author | Christoph Hellwig <hch@lst.de> | 2008-12-03 06:20:36 -0500 |
---|---|---|
committer | Niv Sardi <xaiki@sgi.com> | 2008-12-03 23:39:23 -0500 |
commit | e57481dc269cd3773b22f53bfb869308780a7bf1 (patch) | |
tree | 0f93e375521a9afc49a8b5e143a0cff1945fc365 | |
parent | 070c4616ec62fc207e2aeef9d0f28af294c651d0 (diff) |
no explicit xfs_iflush for special inodes during unmount
Currently we explicitly call xfs_iflush on the quota, real-time and root
inodes from xfs_unmount_flush. But we just called xfs_sync_inodes with
SYNC_ATTR and do an XFS_bflush aka xfs_flush_buftarg to make sure all inodes
are on disk already, so there is no need for these special cases.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
-rw-r--r-- | fs/xfs/linux-2.6/xfs_vnode.h | 5 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 44 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 68 |
5 files changed, 15 insertions, 106 deletions
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index fb49e0f42d31..314ca18bc603 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
@@ -65,11 +65,6 @@ extern void vn_iowait(struct xfs_inode *ip); | |||
65 | extern void vn_iowake(struct xfs_inode *ip); | 65 | extern void vn_iowake(struct xfs_inode *ip); |
66 | extern void vn_ioerror(struct xfs_inode *ip, int error, char *f, int l); | 66 | extern void vn_ioerror(struct xfs_inode *ip, int error, char *f, int l); |
67 | 67 | ||
68 | static inline int vn_count(struct inode *vp) | ||
69 | { | ||
70 | return atomic_read(&vp->i_count); | ||
71 | } | ||
72 | |||
73 | #define IHOLD(ip) \ | 68 | #define IHOLD(ip) \ |
74 | do { \ | 69 | do { \ |
75 | ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \ | 70 | ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \ |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 5b198d15e76b..6b13960cf318 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -395,13 +395,10 @@ xfs_qm_mount_quotas( | |||
395 | /* | 395 | /* |
396 | * Called from the vfsops layer. | 396 | * Called from the vfsops layer. |
397 | */ | 397 | */ |
398 | int | 398 | void |
399 | xfs_qm_unmount_quotas( | 399 | xfs_qm_unmount_quotas( |
400 | xfs_mount_t *mp) | 400 | xfs_mount_t *mp) |
401 | { | 401 | { |
402 | xfs_inode_t *uqp, *gqp; | ||
403 | int error = 0; | ||
404 | |||
405 | /* | 402 | /* |
406 | * Release the dquots that root inode, et al might be holding, | 403 | * Release the dquots that root inode, et al might be holding, |
407 | * before we flush quotas and blow away the quotainfo structure. | 404 | * before we flush quotas and blow away the quotainfo structure. |
@@ -414,43 +411,18 @@ xfs_qm_unmount_quotas( | |||
414 | xfs_qm_dqdetach(mp->m_rsumip); | 411 | xfs_qm_dqdetach(mp->m_rsumip); |
415 | 412 | ||
416 | /* | 413 | /* |
417 | * Flush out the quota inodes. | 414 | * Release the quota inodes. |
418 | */ | 415 | */ |
419 | uqp = gqp = NULL; | ||
420 | if (mp->m_quotainfo) { | 416 | if (mp->m_quotainfo) { |
421 | if ((uqp = mp->m_quotainfo->qi_uquotaip) != NULL) { | 417 | if (mp->m_quotainfo->qi_uquotaip) { |
422 | xfs_ilock(uqp, XFS_ILOCK_EXCL); | 418 | IRELE(mp->m_quotainfo->qi_uquotaip); |
423 | xfs_iflock(uqp); | 419 | mp->m_quotainfo->qi_uquotaip = NULL; |
424 | error = xfs_iflush(uqp, XFS_IFLUSH_SYNC); | ||
425 | xfs_iunlock(uqp, XFS_ILOCK_EXCL); | ||
426 | if (unlikely(error == EFSCORRUPTED)) { | ||
427 | XFS_ERROR_REPORT("xfs_qm_unmount_quotas(1)", | ||
428 | XFS_ERRLEVEL_LOW, mp); | ||
429 | goto out; | ||
430 | } | ||
431 | } | 420 | } |
432 | if ((gqp = mp->m_quotainfo->qi_gquotaip) != NULL) { | 421 | if (mp->m_quotainfo->qi_gquotaip) { |
433 | xfs_ilock(gqp, XFS_ILOCK_EXCL); | 422 | IRELE(mp->m_quotainfo->qi_gquotaip); |
434 | xfs_iflock(gqp); | 423 | mp->m_quotainfo->qi_gquotaip = NULL; |
435 | error = xfs_iflush(gqp, XFS_IFLUSH_SYNC); | ||
436 | xfs_iunlock(gqp, XFS_ILOCK_EXCL); | ||
437 | if (unlikely(error == EFSCORRUPTED)) { | ||
438 | XFS_ERROR_REPORT("xfs_qm_unmount_quotas(2)", | ||
439 | XFS_ERRLEVEL_LOW, mp); | ||
440 | goto out; | ||
441 | } | ||
442 | } | 424 | } |
443 | } | 425 | } |
444 | if (uqp) { | ||
445 | IRELE(uqp); | ||
446 | mp->m_quotainfo->qi_uquotaip = NULL; | ||
447 | } | ||
448 | if (gqp) { | ||
449 | IRELE(gqp); | ||
450 | mp->m_quotainfo->qi_gquotaip = NULL; | ||
451 | } | ||
452 | out: | ||
453 | return XFS_ERROR(error); | ||
454 | } | 426 | } |
455 | 427 | ||
456 | /* | 428 | /* |
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index 4f2de9771728..ddf09166387c 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h | |||
@@ -167,7 +167,7 @@ extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); | |||
167 | extern void xfs_qm_mount_quotas(xfs_mount_t *); | 167 | extern void xfs_qm_mount_quotas(xfs_mount_t *); |
168 | extern int xfs_qm_quotacheck(xfs_mount_t *); | 168 | extern int xfs_qm_quotacheck(xfs_mount_t *); |
169 | extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); | 169 | extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); |
170 | extern int xfs_qm_unmount_quotas(xfs_mount_t *); | 170 | extern void xfs_qm_unmount_quotas(xfs_mount_t *); |
171 | extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t); | 171 | extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t); |
172 | extern int xfs_qm_sync(xfs_mount_t *, int); | 172 | extern int xfs_qm_sync(xfs_mount_t *, int); |
173 | 173 | ||
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 2ab2df57b69a..4f64fd160cc1 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -117,7 +117,7 @@ struct xfs_quotainfo; | |||
117 | 117 | ||
118 | typedef int (*xfs_qminit_t)(struct xfs_mount *, uint *, uint *); | 118 | typedef int (*xfs_qminit_t)(struct xfs_mount *, uint *, uint *); |
119 | typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint); | 119 | typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint); |
120 | typedef int (*xfs_qmunmount_t)(struct xfs_mount *); | 120 | typedef void (*xfs_qmunmount_t)(struct xfs_mount *); |
121 | typedef void (*xfs_qmdone_t)(struct xfs_mount *); | 121 | typedef void (*xfs_qmdone_t)(struct xfs_mount *); |
122 | typedef void (*xfs_dqrele_t)(struct xfs_dquot *); | 122 | typedef void (*xfs_dqrele_t)(struct xfs_dquot *); |
123 | typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint); | 123 | typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint); |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index cad3da36fb22..559fb8d51084 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -68,74 +68,16 @@ xfs_unmount_flush( | |||
68 | rid of. */ | 68 | rid of. */ |
69 | int relocation) /* Called from vfs relocation. */ | 69 | int relocation) /* Called from vfs relocation. */ |
70 | { | 70 | { |
71 | xfs_inode_t *rip = mp->m_rootip; | ||
72 | xfs_inode_t *rbmip; | ||
73 | xfs_inode_t *rsumip = NULL; | ||
74 | int error; | ||
75 | |||
76 | xfs_ilock(rip, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | ||
77 | xfs_iflock(rip); | ||
78 | |||
79 | /* | ||
80 | * Flush out the real time inodes. | ||
81 | */ | ||
82 | if ((rbmip = mp->m_rbmip) != NULL) { | ||
83 | xfs_ilock(rbmip, XFS_ILOCK_EXCL); | ||
84 | xfs_iflock(rbmip); | ||
85 | error = xfs_iflush(rbmip, XFS_IFLUSH_SYNC); | ||
86 | xfs_iunlock(rbmip, XFS_ILOCK_EXCL); | ||
87 | |||
88 | if (error == EFSCORRUPTED) | ||
89 | goto fscorrupt_out; | ||
90 | |||
91 | ASSERT(vn_count(VFS_I(rbmip)) == 1); | ||
92 | |||
93 | rsumip = mp->m_rsumip; | ||
94 | xfs_ilock(rsumip, XFS_ILOCK_EXCL); | ||
95 | xfs_iflock(rsumip); | ||
96 | error = xfs_iflush(rsumip, XFS_IFLUSH_SYNC); | ||
97 | xfs_iunlock(rsumip, XFS_ILOCK_EXCL); | ||
98 | |||
99 | if (error == EFSCORRUPTED) | ||
100 | goto fscorrupt_out; | ||
101 | |||
102 | ASSERT(vn_count(VFS_I(rsumip)) == 1); | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * Synchronously flush root inode to disk | ||
107 | */ | ||
108 | error = xfs_iflush(rip, XFS_IFLUSH_SYNC); | ||
109 | if (error == EFSCORRUPTED) | ||
110 | goto fscorrupt_out2; | ||
111 | |||
112 | if (vn_count(VFS_I(rip)) != 1 && !relocation) { | ||
113 | xfs_iunlock(rip, XFS_ILOCK_EXCL); | ||
114 | return XFS_ERROR(EBUSY); | ||
115 | } | ||
116 | |||
117 | /* | 71 | /* |
118 | * Release dquot that rootinode, rbmino and rsumino might be holding, | 72 | * Release dquot that rootinode, rbmino and rsumino might be holding, |
119 | * flush and purge the quota inodes. | 73 | * flush and purge the quota inodes. |
120 | */ | 74 | */ |
121 | error = XFS_QM_UNMOUNT(mp); | 75 | XFS_QM_UNMOUNT(mp); |
122 | if (error == EFSCORRUPTED) | ||
123 | goto fscorrupt_out2; | ||
124 | 76 | ||
125 | if (rbmip) { | 77 | if (mp->m_rbmip) |
126 | IRELE(rbmip); | 78 | IRELE(mp->m_rbmip); |
127 | IRELE(rsumip); | 79 | if (mp->m_rsumip) |
128 | } | 80 | IRELE(mp->m_rsumip); |
129 | 81 | ||
130 | xfs_iunlock(rip, XFS_ILOCK_EXCL); | ||
131 | return 0; | 82 | return 0; |
132 | |||
133 | fscorrupt_out: | ||
134 | xfs_ifunlock(rip); | ||
135 | |||
136 | fscorrupt_out2: | ||
137 | xfs_iunlock(rip, XFS_ILOCK_EXCL); | ||
138 | |||
139 | return XFS_ERROR(EFSCORRUPTED); | ||
140 | } | 83 | } |
141 | |||