super.c 23.4 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6
/*
 *   Copyright (C) International Business Machines Corp., 2000-2004
 *   Portions Copyright (C) Christoph Hellwig, 2001-2002
 *
 *   This program is free software;  you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
D
Dave Kleikamp 已提交
7
 *   the Free Software Foundation; either version 2 of the License, or
L
Linus Torvalds 已提交
8
 *   (at your option) any later version.
D
Dave Kleikamp 已提交
9
 *
L
Linus Torvalds 已提交
10 11 12 13 14 15
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *   the GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
D
Dave Kleikamp 已提交
16
 *   along with this program;  if not, write to the Free Software
L
Linus Torvalds 已提交
17 18 19 20 21 22 23 24
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <linux/fs.h>
#include <linux/module.h>
#include <linux/parser.h>
#include <linux/completion.h>
#include <linux/vfs.h>
25
#include <linux/quotaops.h>
26
#include <linux/mount.h>
L
Linus Torvalds 已提交
27
#include <linux/moduleparam.h>
C
Christoph Hellwig 已提交
28
#include <linux/kthread.h>
29
#include <linux/posix_acl.h>
30
#include <linux/buffer_head.h>
31
#include <linux/exportfs.h>
C
Coly Li 已提交
32
#include <linux/crc32.h>
33
#include <linux/slab.h>
L
Linus Torvalds 已提交
34
#include <asm/uaccess.h>
35
#include <linux/seq_file.h>
36
#include <linux/blkdev.h>
L
Linus Torvalds 已提交
37 38 39

#include "jfs_incore.h"
#include "jfs_filsys.h"
40
#include "jfs_inode.h"
L
Linus Torvalds 已提交
41 42 43 44 45 46
#include "jfs_metapage.h"
#include "jfs_superblock.h"
#include "jfs_dmap.h"
#include "jfs_imap.h"
#include "jfs_acl.h"
#include "jfs_debug.h"
47
#include "jfs_xattr.h"
L
Linus Torvalds 已提交
48 49 50 51 52

MODULE_DESCRIPTION("The Journaled Filesystem (JFS)");
MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM");
MODULE_LICENSE("GPL");

53
static struct kmem_cache *jfs_inode_cachep;
L
Linus Torvalds 已提交
54

55
static const struct super_operations jfs_super_operations;
56
static const struct export_operations jfs_export_operations;
L
Linus Torvalds 已提交
57 58 59
static struct file_system_type jfs_fs_type;

#define MAX_COMMIT_THREADS 64
60
static int commit_threads;
L
Linus Torvalds 已提交
61 62 63
module_param(commit_threads, int, 0);
MODULE_PARM_DESC(commit_threads, "Number of commit threads");

C
Christoph Hellwig 已提交
64 65 66
static struct task_struct *jfsCommitThread[MAX_COMMIT_THREADS];
struct task_struct *jfsIOthread;
struct task_struct *jfsSyncThread;
L
Linus Torvalds 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

#ifdef CONFIG_JFS_DEBUG
int jfsloglevel = JFS_LOGLEVEL_WARN;
module_param(jfsloglevel, int, 0644);
MODULE_PARM_DESC(jfsloglevel, "Specify JFS loglevel (0, 1 or 2)");
#endif

static void jfs_handle_error(struct super_block *sb)
{
	struct jfs_sb_info *sbi = JFS_SBI(sb);

	if (sb->s_flags & MS_RDONLY)
		return;

	updateSuper(sb, FM_DIRTY);

	if (sbi->flag & JFS_ERR_PANIC)
		panic("JFS (device %s): panic forced after error\n",
			sb->s_id);
	else if (sbi->flag & JFS_ERR_REMOUNT_RO) {
87
		jfs_err("ERROR: (device %s): remounting filesystem as read-only\n",
L
Linus Torvalds 已提交
88 89
			sb->s_id);
		sb->s_flags |= MS_RDONLY;
D
Dave Kleikamp 已提交
90
	}
L
Linus Torvalds 已提交
91 92 93 94

	/* nothing is done for continue beyond marking the superblock dirty */
}

J
Joe Perches 已提交
95
void jfs_error(struct super_block *sb, const char *fmt, ...)
L
Linus Torvalds 已提交
96
{
J
Joe Perches 已提交
97
	struct va_format vaf;
L
Linus Torvalds 已提交
98 99
	va_list args;

J
Joe Perches 已提交
100 101 102 103
	va_start(args, fmt);

	vaf.fmt = fmt;
	vaf.va = &args;
L
Linus Torvalds 已提交
104

J
Joe Perches 已提交
105 106 107 108
	pr_err("ERROR: (device %s): %pf: %pV\n",
	       sb->s_id, __builtin_return_address(0), &vaf);

	va_end(args);
L
Linus Torvalds 已提交
109 110 111 112 113 114 115 116 117 118 119

	jfs_handle_error(sb);
}

static struct inode *jfs_alloc_inode(struct super_block *sb)
{
	struct jfs_inode_info *jfs_inode;

