Blame view

fs/jfs/super.c 24.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
63f83c9fc   Dave Kleikamp   JFS: White space ...
7
   *   the Free Software Foundation; either version 2 of the License, or
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
   *   (at your option) any later version.
63f83c9fc   Dave Kleikamp   JFS: White space ...
9
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
63f83c9fc   Dave Kleikamp   JFS: White space ...
16
   *   along with this program;  if not, write to the Free Software
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
20
   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   */
  
  #include <linux/fs.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
23
24
  #include <linux/module.h>
  #include <linux/parser.h>
  #include <linux/completion.h>
  #include <linux/vfs.h>
74abb9890   Jan Kara   quota: move funct...
25
  #include <linux/quotaops.h>
8fc2751be   Mark Bellon   [PATCH] disk quot...
26
  #include <linux/mount.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
  #include <linux/moduleparam.h>
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
28
  #include <linux/kthread.h>
9a59f452a   Christoph Hellwig   [PATCH] remove <l...
29
  #include <linux/posix_acl.h>
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
30
  #include <linux/buffer_head.h>
a56942551   Christoph Hellwig   knfsd: exportfs: ...
31
  #include <linux/exportfs.h>
b5c816a4f   Coly Li   jfs: return f_fsi...
32
  #include <linux/crc32.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
33
  #include <linux/slab.h>
7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
34
  #include <linux/uaccess.h>
8fc2751be   Mark Bellon   [PATCH] disk quot...
35
  #include <linux/seq_file.h>
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
36
  #include <linux/blkdev.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
38
39
  
  #include "jfs_incore.h"
  #include "jfs_filsys.h"
1868f4aa5   Dave Kleikamp   JFS: fix sparse w...
40
  #include "jfs_inode.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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"
2cc6a5a01   Christoph Hellwig   jfs: use generic ...
47
  #include "jfs_xattr.h"
12fd086d3   Jan Kara   jfs: Set flags on...
48
  #include "jfs_dinode.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
  
  MODULE_DESCRIPTION("The Journaled Filesystem (JFS)");
  MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM");
  MODULE_LICENSE("GPL");
789602e95   Fabian Frederick   fs/jfs/super.c: r...
53
  static struct kmem_cache *jfs_inode_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54

ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
55
  static const struct super_operations jfs_super_operations;
396551644   Christoph Hellwig   exportfs: make st...
56
  static const struct export_operations jfs_export_operations;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
  static struct file_system_type jfs_fs_type;
  
  #define MAX_COMMIT_THREADS 64
789602e95   Fabian Frederick   fs/jfs/super.c: r...
60
  static int commit_threads;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
  module_param(commit_threads, int, 0);
  MODULE_PARM_DESC(commit_threads, "Number of commit threads");
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
63
64
65
  static struct task_struct *jfsCommitThread[MAX_COMMIT_THREADS];
  struct task_struct *jfsIOthread;
  struct task_struct *jfsSyncThread;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
70
71
  
  #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
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
73
74
  static void jfs_handle_error(struct super_block *sb)
  {
  	struct jfs_sb_info *sbi = JFS_SBI(sb);
bc98a42c1   David Howells   VFS: Convert sb->...
75
  	if (sb_rdonly(sb))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
78
79
80
81
82
83
84
  		return;
  
  	updateSuper(sb, FM_DIRTY);
  
  	if (sbi->flag & JFS_ERR_PANIC)
  		panic("JFS (device %s): panic forced after error
  ",
  			sb->s_id);
  	else if (sbi->flag & JFS_ERR_REMOUNT_RO) {
b18db6de2   Joe Perches   jfs: Remove termi...
85
  		jfs_err("ERROR: (device %s): remounting filesystem as read-only",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
  			sb->s_id);
  		sb->s_flags |= MS_RDONLY;
63f83c9fc   Dave Kleikamp   JFS: White space ...
88
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
91
  
  	/* nothing is done for continue beyond marking the superblock dirty */
  }
eb8630d7d   Joe Perches   jfs: Update jfs_e...
92
  void jfs_error(struct super_block *sb, const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
  {
eb8630d7d   Joe Perches   jfs: Update jfs_e...
94
  	struct va_format vaf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
  	va_list args;
eb8630d7d   Joe Perches   jfs: Update jfs_e...
96
97
98
99
  	va_start(args, fmt);
  
  	vaf.fmt = fmt;
  	vaf.va = &args;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100

7d2ac4561   Scott Wood   jfs: %pf is only ...
101
102
  	pr_err("ERROR: (device %s): %ps: %pV
  ",
eb8630d7d   Joe Perches   jfs: Update jfs_e...
103
104
105
  	       sb->s_id, __builtin_return_address(0), &vaf);
  
  	va_end(args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
107
108
109
110
111
112
113
114
115
116
  
  	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;
507e1fa69   Jan Kara   jfs: Convert to p...
117
118
119
  #ifdef CONFIG_QUOTA
  	memset(&jfs_inode->i_dquot, 0, sizeof(jfs_inode->i_dquot));
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
  	return &jfs_inode->vfs_inode;
  }
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
122
123
124
125
  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);
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
126
127
  	kmem_cache_free(jfs_inode_cachep, ji);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
  static void jfs_destroy_inode(struct inode *inode)
  {
  	struct jfs_inode_info *ji = JFS_IP(inode);
8a9cd6d67   Dave Kleikamp   JFS: Fix race in ...
131
  	BUG_ON(!list_empty(&ji->anon_inode_list));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
133
134
135
136
137
138
  	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);
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
139
  	call_rcu(&inode->i_rcu, jfs_i_callback);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  }
726c33422   David Howells   [PATCH] VFS: Perm...
141
  static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
  {
726c33422   David Howells   [PATCH] VFS: Perm...
143
  	struct jfs_sb_info *sbi = JFS_SBI(dentry->d_sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
145
146
147
148
149
150
151
152
153
154
155
  	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.
4de80273a   Philippe De Muyter   fs/jfs: Fix typo ...
156
  	 * We'll try to calculate some guess as to how many inodes we can
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
158
159
160
161
162
163
164
165
166
167
  	 * 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));
b5c816a4f   Coly Li   jfs: return f_fsi...
168
169
170
  	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);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
