super.c 23.3 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",
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

105
	pr_err("ERROR: (device %s): %ps: %pV\n",
J
Joe Perches 已提交
106 107 108
	       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);

499
	sbi = kzalloc(sizeof(struct jfs_sb_info), GFP_KERNEL);
J
Jan Blunck 已提交
500
	if (!sbi)
501
		return -ENOMEM;
J
Jan Blunck 已提交
502

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

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

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

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

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

	/*
	 * 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;
536
	sb->s_xattr = jfs_xattr_handlers;
537 538
#ifdef CONFIG_QUOTA
	sb->dq_op = &dquot_operations;
539
	sb->s_qcop = &dquot_quotactl_ops;
J
Jan Kara 已提交
540
	sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
541
#endif
L
Linus Torvalds 已提交
542

543 544 545 546
	/*
	 * Initialize direct-mapping inode/address-space
	 */
	inode = new_inode(sb);
547 548
	if (inode == NULL) {
		ret = -ENOMEM;
J
Jan Blunck 已提交
549
		goto out_unload;
550
	}
551 552 553
	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 已提交
554
	hlist_add_fake(&inode->i_hash);
555 556 557 558
	mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);

	sbi->direct_inode = inode;

L
Linus Torvalds 已提交
559 560
	rc = jfs_mount(sb);
	if (rc) {
561
		if (!silent)
L
Linus Torvalds 已提交
562
			jfs_err("jfs_mount failed w/return code = %d", rc);
563
		goto out_mount_failed;
L
Linus Torvalds 已提交
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
	}
	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;

580 581 582
	if (sbi->mntflag & JFS_OS2)
		sb->s_d_op = &jfs_ci_dentry_operations;

583 584 585
	inode = jfs_iget(sb, ROOT_I);
	if (IS_ERR(inode)) {
		ret = PTR_ERR(inode);
586
		goto out_no_rw;
587
	}
588
	sb->s_root = d_make_root(inode);
L
Linus Torvalds 已提交
589 590 591 592 593 594 595 596 597 598
	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
	 */
599
	sb->s_maxbytes = min(((u64) PAGE_SIZE << 32) - 1,
600
			     (u64)sb->s_maxbytes);
L
Linus Torvalds 已提交
601 602 603 604 605
#endif
	sb->s_time_gran = 1;
	return 0;

out_no_root:
606
	jfs_err("jfs_read_super: get root dentry failed");
L
Linus Torvalds 已提交
607 608 609

out_no_rw:
	rc = jfs_umount(sb);
610
	if (rc)
L
Linus Torvalds 已提交
611
		jfs_err("jfs_umount failed with return code %d", rc);
612
out_mount_failed:
613
	filemap_write_and_wait(sbi->direct_inode->i_mapping);
614 615 616 617
	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 已提交
618
out_unload:
619
	unload_nls(sbi->nls_tab);
J
Jan Blunck 已提交
620
out_kfree:
L
Linus Torvalds 已提交
621
	kfree(sbi);
622
	return ret;
L
Linus Torvalds 已提交
623 624
}

625
static int jfs_freeze(struct super_block *sb)
L
Linus Torvalds 已提交
626 627 628
{
	struct jfs_sb_info *sbi = JFS_SBI(sb);
	struct jfs_log *log = sbi->log;
629
	int rc = 0;
L
Linus Torvalds 已提交
630 631 632

	if (!(sb->s_flags & MS_RDONLY)) {
		txQuiesce(sb);
633 634
		rc = lmLogShutdown(log);
		if (rc) {
J
Joe Perches 已提交
635
			jfs_error(sb, "lmLogShutdown failed\n");
636 637 638 639 640 641 642 643

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

			return rc;
		}
		rc = updateSuper(sb, FM_CLEAN);
		if (rc) {
644
			jfs_err("jfs_freeze: updateSuper failed");
645 646 647 648 649 650
			/*
			 * 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 已提交
651
	}
652
	return 0;
L
Linus Torvalds 已提交
653 654
}

655
static int jfs_unfreeze(struct super_block *sb)
L
Linus Torvalds 已提交
656 657 658 659 660 661
{
	struct jfs_sb_info *sbi = JFS_SBI(sb);
	struct jfs_log *log = sbi->log;
	int rc = 0;

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

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

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 */
687
	if (log) {
688 689 690 691 692
		/*
		 * Write quota structures to quota file, sync_blockdev() will
		 * write them to disk later
		 */
		dquot_writeback_dquots(sb, -1);
L
Linus Torvalds 已提交
693
		jfs_flush_journal(log, wait);
694
		jfs_syncpt(log, 0);
695
	}
L
Linus Torvalds 已提交
696 697 698 699

	return 0;
}

700
static int jfs_show_options(struct seq_file *seq, struct dentry *root)
701
{
702
	struct jfs_sb_info *sbi = JFS_SBI(root->d_sb);
703

704 705 706 707
	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));
708 709
	if (sbi->umask != -1)
		seq_printf(seq, ",umask=%03o", sbi->umask);
710 711
	if (sbi->flag & JFS_NOINTEGRITY)
		seq_puts(seq, ",nointegrity");
712 713
	if (sbi->flag & JFS_DISCARD)
		seq_printf(seq, ",discard=%u", sbi->minblks_trim);
M
Miklos Szeredi 已提交
714 715 716 717 718 719
	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");
720

721
#ifdef CONFIG_QUOTA
722 723 724 725 726 727 728 729 730 731
	if (sbi->flag & JFS_USRQUOTA)
		seq_puts(seq, ",usrquota");

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

	return 0;
}