	jfs_inode = kmem_cache_alloc(jfs_inode_cachep, GFP_NOFS);
	if (!jfs_inode)
		return NULL;
J
Jan Kara 已提交
120 121 122
#ifdef CONFIG_QUOTA
	memset(&jfs_inode->i_dquot, 0, sizeof(jfs_inode->i_dquot));
#endif
L
Linus Torvalds 已提交
123 124 125
	return &jfs_inode->vfs_inode;
}

N
Nick Piggin 已提交
126 127 128 129 130 131 132
static void jfs_i_callback(struct rcu_head *head)
{
	struct inode *inode = container_of(head, struct inode, i_rcu);
	struct jfs_inode_info *ji = JFS_IP(inode);
	kmem_cache_free(jfs_inode_cachep, ji);
}

L
Linus Torvalds 已提交
133 134 135 136
static void jfs_destroy_inode(struct inode *inode)
{
	struct jfs_inode_info *ji = JFS_IP(inode);

D
Dave Kleikamp 已提交
137 138
	BUG_ON(!list_empty(&ji->anon_inode_list));

L
Linus Torvalds 已提交
139 140 141 142 143 144 145
	spin_lock_irq(&ji->ag_lock);
	if (ji->active_ag != -1) {
		struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap;
		atomic_dec(&bmap->db_active[ji->active_ag]);
		ji->active_ag = -1;
	}
	spin_unlock_irq(&ji->ag_lock);
N
Nick Piggin 已提交
146
	call_rcu(&inode->i_rcu, jfs_i_callback);
L
Linus Torvalds 已提交
147 148
}

149
static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf)
L
Linus Torvalds 已提交
150
{
151
	struct jfs_sb_info *sbi = JFS_SBI(dentry->d_sb);
L
Linus Torvalds 已提交
152 153 154 155 156 157 158 159 160 161 162 163
	s64 maxinodes;
	struct inomap *imap = JFS_IP(sbi->ipimap)->i_imap;

	jfs_info("In jfs_statfs");
	buf->f_type = JFS_SUPER_MAGIC;
	buf->f_bsize = sbi->bsize;
	buf->f_blocks = sbi->bmap->db_mapsize;
	buf->f_bfree = sbi->bmap->db_nfree;
	buf->f_bavail = sbi->bmap->db_nfree;
	/*
	 * If we really return the number of allocated & free inodes, some
	 * applications will fail because they won't see enough free inodes.
164
	 * We'll try to calculate some guess as to how many inodes we can
L
Linus Torvalds 已提交
165 166 167 168 169 170 171 172 173 174 175
	 * really allocate
	 *
	 * buf->f_files = atomic_read(&imap->im_numinos);
	 * buf->f_ffree = atomic_read(&imap->im_numfree);
	 */
	maxinodes = min((s64) atomic_read(&imap->im_numinos) +
			((sbi->bmap->db_nfree >> imap->im_l2nbperiext)
			 << L2INOSPEREXT), (s64) 0xffffffffLL);
	buf->f_files = maxinodes;
	buf->f_ffree = maxinodes - (atomic_read(&imap->im_numinos) -
				    atomic_read(&imap->im_numfree));
C
Coly Li 已提交
176 177 178
	buf->f_fsid.val[0] = (u32)crc32_le(0, sbi->uuid, sizeof(sbi->uuid)/2);
	buf->f_fsid.val[1] = (u32)crc32_le(0, sbi->uuid + sizeof(sbi->uuid)/2,
					sizeof(sbi->uuid)/2);
L
Linus Torvalds 已提交
179 180 181 182 183 184 185 186 187 188 189

	buf->f_namelen = JFS_NAME_MAX;
	return 0;
}

static void jfs_put_super(struct super_block *sb)
{
	struct jfs_sb_info *sbi = JFS_SBI(sb);
	int rc;

	jfs_info("In jfs_put_super");
190

191 192
	dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);

L
Linus Torvalds 已提交
193 194 195
	rc = jfs_umount(sb);
	if (rc)
		jfs_err("jfs_umount failed with return code %d", rc);
196 197

	unload_nls(sbi->nls_tab);
L
Linus Torvalds 已提交
198

199 200 201
	truncate_inode_pages(sbi->direct_inode->i_mapping, 0);
	iput(sbi->direct_inode);

L
Linus Torvalds 已提交
202 203 204 205 206
	kfree(sbi);
}

enum {
	Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
207
	Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
208 209
	Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
	Opt_discard, Opt_nodiscard, Opt_discard_minblk
L
Linus Torvalds 已提交
210 211
};

212
static const match_table_t tokens = {
L
Linus Torvalds 已提交
213 214 215 216 217 218 219 220
	{Opt_integrity, "integrity"},
	{Opt_nointegrity, "nointegrity"},
	{Opt_iocharset, "iocharset=%s"},
	{Opt_resize, "resize=%u"},
	{Opt_resize_nosize, "resize"},
	{Opt_errors, "errors=%s"},
	{Opt_ignore, "noquota"},
	{Opt_ignore, "quota"},
221 222
	{Opt_usrquota, "usrquota"},
	{Opt_grpquota, "grpquota"},
223 224 225
	{Opt_uid, "uid=%u"},
	{Opt_gid, "gid=%u"},
	{Opt_umask, "umask=%u"},
226 227 228
	{Opt_discard, "discard"},
	{Opt_nodiscard, "nodiscard"},
	{Opt_discard_minblk, "discard=%u"},
L
Linus Torvalds 已提交
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
	{Opt_err, NULL}
};

