11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * Copyright (C) International Business Machines Corp., 2000-2004
41da177e4SLinus Torvalds */
51da177e4SLinus Torvalds
61da177e4SLinus Torvalds /*
71da177e4SLinus Torvalds * jfs_umount.c
81da177e4SLinus Torvalds *
91da177e4SLinus Torvalds * note: file system in transition to aggregate/fileset:
101da177e4SLinus Torvalds * (ref. jfs_mount.c)
111da177e4SLinus Torvalds *
121da177e4SLinus Torvalds * file system unmount is interpreted as mount of the single/only
131da177e4SLinus Torvalds * fileset in the aggregate and, if unmount of the last fileset,
141da177e4SLinus Torvalds * as unmount of the aggerate;
151da177e4SLinus Torvalds */
161da177e4SLinus Torvalds
171da177e4SLinus Torvalds #include <linux/fs.h>
181da177e4SLinus Torvalds #include "jfs_incore.h"
191da177e4SLinus Torvalds #include "jfs_filsys.h"
201da177e4SLinus Torvalds #include "jfs_superblock.h"
211da177e4SLinus Torvalds #include "jfs_dmap.h"
221da177e4SLinus Torvalds #include "jfs_imap.h"
231da177e4SLinus Torvalds #include "jfs_metapage.h"
241da177e4SLinus Torvalds #include "jfs_debug.h"
251da177e4SLinus Torvalds
261da177e4SLinus Torvalds /*
271da177e4SLinus Torvalds * NAME: jfs_umount(vfsp, flags, crp)
281da177e4SLinus Torvalds *
291da177e4SLinus Torvalds * FUNCTION: vfs_umount()
301da177e4SLinus Torvalds *
311da177e4SLinus Torvalds * PARAMETERS: vfsp - virtual file system pointer
321da177e4SLinus Torvalds * flags - unmount for shutdown
331da177e4SLinus Torvalds * crp - credential
341da177e4SLinus Torvalds *
351da177e4SLinus Torvalds * RETURN : EBUSY - device has open files
361da177e4SLinus Torvalds */
jfs_umount(struct super_block * sb)371da177e4SLinus Torvalds int jfs_umount(struct super_block *sb)
381da177e4SLinus Torvalds {
391da177e4SLinus Torvalds struct jfs_sb_info *sbi = JFS_SBI(sb);
401da177e4SLinus Torvalds struct inode *ipbmap = sbi->ipbmap;
411da177e4SLinus Torvalds struct inode *ipimap = sbi->ipimap;
421da177e4SLinus Torvalds struct inode *ipaimap = sbi->ipaimap;
431da177e4SLinus Torvalds struct inode *ipaimap2 = sbi->ipaimap2;
441da177e4SLinus Torvalds struct jfs_log *log;
451da177e4SLinus Torvalds int rc = 0;
461da177e4SLinus Torvalds
471da177e4SLinus Torvalds jfs_info("UnMount JFS: sb:0x%p", sb);
481da177e4SLinus Torvalds
491da177e4SLinus Torvalds /*
501da177e4SLinus Torvalds * update superblock and close log
511da177e4SLinus Torvalds *
521da177e4SLinus Torvalds * if mounted read-write and log based recovery was enabled
531da177e4SLinus Torvalds */
541da177e4SLinus Torvalds if ((log = sbi->log))
551da177e4SLinus Torvalds /*
561da177e4SLinus Torvalds * Wait for outstanding transactions to be written to log:
571da177e4SLinus Torvalds */
581c8007b0SDave Kleikamp jfs_flush_journal(log, 2);
591da177e4SLinus Torvalds
601da177e4SLinus Torvalds /*
611da177e4SLinus Torvalds * close fileset inode allocation map (aka fileset inode)
621da177e4SLinus Torvalds */
631da177e4SLinus Torvalds diUnmount(ipimap, 0);
641da177e4SLinus Torvalds
651da177e4SLinus Torvalds diFreeSpecial(ipimap);
661da177e4SLinus Torvalds sbi->ipimap = NULL;
671da177e4SLinus Torvalds
681da177e4SLinus Torvalds /*
691da177e4SLinus Torvalds * close secondary aggregate inode allocation map
701da177e4SLinus Torvalds */
711da177e4SLinus Torvalds if (ipaimap2) {
721da177e4SLinus Torvalds diUnmount(ipaimap2, 0);
731da177e4SLinus Torvalds diFreeSpecial(ipaimap2);
741da177e4SLinus Torvalds sbi->ipaimap2 = NULL;
751da177e4SLinus Torvalds }
761da177e4SLinus Torvalds
771da177e4SLinus Torvalds /*
781da177e4SLinus Torvalds * close aggregate inode allocation map
791da177e4SLinus Torvalds */
801da177e4SLinus Torvalds diUnmount(ipaimap, 0);
811da177e4SLinus Torvalds diFreeSpecial(ipaimap);
821da177e4SLinus Torvalds sbi->ipaimap = NULL;
831da177e4SLinus Torvalds
841da177e4SLinus Torvalds /*
851da177e4SLinus Torvalds * close aggregate block allocation map
861da177e4SLinus Torvalds */
871da177e4SLinus Torvalds dbUnmount(ipbmap, 0);
881da177e4SLinus Torvalds
891da177e4SLinus Torvalds diFreeSpecial(ipbmap);
90*d0e482c4SOleg Kanatov sbi->ipbmap = NULL;
911da177e4SLinus Torvalds
921da177e4SLinus Torvalds /*
931da177e4SLinus Torvalds * Make sure all metadata makes it to disk before we mark
941da177e4SLinus Torvalds * the superblock as clean
951da177e4SLinus Torvalds */
9628fd1298SOGAWA Hirofumi filemap_write_and_wait(sbi->direct_inode->i_mapping);
971da177e4SLinus Torvalds
981da177e4SLinus Torvalds /*
991da177e4SLinus Torvalds * ensure all file system file pages are propagated to their
1001da177e4SLinus Torvalds * home blocks on disk (and their in-memory buffer pages are
1011da177e4SLinus Torvalds * invalidated) BEFORE updating file system superblock state
1021da177e4SLinus Torvalds * (to signify file system is unmounted cleanly, and thus in
1031da177e4SLinus Torvalds * consistent state) and log superblock active file system
1041da177e4SLinus Torvalds * list (to signify skip logredo()).
1051da177e4SLinus Torvalds */
1061da177e4SLinus Torvalds if (log) { /* log = NULL if read-only mount */
1071da177e4SLinus Torvalds updateSuper(sb, FM_CLEAN);
1081da177e4SLinus Torvalds
1091da177e4SLinus Torvalds /*
1101da177e4SLinus Torvalds * close log:
1111da177e4SLinus Torvalds *
1121da177e4SLinus Torvalds * remove file system from log active file system list.
1131da177e4SLinus Torvalds */
1141da177e4SLinus Torvalds rc = lmLogClose(sb);
1151da177e4SLinus Torvalds }
1161da177e4SLinus Torvalds jfs_info("UnMount JFS Complete: rc = %d", rc);
1171da177e4SLinus Torvalds return rc;
1181da177e4SLinus Torvalds }
1191da177e4SLinus Torvalds
1201da177e4SLinus Torvalds
jfs_umount_rw(struct super_block * sb)1211da177e4SLinus Torvalds int jfs_umount_rw(struct super_block *sb)
1221da177e4SLinus Torvalds {
1231da177e4SLinus Torvalds struct jfs_sb_info *sbi = JFS_SBI(sb);
1241da177e4SLinus Torvalds struct jfs_log *log = sbi->log;
1251da177e4SLinus Torvalds
1261da177e4SLinus Torvalds if (!log)
1271da177e4SLinus Torvalds return 0;
1281da177e4SLinus Torvalds
1291da177e4SLinus Torvalds /*
1301da177e4SLinus Torvalds * close log:
1311da177e4SLinus Torvalds *
1321da177e4SLinus Torvalds * remove file system from log active file system list.
1331da177e4SLinus Torvalds */
1341c8007b0SDave Kleikamp jfs_flush_journal(log, 2);
1351da177e4SLinus Torvalds
1361da177e4SLinus Torvalds /*
1371da177e4SLinus Torvalds * Make sure all metadata makes it to disk
1381da177e4SLinus Torvalds */
1391da177e4SLinus Torvalds dbSync(sbi->ipbmap);
1401da177e4SLinus Torvalds diSync(sbi->ipimap);
1411da177e4SLinus Torvalds
1421da177e4SLinus Torvalds /*
1431da177e4SLinus Torvalds * Note that we have to do this even if sync_blockdev() will
1441da177e4SLinus Torvalds * do exactly the same a few instructions later: We can't
1451da177e4SLinus Torvalds * mark the superblock clean before everything is flushed to
1461da177e4SLinus Torvalds * disk.
1471da177e4SLinus Torvalds */
14828fd1298SOGAWA Hirofumi filemap_write_and_wait(sbi->direct_inode->i_mapping);
1491da177e4SLinus Torvalds
1501da177e4SLinus Torvalds updateSuper(sb, FM_CLEAN);
1511da177e4SLinus Torvalds
1521da177e4SLinus Torvalds return lmLogClose(sb);
1531da177e4SLinus Torvalds }
154