diff options
Diffstat (limited to 'fs/jfs/jfs_umount.c')
-rw-r--r-- | fs/jfs/jfs_umount.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c new file mode 100644 index 000000000000..f31a9e3f3fec --- /dev/null +++ b/fs/jfs/jfs_umount.c | |||
@@ -0,0 +1,178 @@ | |||
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 address_space *bdev_mapping = sb->s_bdev->bd_inode->i_mapping; | ||
53 | struct jfs_sb_info *sbi = JFS_SBI(sb); | ||
54 | struct inode *ipbmap = sbi->ipbmap; | ||
55 | struct inode *ipimap = sbi->ipimap; | ||
56 | struct inode *ipaimap = sbi->ipaimap; | ||
57 | struct inode *ipaimap2 = sbi->ipaimap2; | ||
58 | struct jfs_log *log; | ||
59 | int rc = 0; | ||
60 | |||
61 | jfs_info("UnMount JFS: sb:0x%p", sb); | ||
62 | |||
63 | /* | ||
64 | * update superblock and close log | ||
65 | * | ||
66 | * if mounted read-write and log based recovery was enabled | ||
67 | */ | ||
68 | if ((log = sbi->log)) | ||
69 | /* | ||
70 | * Wait for outstanding transactions to be written to log: | ||
71 | */ | ||
72 | jfs_flush_journal(log, 2); | ||
73 | |||
74 | /* | ||
75 | * close fileset inode allocation map (aka fileset inode) | ||
76 | */ | ||
77 | diUnmount(ipimap, 0); | ||
78 | |||
79 | diFreeSpecial(ipimap); | ||
80 | sbi->ipimap = NULL; | ||
81 | |||
82 | /* | ||
83 | * close secondary aggregate inode allocation map | ||
84 | */ | ||
85 | ipaimap2 = sbi->ipaimap2; | ||
86 | if (ipaimap2) { | ||
87 | diUnmount(ipaimap2, 0); | ||
88 | diFreeSpecial(ipaimap2); | ||
89 | sbi->ipaimap2 = NULL; | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * close aggregate inode allocation map | ||
94 | */ | ||
95 | ipaimap = sbi->ipaimap; | ||
96 | diUnmount(ipaimap, 0); | ||
97 | diFreeSpecial(ipaimap); | ||
98 | sbi->ipaimap = NULL; | ||
99 | |||
100 | /* | ||
101 | * close aggregate block allocation map | ||
102 | */ | ||
103 | dbUnmount(ipbmap, 0); | ||
104 | |||
105 | diFreeSpecial(ipbmap); | ||
106 | sbi->ipimap = NULL; | ||
107 | |||
108 | /* | ||
109 | * Make sure all metadata makes it to disk before we mark | ||
110 | * the superblock as clean | ||
111 | */ | ||
112 | filemap_fdatawrite(bdev_mapping); | ||
113 | filemap_fdatawait(bdev_mapping); | ||
114 | |||
115 | /* | ||
116 | * ensure all file system file pages are propagated to their | ||
117 | * home blocks on disk (and their in-memory buffer pages are | ||
118 | * invalidated) BEFORE updating file system superblock state | ||
119 | * (to signify file system is unmounted cleanly, and thus in | ||
120 | * consistent state) and log superblock active file system | ||
121 | * list (to signify skip logredo()). | ||
122 | */ | ||
123 | if (log) { /* log = NULL if read-only mount */ | ||
124 | updateSuper(sb, FM_CLEAN); | ||
125 | |||
126 | /* Restore default gfp_mask for bdev */ | ||
127 | mapping_set_gfp_mask(bdev_mapping, GFP_USER); | ||
128 | |||
129 | /* | ||
130 | * close log: | ||
131 | * | ||
132 | * remove file system from log active file system list. | ||
133 | */ | ||
134 | rc = lmLogClose(sb); | ||
135 | } | ||
136 | jfs_info("UnMount JFS Complete: rc = %d", rc); | ||
137 | return rc; | ||
138 | } | ||
139 | |||
140 | |||
141 | int jfs_umount_rw(struct super_block *sb) | ||
142 | { | ||
143 | struct address_space *bdev_mapping = sb->s_bdev->bd_inode->i_mapping; | ||
144 | struct jfs_sb_info *sbi = JFS_SBI(sb); | ||
145 | struct jfs_log *log = sbi->log; | ||
146 | |||
147 | if (!log) | ||
148 | return 0; | ||
149 | |||
150 | /* | ||
151 | * close log: | ||
152 | * | ||
153 | * remove file system from log active file system list. | ||
154 | */ | ||
155 | jfs_flush_journal(log, 2); | ||
156 | |||
157 | /* | ||
158 | * Make sure all metadata makes it to disk | ||
159 | */ | ||
160 | dbSync(sbi->ipbmap); | ||
161 | diSync(sbi->ipimap); | ||
162 | |||
163 | /* | ||
164 | * Note that we have to do this even if sync_blockdev() will | ||
165 | * do exactly the same a few instructions later: We can't | ||
166 | * mark the superblock clean before everything is flushed to | ||
167 | * disk. | ||
168 | */ | ||
169 | filemap_fdatawrite(bdev_mapping); | ||
170 | filemap_fdatawait(bdev_mapping); | ||
171 | |||
172 | updateSuper(sb, FM_CLEAN); | ||
173 | |||
174 | /* Restore default gfp_mask for bdev */ | ||
175 | mapping_set_gfp_mask(bdev_mapping, GFP_USER); | ||
176 | |||
177 | return lmLogClose(sb); | ||
178 | } | ||