static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
			 int *flag)
{
	void *nls_map = (void *)-1;	/* -1: no change;  NULL: none */
	char *p;
	struct jfs_sb_info *sbi = JFS_SBI(sb);

	*newLVSize = 0;

	if (!options)
		return 1;

	while ((p = strsep(&options, ",")) != NULL) {
		substring_t args[MAX_OPT_ARGS];
		int token;
		if (!*p)
			continue;

		token = match_token(p, tokens, args);
		switch (token) {
		case Opt_integrity:
			*flag &= ~JFS_NOINTEGRITY;
			break;
		case Opt_nointegrity:
			*flag |= JFS_NOINTEGRITY;
			break;
		case Opt_ignore:
			/* Silently ignore the quota options */
			/* Don't do anything ;-) */
			break;
		case Opt_iocharset:
			if (nls_map && nls_map != (void *) -1)
				unload_nls(nls_map);
			if (!strcmp(args[0].from, "none"))
				nls_map = NULL;
			else {
				nls_map = load_nls(args[0].from);
				if (!nls_map) {
270
					pr_err("JFS: charset not found\n");
L
Linus Torvalds 已提交
271 272 273 274 275 276 277
					goto cleanup;
				}
			}
			break;
		case Opt_resize:
		{
			char *resize = args[0].from;
278 279 280 281
			int rc = kstrtoll(resize, 0, newLVSize);

			if (rc)
				goto cleanup;
L
Linus Torvalds 已提交
282 283 284 285 286 287 288
			break;
		}
		case Opt_resize_nosize:
		{
			*newLVSize = sb->s_bdev->bd_inode->i_size >>
				sb->s_blocksize_bits;
			if (*newLVSize == 0)
289
				pr_err("JFS: Cannot determine volume size\n");
L
Linus Torvalds 已提交
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
			break;
		}
		case Opt_errors:
		{
			char *errors = args[0].from;
			if (!errors || !*errors)
				goto cleanup;
			if (!strcmp(errors, "continue")) {
				*flag &= ~JFS_ERR_REMOUNT_RO;
				*flag &= ~JFS_ERR_PANIC;
				*flag |= JFS_ERR_CONTINUE;
			} else if (!strcmp(errors, "remount-ro")) {
				*flag &= ~JFS_ERR_CONTINUE;
				*flag &= ~JFS_ERR_PANIC;
				*flag |= JFS_ERR_REMOUNT_RO;
			} else if (!strcmp(errors, "panic")) {
				*flag &= ~JFS_ERR_CONTINUE;
				*flag &= ~JFS_ERR_REMOUNT_RO;
				*flag |= JFS_ERR_PANIC;
			} else {
310
				pr_err("JFS: %s is an invalid error handler\n",
L
Linus Torvalds 已提交
311 312 313 314 315
				       errors);
				goto cleanup;
			}
			break;
		}
316

317
#ifdef CONFIG_QUOTA
318 319 320 321 322 323 324 325 326 327 328
		case Opt_quota:
		case Opt_usrquota:
			*flag |= JFS_USRQUOTA;
			break;
		case Opt_grpquota:
			*flag |= JFS_GRPQUOTA;
			break;
#else
		case Opt_usrquota:
		case Opt_grpquota:
		case Opt_quota:
329
			pr_err("JFS: quota operations not supported\n");
330 331
			break;
#endif
332 333 334
		case Opt_uid:
		{
			char *uid = args[0].from;
335 336 337 338 339
			uid_t val;
			int rc = kstrtouint(uid, 0, &val);

			if (rc)
				goto cleanup;
340 341 342
			sbi->uid = make_kuid(current_user_ns(), val);
			if (!uid_valid(sbi->uid))
				goto cleanup;
343 344
			break;
		}
345

346 347 348
		case Opt_gid:
		{
			char *gid = args[0].from;
349 350 351 352 353
			gid_t val;
			int rc = kstrtouint(gid, 0, &val);

			if (rc)
				goto cleanup;
354 355 356
			sbi->gid = make_kgid(current_user_ns(), val);
			if (!gid_valid(sbi->gid))
				goto cleanup;
357 358
			break;
		}
359

360 361 362
		case Opt_umask:
		{
			char *umask = args[0].from;
363 364 365 366
			int rc = kstrtouint(umask, 8, &sbi->umask);

			if (rc)
				goto cleanup;
367
			if (sbi->umask & ~0777) {
368
				pr_err("JFS: Invalid value of umask\n");
369 370 371 372
				goto cleanup;
			}
			break;
		}
373 374 375 376 377 378 379 380 381

		case Opt_discard:
		{
			struct request_queue *q = bdev_get_queue(sb->s_bdev);
			/* if set to 1, even copying files will cause
			 * trimming :O
			 * -> user has more control over the online trimming
			 */
			sbi->minblks_trim = 64;
382
			if (blk_queue_discard(q))
383
				*flag |= JFS_DISCARD;
384 385
			else
				pr_err("JFS: discard option not supported on device\n");
386 387 388 389 390 391 392 393 394 395 396
			break;
		}

		case Opt_nodiscard:
			*flag &= ~JFS_DISCARD;
			break;

		case Opt_discard_minblk:
		{
			struct request_queue *q = bdev_get_queue(sb->s_bdev);
			char *minblks_trim = args[0].from;
397
			int rc;
398 399
			if (blk_queue_discard(q)) {
				*flag |= JFS_DISCARD;
400 401 402 403 404
				rc = kstrtouint(minblks_trim, 0,
						&sbi->minblks_trim);
				if (rc)
					goto cleanup;
			} else
405
				pr_err("JFS: discard option not supported on device\n");
406 407 408
			break;
		}

L
Linus Torvalds 已提交
409
		default:
410 411
			printk("jfs: Unrecognized mount option \"%s\" or missing value\n",
			       p);
L
Linus Torvalds 已提交
412 413 414 415 416 417
			goto cleanup;
		}
	}

	if (nls_map != (void *) -1) {
		/* Discard old (if remount) */
418
		unload_nls(sbi->nls_tab);
L
Linus Torvalds 已提交
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
		sbi->nls_tab = nls_map;
	}
	return 1;

cleanup:
	if (nls_map && nls_map != (void *) -1)
		unload_nls(nls_map);
	return 0;
}