172
173
174
  
  	buf->f_namelen = JFS_NAME_MAX;
  	return 0;
  }
12fd086d3   Jan Kara   jfs: Set flags on...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
  #ifdef CONFIG_QUOTA
  static int jfs_quota_off(struct super_block *sb, int type);
  static int jfs_quota_on(struct super_block *sb, int type, int format_id,
  			const struct path *path);
  
  static void jfs_quota_off_umount(struct super_block *sb)
  {
  	int type;
  
  	for (type = 0; type < MAXQUOTAS; type++)
  		jfs_quota_off(sb, type);
  }
  
  static const struct quotactl_ops jfs_quotactl_ops = {
  	.quota_on	= jfs_quota_on,
  	.quota_off	= jfs_quota_off,
  	.quota_sync	= dquot_quota_sync,
  	.get_state	= dquot_get_state,
  	.set_info	= dquot_set_dqinfo,
  	.get_dqblk	= dquot_get_dqblk,
  	.set_dqblk	= dquot_set_dqblk,
  	.get_nextdqblk	= dquot_get_next_dqblk,
  };
  #else
  static inline void jfs_quota_off_umount(struct super_block *sb)
  {
  }
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
205
206
207
208
  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");
6cfd01484   Christoph Hellwig   push BKL down int...
209

12fd086d3   Jan Kara   jfs: Set flags on...
210
  	jfs_quota_off_umount(sb);
e0ccfd959   Christoph Hellwig   quota: move unmou...
211

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
213
214
  	rc = jfs_umount(sb);
  	if (rc)
  		jfs_err("jfs_umount failed with return code %d", rc);
6d729e44a   Thomas Gleixner   fs: Make unload_n...
215
216
  
  	unload_nls(sbi->nls_tab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217

7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
218
219
  	truncate_inode_pages(sbi->direct_inode->i_mapping, 0);
  	iput(sbi->direct_inode);
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
220

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
222
223
224
225
  	kfree(sbi);
  }
  
  enum {
  	Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
8fc2751be   Mark Bellon   [PATCH] disk quot...
226
  	Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
227
228
  	Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
  	Opt_discard, Opt_nodiscard, Opt_discard_minblk
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
  };
a447c0932   Steven Whitehouse   vfs: Use const fo...
230
  static const match_table_t tokens = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
