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