static int jfs_remount(struct super_block *sb, int *flags, char *data)
{
	s64 newLVSize = 0;
	int rc = 0;
	int flag = JFS_SBI(sb)->flag;
434
	int ret;
L
Linus Torvalds 已提交
435

436
	sync_filesystem(sb);
437
	if (!parse_options(data, sb, &newLVSize, &flag))
L
Linus Torvalds 已提交
438
		return -EINVAL;
J
Jan Blunck 已提交
439

L
Linus Torvalds 已提交
440 441
	if (newLVSize) {
		if (sb->s_flags & MS_RDONLY) {
442
			pr_err("JFS: resize requires volume to be mounted read-write\n");
L
Linus Torvalds 已提交
443 444 445
			return -EROFS;
		}
		rc = jfs_extendfs(sb, newLVSize, 0);
J
Jan Blunck 已提交
446
		if (rc)
L
Linus Torvalds 已提交
447 448 449 450
			return rc;
	}

	if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
451 452 453 454 455 456
		/*
		 * Invalidate any previously read metadata.  fsck may have
		 * changed the on-disk data since we mounted r/o
		 */
		truncate_inode_pages(JFS_SBI(sb)->direct_inode->i_mapping, 0);

L
Linus Torvalds 已提交
457
		JFS_SBI(sb)->flag = flag;
458
		ret = jfs_mount_rw(sb, 1);
459 460 461 462

		/* mark the fs r/w for quota activity */
		sb->s_flags &= ~MS_RDONLY;

463
		dquot_resume(sb, -1);
464
		return ret;
L
Linus Torvalds 已提交
465 466
	}
	if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) {
467
		rc = dquot_suspend(sb, -1);
468
		if (rc < 0)
469
			return rc;
L
Linus Torvalds 已提交
470 471 472 473 474 475 476
		rc = jfs_umount_rw(sb);
		JFS_SBI(sb)->flag = flag;
		return rc;
	}
	if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY))
		if (!(sb->s_flags & MS_RDONLY)) {
			rc = jfs_umount_rw(sb);
J
Jan Blunck 已提交
477
			if (rc)
L
Linus Torvalds 已提交
478
				return rc;
J
Jan Blunck 已提交
479

L
Linus Torvalds 已提交
480
			JFS_SBI(sb)->flag = flag;
481 482
			ret = jfs_mount_rw(sb, 1);
			return ret;
L
Linus Torvalds 已提交
483 484 485 486 487 488 489 490 491 492 493 494
		}
	JFS_SBI(sb)->flag = flag;

	return 0;
}

static int jfs_fill_super(struct super_block *sb, void *data, int silent)
{
	struct jfs_sb_info *sbi;
	struct inode *inode;
	int rc;
	s64 newLVSize = 0;
495
	int flag, ret = -EINVAL;
L
Linus Torvalds 已提交
496 497 498

	jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags);

J
Jan Blunck 已提交
499
	if (!new_valid_dev(sb->s_bdev->bd_dev))
L
Linus Torvalds 已提交
500 501
		return -EOVERFLOW;

502
	sbi = kzalloc(sizeof(struct jfs_sb_info), GFP_KERNEL);
J
Jan Blunck 已提交
503
	if (!sbi)
504
		return -ENOMEM;
J
Jan Blunck 已提交
505

L
Linus Torvalds 已提交
506
	sb->s_fs_info = sbi;
507
	sb->s_max_links = JFS_LINK_MAX;
