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