xref: /linux/fs/jfs/jfs_umount.c (revision 1c8007b0769d37aa5fcb343b383b0af89ade2f71)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *   Copyright (C) International Business Machines Corp., 2000-2004
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  *   This program is free software;  you can redistribute it and/or modify
51da177e4SLinus Torvalds  *   it under the terms of the GNU General Public License as published by
61da177e4SLinus Torvalds  *   the Free Software Foundation; either version 2 of the License, or
71da177e4SLinus Torvalds  *   (at your option) any later version.
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  *   This program is distributed in the hope that it will be useful,
101da177e4SLinus Torvalds  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
111da177e4SLinus Torvalds  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
121da177e4SLinus Torvalds  *   the GNU General Public License for more details.
131da177e4SLinus Torvalds  *
141da177e4SLinus Torvalds  *   You should have received a copy of the GNU General Public License
151da177e4SLinus Torvalds  *   along with this program;  if not, write to the Free Software
161da177e4SLinus Torvalds  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
171da177e4SLinus Torvalds  */
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds /*
201da177e4SLinus Torvalds  *	jfs_umount.c
211da177e4SLinus Torvalds  *
221da177e4SLinus Torvalds  * note: file system in transition to aggregate/fileset:
231da177e4SLinus Torvalds  * (ref. jfs_mount.c)
241da177e4SLinus Torvalds  *
251da177e4SLinus Torvalds  * file system unmount is interpreted as mount of the single/only
261da177e4SLinus Torvalds  * fileset in the aggregate and, if unmount of the last fileset,
271da177e4SLinus Torvalds  * as unmount of the aggerate;
281da177e4SLinus Torvalds  */
291da177e4SLinus Torvalds 
301da177e4SLinus Torvalds #include <linux/fs.h>
311da177e4SLinus Torvalds #include "jfs_incore.h"
321da177e4SLinus Torvalds #include "jfs_filsys.h"
331da177e4SLinus Torvalds #include "jfs_superblock.h"
341da177e4SLinus Torvalds #include "jfs_dmap.h"
351da177e4SLinus Torvalds #include "jfs_imap.h"
361da177e4SLinus Torvalds #include "jfs_metapage.h"
371da177e4SLinus Torvalds #include "jfs_debug.h"
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds /*
401da177e4SLinus Torvalds  * NAME:	jfs_umount(vfsp, flags, crp)
411da177e4SLinus Torvalds  *
421da177e4SLinus Torvalds  * FUNCTION:	vfs_umount()
431da177e4SLinus Torvalds  *
441da177e4SLinus Torvalds  * PARAMETERS:	vfsp	- virtual file system pointer
451da177e4SLinus Torvalds  *		flags	- unmount for shutdown
461da177e4SLinus Torvalds  *		crp	- credential
471da177e4SLinus Torvalds  *
481da177e4SLinus Torvalds  * RETURN :	EBUSY	- device has open files
491da177e4SLinus Torvalds  */
501da177e4SLinus Torvalds int jfs_umount(struct super_block *sb)
511da177e4SLinus Torvalds {
521da177e4SLinus Torvalds 	struct jfs_sb_info *sbi = JFS_SBI(sb);
531da177e4SLinus Torvalds 	struct inode *ipbmap = sbi->ipbmap;
541da177e4SLinus Torvalds 	struct inode *ipimap = sbi->ipimap;
551da177e4SLinus Torvalds 	struct inode *ipaimap = sbi->ipaimap;
561da177e4SLinus Torvalds 	struct inode *ipaimap2 = sbi->ipaimap2;
571da177e4SLinus Torvalds 	struct jfs_log *log;
581da177e4SLinus Torvalds 	int rc = 0;
591da177e4SLinus Torvalds 
601da177e4SLinus Torvalds 	jfs_info("UnMount JFS: sb:0x%p", sb);
611da177e4SLinus Torvalds 
621da177e4SLinus Torvalds 	/*
631da177e4SLinus Torvalds 	 *	update superblock and close log
641da177e4SLinus Torvalds 	 *
651da177e4SLinus Torvalds 	 * if mounted read-write and log based recovery was enabled
661da177e4SLinus Torvalds 	 */
671da177e4SLinus Torvalds 	if ((log = sbi->log))
681da177e4SLinus Torvalds 		/*
691da177e4SLinus Torvalds 		 * Wait for outstanding transactions to be written to log:
701da177e4SLinus Torvalds 		 */
71*1c8007b0SDave Kleikamp 		jfs_flush_journal(log, 2);
721da177e4SLinus Torvalds 
731da177e4SLinus Torvalds 	/*
741da177e4SLinus Torvalds 	 * close fileset inode allocation map (aka fileset inode)
751da177e4SLinus Torvalds 	 */
761da177e4SLinus Torvalds 	diUnmount(ipimap, 0);
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds 	diFreeSpecial(ipimap);
791da177e4SLinus Torvalds 	sbi->ipimap = NULL;
801da177e4SLinus Torvalds 
811da177e4SLinus Torvalds 	/*
821da177e4SLinus Torvalds 	 * close secondary aggregate inode allocation map
831da177e4SLinus Torvalds 	 */
841da177e4SLinus Torvalds 	ipaimap2 = sbi->ipaimap2;
851da177e4SLinus Torvalds 	if (ipaimap2) {
861da177e4SLinus Torvalds 		diUnmount(ipaimap2, 0);
871da177e4SLinus Torvalds 		diFreeSpecial(ipaimap2);
881da177e4SLinus Torvalds 		sbi->ipaimap2 = NULL;
891da177e4SLinus Torvalds 	}
901da177e4SLinus Torvalds 
911da177e4SLinus Torvalds 	/*
921da177e4SLinus Torvalds 	 * close aggregate inode allocation map
931da177e4SLinus Torvalds 	 */
941da177e4SLinus Torvalds 	ipaimap = sbi->ipaimap;
951da177e4SLinus Torvalds 	diUnmount(ipaimap, 0);
961da177e4SLinus Torvalds 	diFreeSpecial(ipaimap);
971da177e4SLinus Torvalds 	sbi->ipaimap = NULL;
981da177e4SLinus Torvalds 
991da177e4SLinus Torvalds 	/*
1001da177e4SLinus Torvalds 	 * close aggregate block allocation map
1011da177e4SLinus Torvalds 	 */
1021da177e4SLinus Torvalds 	dbUnmount(ipbmap, 0);
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds 	diFreeSpecial(ipbmap);
1051da177e4SLinus Torvalds 	sbi->ipimap = NULL;
1061da177e4SLinus Torvalds 
1071da177e4SLinus Torvalds 	/*
1081da177e4SLinus Torvalds 	 * Make sure all metadata makes it to disk before we mark
1091da177e4SLinus Torvalds 	 * the superblock as clean
1101da177e4SLinus Torvalds 	 */
11128fd1298SOGAWA Hirofumi 	filemap_write_and_wait(sbi->direct_inode->i_mapping);
1121da177e4SLinus Torvalds 
1131da177e4SLinus Torvalds 	/*
1141da177e4SLinus Torvalds 	 * ensure all file system file pages are propagated to their
1151da177e4SLinus Torvalds 	 * home blocks on disk (and their in-memory buffer pages are
1161da177e4SLinus Torvalds 	 * invalidated) BEFORE updating file system superblock state
1171da177e4SLinus Torvalds 	 * (to signify file system is unmounted cleanly, and thus in
1181da177e4SLinus Torvalds 	 * consistent state) and log superblock active file system
1191da177e4SLinus Torvalds 	 * list (to signify skip logredo()).
1201da177e4SLinus Torvalds 	 */
1211da177e4SLinus Torvalds 	if (log) {		/* log = NULL if read-only mount */
1221da177e4SLinus Torvalds 		updateSuper(sb, FM_CLEAN);
1231da177e4SLinus Torvalds 
1241da177e4SLinus Torvalds 		/*
1251da177e4SLinus Torvalds 		 * close log:
1261da177e4SLinus Torvalds 		 *
1271da177e4SLinus Torvalds 		 * remove file system from log active file system list.
1281da177e4SLinus Torvalds 		 */
1291da177e4SLinus Torvalds 		rc = lmLogClose(sb);
1301da177e4SLinus Torvalds 	}
1311da177e4SLinus Torvalds 	jfs_info("UnMount JFS Complete: rc = %d", rc);
1321da177e4SLinus Torvalds 	return rc;
1331da177e4SLinus Torvalds }
1341da177e4SLinus Torvalds 
1351da177e4SLinus Torvalds 
1361da177e4SLinus Torvalds int jfs_umount_rw(struct super_block *sb)
1371da177e4SLinus Torvalds {
1381da177e4SLinus Torvalds 	struct jfs_sb_info *sbi = JFS_SBI(sb);
1391da177e4SLinus Torvalds 	struct jfs_log *log = sbi->log;
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds 	if (!log)
1421da177e4SLinus Torvalds 		return 0;
1431da177e4SLinus Torvalds 
1441da177e4SLinus Torvalds 	/*
1451da177e4SLinus Torvalds 	 * close log:
1461da177e4SLinus Torvalds 	 *
1471da177e4SLinus Torvalds 	 * remove file system from log active file system list.
1481da177e4SLinus Torvalds 	 */
149*1c8007b0SDave Kleikamp 	jfs_flush_journal(log, 2);
1501da177e4SLinus Torvalds 
1511da177e4SLinus Torvalds 	/*
1521da177e4SLinus Torvalds 	 * Make sure all metadata makes it to disk
1531da177e4SLinus Torvalds 	 */
1541da177e4SLinus Torvalds 	dbSync(sbi->ipbmap);
1551da177e4SLinus Torvalds 	diSync(sbi->ipimap);
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds 	/*
1581da177e4SLinus Torvalds 	 * Note that we have to do this even if sync_blockdev() will
1591da177e4SLinus Torvalds 	 * do exactly the same a few instructions later:  We can't
1601da177e4SLinus Torvalds 	 * mark the superblock clean before everything is flushed to
1611da177e4SLinus Torvalds 	 * disk.
1621da177e4SLinus Torvalds 	 */
16328fd1298SOGAWA Hirofumi 	filemap_write_and_wait(sbi->direct_inode->i_mapping);
1641da177e4SLinus Torvalds 
1651da177e4SLinus Torvalds 	updateSuper(sb, FM_CLEAN);
1661da177e4SLinus Torvalds 
1671da177e4SLinus Torvalds 	return lmLogClose(sb);
1681da177e4SLinus Torvalds }
169