aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h5
-rw-r--r--fs/xfs/quota/xfs_qm.c44
-rw-r--r--fs/xfs/quota/xfs_qm.h2
-rw-r--r--fs/xfs/xfs_mount.h2
-rw-r--r--fs/xfs/xfs_vfsops.c68
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);
65extern void vn_iowake(struct xfs_inode *ip); 65extern void vn_iowake(struct xfs_inode *ip);
66extern void vn_ioerror(struct xfs_inode *ip, int error, char *f, int l); 66extern void vn_ioerror(struct xfs_inode *ip, int error, char *f, int l);
67 67
68static 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) \
74do { \ 69do { \
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 */
398int 398void
399xfs_qm_unmount_quotas( 399xfs_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 }
452out:
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 *);
167extern void xfs_qm_mount_quotas(xfs_mount_t *); 167extern void xfs_qm_mount_quotas(xfs_mount_t *);
168extern int xfs_qm_quotacheck(xfs_mount_t *); 168extern int xfs_qm_quotacheck(xfs_mount_t *);
169extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); 169extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *);
170extern int xfs_qm_unmount_quotas(xfs_mount_t *); 170extern void xfs_qm_unmount_quotas(xfs_mount_t *);
171extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t); 171extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
172extern int xfs_qm_sync(xfs_mount_t *, int); 172extern 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
118typedef int (*xfs_qminit_t)(struct xfs_mount *, uint *, uint *); 118typedef int (*xfs_qminit_t)(struct xfs_mount *, uint *, uint *);
119typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint); 119typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint);
120typedef int (*xfs_qmunmount_t)(struct xfs_mount *); 120typedef void (*xfs_qmunmount_t)(struct xfs_mount *);
121typedef void (*xfs_qmdone_t)(struct xfs_mount *); 121typedef void (*xfs_qmdone_t)(struct xfs_mount *);
122typedef void (*xfs_dqrele_t)(struct xfs_dquot *); 122typedef void (*xfs_dqrele_t)(struct xfs_dquot *);
123typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint); 123typedef 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
133fscorrupt_out:
134 xfs_ifunlock(rip);
135
136fscorrupt_out2:
137 xfs_iunlock(rip, XFS_ILOCK_EXCL);
138
139 return XFS_ERROR(EFSCORRUPTED);
140} 83}
141