xref: /linux/fs/jfs/jfs_umount.c (revision 776cfebb430c7b22c208b1b17add97f354d97cab)
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  */
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_fdatawrite(sbi->direct_inode->i_mapping);
112 	filemap_fdatawait(sbi->direct_inode->i_mapping);
113 
114 	/*
115 	 * ensure all file system file pages are propagated to their
116 	 * home blocks on disk (and their in-memory buffer pages are
117 	 * invalidated) BEFORE updating file system superblock state
118 	 * (to signify file system is unmounted cleanly, and thus in
119 	 * consistent state) and log superblock active file system
120 	 * list (to signify skip logredo()).
121 	 */
122 	if (log) {		/* log = NULL if read-only mount */
123 		updateSuper(sb, FM_CLEAN);
124 
125 		/*
126 		 * close log:
127 		 *
128 		 * remove file system from log active file system list.
129 		 */
130 		rc = lmLogClose(sb);
131 	}
132 	jfs_info("UnMount JFS Complete: rc = %d", rc);
133 	return rc;
134 }
135 
136 
137 int jfs_umount_rw(struct super_block *sb)
138 {
139 	struct jfs_sb_info *sbi = JFS_SBI(sb);
140 	struct jfs_log *log = sbi->log;
141 
142 	if (!log)
143 		return 0;
144 
145 	/*
146 	 * close log:
147 	 *
148 	 * remove file system from log active file system list.
149 	 */
150 	jfs_flush_journal(log, 2);
151 
152 	/*
153 	 * Make sure all metadata makes it to disk
154 	 */
155 	dbSync(sbi->ipbmap);
156 	diSync(sbi->ipimap);
157 
158 	/*
159 	 * Note that we have to do this even if sync_blockdev() will
160 	 * do exactly the same a few instructions later:  We can't
161 	 * mark the superblock clean before everything is flushed to
162 	 * disk.
163 	 */
164 	filemap_fdatawrite(sbi->direct_inode->i_mapping);
165 	filemap_fdatawait(sbi->direct_inode->i_mapping);
166 
167 	updateSuper(sb, FM_CLEAN);
168 
169 	return lmLogClose(sb);
170 }
171