L
Linus Torvalds 已提交
508
	sbi->sb = sb;
509 510 511
	sbi->uid = INVALID_UID;
	sbi->gid = INVALID_GID;
	sbi->umask = -1;
L
Linus Torvalds 已提交
512 513 514 515

	/* initialize the mount flag and determine the default error handler */
	flag = JFS_ERR_REMOUNT_RO;

J
Jan Blunck 已提交
516 517
	if (!parse_options((char *) data, sb, &newLVSize, &flag))
		goto out_kfree;
L
Linus Torvalds 已提交
518 519 520 521 522 523 524
	sbi->flag = flag;

#ifdef CONFIG_JFS_POSIX_ACL
	sb->s_flags |= MS_POSIXACL;
#endif

	if (newLVSize) {
525
		pr_err("resize option for remount only\n");
J
Jan Blunck 已提交
526
		goto out_kfree;
L
Linus Torvalds 已提交
527 528 529 530 531 532 533 534 535 536 537 538
	}

	/*
	 * Initialize blocksize to 4K.
	 */
	sb_set_blocksize(sb, PSIZE);

	/*
	 * Set method vectors.
	 */
	sb->s_op = &jfs_super_operations;
	sb->s_export_op = &jfs_export_operations;
539
	sb->s_xattr = jfs_xattr_handlers;
540 541
#ifdef CONFIG_QUOTA
	sb->dq_op = &dquot_operations;
542
	sb->s_qcop = &dquot_quotactl_ops;
J
Jan Kara 已提交
543
	sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
544
#endif
L
Linus Torvalds 已提交
545

546 547 548 549
	/*
	 * Initialize direct-mapping inode/address-space
	 */
	inode = new_inode(sb);
550 551
	if (inode == NULL) {
		ret = -ENOMEM;
J
Jan Blunck 已提交
552
		goto out_unload;
553
	}
554 555 556
	inode->i_ino = 0;
	inode->i_size = sb->s_bdev->bd_inode->i_size;
	inode->i_mapping->a_ops = &jfs_metapage_aops;
A
Al Viro 已提交
557
	hlist_add_fake(&inode->i_hash);
558 559 560 561
	mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);

	sbi->direct_inode = inode;

L
Linus Torvalds 已提交
562 563
	rc = jfs_mount(sb);
	if (rc) {
564
		if (!silent)
L
Linus Torvalds 已提交
565
			jfs_err("jfs_mount failed w/return code = %d", rc);
566
		goto out_mount_failed;
L
Linus Torvalds 已提交
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
	}
	if (sb->s_flags & MS_RDONLY)
		sbi->log = NULL;
	else {
		rc = jfs_mount_rw(sb, 0);
		if (rc) {
			if (!silent) {
				jfs_err("jfs_mount_rw failed, return code = %d",
					rc);
			}
			goto out_no_rw;
		}
	}

	sb->s_magic = JFS_SUPER_MAGIC;

583 584 585
	if (sbi->mntflag & JFS_OS2)
		sb->s_d_op = &jfs_ci_dentry_operations;

586 587 588
	inode = jfs_iget(sb, ROOT_I);
	if (IS_ERR(inode)) {
		ret = PTR_ERR(inode);
589
		goto out_no_rw;
590
	}
591
	sb->s_root = d_make_root(inode);
L
Linus Torvalds 已提交
592 593 594 595 596 597 598 599 600 601
	if (!sb->s_root)
		goto out_no_root;

	/* logical blocks are represented by 40 bits in pxd_t, etc. */
	sb->s_maxbytes = ((u64) sb->s_blocksize) << 40;
#if BITS_PER_LONG == 32
	/*
	 * Page cache is indexed by long.
	 * I would use MAX_LFS_FILESIZE, but it's only half as big
	 */
602 603
	sb->s_maxbytes = min(((u64) PAGE_CACHE_SIZE << 32) - 1,
			     (u64)sb->s_maxbytes);
L
Linus Torvalds 已提交
604 605 606 607 608
#endif
	sb->s_time_gran = 1;
	return 0;

out_no_root:
609
	jfs_err("jfs_read_super: get root dentry failed");
L
Linus Torvalds 已提交
610 611 612

out_no_rw:
	rc = jfs_umount(sb);
613
	if (rc)
L
Linus Torvalds 已提交
614
		jfs_err("jfs_umount failed with return code %d", rc);
615
out_mount_failed:
616
	filemap_write_and_wait(sbi->direct_inode->i_mapping);
617 618 619 620
	truncate_inode_pages(sbi->direct_inode->i_mapping, 0);
	make_bad_inode(sbi->direct_inode);
	iput(sbi->direct_inode);
	sbi->direct_inode = NULL;
J
Jan Blunck 已提交
621
out_unload:
L
Linus Torvalds 已提交
622 623
	if (sbi->nls_tab)
		unload_nls(sbi->nls_tab);
J
Jan Blunck 已提交
624
out_kfree:
L
Linus Torvalds 已提交
625
	kfree(sbi);
626
	return ret;
L
Linus Torvalds 已提交
627 628
}

