Blame view

fs/jfs/super.c 21 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>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
  #include <asm/uaccess.h>
8fc2751be   Mark Bellon   [PATCH] disk quot...
35
  #include <linux/seq_file.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
38
  
  #include "jfs_incore.h"
  #include "jfs_filsys.h"
1868f4aa5   Dave Kleikamp   JFS: fix sparse w...
39
  #include "jfs_inode.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
43
44
45
46
47
48
49
  #include "jfs_metapage.h"
  #include "jfs_superblock.h"
  #include "jfs_dmap.h"
  #include "jfs_imap.h"
  #include "jfs_acl.h"
  #include "jfs_debug.h"
  
  MODULE_DESCRIPTION("The Journaled Filesystem (JFS)");
  MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM");
  MODULE_LICENSE("GPL");
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
50
  static struct kmem_cache * jfs_inode_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51

ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
52
  static const struct super_operations jfs_super_operations;
396551644   Christoph Hellwig   exportfs: make st...
53
  static const struct export_operations jfs_export_operations;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
57
58
59
  static struct file_system_type jfs_fs_type;
  
  #define MAX_COMMIT_THREADS 64
  static int commit_threads = 0;
  module_param(commit_threads, int, 0);
  MODULE_PARM_DESC(commit_threads, "Number of commit threads");
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
60
61
62
  static struct task_struct *jfsCommitThread[MAX_COMMIT_THREADS];
  struct task_struct *jfsIOthread;
  struct task_struct *jfsSyncThread;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
