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 if (ipaimap2) { 72 diUnmount(ipaimap2, 0); 73 diFreeSpecial(ipaimap2); 74 sbi->ipaimap2 = NULL; 75 } 76 77 /* 78 * close aggregate inode allocation map 79 */ 80 diUnmount(ipaimap, 0); 81 diFreeSpecial(ipaimap); 82 sbi->ipaimap = NULL; 83 84 /* 85 * close aggregate block allocation map 86 */ 87 dbUnmount(ipbmap, 0); 88 89 diFreeSpecial(ipbmap); 90 sbi->ipbmap = NULL; 91 92 /* 93 * Make sure all metadata makes it to disk before we mark 94 * the superblock as clean 95 */ 96 filemap_write_and_wait(sbi->direct_inode->i_mapping); 97 98 /* 99 * ensure all file system file pages are propagated to their 100 * home blocks on disk (and their in-memory buffer pages are 101 * invalidated) BEFORE updating file system superblock state 102 * (to signify file system is unmounted cleanly, and thus in 103 * consistent state) and log superblock active file system 104 * list (to signify skip logredo()). 105 */ 106 if (log) { /* log = NULL if read-only mount */ 107 updateSuper(sb, FM_CLEAN); 108 109 /* 110 * close log: 111 * 112 * remove file system from log active file system list. 113 */ 114 rc = lmLogClose(sb); 115 } 116 jfs_info("UnMount JFS Complete: rc = %d", rc); 117 return rc; 118 } 119 120 121 int jfs_umount_rw(struct super_block *sb) 122 { 123 struct jfs_sb_info *sbi = JFS_SBI(sb); 124 struct jfs_log *log = sbi->log; 125 126 if (!log) 127 return 0; 128 129 /* 130 * close log: 131 * 132 * remove file system from log active file system list. 133 */ 134 jfs_flush_journal(log, 2); 135 136 /* 137 * Make sure all metadata makes it to disk 138 */ 139 dbSync(sbi->ipbmap); 140 diSync(sbi->ipimap); 141 142 /* 143 * Note that we have to do this even if sync_blockdev() will 144 * do exactly the same a few instructions later: We can't 145 * mark the superblock clean before everything is flushed to 146 * disk. 147 */ 148 filemap_write_and_wait(sbi->direct_inode->i_mapping); 149 150 updateSuper(sb, FM_CLEAN); 151 152 return lmLogClose(sb); 153 } 154