1 /*
2  *   Copyright (C) International Business Machines Corp., 2000-2004
3  *
4  *   This program is free software;  you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation; either version 2 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12  *   the GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program;  if not, write to the Free Software
16  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 
19 /*
20  *	jfs_umount.c
21  *
22  * note: file system in transition to aggregate/fileset:
23  * (ref. jfs_mount.c)
24  *
25  * file system unmount is interpreted as mount of the single/only
26  * fileset in the aggregate and, if unmount of the last fileset,
27  * as unmount of the aggerate;
28  */
29 
30 #include <linux/fs.h>
31 #include "jfs_incore.h"
32 #include "jfs_filsys.h"
33 #include "jfs_superblock.h"
34 #include "jfs_dmap.h"
35 #include "jfs_imap.h"
36 #include "jfs_metapage.h"
37 #include "jfs_debug.h"
38 
39 /*
40  * NAME:	jfs_umount(vfsp, flags, crp)
41  *
42  * FUNCTION:	vfs_umount()
43  *
44  * PARAMETERS:	vfsp	- virtual file system pointer
45  *		flags	- unmount for shutdown
46  *		crp	- credential
47  *
48  * RETURN :	EBUSY	- device has open files
49  */
jfs_umount(struct super_block * sb)50 int jfs_umount(struct super_block *sb)
51 {
52 	struct jfs_sb_info *sbi = JFS_SBI(sb);
53 	struct inode *ipbmap = sbi->ipbmap;
54 	struct inode *ipimap = sbi->ipimap;
55 	struct inode *ipaimap = sbi->ipaimap;
56 	struct inode *ipaimap2 = sbi->ipaimap2;
57 	struct jfs_log *log;
58 	int rc = 0;
59 
60 	jfs_info("UnMount JFS: sb:0x%p", sb);
61 
62 	/*
63 	 *	update superblock and close log
64 	 *
65 	 * if mounted read-write and log based recovery was enabled
66 	 */
67 	if ((log = sbi->log))
68 		/*
69 		 * Wait for outstanding transactions to be written to log:
70 		 */
71 		jfs_flush_journal(log, 2);
72 
73 	/*
74 	 * close fileset inode allocation map (aka fileset inode)
75 	 */
76 	diUnmount(ipimap, 0);
77 
78 	diFreeSpecial(ipimap);
79 	sbi->ipimap = NULL;
80 
81 	/*
82 	 * close secondary aggregate inode allocation map
83 	 */
84 	ipaimap2 = sbi->ipaimap2;
85 	if (ipaimap2) {
86 		diUnmount(ipaimap2, 0);
87 		diFreeSpecial(ipaimap2);
88 		sbi->ipaimap2 = NULL;
89 	}
90 
91 	/*
92 	 * close aggregate inode allocation map
93 	 */
94 	ipaimap = sbi->ipaimap;
95 	diUnmount(ipaimap, 0);
96 	diFreeSpecial(ipaimap);
97 	sbi->ipaimap = NULL;
98 
99 	/*
100 	 * close aggregate block allocation map
101 	 */
102 	dbUnmount(ipbmap, 0);
103 
104 	diFreeSpecial(ipbmap);
105 	sbi->ipimap = NULL;
106 
107 	/*
108 	 * Make sure all metadata makes it to disk before we mark
109 	 * the superblock as clean
110 	 */
111 	filemap_write_and_wait(sbi->direct_inode->i_mapping);
112 
113 	/*
114 	 * ensure all file system file pages are propagated to their
115 	 * home blocks on disk (and their in-memory buffer pages are
116 	 * invalidated) BEFORE updating file system superblock state
117 	 * (to signify file system is unmounted cleanly, and thus in
118 	 * consistent state) and log superblock active file system
119 	 * list (to signify skip logredo()).
120 	 */
121 	if (log) {		/* log = NULL if read-only mount */
122 		updateSuper(sb, FM_CLEAN);
123 
124 		/*
125 		 * close log:
126 		 *
127 		 * remove file system from log active file system list.
128 		 */
129 		rc = lmLogClose(sb);
130 	}
131 	jfs_info("UnMount JFS Complete: rc = %d", rc);
132 	return rc;
133 }
134 
135 
jfs_umount_rw(struct super_block * sb)136 int jfs_umount_rw(struct super_block *sb)
137 {
138 	struct jfs_sb_info *sbi = JFS_SBI(sb);
139 	struct jfs_log *log = sbi->log;
140 
141 	if (!log)
142 		return 0;
143 
144 	/*
145 	 * close log:
146 	 *
147 	 * remove file system from log active file system list.
148 	 */
149 	jfs_flush_journal(log, 2);
150 
151 	/*
152 	 * Make sure all metadata makes it to disk
153 	 */
154 	dbSync(sbi->ipbmap);
155 	diSync(sbi->ipimap);
156 
157 	/*
158 	 * Note that we have to do this even if sync_blockdev() will
159 	 * do exactly the same a few instructions later:  We can't
160 	 * mark the superblock clean before everything is flushed to
161 	 * disk.
162 	 */
163 	filemap_write_and_wait(sbi->direct_inode->i_mapping);
164 
165 	updateSuper(sb, FM_CLEAN);
166 
167 	return lmLogClose(sb);
168 }
169