2005-04-16 15:20:36 -07:00
/*
2005-11-02 14:58:39 +11:00
* Copyright ( c ) 2000 - 2005 Silicon Graphics , Inc .
* All Rights Reserved .
2005-04-16 15:20:36 -07:00
*
2005-11-02 14:58:39 +11:00
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
2005-04-16 15:20:36 -07:00
* published by the Free Software Foundation .
*
2005-11-02 14:58:39 +11:00
* This program is distributed in the hope that it would be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2005-04-16 15:20:36 -07:00
*
2005-11-02 14:58:39 +11:00
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
2005-04-16 15:20:36 -07:00
*/
# include "xfs.h"
2005-11-02 14:38:42 +11:00
# include "xfs_fs.h"
2005-04-16 15:20:36 -07:00
# include "xfs_types.h"
2005-11-02 14:38:42 +11:00
# include "xfs_bit.h"
2005-04-16 15:20:36 -07:00
# include "xfs_log.h"
2005-11-02 14:38:42 +11:00
# include "xfs_inum.h"
2005-04-16 15:20:36 -07:00
# include "xfs_trans.h"
# include "xfs_sb.h"
2005-11-02 14:38:42 +11:00
# include "xfs_ag.h"
2005-04-16 15:20:36 -07:00
# include "xfs_dir2.h"
# include "xfs_dmapi.h"
# include "xfs_mount.h"
2005-11-02 14:38:42 +11:00
# include "xfs_da_btree.h"
2005-04-16 15:20:36 -07:00
# include "xfs_bmap_btree.h"
# include "xfs_ialloc_btree.h"
# include "xfs_alloc_btree.h"
# include "xfs_dir2_sf.h"
2005-11-02 14:38:42 +11:00
# include "xfs_attr_sf.h"
2005-04-16 15:20:36 -07:00
# include "xfs_dinode.h"
# include "xfs_inode.h"
2005-11-02 14:38:42 +11:00
# include "xfs_inode_item.h"
# include "xfs_btree.h"
# include "xfs_alloc.h"
# include "xfs_ialloc.h"
# include "xfs_quota.h"
2005-04-16 15:20:36 -07:00
# include "xfs_error.h"
# include "xfs_bmap.h"
# include "xfs_rw.h"
# include "xfs_buf_item.h"
2005-11-02 14:38:42 +11:00
# include "xfs_log_priv.h"
2005-04-16 15:20:36 -07:00
# include "xfs_dir2_trace.h"
2005-11-02 14:38:42 +11:00
# include "xfs_extfree_item.h"
2005-04-16 15:20:36 -07:00
# include "xfs_acl.h"
# include "xfs_attr.h"
# include "xfs_clnt.h"
2007-07-11 11:09:12 +10:00
# include "xfs_mru_cache.h"
# include "xfs_filestream.h"
2006-01-11 15:30:08 +11:00
# include "xfs_fsops.h"
2007-08-29 10:58:01 +10:00
# include "xfs_vnodeops.h"
2007-08-30 17:20:31 +10:00
# include "xfs_vfsops.h"
2008-03-27 18:01:08 +11:00
# include "xfs_utils.h"
2008-10-30 17:06:08 +11:00
# include "xfs_sync.h"
2007-08-29 10:58:01 +10:00
2005-04-16 15:20:36 -07:00
/*
* xfs_unmount_flush implements a set of flush operation on special
* inodes , which are needed as a separate set of operations so that
* they can be called as part of relocation process .
*/
int
xfs_unmount_flush (
xfs_mount_t * mp , /* Mount structure we are getting
rid of . */
int relocation ) /* Called from vfs relocation. */
{
xfs_inode_t * rip = mp - > m_rootip ;
xfs_inode_t * rbmip ;
xfs_inode_t * rsumip = NULL ;
int error ;
2007-05-08 13:50:19 +10:00
xfs_ilock ( rip , XFS_ILOCK_EXCL | XFS_ILOCK_PARENT ) ;
2005-04-16 15:20:36 -07:00
xfs_iflock ( rip ) ;
/*
* Flush out the real time inodes .
*/
if ( ( rbmip = mp - > m_rbmip ) ! = NULL ) {
xfs_ilock ( rbmip , XFS_ILOCK_EXCL ) ;
xfs_iflock ( rbmip ) ;
error = xfs_iflush ( rbmip , XFS_IFLUSH_SYNC ) ;
xfs_iunlock ( rbmip , XFS_ILOCK_EXCL ) ;
if ( error = = EFSCORRUPTED )
goto fscorrupt_out ;
2008-08-13 16:00:45 +10:00
ASSERT ( vn_count ( VFS_I ( rbmip ) ) = = 1 ) ;
2005-04-16 15:20:36 -07:00
rsumip = mp - > m_rsumip ;
xfs_ilock ( rsumip , XFS_ILOCK_EXCL ) ;
xfs_iflock ( rsumip ) ;
error = xfs_iflush ( rsumip , XFS_IFLUSH_SYNC ) ;
xfs_iunlock ( rsumip , XFS_ILOCK_EXCL ) ;
if ( error = = EFSCORRUPTED )
goto fscorrupt_out ;
2008-08-13 16:00:45 +10:00
ASSERT ( vn_count ( VFS_I ( rsumip ) ) = = 1 ) ;
2005-04-16 15:20:36 -07:00
}
/*
* Synchronously flush root inode to disk
*/
error = xfs_iflush ( rip , XFS_IFLUSH_SYNC ) ;
if ( error = = EFSCORRUPTED )
goto fscorrupt_out2 ;
2008-08-13 16:22:09 +10:00
if ( vn_count ( VFS_I ( rip ) ) ! = 1 & & ! relocation ) {
2005-04-16 15:20:36 -07:00
xfs_iunlock ( rip , XFS_ILOCK_EXCL ) ;
return XFS_ERROR ( EBUSY ) ;
}
/*
* Release dquot that rootinode , rbmino and rsumino might be holding ,
* flush and purge the quota inodes .
*/
error = XFS_QM_UNMOUNT ( mp ) ;
if ( error = = EFSCORRUPTED )
goto fscorrupt_out2 ;
if ( rbmip ) {
2008-03-27 18:01:08 +11:00
IRELE ( rbmip ) ;
IRELE ( rsumip ) ;
2005-04-16 15:20:36 -07:00
}
xfs_iunlock ( rip , XFS_ILOCK_EXCL ) ;
return 0 ;
fscorrupt_out :
xfs_ifunlock ( rip ) ;
fscorrupt_out2 :
xfs_iunlock ( rip , XFS_ILOCK_EXCL ) ;
return XFS_ERROR ( EFSCORRUPTED ) ;
}