Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *   Copyright (C) International Business Machines Corp., 2000-2004
0004  */
0005 
0006 /*
0007  *  jfs_umount.c
0008  *
0009  * note: file system in transition to aggregate/fileset:
0010  * (ref. jfs_mount.c)
0011  *
0012  * file system unmount is interpreted as mount of the single/only
0013  * fileset in the aggregate and, if unmount of the last fileset,
0014  * as unmount of the aggerate;
0015  */
0016 
0017 #include <linux/fs.h>
0018 #include "jfs_incore.h"
0019 #include "jfs_filsys.h"
0020 #include "jfs_superblock.h"
0021 #include "jfs_dmap.h"
0022 #include "jfs_imap.h"
0023 #include "jfs_metapage.h"
0024 #include "jfs_debug.h"
0025 
0026 /*
0027  * NAME:    jfs_umount(vfsp, flags, crp)
0028  *
0029  * FUNCTION:    vfs_umount()
0030  *
0031  * PARAMETERS:  vfsp    - virtual file system pointer
0032  *      flags   - unmount for shutdown
0033  *      crp - credential
0034  *
0035  * RETURN : EBUSY   - device has open files
0036  */
0037 int jfs_umount(struct super_block *sb)
0038 {
0039     struct jfs_sb_info *sbi = JFS_SBI(sb);
0040     struct inode *ipbmap = sbi->ipbmap;
0041     struct inode *ipimap = sbi->ipimap;
0042     struct inode *ipaimap = sbi->ipaimap;
0043     struct inode *ipaimap2 = sbi->ipaimap2;
0044     struct jfs_log *log;
0045     int rc = 0;
0046 
0047     jfs_info("UnMount JFS: sb:0x%p", sb);
0048 
0049     /*
0050      *  update superblock and close log
0051      *
0052      * if mounted read-write and log based recovery was enabled
0053      */
0054     if ((log = sbi->log))
0055         /*
0056          * Wait for outstanding transactions to be written to log:
0057          */
0058         jfs_flush_journal(log, 2);
0059 
0060     /*
0061      * close fileset inode allocation map (aka fileset inode)
0062      */
0063     diUnmount(ipimap, 0);
0064 
0065     diFreeSpecial(ipimap);
0066     sbi->ipimap = NULL;
0067 
0068     /*
0069      * close secondary aggregate inode allocation map
0070      */
0071     ipaimap2 = sbi->ipaimap2;
0072     if (ipaimap2) {
0073         diUnmount(ipaimap2, 0);
0074         diFreeSpecial(ipaimap2);
0075         sbi->ipaimap2 = NULL;
0076     }
0077 
0078     /*
0079      * close aggregate inode allocation map
0080      */
0081     ipaimap = sbi->ipaimap;
0082     diUnmount(ipaimap, 0);
0083     diFreeSpecial(ipaimap);
0084     sbi->ipaimap = NULL;
0085 
0086     /*
0087      * close aggregate block allocation map
0088      */
0089     dbUnmount(ipbmap, 0);
0090 
0091     diFreeSpecial(ipbmap);
0092     sbi->ipimap = NULL;
0093 
0094     /*
0095      * Make sure all metadata makes it to disk before we mark
0096      * the superblock as clean
0097      */
0098     filemap_write_and_wait(sbi->direct_inode->i_mapping);
0099 
0100     /*
0101      * ensure all file system file pages are propagated to their
0102      * home blocks on disk (and their in-memory buffer pages are
0103      * invalidated) BEFORE updating file system superblock state
0104      * (to signify file system is unmounted cleanly, and thus in
0105      * consistent state) and log superblock active file system
0106      * list (to signify skip logredo()).
0107      */
0108     if (log) {      /* log = NULL if read-only mount */
0109         updateSuper(sb, FM_CLEAN);
0110 
0111         /*
0112          * close log:
0113          *
0114          * remove file system from log active file system list.
0115          */
0116         rc = lmLogClose(sb);
0117     }
0118     jfs_info("UnMount JFS Complete: rc = %d", rc);
0119     return rc;
0120 }
0121 
0122 
0123 int jfs_umount_rw(struct super_block *sb)
0124 {
0125     struct jfs_sb_info *sbi = JFS_SBI(sb);
0126     struct jfs_log *log = sbi->log;
0127 
0128     if (!log)
0129         return 0;
0130 
0131     /*
0132      * close log:
0133      *
0134      * remove file system from log active file system list.
0135      */
0136     jfs_flush_journal(log, 2);
0137 
0138     /*
0139      * Make sure all metadata makes it to disk
0140      */
0141     dbSync(sbi->ipbmap);
0142     diSync(sbi->ipimap);
0143 
0144     /*
0145      * Note that we have to do this even if sync_blockdev() will
0146      * do exactly the same a few instructions later:  We can't
0147      * mark the superblock clean before everything is flushed to
0148      * disk.
0149      */
0150     filemap_write_and_wait(sbi->direct_inode->i_mapping);
0151 
0152     updateSuper(sb, FM_CLEAN);
0153 
0154     return lmLogClose(sb);
0155 }