629
static int jfs_freeze(struct super_block *sb)
L
Linus Torvalds 已提交
630 631 632
{
	struct jfs_sb_info *sbi = JFS_SBI(sb);
	struct jfs_log *log = sbi->log;
633
	int rc = 0;
L
Linus Torvalds 已提交
634 635 636

	if (!(sb->s_flags & MS_RDONLY)) {
		txQuiesce(sb);
637 638
		rc = lmLogShutdown(log);
		if (rc) {
J
Joe Perches 已提交
639
			jfs_error(sb, "lmLogShutdown failed\n");
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654

			/* let operations fail rather than hang */
			txResume(sb);

			return rc;
		}
		rc = updateSuper(sb, FM_CLEAN);
		if (rc) {
			jfs_err("jfs_freeze: updateSuper failed\n");
			/*
			 * Don't fail here. Everything succeeded except
			 * marking the superblock clean, so there's really
			 * no harm in leaving it frozen for now.
			 */
		}
L
Linus Torvalds 已提交
655
	}
656
	return 0;
L
Linus Torvalds 已提交
657 658
}

659
static int jfs_unfreeze(struct super_block *sb)
L
Linus Torvalds 已提交
660 661 662 663 664 665
{
	struct jfs_sb_info *sbi = JFS_SBI(sb);
	struct jfs_log *log = sbi->log;
	int rc = 0;

	if (!(sb->s_flags & MS_RDONLY)) {
666 667
		rc = updateSuper(sb, FM_MOUNT);
		if (rc) {
J
Joe Perches 已提交
668
			jfs_error(sb, "updateSuper failed\n");
669 670 671 672
			goto out;
		}
		rc = lmLogInit(log);
		if (rc)
J
Joe Perches 已提交
673
			jfs_error(sb, "lmLogInit failed\n");
674 675
out:
		txResume(sb);
L
Linus Torvalds 已提交
676
	}
677
	return rc;
L
Linus Torvalds 已提交
678 679
}

A
Al Viro 已提交
680 681
static struct dentry *jfs_do_mount(struct file_system_type *fs_type,
	int flags, const char *dev_name, void *data)
L
Linus Torvalds 已提交
682
{
A
Al Viro 已提交
683
	return mount_bdev(fs_type, flags, dev_name, data, jfs_fill_super);
L
Linus Torvalds 已提交
684 685 686 687 688 689 690
}

static int jfs_sync_fs(struct super_block *sb, int wait)
{
	struct jfs_log *log = JFS_SBI(sb)->log;

	/* log == NULL indicates read-only mount */
691
	if (log) {
692 693 694 695 696
		/*
		 * Write quota structures to quota file, sync_blockdev() will
		 * write them to disk later
		 */
		dquot_writeback_dquots(sb, -1);
L
Linus Torvalds 已提交
697
		jfs_flush_journal(log, wait);
698
		jfs_syncpt(log, 0);
699
	}
L
Linus Torvalds 已提交
700 701 702 703

	return 0;
}

704
static int jfs_show_options(struct seq_file *seq, struct dentry *root)
705
{
706
	struct jfs_sb_info *sbi = JFS_SBI(root->d_sb);
707

708 709 710 711
	if (uid_valid(sbi->uid))
		seq_printf(seq, ",uid=%d", from_kuid(&init_user_ns, sbi->uid));
	if (gid_valid(sbi->gid))
		seq_printf(seq, ",gid=%d", from_kgid(&init_user_ns, sbi->gid));
712 713
	if (sbi->umask != -1)
		seq_printf(seq, ",umask=%03o", sbi->umask);
714 715
	if (sbi->flag & JFS_NOINTEGRITY)
		seq_puts(seq, ",nointegrity");
716 717
	if (sbi->flag & JFS_DISCARD)
		seq_printf(seq, ",discard=%u", sbi->minblks_trim);
M
Miklos Szeredi 已提交
718 719 720 721 722 723
	if (sbi->nls_tab)
		seq_printf(seq, ",iocharset=%s", sbi->nls_tab->charset);
	if (sbi->flag & JFS_ERR_CONTINUE)
		seq_printf(seq, ",errors=continue");
	if (sbi->flag & JFS_ERR_PANIC)
		seq_printf(seq, ",errors=panic");
724

725
#ifdef CONFIG_QUOTA
726 727 728 729 730 731 732 733 734 735
	if (sbi->flag & JFS_USRQUOTA)
		seq_puts(seq, ",usrquota");

	if (sbi->flag & JFS_GRPQUOTA)
		seq_puts(seq, ",grpquota");
#endif

	return 0;
}

736 737 738 739
#ifdef CONFIG_QUOTA

/* Read data from quotafile - avoid pagecache and such because we cannot afford
 * acquiring the locks... As quota files are never truncated and quota code
L
Lucas De Marchi 已提交
740
 * itself serializes the operations (and no one else should touch the files)
741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
 * we don't have to be afraid of races */
