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, wait: 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, mounterror: 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(mapping: 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, wait: 2); |
135 | |
136 | /* |
137 | * Make sure all metadata makes it to disk |
138 | */ |
139 | dbSync(ipbmap: 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(mapping: sbi->direct_inode->i_mapping); |
149 | |
150 | updateSuper(sb, FM_CLEAN); |
151 | |
152 | return lmLogClose(sb); |
153 | } |
154 | |