232
233
234
235
236
237
238
  	{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"},
8fc2751be   Mark Bellon   [PATCH] disk quot...
239
240
  	{Opt_usrquota, "usrquota"},
  	{Opt_grpquota, "grpquota"},
69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
241
242
243
  	{Opt_uid, "uid=%u"},
  	{Opt_gid, "gid=%u"},
  	{Opt_umask, "umask=%u"},
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
244
245
246
  	{Opt_discard, "discard"},
  	{Opt_nodiscard, "nodiscard"},
  	{Opt_discard_minblk, "discard=%u"},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
  	{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) {
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
288
289
  					pr_err("JFS: charset not found
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
291
292
293
294
295
296
  					goto cleanup;
  				}
  			}
  			break;
  		case Opt_resize:
  		{
  			char *resize = args[0].from;
bb5e50aaa   Fabian Frederick   fs/jfs/super.c: c...
297
298
299
300
  			int rc = kstrtoll(resize, 0, newLVSize);
  
  			if (rc)
  				goto cleanup;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
302
303
304
  			break;
  		}
  		case Opt_resize_nosize:
  		{
684666e51   Fabian Frederick   jfs: atomically r...
305
  			*newLVSize = i_size_read(sb->s_bdev->bd_inode) >>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
307
  				sb->s_blocksize_bits;
  			if (*newLVSize == 0)
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
308
309
  				pr_err("JFS: Cannot determine volume size
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
  			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 {
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
330
331
  				pr_err("JFS: %s is an invalid error handler
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
332
333
334
335
336
  				       errors);
  				goto cleanup;
  			}
  			break;
  		}
8fc2751be   Mark Bellon   [PATCH] disk quot...
337

115ff50ba   Dave Kleikamp   JFS: Quota suppor...
338
  #ifdef CONFIG_QUOTA
8fc2751be   Mark Bellon   [PATCH] disk quot...
339
340
341
342
343
344
345
346
347
348
349
  		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:
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
350
351
  			pr_err("JFS: quota operations not supported
  ");
8fc2751be   Mark Bellon   [PATCH] disk quot...
352
353
  			break;
  #endif
69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
354
355
356
  		case Opt_uid:
  		{
  			char *uid = args[0].from;
bb5e50aaa   Fabian Frederick   fs/jfs/super.c: c...
357
358
359
360
361
  			uid_t val;
  			int rc = kstrtouint(uid, 0, &val);
  
  			if (rc)
  				goto cleanup;
c18cdc1a3   Eric W. Biederman   userns: Convert j...
362
363
364
  			sbi->uid = make_kuid(current_user_ns(), val);
  			if (!uid_valid(sbi->uid))
  				goto cleanup;
69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
365
366
  			break;
  		}
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
367

69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
368
369
370
  		case Opt_gid:
  		{
  			char *gid = args[0].from;
bb5e50aaa   Fabian Frederick   fs/jfs/super.c: c...
371
372
373
374
375
  			gid_t val;
  			int rc = kstrtouint(gid, 0, &val);
  
  			if (rc)
  				goto cleanup;
c18cdc1a3   Eric W. Biederman   userns: Convert j...
376
377
378
  			sbi->gid = make_kgid(current_user_ns(), val);
  			if (!gid_valid(sbi->gid))
  				goto cleanup;
69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
379
380
  			break;
  		}
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
381

69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
382
383
384
  		case Opt_umask:
  		{
  			char *umask = args[0].from;
bb5e50aaa   Fabian Frederick   fs/jfs/super.c: c...
385
386
387
388
  			int rc = kstrtouint(umask, 8, &sbi->umask);
  
  			if (rc)
  				goto cleanup;
69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
389
  			if (sbi->umask & ~0777) {
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
390
391
  				pr_err("JFS: Invalid value of umask
  ");
69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
392
393
394
395
  				goto cleanup;
  			}
  			break;
  		}
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
396
397
398
399
400
401
402
403
404
  
  		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;
789602e95   Fabian Frederick   fs/jfs/super.c: r...
405
  			if (blk_queue_discard(q))
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
406
  				*flag |= JFS_DISCARD;
789602e95   Fabian Frederick   fs/jfs/super.c: r...
407
408
409
  			else
  				pr_err("JFS: discard option not supported on device
  ");
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
410
411
412
413
414
415
416
417
418
419
420
  			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;
bb5e50aaa   Fabian Frederick   fs/jfs/super.c: c...
421
  			int rc;
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
422
423
  			if (blk_queue_discard(q)) {
  				*flag |= JFS_DISCARD;
bb5e50aaa   Fabian Frederick   fs/jfs/super.c: c...
424
425
426
427
428
  				rc = kstrtouint(minblks_trim, 0,
  						&sbi->minblks_trim);
  				if (rc)
  					goto cleanup;
  			} else
789602e95   Fabian Frederick   fs/jfs/super.c: r...
429
430
  				pr_err("JFS: discard option not supported on device
  ");
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
431
432
  			break;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433
  		default:
789602e95   Fabian Frederick   fs/jfs/super.c: r...
434
435
436
  			printk("jfs: Unrecognized mount option \"%s\" or missing value
  ",
  			       p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
437
438
439
440
441
442
  			goto cleanup;
  		}
  	}
  
  	if (nls_map != (void *) -1) {
  		/* Discard old (if remount) */
6d729e44a   Thomas Gleixner   fs: Make unload_n...
443
  		unload_nls(sbi->nls_tab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
  		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;
337eb00a2   Alessio Igor Bogani   Push BKL down int...
459
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460

02b9984d6   Theodore Ts'o   fs: push sync_fil...
461
  	sync_filesystem(sb);
789602e95   Fabian Frederick   fs/jfs/super.c: r...
462
  	if (!parse_options(data, sb, &newLVSize, &flag))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
  		return -EINVAL;
22b26db6f   Jan Blunck   BKL: Remove BKL f...
464

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
  	if (newLVSize) {
bc98a42c1   David Howells   VFS: Convert sb->...
466
  		if (sb_rdonly(sb)) {
789602e95   Fabian Frederick   fs/jfs/super.c: r...
467
468
  			pr_err("JFS: resize requires volume to be mounted read-write
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469
470
471
  			return -EROFS;
  		}
  		rc = jfs_extendfs(sb, newLVSize, 0);
22b26db6f   Jan Blunck   BKL: Remove BKL f...
472
  		if (rc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
473
474
  			return rc;
  	}
bc98a42c1   David Howells   VFS: Convert sb->...
475
  	if (sb_rdonly(sb) && !(*flags & MS_RDONLY)) {
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
476
477
478
479
480
  		/*
  		 * 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);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
  		JFS_SBI(sb)->flag = flag;
337eb00a2   Alessio Igor Bogani   Push BKL down int...
482
  		ret = jfs_mount_rw(sb, 1);
c79d967de   Christoph Hellwig   quota: move remou...
483
484
485
  
  		/* mark the fs r/w for quota activity */
  		sb->s_flags &= ~MS_RDONLY;
0f0dd62fd   Christoph Hellwig   quota: kill the v...
486
  		dquot_resume(sb, -1);
337eb00a2   Alessio Igor Bogani   Push BKL down int...
487
  		return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
488
  	}
bc98a42c1   David Howells   VFS: Convert sb->...
489
  	if (!sb_rdonly(sb) && (*flags & MS_RDONLY)) {
0f0dd62fd   Christoph Hellwig   quota: kill the v...
490
  		rc = dquot_suspend(sb, -1);
789602e95   Fabian Frederick   fs/jfs/super.c: r...
491
  		if (rc < 0)
0f0dd62fd   Christoph Hellwig   quota: kill the v...
492
  			return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493
494
495
496
497
  		rc = jfs_umount_rw(sb);
  		JFS_SBI(sb)->flag = flag;
  		return rc;
  	}
  	if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY))
bc98a42c1   David Howells   VFS: Convert sb->...
498
  		if (!sb_rdonly(sb)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
499
  			rc = jfs_umount_rw(sb);
22b26db6f   Jan Blunck   BKL: Remove BKL f...
500
  			if (rc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
  				return rc;
22b26db6f   Jan Blunck   BKL: Remove BKL f...
502

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
  			JFS_SBI(sb)->flag = flag;
337eb00a2   Alessio Igor Bogani   Push BKL down int...
504
  			ret = jfs_mount_rw(sb, 1);
337eb00a2   Alessio Igor Bogani   Push BKL down int...
505
  			return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
507
508
509
510
511
512
513
514
515
516
517
  		}
  	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;
eab1df71a   David Howells   iget: stop JFS fr...
518
  	int flag, ret = -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519
520
  
  	jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags);
789602e95   Fabian Frederick   fs/jfs/super.c: r...
521
  	sbi = kzalloc(sizeof(struct jfs_sb_info), GFP_KERNEL);
22b26db6f   Jan Blunck   BKL: Remove BKL f...
522
  	if (!sbi)
087387f90   Akinobu Mita   [PATCH] JFS: retu...
523
  		return -ENOMEM;
22b26db6f   Jan Blunck   BKL: Remove BKL f...
524

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
525
  	sb->s_fs_info = sbi;
8de527787   Al Viro   vfs: check i_nlin...
526
  	sb->s_max_links = JFS_LINK_MAX;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527
  	sbi->sb = sb;
c18cdc1a3   Eric W. Biederman   userns: Convert j...
528
529
530
  	sbi->uid = INVALID_UID;
  	sbi->gid = INVALID_GID;
  	sbi->umask = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
532
533
  
  	/* initialize the mount flag and determine the default error handler */
  	flag = JFS_ERR_REMOUNT_RO;
684bdc7ff   Jan Blunck   JFS: Free sbi mem...
534
535
  	if (!parse_options((char *) data, sb, &newLVSize, &flag))
  		goto out_kfree;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
537
538
539
540
541
542
  	sbi->flag = flag;
  
  #ifdef CONFIG_JFS_POSIX_ACL
  	sb->s_flags |= MS_POSIXACL;
  #endif
  
  	if (newLVSize) {
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
543
544
  		pr_err("resize option for remount only
  ");
684bdc7ff   Jan Blunck   JFS: Free sbi mem...
545
  		goto out_kfree;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
546
547
548
549
550
551
552
553
554
555
556
557
  	}
  
  	/*
  	 * 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;
2cc6a5a01   Christoph Hellwig   jfs: use generic ...
558
  	sb->s_xattr = jfs_xattr_handlers;
123e9caf1   Christoph Hellwig   quota: explicitly...
559
560
  #ifdef CONFIG_QUOTA
  	sb->dq_op = &dquot_operations;
12fd086d3   Jan Kara   jfs: Set flags on...
561
  	sb->s_qcop = &jfs_quotactl_ops;
507e1fa69   Jan Kara   jfs: Convert to p...
562
  	sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
123e9caf1   Christoph Hellwig   quota: explicitly...
563
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
564

7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
565
566
567
568
  	/*
  	 * Initialize direct-mapping inode/address-space
  	 */
  	inode = new_inode(sb);
eab1df71a   David Howells   iget: stop JFS fr...
569
570
  	if (inode == NULL) {
  		ret = -ENOMEM;
684bdc7ff   Jan Blunck   JFS: Free sbi mem...
571
  		goto out_unload;
eab1df71a   David Howells   iget: stop JFS fr...
572
  	}
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
573
  	inode->i_ino = 0;
684666e51   Fabian Frederick   jfs: atomically r...
574
  	inode->i_size = i_size_read(sb->s_bdev->bd_inode);
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
575
  	inode->i_mapping->a_ops = &jfs_metapage_aops;
9bb8730ed   Al Viro   jfs: don't hash d...
576
  	hlist_add_fake(&inode->i_hash);
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
577
578
579
  	mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
  
  	sbi->direct_inode = inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
580
581
  	rc = jfs_mount(sb);
  	if (rc) {
789602e95   Fabian Frederick   fs/jfs/super.c: r...
582
  		if (!silent)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
583
  			jfs_err("jfs_mount failed w/return code = %d", rc);
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
584
  		goto out_mount_failed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
585
  	}
bc98a42c1   David Howells   VFS: Convert sb->...
586
  	if (sb_rdonly(sb))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
588
589
590
591
592
593
594
595
596
597
598
599
  		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;
94b77bd86   Al Viro   switch jfs to ->s...
600
601
  	if (sbi->mntflag & JFS_OS2)
  		sb->s_d_op = &jfs_ci_dentry_operations;
eab1df71a   David Howells   iget: stop JFS fr...
602
603
604
  	inode = jfs_iget(sb, ROOT_I);
  	if (IS_ERR(inode)) {
  		ret = PTR_ERR(inode);
6536d2891   Dave Kleikamp   JFS: skip bad ipu...
605
  		goto out_no_rw;
eab1df71a   David Howells   iget: stop JFS fr...
606
  	}
48fde701a   Al Viro   switch open-coded...
607
  	sb->s_root = d_make_root(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
608
609
  	if (!sb->s_root)
  		goto out_no_root;
c227390c9   Dave Kleikamp   jfs should use MA...
610
611
  	/* logical blocks are represented by 40 bits in pxd_t, etc.
  	 * and page cache is indexed by long
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
612
  	 */
c227390c9   Dave Kleikamp   jfs should use MA...
613
  	sb->s_maxbytes = min(((loff_t)sb->s_blocksize) << 40, MAX_LFS_FILESIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
614
615
616
617
  	sb->s_time_gran = 1;
  	return 0;
  
  out_no_root:
6536d2891   Dave Kleikamp   JFS: skip bad ipu...
618
  	jfs_err("jfs_read_super: get root dentry failed");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619
620
621
  
  out_no_rw:
  	rc = jfs_umount(sb);
789602e95   Fabian Frederick   fs/jfs/super.c: r...
622
  	if (rc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
  		jfs_err("jfs_umount failed with return code %d", rc);
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
624
  out_mount_failed:
28fd12982   OGAWA Hirofumi   [PATCH] Fix and a...
625
  	filemap_write_and_wait(sbi->direct_inode->i_mapping);
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
626
627
628
629
  	truncate_inode_pages(sbi->direct_inode->i_mapping, 0);
  	make_bad_inode(sbi->direct_inode);
  	iput(sbi->direct_inode);
  	sbi->direct_inode = NULL;
684bdc7ff   Jan Blunck   JFS: Free sbi mem...
630
  out_unload:
648695c74   Markus Elfring   jfs: Deletion of ...
631
  	unload_nls(sbi->nls_tab);
684bdc7ff   Jan Blunck   JFS: Free sbi mem...
632
  out_kfree:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
  	kfree(sbi);
eab1df71a   David Howells   iget: stop JFS fr...
634
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
635
  }
c4be0c1dc   Takashi Sato   filesystem freeze...
636
  static int jfs_freeze(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
637
638
639
  {
  	struct jfs_sb_info *sbi = JFS_SBI(sb);
  	struct jfs_log *log = sbi->log;
e9b376671   Vahram Martirosyan   jfs: Several bugs...
640
  	int rc = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641

bc98a42c1   David Howells   VFS: Convert sb->...
642
  	if (!sb_rdonly(sb)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643
  		txQuiesce(sb);
e9b376671   Vahram Martirosyan   jfs: Several bugs...
644
645
  		rc = lmLogShutdown(log);
  		if (rc) {
eb8630d7d   Joe Perches   jfs: Update jfs_e...
646
647
  			jfs_error(sb, "lmLogShutdown failed
  ");
e9b376671   Vahram Martirosyan   jfs: Several bugs...
648
649
650
651
652
653
654
655
  
  			/* let operations fail rather than hang */
  			txResume(sb);
  
  			return rc;
  		}
  		rc = updateSuper(sb, FM_CLEAN);
  		if (rc) {
b18db6de2   Joe Perches   jfs: Remove termi...
656
  			jfs_err("jfs_freeze: updateSuper failed");
e9b376671   Vahram Martirosyan   jfs: Several bugs...
657
658
659
660
661
662
  			/*
  			 * Don't fail here. Everything succeeded except
  			 * marking the superblock clean, so there's really
  			 * no harm in leaving it frozen for now.
  			 */
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
663
  	}
c4be0c1dc   Takashi Sato   filesystem freeze...
664
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
665
  }
c4be0c1dc   Takashi Sato   filesystem freeze...
666
  static int jfs_unfreeze(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
667
668
669
670
  {
  	struct jfs_sb_info *sbi = JFS_SBI(sb);
  	struct jfs_log *log = sbi->log;
  	int rc = 0;
bc98a42c1   David Howells   VFS: Convert sb->...
671
  	if (!sb_rdonly(sb)) {
e9b376671   Vahram Martirosyan   jfs: Several bugs...
672
673
  		rc = updateSuper(sb, FM_MOUNT);
  		if (rc) {
eb8630d7d   Joe Perches   jfs: Update jfs_e...
674
675
  			jfs_error(sb, "updateSuper failed
  ");
e9b376671   Vahram Martirosyan   jfs: Several bugs...
676
677
678
679
  			goto out;
  		}
  		rc = lmLogInit(log);
  		if (rc)
eb8630d7d   Joe Perches   jfs: Update jfs_e...
680
681
  			jfs_error(sb, "lmLogInit failed
  ");
e9b376671   Vahram Martirosyan   jfs: Several bugs...
682
683
  out:
  		txResume(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
684
  	}
e9b376671   Vahram Martirosyan   jfs: Several bugs...
685
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
686
  }
152a08366   Al Viro   new helper: mount...
687
688
  static struct dentry *jfs_do_mount(struct file_system_type *fs_type,
  	int flags, const char *dev_name, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
689
  {
152a08366   Al Viro   new helper: mount...
690
  	return mount_bdev(fs_type, flags, dev_name, data, jfs_fill_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691
692
693
694
695
696
697
  }
  
  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 */
1c6278295   Dave Kleikamp   [PATCH] JFS: Writ...
698
  	if (log) {
a11778257   Jan Kara   quota: Move quota...
699
700
701
702
703
  		/*
  		 * Write quota structures to quota file, sync_blockdev() will
  		 * write them to disk later
  		 */
  		dquot_writeback_dquots(sb, -1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
704
  		jfs_flush_journal(log, wait);
cbc3d65eb   Dave Kleikamp   JFS: Improve sync...
705
  		jfs_syncpt(log, 0);
1c6278295   Dave Kleikamp   [PATCH] JFS: Writ...
706
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
707
708
709
  
  	return 0;
  }
34c80b1d9   Al Viro   vfs: switch ->sho...
710
  static int jfs_show_options(struct seq_file *seq, struct dentry *root)
8fc2751be   Mark Bellon   [PATCH] disk quot...
711
  {
34c80b1d9   Al Viro   vfs: switch ->sho...
712
  	struct jfs_sb_info *sbi = JFS_SBI(root->d_sb);
8fc2751be   Mark Bellon   [PATCH] disk quot...
713

c18cdc1a3   Eric W. Biederman   userns: Convert j...
714
715
716
717
  	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));
69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
718
719
  	if (sbi->umask != -1)
  		seq_printf(seq, ",umask=%03o", sbi->umask);
8fc2751be   Mark Bellon   [PATCH] disk quot...
720
721
  	if (sbi->flag & JFS_NOINTEGRITY)
  		seq_puts(seq, ",nointegrity");
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
722
723
  	if (sbi->flag & JFS_DISCARD)
  		seq_printf(seq, ",discard=%u", sbi->minblks_trim);
5c5e32cee   Miklos Szeredi   mount options: fi...
724
725
726
727
728
729
  	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");
8fc2751be   Mark Bellon   [PATCH] disk quot...
730

115ff50ba   Dave Kleikamp   JFS: Quota suppor...
731
  #ifdef CONFIG_QUOTA
8fc2751be   Mark Bellon   [PATCH] disk quot...
732
733
734
735
736
737
738
739
740
  	if (sbi->flag & JFS_USRQUOTA)
  		seq_puts(seq, ",usrquota");
  
  	if (sbi->flag & JFS_GRPQUOTA)
  		seq_puts(seq, ",grpquota");
  #endif
  
  	return 0;
  }
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
741
742
743
744
  #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
25985edce   Lucas De Marchi   Fix common misspe...
745
   * itself serializes the operations (and no one else should touch the files)
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
   * 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;
93407472a   Fabian Frederick   fs: add i_blocksi...
770
  		tmp_bh.b_size = i_blocksize(inode);
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
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
  		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;
5955102c9   Al Viro   wrappers for ->i_...
803
  	inode_lock(inode);
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
804
805
806
807
808
  	while (towrite > 0) {
  		tocopy = sb->s_blocksize - offset < towrite ?
  				sb->s_blocksize - offset : towrite;
  
  		tmp_bh.b_state = 0;
93407472a   Fabian Frederick   fs: add i_blocksi...
809
  		tmp_bh.b_size = i_blocksize(inode);
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
  		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:
9c83633ad   Dan Carpenter   missing unlock in...
834
  	if (len == towrite) {
5955102c9   Al Viro   wrappers for ->i_...
835
  		inode_unlock(inode);
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
836
  		return err;
9c83633ad   Dan Carpenter   missing unlock in...
837
  	}
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
838
839
840
  	if (inode->i_size < off+len-towrite)
  		i_size_write(inode, off+len-towrite);
  	inode->i_version++;
078cd8279   Deepa Dinamani   fs: Replace CURRE...
841
  	inode->i_mtime = inode->i_ctime = current_time(inode);
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
842
  	mark_inode_dirty(inode);
5955102c9   Al Viro   wrappers for ->i_...
843
  	inode_unlock(inode);
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
844
845
  	return len - towrite;
  }
507e1fa69   Jan Kara   jfs: Convert to p...
846
847
848
849
  static struct dquot **jfs_get_dquots(struct inode *inode)
  {
  	return JFS_IP(inode)->i_dquot;
  }
12fd086d3   Jan Kara   jfs: Set flags on...
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
  
  static int jfs_quota_on(struct super_block *sb, int type, int format_id,
  			const struct path *path)
  {
  	int err;
  	struct inode *inode;
  
  	err = dquot_quota_on(sb, type, format_id, path);
  	if (err)
  		return err;
  
  	inode = d_inode(path->dentry);
  	inode_lock(inode);
  	JFS_IP(inode)->mode2 |= JFS_NOATIME_FL | JFS_IMMUTABLE_FL;
  	inode_set_flags(inode, S_NOATIME | S_IMMUTABLE,
  			S_NOATIME | S_IMMUTABLE);
  	inode_unlock(inode);
  	mark_inode_dirty(inode);
  
  	return 0;
  }
  
  static int jfs_quota_off(struct super_block *sb, int type)
  {
  	struct inode *inode = sb_dqopt(sb)->files[type];
  	int err;
  
  	if (!inode || !igrab(inode))
  		goto out;
  
  	err = dquot_quota_off(sb, type);
  	if (err)
  		goto out_put;
  
  	inode_lock(inode);
  	JFS_IP(inode)->mode2 &= ~(JFS_NOATIME_FL | JFS_IMMUTABLE_FL);
  	inode_set_flags(inode, 0, S_NOATIME | S_IMMUTABLE);
  	inode_unlock(inode);
  	mark_inode_dirty(inode);
  out_put:
  	iput(inode);
  	return err;
  out:
  	return dquot_quota_off(sb, type);
  }
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
895
  #endif
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
896
  static const struct super_operations jfs_super_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
897
898
  	.alloc_inode	= jfs_alloc_inode,
  	.destroy_inode	= jfs_destroy_inode,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
899
900
  	.dirty_inode	= jfs_dirty_inode,
  	.write_inode	= jfs_write_inode,
62aff86fd   Al Viro   switch jfs to ->e...
901
  	.evict_inode	= jfs_evict_inode,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
903
  	.put_super	= jfs_put_super,
  	.sync_fs	= jfs_sync_fs,
c4be0c1dc   Takashi Sato   filesystem freeze...
904
905
  	.freeze_fs	= jfs_freeze,
  	.unfreeze_fs	= jfs_unfreeze,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
906
907
  	.statfs		= jfs_statfs,
  	.remount_fs	= jfs_remount,
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
908
909
910
911
  	.show_options	= jfs_show_options,
  #ifdef CONFIG_QUOTA
  	.quota_read	= jfs_quota_read,
  	.quota_write	= jfs_quota_write,
507e1fa69   Jan Kara   jfs: Convert to p...
912
  	.get_dquots	= jfs_get_dquots,
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
913
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
914
  };
396551644   Christoph Hellwig   exportfs: make st...
915
  static const struct export_operations jfs_export_operations = {
d425de704   Christoph Hellwig   jfs: new export ops
916
917
  	.fh_to_dentry	= jfs_fh_to_dentry,
  	.fh_to_parent	= jfs_fh_to_parent,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
918
919
920
921
922
923
  	.get_parent	= jfs_get_parent,
  };
  
  static struct file_system_type jfs_fs_type = {
  	.owner		= THIS_MODULE,
  	.name		= "jfs",
152a08366   Al Viro   new helper: mount...
924
  	.mount		= jfs_do_mount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
925
926
927
  	.kill_sb	= kill_block_super,
  	.fs_flags	= FS_REQUIRES_DEV,
  };
7f78e0351   Eric W. Biederman   fs: Limit sys_mou...
928
  MODULE_ALIAS_FS("jfs");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
929

51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
930
  static void init_once(void *foo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
931
932
  {
  	struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo;
a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
933
934
935
936
937
938
939
  	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;
a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
940
  	inode_init_once(&jfs_ip->vfs_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
941
942
943
944
945
946
947
948
  }
  
  static int __init init_jfs_fs(void)
  {
  	int i;
  	int rc;
  
  	jfs_inode_cachep =
63f83c9fc   Dave Kleikamp   JFS: White space ...
949
  	    kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0,
5d097056c   Vladimir Davydov   kmemcg: account c...
950
  			    SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD|SLAB_ACCOUNT,
20c2df83d   Paul Mundt   mm: Remove slab d...
951
  			    init_once);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
  	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)
  	 */
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
976
977
978
979
  	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);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
980
981
  		goto end_txmngr;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
982
983
984
985
986
987
988
  
  	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++) {
789602e95   Fabian Frederick   fs/jfs/super.c: r...
989
990
  		jfsCommitThread[i] = kthread_run(jfs_lazycommit, NULL,
  						 "jfsCommit");
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
991
992
993
  		if (IS_ERR(jfsCommitThread[i])) {
  			rc = PTR_ERR(jfsCommitThread[i]);
  			jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
994
995
996
  			commit_threads = i;
  			goto kill_committask;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997
  	}
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
998
999
1000
1001
  	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);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1002
1003
  		goto kill_committask;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1004
1005
1006
1007
  
  #ifdef PROC_FS_JFS
  	jfs_proc_init();
  #endif
76bf09fcf   Al Viro   jfs: mising clean...
1008
1009
1010
  	rc = register_filesystem(&jfs_fs_type);
  	if (!rc)
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1011

76bf09fcf   Al Viro   jfs: mising clean...
1012
1013
1014
1015
  #ifdef PROC_FS_JFS
  	jfs_proc_clean();
  #endif
  	kthread_stop(jfsSyncThread);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1016
  kill_committask:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1017
  	for (i = 0; i < commit_threads; i++)
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
1018
1019
  		kthread_stop(jfsCommitThread[i]);
  	kthread_stop(jfsIOthread);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
  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");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1034
1035
  	txExit();
  	metapage_exit();
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
1036
1037
  
  	kthread_stop(jfsIOthread);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1038
  	for (i = 0; i < commit_threads; i++)
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
1039
1040
  		kthread_stop(jfsCommitThread[i]);
  	kthread_stop(jfsSyncThread);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1041
1042
1043
1044
  #ifdef PROC_FS_JFS
  	jfs_proc_clean();
  #endif
  	unregister_filesystem(&jfs_fs_type);
8c0a85377   Kirill A. Shutemov   fs: push rcu_barr...
1045
1046
1047
1048
1049
1050
  
  	/*
  	 * Make sure all delayed rcu free inodes are flushed before we
  	 * destroy cache.
  	 */
  	rcu_barrier();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1051
1052
1053
1054
1055
  	kmem_cache_destroy(jfs_inode_cachep);
  }
  
  module_init(init_jfs_fs)
  module_exit(exit_jfs_fs)