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