static ssize_t jfs_quota_read(struct super_block *sb, int type, char *data,
			      size_t len, loff_t off)
{
	struct inode *inode = sb_dqopt(sb)->files[type];
	sector_t blk = off >> sb->s_blocksize_bits;
	int err = 0;
	int offset = off & (sb->s_blocksize - 1);
	int tocopy;
	size_t toread;
	struct buffer_head tmp_bh;
	struct buffer_head *bh;
	loff_t i_size = i_size_read(inode);

	if (off > i_size)
		return 0;
	if (off+len > i_size)
		len = i_size-off;
	toread = len;
	while (toread > 0) {
		tocopy = sb->s_blocksize - offset < toread ?
				sb->s_blocksize - offset : toread;

		tmp_bh.b_state = 0;
		tmp_bh.b_size = 1 << inode->i_blkbits;
		err = jfs_get_block(inode, blk, &tmp_bh, 0);
		if (err)
			return err;
		if (!buffer_mapped(&tmp_bh))	/* A hole? */
			memset(data, 0, tocopy);
		else {
			bh = sb_bread(sb, tmp_bh.b_blocknr);
			if (!bh)
				return -EIO;
			memcpy(data, bh->b_data+offset, tocopy);
			brelse(bh);
		}
		offset = 0;
		toread -= tocopy;
		data += tocopy;
		blk++;
	}
	return len;
}

/* Write to quotafile */
static ssize_t jfs_quota_write(struct super_block *sb, int type,
			       const char *data, size_t len, loff_t off)
{
	struct inode *inode = sb_dqopt(sb)->files[type];
	sector_t blk = off >> sb->s_blocksize_bits;
	int err = 0;
	int offset = off & (sb->s_blocksize - 1);
	int tocopy;
	size_t towrite = len;
	struct buffer_head tmp_bh;
	struct buffer_head *bh;

	mutex_lock(&inode->i_mutex);
	while (towrite > 0) {
		tocopy = sb->s_blocksize - offset < towrite ?
				sb->s_blocksize - offset : towrite;

		tmp_bh.b_state = 0;
805
		tmp_bh.b_size = 1 << inode->i_blkbits;
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829
		err = jfs_get_block(inode, blk, &tmp_bh, 1);
		if (err)
			goto out;
		if (offset || tocopy != sb->s_blocksize)
			bh = sb_bread(sb, tmp_bh.b_blocknr);
		else
			bh = sb_getblk(sb, tmp_bh.b_blocknr);
		if (!bh) {
			err = -EIO;
			goto out;
		}
		lock_buffer(bh);
		memcpy(bh->b_data+offset, data, tocopy);
		flush_dcache_page(bh->b_page);
		set_buffer_uptodate(bh);
		mark_buffer_dirty(bh);
		unlock_buffer(bh);
		brelse(bh);
		offset = 0;
		towrite -= tocopy;
		data += tocopy;
		blk++;
	}
out:
830 831
	if (len == towrite) {
		mutex_unlock(&inode->i_mutex);
832
		return err;
833
	}
834 835 836 837 838 839 840 841 842
	if (inode->i_size < off+len-towrite)
		i_size_write(inode, off+len-towrite);
	inode->i_version++;
	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
	mark_inode_dirty(inode);
	mutex_unlock(&inode->i_mutex);
	return len - towrite;
}

J
Jan Kara 已提交
843 844 845 846
static struct dquot **jfs_get_dquots(struct inode *inode)
{
	return JFS_IP(inode)->i_dquot;
}
847 848
#endif

849
static const struct super_operations jfs_super_operations = {
L
Linus Torvalds 已提交
850 851 852 853
	.alloc_inode	= jfs_alloc_inode,
	.destroy_inode	= jfs_destroy_inode,
	.dirty_inode	= jfs_dirty_inode,
	.write_inode	= jfs_write_inode,
A
Al Viro 已提交
854
	.evict_inode	= jfs_evict_inode,
L
Linus Torvalds 已提交
855 856
	.put_super	= jfs_put_super,
	.sync_fs	= jfs_sync_fs,
857 858
	.freeze_fs	= jfs_freeze,
	.unfreeze_fs	= jfs_unfreeze,
L
Linus Torvalds 已提交
859 860
	.statfs		= jfs_statfs,
	.remount_fs	= jfs_remount,
861 862 863 864
	.show_options	= jfs_show_options,
#ifdef CONFIG_QUOTA
	.quota_read	= jfs_quota_read,
	.quota_write	= jfs_quota_write,
J
Jan Kara 已提交
865
	.get_dquots	= jfs_get_dquots,
866
#endif
L
Linus Torvalds 已提交
867 868
};

869
static const struct export_operations jfs_export_operations = {
C
Christoph Hellwig 已提交
870 871
	.fh_to_dentry	= jfs_fh_to_dentry,
	.fh_to_parent	= jfs_fh_to_parent,
L
Linus Torvalds 已提交
872 873 874 875 876 877
	.get_parent	= jfs_get_parent,
};

static struct file_system_type jfs_fs_type = {
	.owner		= THIS_MODULE,
	.name		= "jfs",
A
Al Viro 已提交
878
	.mount		= jfs_do_mount,
L
Linus Torvalds 已提交
879 880 881
	.kill_sb	= kill_block_super,
	.fs_flags	= FS_REQUIRES_DEV,
};
882
MODULE_ALIAS_FS("jfs");
L
Linus Torvalds 已提交
883

