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