1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) International Business Machines Corp., 2000-2004
4 */
5
6 /*
7 * Module: jfs_mount.c
8 *
9 * note: file system in transition to aggregate/fileset:
10 *
11 * file system mount is interpreted as the mount of aggregate,
12 * if not already mounted, and mount of the single/only fileset in
13 * the aggregate;
14 *
15 * a file system/aggregate is represented by an internal inode
16 * (aka mount inode) initialized with aggregate superblock;
17 * each vfs represents a fileset, and points to its "fileset inode
18 * allocation map inode" (aka fileset inode):
19 * (an aggregate itself is structured recursively as a filset:
20 * an internal vfs is constructed and points to its "fileset inode
21 * allocation map inode" (aka aggregate inode) where each inode
22 * represents a fileset inode) so that inode number is mapped to
23 * on-disk inode in uniform way at both aggregate and fileset level;
24 *
25 * each vnode/inode of a fileset is linked to its vfs (to facilitate
26 * per fileset inode operations, e.g., unmount of a fileset, etc.);
27 * each inode points to the mount inode (to facilitate access to
28 * per aggregate information, e.g., block size, etc.) as well as
29 * its file set inode.
30 *
31 * aggregate
32 * ipmnt
33 * mntvfs -> fileset ipimap+ -> aggregate ipbmap -> aggregate ipaimap;
34 * fileset vfs -> vp(1) <-> ... <-> vp(n) <->vproot;
35 */
36
37 #include <linux/fs.h>
38 #include <linux/buffer_head.h>
39 #include <linux/log2.h>
40
41 #include "jfs_incore.h"
42 #include "jfs_filsys.h"
43 #include "jfs_superblock.h"
44 #include "jfs_dmap.h"
45 #include "jfs_imap.h"
46 #include "jfs_metapage.h"
47 #include "jfs_debug.h"
48
49
50 /*
51 * forward references
52 */
53 static int chkSuper(struct super_block *);
54 static int logMOUNT(struct super_block *sb);
55
56 /*
57 * NAME: jfs_mount(sb)
58 *
59 * FUNCTION: vfs_mount()
60 *
61 * PARAMETER: sb - super block
62 *
63 * RETURN: -EBUSY - device already mounted or open for write
64 * -EBUSY - cvrdvp already mounted;
65 * -EBUSY - mount table full
66 * -ENOTDIR- cvrdvp not directory on a device mount
67 * -ENXIO - device open failure
68 */
jfs_mount(struct super_block * sb)69 int jfs_mount(struct super_block *sb)
70 {
71 int rc = 0; /* Return code */
72 struct jfs_sb_info *sbi = JFS_SBI(sb);
73 struct inode *ipaimap = NULL;
74 struct inode *ipaimap2 = NULL;
75 struct inode *ipimap = NULL;
76 struct inode *ipbmap = NULL;
77
78 /*
79 * read/validate superblock
80 * (initialize mount inode from the superblock)
81 */
82 if ((rc = chkSuper(sb))) {
83 goto out;
84 }
85
86 ipaimap = diReadSpecial(sb, AGGREGATE_I, 0);
87 if (ipaimap == NULL) {
88 jfs_err("jfs_mount: Failed to read AGGREGATE_I");
89 rc = -EIO;
90 goto out;
91 }
92 sbi->ipaimap = ipaimap;
93
94 jfs_info("jfs_mount: ipaimap:0x%p", ipaimap);
95
96 /*
97 * initialize aggregate inode allocation map
98 */
99 if ((rc = diMount(ipaimap))) {
100 jfs_err("jfs_mount: diMount(ipaimap) failed w/rc = %d", rc);
101 goto err_ipaimap;
102 }
103
104 /*
105 * open aggregate block allocation map
106 */
107 ipbmap = diReadSpecial(sb, BMAP_I, 0);
108 if (ipbmap == NULL) {
109 rc = -EIO;
110 goto err_umount_ipaimap;
111 }
112
113 jfs_info("jfs_mount: ipbmap:0x%p", ipbmap);
114
115 sbi->ipbmap = ipbmap;
116
117 /*
118 * initialize aggregate block allocation map
119 */
120 if ((rc = dbMount(ipbmap))) {
121 jfs_err("jfs_mount: dbMount failed w/rc = %d", rc);
122 goto err_ipbmap;
123 }
124
125 /*
126 * open the secondary aggregate inode allocation map
127 *
128 * This is a duplicate of the aggregate inode allocation map.
129 *
130 * hand craft a vfs in the same fashion as we did to read ipaimap.
131 * By adding INOSPEREXT (32) to the inode number, we are telling
132 * diReadSpecial that we are reading from the secondary aggregate
133 * inode table. This also creates a unique entry in the inode hash
134 * table.
135 */
136 if ((sbi->mntflag & JFS_BAD_SAIT) == 0) {
137 ipaimap2 = diReadSpecial(sb, AGGREGATE_I, 1);
138 if (!ipaimap2) {
139 jfs_err("jfs_mount: Failed to read AGGREGATE_I");
140 rc = -EIO;
141 goto err_umount_ipbmap;
142 }
143 sbi->ipaimap2 = ipaimap2;
144
145 jfs_info("jfs_mount: ipaimap2:0x%p", ipaimap2);
146
147 /*
148 * initialize secondary aggregate inode allocation map
149 */
150 if ((rc = diMount(ipaimap2))) {
151 jfs_err("jfs_mount: diMount(ipaimap2) failed, rc = %d",
152 rc);
153 goto err_ipaimap2;
154 }
155 } else
156 /* Secondary aggregate inode table is not valid */
157 sbi->ipaimap2 = NULL;
158
159 /*
160 * mount (the only/single) fileset
161 */
162 /*
163 * open fileset inode allocation map (aka fileset inode)
164 */
165 ipimap = diReadSpecial(sb, FILESYSTEM_I, 0);
166 if (ipimap == NULL) {
167 jfs_err("jfs_mount: Failed to read FILESYSTEM_I");
168 /* open fileset secondary inode allocation map */
169 rc = -EIO;
170 goto err_umount_ipaimap2;
171 }
172 jfs_info("jfs_mount: ipimap:0x%p", ipimap);
173
174 /* initialize fileset inode allocation map */
175 if ((rc = diMount(ipimap))) {
176 jfs_err("jfs_mount: diMount failed w/rc = %d", rc);
177 goto err_ipimap;
178 }
179
180 /* map further access of per fileset inodes by the fileset inode */
181 sbi->ipimap = ipimap;
182
183 return rc;
184
185 /*
186 * unwind on error
187 */
188 err_ipimap:
189 /* close fileset inode allocation map inode */
190 diFreeSpecial(ipimap);
191 err_umount_ipaimap2:
192 /* close secondary aggregate inode allocation map */
193 if (ipaimap2)
194 diUnmount(ipaimap2, 1);
195 err_ipaimap2:
196 /* close aggregate inodes */
197 if (ipaimap2)
198 diFreeSpecial(ipaimap2);
199 err_umount_ipbmap: /* close aggregate block allocation map */
200 dbUnmount(ipbmap, 1);
201 err_ipbmap: /* close aggregate inodes */
202 diFreeSpecial(ipbmap);
203 err_umount_ipaimap: /* close aggregate inode allocation map */
204 diUnmount(ipaimap, 1);
205 err_ipaimap: /* close aggregate inodes */
206 diFreeSpecial(ipaimap);
207 out:
208 if (rc)
209 jfs_err("Mount JFS Failure: %d", rc);
210
211 return rc;
212 }
213
214 /*
215 * NAME: jfs_mount_rw(sb, remount)
216 *
217 * FUNCTION: Completes read-write mount, or remounts read-only volume
218 * as read-write
219 */
jfs_mount_rw(struct super_block * sb,int remount)220 int jfs_mount_rw(struct super_block *sb, int remount)
221 {
222 struct jfs_sb_info *sbi = JFS_SBI(sb);
223 int rc;
224
225 /*
226 * If we are re-mounting a previously read-only volume, we want to
227 * re-read the inode and block maps, since fsck.jfs may have updated
228 * them.
229 */
230 if (remount) {
231 if (chkSuper(sb) || (sbi->state != FM_CLEAN))
232 return -EINVAL;
233
234 truncate_inode_pages(sbi->ipimap->i_mapping, 0);
235 truncate_inode_pages(sbi->ipbmap->i_mapping, 0);
236 diUnmount(sbi->ipimap, 1);
237 if ((rc = diMount(sbi->ipimap))) {
238 jfs_err("jfs_mount_rw: diMount failed!");
239 return rc;
240 }
241
242 dbUnmount(sbi->ipbmap, 1);
243 if ((rc = dbMount(sbi->ipbmap))) {
244 jfs_err("jfs_mount_rw: dbMount failed!");
245 return rc;
246 }
247 }
248
249 /*
250 * open/initialize log
251 */
252 if ((rc = lmLogOpen(sb)))
253 return rc;
254
255 /*
256 * update file system superblock;
257 */
258 if ((rc = updateSuper(sb, FM_MOUNT))) {
259 jfs_err("jfs_mount: updateSuper failed w/rc = %d", rc);
260 lmLogClose(sb);
261 return rc;
262 }
263
264 /*
265 * write MOUNT log record of the file system
266 */
267 logMOUNT(sb);
268
269 return rc;
270 }
271
272 /*
273 * chkSuper()
274 *
275 * validate the superblock of the file system to be mounted and
276 * get the file system parameters.
277 *
278 * returns
279 * 0 with fragsize set if check successful
280 * error code if not successful
281 */
chkSuper(struct super_block * sb)282 static int chkSuper(struct super_block *sb)
283 {
284 int rc = 0;
285 struct jfs_sb_info *sbi = JFS_SBI(sb);
286 struct jfs_superblock *j_sb;
287 struct buffer_head *bh;
288 int AIM_bytesize, AIT_bytesize;
289 int expected_AIM_bytesize, expected_AIT_bytesize;
290 s64 AIM_byte_addr, AIT_byte_addr, fsckwsp_addr;
291 s64 byte_addr_diff0, byte_addr_diff1;
292 s32 bsize;
293
294 if ((rc = readSuper(sb, &bh)))
295 return rc;
296 j_sb = (struct jfs_superblock *)bh->b_data;
297
298 /*
299 * validate superblock
300 */
301 /* validate fs signature */
302 if (strncmp(j_sb->s_magic, JFS_MAGIC, 4) ||
303 le32_to_cpu(j_sb->s_version) > JFS_VERSION) {
304 rc = -EINVAL;
305 goto out;
306 }
307
308 bsize = le32_to_cpu(j_sb->s_bsize);
309 #ifdef _JFS_4K
310 if (bsize != PSIZE) {
311 jfs_err("Currently only 4K block size supported!");
312 rc = -EINVAL;
313 goto out;
314 }
315 #endif /* _JFS_4K */
316
317 jfs_info("superblock: flag:0x%08x state:0x%08x size:0x%Lx",
318 le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state),
319 (unsigned long long) le64_to_cpu(j_sb->s_size));
320
321 /* validate the descriptors for Secondary AIM and AIT */
322 if ((j_sb->s_flag & cpu_to_le32(JFS_BAD_SAIT)) !=
323 cpu_to_le32(JFS_BAD_SAIT)) {
324 expected_AIM_bytesize = 2 * PSIZE;
325 AIM_bytesize = lengthPXD(&(j_sb->s_aim2)) * bsize;
326 expected_AIT_bytesize = 4 * PSIZE;
327 AIT_bytesize = lengthPXD(&(j_sb->s_ait2)) * bsize;
328 AIM_byte_addr = addressPXD(&(j_sb->s_aim2)) * bsize;
329 AIT_byte_addr = addressPXD(&(j_sb->s_ait2)) * bsize;
330 byte_addr_diff0 = AIT_byte_addr - AIM_byte_addr;
331 fsckwsp_addr = addressPXD(&(j_sb->s_fsckpxd)) * bsize;
332 byte_addr_diff1 = fsckwsp_addr - AIT_byte_addr;
333 if ((AIM_bytesize != expected_AIM_bytesize) ||
334 (AIT_bytesize != expected_AIT_bytesize) ||
335 (byte_addr_diff0 != AIM_bytesize) ||
336 (byte_addr_diff1 <= AIT_bytesize))
337 j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT);
338 }
339
340 if ((j_sb->s_flag & cpu_to_le32(JFS_GROUPCOMMIT)) !=
341 cpu_to_le32(JFS_GROUPCOMMIT))
342 j_sb->s_flag |= cpu_to_le32(JFS_GROUPCOMMIT);
343
344 /* validate fs state */
345 if (j_sb->s_state != cpu_to_le32(FM_CLEAN) &&
346 !sb_rdonly(sb)) {
347 jfs_err("jfs_mount: Mount Failure: File System Dirty.");
348 rc = -EINVAL;
349 goto out;
350 }
351
352 sbi->state = le32_to_cpu(j_sb->s_state);
353 sbi->mntflag = le32_to_cpu(j_sb->s_flag);
354
355 /*
356 * JFS always does I/O by 4K pages. Don't tell the buffer cache
357 * that we use anything else (leave s_blocksize alone).
358 */
359 sbi->bsize = bsize;
360 sbi->l2bsize = le16_to_cpu(j_sb->s_l2bsize);
361
362 /* check some fields for possible corruption */
363 if (sbi->l2bsize != ilog2((u32)bsize) ||
364 j_sb->pad != 0 ||
365 le32_to_cpu(j_sb->s_state) > FM_STATE_MAX) {
366 rc = -EINVAL;
367 jfs_err("jfs_mount: Mount Failure: superblock is corrupt!");
368 goto out;
369 }
370
371 /*
372 * For now, ignore s_pbsize, l2bfactor. All I/O going through buffer
373 * cache.
374 */
375 sbi->nbperpage = PSIZE >> sbi->l2bsize;
376 sbi->l2nbperpage = L2PSIZE - sbi->l2bsize;
377 sbi->l2niperblk = sbi->l2bsize - L2DISIZE;
378 if (sbi->mntflag & JFS_INLINELOG)
379 sbi->logpxd = j_sb->s_logpxd;
380 else {
381 sbi->logdev = new_decode_dev(le32_to_cpu(j_sb->s_logdev));
382 uuid_copy(&sbi->uuid, &j_sb->s_uuid);
383 uuid_copy(&sbi->loguuid, &j_sb->s_loguuid);
384 }
385 sbi->fsckpxd = j_sb->s_fsckpxd;
386 sbi->ait2 = j_sb->s_ait2;
387
388 out:
389 brelse(bh);
390 return rc;
391 }
392
393
394 /*
395 * updateSuper()
396 *
397 * update synchronously superblock if it is mounted read-write.
398 */
updateSuper(struct super_block * sb,uint state)399 int updateSuper(struct super_block *sb, uint state)
400 {
401 struct jfs_superblock *j_sb;
402 struct jfs_sb_info *sbi = JFS_SBI(sb);
403 struct buffer_head *bh;
404 int rc;
405
406 if (sbi->flag & JFS_NOINTEGRITY) {
407 if (state == FM_DIRTY) {
408 sbi->p_state = state;
409 return 0;
410 } else if (state == FM_MOUNT) {
411 sbi->p_state = sbi->state;
412 state = FM_DIRTY;
413 } else if (state == FM_CLEAN) {
414 state = sbi->p_state;
415 } else
416 jfs_err("updateSuper: bad state");
417 } else if (sbi->state == FM_DIRTY)
418 return 0;
419
420 if ((rc = readSuper(sb, &bh)))
421 return rc;
422
423 j_sb = (struct jfs_superblock *)bh->b_data;
424
425 j_sb->s_state = cpu_to_le32(state);
426 sbi->state = state;
427
428 if (state == FM_MOUNT) {
429 /* record log's dev_t and mount serial number */
430 j_sb->s_logdev = cpu_to_le32(new_encode_dev(sbi->log->bdev->bd_dev));
431 j_sb->s_logserial = cpu_to_le32(sbi->log->serial);
432 } else if (state == FM_CLEAN) {
433 /*
434 * If this volume is shared with OS/2, OS/2 will need to
435 * recalculate DASD usage, since we don't deal with it.
436 */
437 if (j_sb->s_flag & cpu_to_le32(JFS_DASD_ENABLED))
438 j_sb->s_flag |= cpu_to_le32(JFS_DASD_PRIME);
439 }
440
441 mark_buffer_dirty(bh);
442 sync_dirty_buffer(bh);
443 brelse(bh);
444
445 return 0;
446 }
447
448
449 /*
450 * readSuper()
451 *
452 * read superblock by raw sector address
453 */
readSuper(struct super_block * sb,struct buffer_head ** bpp)454 int readSuper(struct super_block *sb, struct buffer_head **bpp)
455 {
456 /* read in primary superblock */
457 *bpp = sb_bread(sb, SUPER1_OFF >> sb->s_blocksize_bits);
458 if (*bpp)
459 return 0;
460
461 /* read in secondary/replicated superblock */
462 *bpp = sb_bread(sb, SUPER2_OFF >> sb->s_blocksize_bits);
463 if (*bpp)
464 return 0;
465
466 return -EIO;
467 }
468
469
470 /*
471 * logMOUNT()
472 *
473 * function: write a MOUNT log record for file system.
474 *
475 * MOUNT record keeps logredo() from processing log records
476 * for this file system past this point in log.
477 * it is harmless if mount fails.
478 *
479 * note: MOUNT record is at aggregate level, not at fileset level,
480 * since log records of previous mounts of a fileset
481 * (e.g., AFTER record of extent allocation) have to be processed
482 * to update block allocation map at aggregate level.
483 */
logMOUNT(struct super_block * sb)484 static int logMOUNT(struct super_block *sb)
485 {
486 struct jfs_log *log = JFS_SBI(sb)->log;
487 struct lrd lrd;
488
489 lrd.logtid = 0;
490 lrd.backchain = 0;
491 lrd.type = cpu_to_le16(LOG_MOUNT);
492 lrd.length = 0;
493 lrd.aggregate = cpu_to_le32(new_encode_dev(sb->s_bdev->bd_dev));
494 lmLog(log, NULL, &lrd, NULL);
495
496 return 0;
497 }
498