64
65
66
67
68
  
  #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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  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
  ",
  			sb->s_id);
  	else if (sbi->flag & JFS_ERR_REMOUNT_RO) {
  		jfs_err("ERROR: (device %s): remounting filesystem "
  			"as read-only
  ",
  			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
92
93
94
95
96
97
98
  
  	/* nothing is done for continue beyond marking the superblock dirty */
  }
  
  void jfs_error(struct super_block *sb, const char * function, ...)
  {
  	static char error_buf[256];
  	va_list args;
  
  	va_start(args, function);
4a6e617a4   Alexey Dobriyan   [PATCH] fs/*: tri...
99
  	vsnprintf(error_buf, sizeof(error_buf), function, args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
  	va_end(args);
  
  	printk(KERN_ERR "ERROR: (device %s): %s
  ", sb->s_id, error_buf);
  
  	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;
  	return &jfs_inode->vfs_inode;
  }
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
117
118
119
120
  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...
121
122
  	kmem_cache_free(jfs_inode_cachep, ji);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
124
125
  static void jfs_destroy_inode(struct inode *inode)
  {
  	struct jfs_inode_info *ji = JFS_IP(inode);
8a9cd6d67   Dave Kleikamp   JFS: Fix race in ...
126
  	BUG_ON(!list_empty(&ji->anon_inode_list));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
130
131
132
133
  	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...
134
  	call_rcu(&inode->i_rcu, jfs_i_callback);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
  }
726c33422   David Howells   [PATCH] VFS: Perm...
136
  static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
  {
726c33422   David Howells   [PATCH] VFS: Perm...
138
  	struct jfs_sb_info *sbi = JFS_SBI(dentry->d_sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  	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.
  	 * We'll try to calculate some guess as to how may inodes we can
  	 * 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...
163
164
165
  	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
166
167
168
169
170
171
172
173
174
175
176
  
  	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");
6cfd01484   Christoph Hellwig   push BKL down int...
177

e0ccfd959   Christoph Hellwig   quota: move unmou...
178
  	dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
180
181
  	rc = jfs_umount(sb);
  	if (rc)
  		jfs_err("jfs_umount failed with return code %d", rc);
6d729e44a   Thomas Gleixner   fs: Make unload_n...
182
183
  
  	unload_nls(sbi->nls_tab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184

7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
185
186
  	truncate_inode_pages(sbi->direct_inode->i_mapping, 0);
  	iput(sbi->direct_inode);
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
187

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
190
191
192
  	kfree(sbi);
  }
  
  enum {
  	Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
8fc2751be   Mark Bellon   [PATCH] disk quot...
193
  	Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
194
  	Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
  };
a447c0932   Steven Whitehouse   vfs: Use const fo...
196
  static const match_table_t tokens = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
198
199
200
201
202
203
204
  	{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...
205
206
  	{Opt_usrquota, "usrquota"},
  	{Opt_grpquota, "grpquota"},
69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
207
208
209
  	{Opt_uid, "uid=%u"},
  	{Opt_gid, "gid=%u"},
  	{Opt_umask, "umask=%u"},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
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
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
  	{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) {
  					printk(KERN_ERR
  					       "JFS: charset not found
  ");
  					goto cleanup;
  				}
  			}
  			break;
  		case Opt_resize:
  		{
  			char *resize = args[0].from;
  			*newLVSize = simple_strtoull(resize, &resize, 0);
  			break;
  		}
  		case Opt_resize_nosize:
  		{
  			*newLVSize = sb->s_bdev->bd_inode->i_size >>
  				sb->s_blocksize_bits;
  			if (*newLVSize == 0)
  				printk(KERN_ERR
  				       "JFS: Cannot determine volume size
  ");
  			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 {
  				printk(KERN_ERR
  				       "JFS: %s is an invalid error handler
  ",
  				       errors);
  				goto cleanup;
  			}
  			break;
  		}
8fc2751be   Mark Bellon   [PATCH] disk quot...
300

115ff50ba   Dave Kleikamp   JFS: Quota suppor...
301
  #ifdef CONFIG_QUOTA
8fc2751be   Mark Bellon   [PATCH] disk quot...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
  		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:
  			printk(KERN_ERR
  			       "JFS: quota operations not supported
  ");
  			break;
  #endif
69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
  		case Opt_uid:
  		{
  			char *uid = args[0].from;
  			sbi->uid = simple_strtoul(uid, &uid, 0);
  			break;
  		}
  		case Opt_gid:
  		{
  			char *gid = args[0].from;
  			sbi->gid = simple_strtoul(gid, &gid, 0);
  			break;
  		}
  		case Opt_umask:
  		{
  			char *umask = args[0].from;
  			sbi->umask = simple_strtoul(umask, &umask, 8);
  			if (sbi->umask & ~0777) {
  				printk(KERN_ERR
  				       "JFS: Invalid value of umask
  ");
  				goto cleanup;
  			}
  			break;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
343
344
345
346
347
348
349
350
351
  		default:
  			printk("jfs: Unrecognized mount option \"%s\" "
  					" or missing value
  ", p);
  			goto cleanup;
  		}
  	}
  
  	if (nls_map != (void *) -1) {
  		/* Discard old (if remount) */
6d729e44a   Thomas Gleixner   fs: Make unload_n...
352
  		unload_nls(sbi->nls_tab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
  		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...
368
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
370
371
372
  
  	if (!parse_options(data, sb, &newLVSize, &flag)) {
  		return -EINVAL;
  	}
22b26db6f   Jan Blunck   BKL: Remove BKL f...
373

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
375
376
377
378
379
380
381
  	if (newLVSize) {
  		if (sb->s_flags & MS_RDONLY) {
  			printk(KERN_ERR
  		  "JFS: resize requires volume to be mounted read-write
  ");
  			return -EROFS;
  		}
  		rc = jfs_extendfs(sb, newLVSize, 0);
22b26db6f   Jan Blunck   BKL: Remove BKL f...
382
  		if (rc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
384
385
386
  			return rc;
  	}
  
  	if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
387
388
389
390
391
  		/*
  		 * 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
392
  		JFS_SBI(sb)->flag = flag;
337eb00a2   Alessio Igor Bogani   Push BKL down int...
393
  		ret = jfs_mount_rw(sb, 1);
c79d967de   Christoph Hellwig   quota: move remou...
394
395
396
  
  		/* mark the fs r/w for quota activity */
  		sb->s_flags &= ~MS_RDONLY;
0f0dd62fd   Christoph Hellwig   quota: kill the v...
397
  		dquot_resume(sb, -1);
337eb00a2   Alessio Igor Bogani   Push BKL down int...
398
  		return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
400
  	}
  	if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) {
0f0dd62fd   Christoph Hellwig   quota: kill the v...
401
402
  		rc = dquot_suspend(sb, -1);
  		if (rc < 0) {
0f0dd62fd   Christoph Hellwig   quota: kill the v...
403
  			return rc;
c79d967de   Christoph Hellwig   quota: move remou...
404
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405
406
407
408
409
410
411
  		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);
22b26db6f   Jan Blunck   BKL: Remove BKL f...
412
  			if (rc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
413
  				return rc;
22b26db6f   Jan Blunck   BKL: Remove BKL f...
414

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
  			JFS_SBI(sb)->flag = flag;
337eb00a2   Alessio Igor Bogani   Push BKL down int...
416
  			ret = jfs_mount_rw(sb, 1);
337eb00a2   Alessio Igor Bogani   Push BKL down int...
417
  			return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
419
420
421
422
423
424
425
426
427
428
429
  		}
  	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...
430
  	int flag, ret = -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431
432
  
  	jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags);
22b26db6f   Jan Blunck   BKL: Remove BKL f...
433
  	if (!new_valid_dev(sb->s_bdev->bd_dev))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
  		return -EOVERFLOW;
5b3030e39   Eric Sesterhenn   JFS: kzalloc conv...
435
  	sbi = kzalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
22b26db6f   Jan Blunck   BKL: Remove BKL f...
436
  	if (!sbi)
087387f90   Akinobu Mita   [PATCH] JFS: retu...
437
  		return -ENOMEM;
22b26db6f   Jan Blunck   BKL: Remove BKL f...
438

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
440
  	sb->s_fs_info = sbi;
  	sbi->sb = sb;
69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
441
  	sbi->uid = sbi->gid = sbi->umask = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
443
444
  
  	/* initialize the mount flag and determine the default error handler */
  	flag = JFS_ERR_REMOUNT_RO;
684bdc7ff   Jan Blunck   JFS: Free sbi mem...
445
446
  	if (!parse_options((char *) data, sb, &newLVSize, &flag))
  		goto out_kfree;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
448
449
450
451
452
453
454
455
  	sbi->flag = flag;
  
  #ifdef CONFIG_JFS_POSIX_ACL
  	sb->s_flags |= MS_POSIXACL;
  #endif
  
  	if (newLVSize) {
  		printk(KERN_ERR "resize option for remount only
  ");
684bdc7ff   Jan Blunck   JFS: Free sbi mem...
456
  		goto out_kfree;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
458
459
460
461
462
463
464
465
466
467
468
  	}
  
  	/*
  	 * 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;
123e9caf1   Christoph Hellwig   quota: explicitly...
469
470
  #ifdef CONFIG_QUOTA
  	sb->dq_op = &dquot_operations;
287a80958   Christoph Hellwig   quota: rename def...
471
  	sb->s_qcop = &dquot_quotactl_ops;
123e9caf1   Christoph Hellwig   quota: explicitly...
472
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
473

7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
474
475
476
477
  	/*
  	 * Initialize direct-mapping inode/address-space
  	 */
  	inode = new_inode(sb);
eab1df71a   David Howells   iget: stop JFS fr...
478
479
  	if (inode == NULL) {
  		ret = -ENOMEM;
684bdc7ff   Jan Blunck   JFS: Free sbi mem...
480
  		goto out_unload;
eab1df71a   David Howells   iget: stop JFS fr...
481
  	}
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
482
  	inode->i_ino = 0;
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
483
484
  	inode->i_size = sb->s_bdev->bd_inode->i_size;
  	inode->i_mapping->a_ops = &jfs_metapage_aops;
ac17b8b57   Dave Kleikamp   JFS: make special...
485
  	insert_inode_hash(inode);
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
486
487
488
  	mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
  
  	sbi->direct_inode = inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
490
491
492
493
  	rc = jfs_mount(sb);
  	if (rc) {
  		if (!silent) {
  			jfs_err("jfs_mount failed w/return code = %d", rc);
  		}
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
494
  		goto out_mount_failed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
  	}
  	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;
94b77bd86   Al Viro   switch jfs to ->s...
510
511
  	if (sbi->mntflag & JFS_OS2)
  		sb->s_d_op = &jfs_ci_dentry_operations;
eab1df71a   David Howells   iget: stop JFS fr...
512
513
514
  	inode = jfs_iget(sb, ROOT_I);
  	if (IS_ERR(inode)) {
  		ret = PTR_ERR(inode);
6536d2891   Dave Kleikamp   JFS: skip bad ipu...
515
  		goto out_no_rw;
eab1df71a   David Howells   iget: stop JFS fr...
516
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
517
518
519
  	sb->s_root = d_alloc_root(inode);
  	if (!sb->s_root)
  		goto out_no_root;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
521
522
523
524
525
526
  	/* 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
  	 */
28ba0ec64   Alan Cox   jfs: Fix 32bit bu...
527
  	sb->s_maxbytes = min(((u64) PAGE_CACHE_SIZE << 32) - 1, (u64)sb->s_maxbytes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
529
530
531
532
  #endif
  	sb->s_time_gran = 1;
  	return 0;
  
  out_no_root:
6536d2891   Dave Kleikamp   JFS: skip bad ipu...
533
534
  	jfs_err("jfs_read_super: get root dentry failed");
  	iput(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535
536
537
538
539
540
  
  out_no_rw:
  	rc = jfs_umount(sb);
  	if (rc) {
  		jfs_err("jfs_umount failed with return code %d", rc);
  	}
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
541
  out_mount_failed:
28fd12982   OGAWA Hirofumi   [PATCH] Fix and a...
542
  	filemap_write_and_wait(sbi->direct_inode->i_mapping);
7fab479be   Dave Kleikamp   [PATCH] JFS: Supp...
543
544
545
546
  	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...
547
  out_unload:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
548
549
  	if (sbi->nls_tab)
  		unload_nls(sbi->nls_tab);
684bdc7ff   Jan Blunck   JFS: Free sbi mem...
550
  out_kfree:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551
  	kfree(sbi);
eab1df71a   David Howells   iget: stop JFS fr...
552
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
553
  }
c4be0c1dc   Takashi Sato   filesystem freeze...
554
  static int jfs_freeze(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555
556
557
558
559
560
561
562
563
  {
  	struct jfs_sb_info *sbi = JFS_SBI(sb);
  	struct jfs_log *log = sbi->log;
  
  	if (!(sb->s_flags & MS_RDONLY)) {
  		txQuiesce(sb);
  		lmLogShutdown(log);
  		updateSuper(sb, FM_CLEAN);
  	}
c4be0c1dc   Takashi Sato   filesystem freeze...
564
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
565
  }
c4be0c1dc   Takashi Sato   filesystem freeze...
566
  static int jfs_unfreeze(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
567
568
569
570
571
572
573
574
575
576
577
578
  {
  	struct jfs_sb_info *sbi = JFS_SBI(sb);
  	struct jfs_log *log = sbi->log;
  	int rc = 0;
  
  	if (!(sb->s_flags & MS_RDONLY)) {
  		updateSuper(sb, FM_MOUNT);
  		if ((rc = lmLogInit(log)))
  			jfs_err("jfs_unlock failed with return code %d", rc);
  		else
  			txResume(sb);
  	}
c4be0c1dc   Takashi Sato   filesystem freeze...
579
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
580
  }
152a08366   Al Viro   new helper: mount...
581
582
  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
583
  {
152a08366   Al Viro   new helper: mount...
584
  	return mount_bdev(fs_type, flags, dev_name, data, jfs_fill_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
585
586
587
588
589
590
591
  }
  
  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...
592
  	if (log) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
  		jfs_flush_journal(log, wait);
cbc3d65eb   Dave Kleikamp   JFS: Improve sync...
594
  		jfs_syncpt(log, 0);
1c6278295   Dave Kleikamp   [PATCH] JFS: Writ...
595
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596
597
598
  
  	return 0;
  }
34c80b1d9   Al Viro   vfs: switch ->sho...
599
  static int jfs_show_options(struct seq_file *seq, struct dentry *root)
8fc2751be   Mark Bellon   [PATCH] disk quot...
600
  {
34c80b1d9   Al Viro   vfs: switch ->sho...
601
  	struct jfs_sb_info *sbi = JFS_SBI(root->d_sb);
8fc2751be   Mark Bellon   [PATCH] disk quot...
602

69eb66d7d   Dave Kleikamp   JFS: add uid, gid...
603
604
605
606
607
608
  	if (sbi->uid != -1)
  		seq_printf(seq, ",uid=%d", sbi->uid);
  	if (sbi->gid != -1)
  		seq_printf(seq, ",gid=%d", sbi->gid);
  	if (sbi->umask != -1)
  		seq_printf(seq, ",umask=%03o", sbi->umask);
8fc2751be   Mark Bellon   [PATCH] disk quot...
609
610
  	if (sbi->flag & JFS_NOINTEGRITY)
  		seq_puts(seq, ",nointegrity");
5c5e32cee   Miklos Szeredi   mount options: fi...
611
612
613
614
615
616
  	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...
617

115ff50ba   Dave Kleikamp   JFS: Quota suppor...
618
  #ifdef CONFIG_QUOTA
8fc2751be   Mark Bellon   [PATCH] disk quot...
619
620
621
622
623
624
625
626
627
  	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...
628
629
630
631
  #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...
632
   * itself serializes the operations (and no one else should touch the files)
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
   * 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;
8bcb2839b   Dave Kleikamp   JFS: Fix bug in q...
697
  		tmp_bh.b_size = 1 << inode->i_blkbits;
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
  		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...
722
723
  	if (len == towrite) {
  		mutex_unlock(&inode->i_mutex);
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
724
  		return err;
9c83633ad   Dan Carpenter   missing unlock in...
725
  	}
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
726
727
728
729
730
731
732
733
734
735
  	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;
  }
  
  #endif
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
736
  static const struct super_operations jfs_super_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
737
738
  	.alloc_inode	= jfs_alloc_inode,
  	.destroy_inode	= jfs_destroy_inode,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739
740
  	.dirty_inode	= jfs_dirty_inode,
  	.write_inode	= jfs_write_inode,
62aff86fd   Al Viro   switch jfs to ->e...
741
  	.evict_inode	= jfs_evict_inode,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
742
743
  	.put_super	= jfs_put_super,
  	.sync_fs	= jfs_sync_fs,
c4be0c1dc   Takashi Sato   filesystem freeze...
744
745
  	.freeze_fs	= jfs_freeze,
  	.unfreeze_fs	= jfs_unfreeze,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
746
747
  	.statfs		= jfs_statfs,
  	.remount_fs	= jfs_remount,
115ff50ba   Dave Kleikamp   JFS: Quota suppor...
748
749
750
751
752
  	.show_options	= jfs_show_options,
  #ifdef CONFIG_QUOTA
  	.quota_read	= jfs_quota_read,
  	.quota_write	= jfs_quota_write,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
753
  };
396551644   Christoph Hellwig   exportfs: make st...
754
  static const struct export_operations jfs_export_operations = {
d425de704   Christoph Hellwig   jfs: new export ops
755
756
  	.fh_to_dentry	= jfs_fh_to_dentry,
  	.fh_to_parent	= jfs_fh_to_parent,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
757
758
759
760
761
762
  	.get_parent	= jfs_get_parent,
  };
  
  static struct file_system_type jfs_fs_type = {
  	.owner		= THIS_MODULE,
  	.name		= "jfs",
152a08366   Al Viro   new helper: mount...
763
  	.mount		= jfs_do_mount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
764
765
766
  	.kill_sb	= kill_block_super,
  	.fs_flags	= FS_REQUIRES_DEV,
  };
51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
767
  static void init_once(void *foo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
768
769
  {
  	struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo;
a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
770
771
772
773
774
775
776
  	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_...
777
  	inode_init_once(&jfs_ip->vfs_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
778
779
780
781
782
783
784
785
  }
  
  static int __init init_jfs_fs(void)
  {
  	int i;
  	int rc;
  
  	jfs_inode_cachep =
63f83c9fc   Dave Kleikamp   JFS: White space ...
786
  	    kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0,
fffb60f93   Paul Jackson   [PATCH] cpuset me...
787
  			    SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
20c2df83d   Paul Mundt   mm: Remove slab d...
788
  			    init_once);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
  	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...
813
814
815
816
  	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
817
818
  		goto end_txmngr;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
819
820
821
822
823
824
825
  
  	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++) {
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
826
827
828
829
  		jfsCommitThread[i] = kthread_run(jfs_lazycommit, NULL, "jfsCommit");
  		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
830
831
832
  			commit_threads = i;
  			goto kill_committask;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833
  	}
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
834
835
836
837
  	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
838
839
  		goto kill_committask;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
840
841
842
843
844
845
846
847
  
  #ifdef PROC_FS_JFS
  	jfs_proc_init();
  #endif
  
  	return register_filesystem(&jfs_fs_type);
  
  kill_committask:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
848
  	for (i = 0; i < commit_threads; i++)
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
849
850
  		kthread_stop(jfsCommitThread[i]);
  	kthread_stop(jfsIOthread);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851
852
853
854
855
856
857
858
859
860
861
862
863
864
  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
865
866
  	txExit();
  	metapage_exit();
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
867
868
  
  	kthread_stop(jfsIOthread);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
869
  	for (i = 0; i < commit_threads; i++)
91dbb4deb   Christoph Hellwig   JFS: Use the kthr...
870
871
  		kthread_stop(jfsCommitThread[i]);
  	kthread_stop(jfsSyncThread);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
873
874
875
876
877
878
879
880
  #ifdef PROC_FS_JFS
  	jfs_proc_clean();
  #endif
  	unregister_filesystem(&jfs_fs_type);
  	kmem_cache_destroy(jfs_inode_cachep);
  }
  
  module_init(init_jfs_fs)
  module_exit(exit_jfs_fs)