732 733 734 735
#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 已提交
736
 * itself serializes the operations (and no one else should touch the files)
737 738 739 740 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
 * 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;

A
Al Viro 已提交
795
	inode_lock(inode);
796 797 798 799 800
	while (towrite > 0) {
		tocopy = sb->s_blocksize - offset < towrite ?
				sb->s_blocksize - offset : towrite;

		tmp_bh.b_state = 0;
801
		tmp_bh.b_size = 1 << inode->i_blkbits;
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
		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:
826
	if (len == towrite) {
A
Al Viro 已提交
827
		inode_unlock(inode);
828
		return err;
829
	}
830 831 832 833 834
	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);
A
Al Viro 已提交
835
	inode_unlock(inode);
836 837 838
	return len - towrite;
}

J
Jan Kara 已提交
839 840 841 842
static struct dquot **jfs_get_dquots(struct inode *inode)
{
	return JFS_IP(inode)->i_dquot;
}
843 844
#endif

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

865
static const struct export_operations jfs_export_operations = {
C
Christoph Hellwig 已提交
866 867
	.fh_to_dentry	= jfs_fh_to_dentry,
	.fh_to_parent	= jfs_fh_to_parent,
L
Linus Torvalds 已提交
868 869 870 871 872 873
	.get_parent	= jfs_get_parent,
};

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

880
static void init_once(void *foo)
L
Linus Torvalds 已提交
881 882 883
{
	struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo;

C
Christoph Lameter 已提交
884 885 886 887 888 889 890 891
	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 已提交
892 893 894 895 896 897 898 899
}

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

	jfs_inode_cachep =
D
Dave Kleikamp 已提交
900
	    kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0,
901
			    SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD|SLAB_ACCOUNT,
902
			    init_once);
L
Linus Torvalds 已提交
903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926
	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 已提交
927 928 929 930
	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 已提交
931 932 933 934 935 936 937 938 939
		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++) {
940 941
		jfsCommitThread[i] = kthread_run(jfs_lazycommit, NULL,
						 "jfsCommit");
C
Christoph Hellwig 已提交
942 943 944
		if (IS_ERR(jfsCommitThread[i])) {
			rc = PTR_ERR(jfsCommitThread[i]);
			jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
L
Linus Torvalds 已提交
945 946 947 948 949
			commit_threads = i;
			goto kill_committask;
		}
	}

C
Christoph Hellwig 已提交
950 951 952 953
	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 已提交
954 955 956 957 958 959 960
		goto kill_committask;
	}

#ifdef PROC_FS_JFS
	jfs_proc_init();
#endif

961 962 963
	rc = register_filesystem(&jfs_fs_type);
	if (!rc)
		return 0;
L
Linus Torvalds 已提交
964

965 966 967 968
#ifdef PROC_FS_JFS
	jfs_proc_clean();
#endif
	kthread_stop(jfsSyncThread);
L
Linus Torvalds 已提交
969 970
kill_committask:
	for (i = 0; i < commit_threads; i++)
C
Christoph Hellwig 已提交
971 972
		kthread_stop(jfsCommitThread[i]);
	kthread_stop(jfsIOthread);
L
Linus Torvalds 已提交
973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989
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 已提交
990 991

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

	/*
	 * Make sure all delayed rcu free inodes are flushed before we
	 * destroy cache.
	 */
	rcu_barrier();
L
Linus Torvalds 已提交
1005 1006 1007 1008 1009
	kmem_cache_destroy(jfs_inode_cachep);
}

module_init(init_jfs_fs)
module_exit(exit_jfs_fs)