linux/fs/jfs/jfs_umount.c
<<
>>
Prefs
   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 */
  37int 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
 123int 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