884
static void init_once(void *foo)
L
Linus Torvalds 已提交
885 886 887
{
	struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo;

C
Christoph Lameter 已提交
888 889 890 891 892 893 894 895
	memset(jfs_ip, 0, sizeof(struct jfs_inode_info));
	INIT_LIST_HEAD(&jfs_ip->anon_inode_list);
	init_rwsem(&jfs_ip->rdwrlock);
	mutex_init(&jfs_ip->commit_mutex);
	init_rwsem(&jfs_ip->xattr_sem);
	spin_lock_init(&jfs_ip->ag_lock);
	jfs_ip->active_ag = -1;
	inode_init_once(&jfs_ip->vfs_inode);
L
Linus Torvalds 已提交
896 897 898 899 900 901 902 903
}

static int __init init_jfs_fs(void)
{
	int i;
	int rc;

	jfs_inode_cachep =
D
Dave Kleikamp 已提交
904
	    kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0,
905
			    SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
906
			    init_once);
L
Linus Torvalds 已提交
907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930
	if (jfs_inode_cachep == NULL)
		return -ENOMEM;

	/*
	 * Metapage initialization
	 */
	rc = metapage_init();
	if (rc) {
		jfs_err("metapage_init failed w/rc = %d", rc);
		goto free_slab;
	}

	/*
	 * Transaction Manager initialization
	 */
	rc = txInit();
	if (rc) {
		jfs_err("txInit failed w/rc = %d", rc);
		goto free_metapage;
	}

	/*
	 * I/O completion thread (endio)
	 */
C
Christoph Hellwig 已提交
931 932 933 934
	jfsIOthread = kthread_run(jfsIOWait, NULL, "jfsIO");
	if (IS_ERR(jfsIOthread)) {
		rc = PTR_ERR(jfsIOthread);
		jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
L
Linus Torvalds 已提交
935 936 937 938 939 940 941 942 943
		goto end_txmngr;
	}

	if (commit_threads < 1)
		commit_threads = num_online_cpus();
	if (commit_threads > MAX_COMMIT_THREADS)
		commit_threads = MAX_COMMIT_THREADS;

	for (i = 0; i < commit_threads; i++) {
944 945
		jfsCommitThread[i] = kthread_run(jfs_lazycommit, NULL,
						 "jfsCommit");
C
Christoph Hellwig 已提交
946 947 948
		if (IS_ERR(jfsCommitThread[i])) {
			rc = PTR_ERR(jfsCommitThread[i]);
			jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
L
Linus Torvalds 已提交
949 950 951 952 953
			commit_threads = i;
			goto kill_committask;
		}
	}

C
Christoph Hellwig 已提交
954 955 956 957
	jfsSyncThread = kthread_run(jfs_sync, NULL, "jfsSync");
	if (IS_ERR(jfsSyncThread)) {
		rc = PTR_ERR(jfsSyncThread);
		jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
L
Linus Torvalds 已提交
958 959 960 961 962 963 964
		goto kill_committask;
	}

#ifdef PROC_FS_JFS
	jfs_proc_init();
#endif

965 966 967
	rc = register_filesystem(&jfs_fs_type);
	if (!rc)
		return 0;
L
Linus Torvalds 已提交
968

969 970 971 972
#ifdef PROC_FS_JFS
	jfs_proc_clean();
#endif
	kthread_stop(jfsSyncThread);
L
Linus Torvalds 已提交
973 974
kill_committask:
	for (i = 0; i < commit_threads; i++)
C
Christoph Hellwig 已提交
975 976
		kthread_stop(jfsCommitThread[i]);
	kthread_stop(jfsIOthread);
L
Linus Torvalds 已提交
977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
end_txmngr:
	txExit();
free_metapage:
	metapage_exit();
free_slab:
	kmem_cache_destroy(jfs_inode_cachep);
	return rc;
}

static void __exit exit_jfs_fs(void)
{
	int i;

	jfs_info("exit_jfs_fs called");

	txExit();
	metapage_exit();
C
Christoph Hellwig 已提交
994 995

	kthread_stop(jfsIOthread);
L
Linus Torvalds 已提交
996
	for (i = 0; i < commit_threads; i++)
C
Christoph Hellwig 已提交
997 998
		kthread_stop(jfsCommitThread[i]);
	kthread_stop(jfsSyncThread);
L
Linus Torvalds 已提交
999 1000 1001 1002
#ifdef PROC_FS_JFS
	jfs_proc_clean();
#endif
	unregister_filesystem(&jfs_fs_type);
1003 1004 1005 1006 1007 1008

	/*
	 * Make sure all delayed rcu free inodes are flushed before we
	 * destroy cache.
	 */
	rcu_barrier();
L
Linus Torvalds 已提交
1009 1010 1011 1012 1013
	kmem_cache_destroy(jfs_inode_cachep);
}

module_init(init_jfs_fs)
module_exit(exit_jfs_fs)