Blame view

fs/ufs/super.c 43.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  /*
   *  linux/fs/ufs/super.c
   *
   * Copyright (C) 1998
   * Daniel Pirkl <daniel.pirkl@email.cz>
   * Charles University, Faculty of Mathematics and Physics
   */
  
  /* Derived from
   *
   *  linux/fs/ext2/super.c
   *
   * Copyright (C) 1992, 1993, 1994, 1995
   * Remy Card (card@masi.ibp.fr)
   * Laboratoire MASI - Institut Blaise Pascal
   * Universite Pierre et Marie Curie (Paris VI)
   *
   *  from
   *
   *  linux/fs/minix/inode.c
   *
   *  Copyright (C) 1991, 1992  Linus Torvalds
   *
   *  Big-endian to little-endian byte-swapping/bitmaps by
   *        David S. Miller (davem@caip.rutgers.edu), 1995
   */
   
  /*
   * Inspired by
   *
   *  linux/fs/ufs/super.c
   *
   * Copyright (C) 1996
   * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
   * Laboratory for Computer Science Research Computing Facility
   * Rutgers, The State University of New Jersey
   *
   * Copyright (C) 1996  Eddie C. Dost  (ecd@skynet.be)
   *
   * Kernel module support added on 96/04/26 by
   * Stefan Reinauer <stepan@home.culture.mipt.ru>
   *
   * Module usage counts added on 96/04/29 by
f762dd682   Gertjan van Wingerde   Update my email a...
44
   * Gertjan van Wingerde <gwingerde@gmail.com>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
   *
   * Clean swab support on 19970406 by
   * Francois-Rene Rideau <fare@tunes.org>
   *
   * 4.4BSD (FreeBSD) support added on February 1st 1998 by
   * Niels Kristian Bech Jensen <nkbj@image.dk> partially based
   * on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>.
   *
   * NeXTstep support added on February 5th 1998 by
   * Niels Kristian Bech Jensen <nkbj@image.dk>.
   *
   * write support Daniel Pirkl <daniel.pirkl@email.cz> 1998
   * 
   * HP/UX hfs filesystem support added by
   * Martin K. Petersen <mkp@mkp.net>, August 1999
   *
   * UFS2 (of FreeBSD 5.x) support added by
   * Niraj Kumar <niraj17@iitbombay.org>, Jan 2004
   *
cbcae39fa   Evgeniy Dushistov   [PATCH] ufs2 writ...
64
65
   * UFS2 write support added by
   * Evgeniy Dushistov <dushistov@mail.ru>, 2007
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
   */
f3e2a520f   Alexey Dobriyan   ufs: NFS support
67
  #include <linux/exportfs.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
70
71
72
73
74
75
76
77
  #include <linux/module.h>
  #include <linux/bitops.h>
  
  #include <stdarg.h>
  
  #include <asm/uaccess.h>
  #include <asm/system.h>
  
  #include <linux/errno.h>
  #include <linux/fs.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
78
79
80
81
82
83
84
  #include <linux/slab.h>
  #include <linux/time.h>
  #include <linux/stat.h>
  #include <linux/string.h>
  #include <linux/blkdev.h>
  #include <linux/init.h>
  #include <linux/parser.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
86
  #include <linux/buffer_head.h>
  #include <linux/vfs.h>
9e8c4273e   vignesh babu   is_power_of_2: uf...
87
  #include <linux/log2.h>
2a9807c0d   Evgeniy Dushistov   ufs: implement sh...
88
89
  #include <linux/mount.h>
  #include <linux/seq_file.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90

e54205988   Mike Frysinger   drop linux/ufs_fs...
91
  #include "ufs_fs.h"
bcd6d4ecf   Christoph Hellwig   ufs: move non-lay...
92
  #include "ufs.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
94
  #include "swab.h"
  #include "util.h"
788257d61   Arnd Bergmann   ufs: remove the BKL
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  void lock_ufs(struct super_block *sb)
  {
  #if defined(CONFIG_SMP) || defined (CONFIG_PREEMPT)
  	struct ufs_sb_info *sbi = UFS_SB(sb);
  
  	mutex_lock(&sbi->mutex);
  	sbi->mutex_owner = current;
  #endif
  }
  
  void unlock_ufs(struct super_block *sb)
  {
  #if defined(CONFIG_SMP) || defined (CONFIG_PREEMPT)
  	struct ufs_sb_info *sbi = UFS_SB(sb);
  
  	sbi->mutex_owner = NULL;
  	mutex_unlock(&sbi->mutex);
  #endif
  }
f3e2a520f   Alexey Dobriyan   ufs: NFS support
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  static struct inode *ufs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation)
  {
  	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
  	struct inode *inode;
  
  	if (ino < UFS_ROOTINO || ino > uspi->s_ncg * uspi->s_ipg)
  		return ERR_PTR(-ESTALE);
  
  	inode = ufs_iget(sb, ino);
  	if (IS_ERR(inode))
  		return ERR_CAST(inode);
  	if (generation && inode->i_generation != generation) {
  		iput(inode);
  		return ERR_PTR(-ESTALE);
  	}
  	return inode;
  }
  
  static struct dentry *ufs_fh_to_dentry(struct super_block *sb, struct fid *fid,
  				       int fh_len, int fh_type)
  {
  	return generic_fh_to_dentry(sb, fid, fh_len, fh_type, ufs_nfs_get_inode);
  }
  
  static struct dentry *ufs_fh_to_parent(struct super_block *sb, struct fid *fid,
  				       int fh_len, int fh_type)
  {
  	return generic_fh_to_parent(sb, fid, fh_len, fh_type, ufs_nfs_get_inode);
  }
  
  static struct dentry *ufs_get_parent(struct dentry *child)
  {
  	struct qstr dot_dot = {
  		.name	= "..",
  		.len	= 2,
  	};
  	ino_t ino;
  
  	ino = ufs_inode_by_name(child->d_inode, &dot_dot);
  	if (!ino)
  		return ERR_PTR(-ENOENT);
  	return d_obtain_alias(ufs_iget(child->d_inode->i_sb, ino));
  }
  
  static const struct export_operations ufs_export_ops = {
  	.fh_to_dentry	= ufs_fh_to_dentry,
  	.fh_to_parent	= ufs_fh_to_parent,
  	.get_parent	= ufs_get_parent,
  };
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
163
  #ifdef CONFIG_UFS_DEBUG
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
166
  /*
   * Print contents of ufs_super_block, useful for debugging
   */
3313e2926   Evgeniy Dushistov   [PATCH] ufs2 writ...
167
  static void ufs_print_super_stuff(struct super_block *sb,
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
168
169
170
  				  struct ufs_super_block_first *usb1,
  				  struct ufs_super_block_second *usb2,
  				  struct ufs_super_block_third *usb3)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
  {
3313e2926   Evgeniy Dushistov   [PATCH] ufs2 writ...
172
  	u32 magic = fs32_to_cpu(sb, usb3->fs_magic);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
174
  	printk("ufs_print_super_stuff
  ");
3313e2926   Evgeniy Dushistov   [PATCH] ufs2 writ...
175
176
177
  	printk("  magic:     0x%x
  ", magic);
  	if (fs32_to_cpu(sb, usb3->fs_magic) == UFS2_MAGIC) {
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  		printk("  fs_size:   %llu
  ", (unsigned long long)
  		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size));
  		printk("  fs_dsize:  %llu
  ", (unsigned long long)
  		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize));
  		printk("  bsize:         %u
  ",
  		       fs32_to_cpu(sb, usb1->fs_bsize));
  		printk("  fsize:         %u
  ",
  		       fs32_to_cpu(sb, usb1->fs_fsize));
  		printk("  fs_volname:  %s
  ", usb2->fs_un.fs_u2.fs_volname);
  		printk("  fs_sblockloc: %llu
  ", (unsigned long long)
  		       fs64_to_cpu(sb, usb2->fs_un.fs_u2.fs_sblockloc));
  		printk("  cs_ndir(No of dirs):  %llu
  ", (unsigned long long)
  		       fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_ndir));
  		printk("  cs_nbfree(No of free blocks):  %llu
  ",
  		       (unsigned long long)
  		       fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree));
3313e2926   Evgeniy Dushistov   [PATCH] ufs2 writ...
202
203
204
205
206
207
208
209
  		printk(KERN_INFO"  cs_nifree(Num of free inodes): %llu
  ",
  		       (unsigned long long)
  		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree));
  		printk(KERN_INFO"  cs_nffree(Num of free frags): %llu
  ",
  		       (unsigned long long)
  		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree));
90b315af1   Evgeniy Dushistov   ufs: fix symlink ...
210
211
212
  		printk(KERN_INFO"  fs_maxsymlinklen: %u
  ",
  		       fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen));
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
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
  	} else {
  		printk(" sblkno:      %u
  ", fs32_to_cpu(sb, usb1->fs_sblkno));
  		printk(" cblkno:      %u
  ", fs32_to_cpu(sb, usb1->fs_cblkno));
  		printk(" iblkno:      %u
  ", fs32_to_cpu(sb, usb1->fs_iblkno));
  		printk(" dblkno:      %u
  ", fs32_to_cpu(sb, usb1->fs_dblkno));
  		printk(" cgoffset:    %u
  ",
  		       fs32_to_cpu(sb, usb1->fs_cgoffset));
  		printk(" ~cgmask:     0x%x
  ",
  		       ~fs32_to_cpu(sb, usb1->fs_cgmask));
  		printk(" size:        %u
  ", fs32_to_cpu(sb, usb1->fs_size));
  		printk(" dsize:       %u
  ", fs32_to_cpu(sb, usb1->fs_dsize));
  		printk(" ncg:         %u
  ", fs32_to_cpu(sb, usb1->fs_ncg));
  		printk(" bsize:       %u
  ", fs32_to_cpu(sb, usb1->fs_bsize));
  		printk(" fsize:       %u
  ", fs32_to_cpu(sb, usb1->fs_fsize));
  		printk(" frag:        %u
  ", fs32_to_cpu(sb, usb1->fs_frag));
  		printk(" fragshift:   %u
  ",
  		       fs32_to_cpu(sb, usb1->fs_fragshift));
  		printk(" ~fmask:      %u
  ", ~fs32_to_cpu(sb, usb1->fs_fmask));
  		printk(" fshift:      %u
  ", fs32_to_cpu(sb, usb1->fs_fshift));
  		printk(" sbsize:      %u
  ", fs32_to_cpu(sb, usb1->fs_sbsize));
  		printk(" spc:         %u
  ", fs32_to_cpu(sb, usb1->fs_spc));
  		printk(" cpg:         %u
  ", fs32_to_cpu(sb, usb1->fs_cpg));
  		printk(" ipg:         %u
  ", fs32_to_cpu(sb, usb1->fs_ipg));
  		printk(" fpg:         %u
  ", fs32_to_cpu(sb, usb1->fs_fpg));
  		printk(" csaddr:      %u
  ", fs32_to_cpu(sb, usb1->fs_csaddr));
  		printk(" cssize:      %u
  ", fs32_to_cpu(sb, usb1->fs_cssize));
  		printk(" cgsize:      %u
  ", fs32_to_cpu(sb, usb1->fs_cgsize));
  		printk(" fstodb:      %u
  ",
  		       fs32_to_cpu(sb, usb1->fs_fsbtodb));
  		printk(" nrpos:       %u
  ", fs32_to_cpu(sb, usb3->fs_nrpos));
  		printk(" ndir         %u
  ",
  		       fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir));
  		printk(" nifree       %u
  ",
  		       fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree));
  		printk(" nbfree       %u
  ",
  		       fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree));
  		printk(" nffree       %u
  ",
  		       fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree));
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281
282
283
284
285
286
287
  	printk("
  ");
  }
  
  /*
   * Print contents of ufs_cylinder_group, useful for debugging
   */
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
288
289
  static void ufs_print_cylinder_stuff(struct super_block *sb,
  				     struct ufs_cylinder_group *cg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
291
292
293
  {
  	printk("
  ufs_print_cylinder_stuff
  ");
96710b29e   Andrew Morton   [PATCH] ufs: prin...
294
295
  	printk("size of ucg: %zu
  ", sizeof(struct ufs_cylinder_group));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
  	printk("  magic:        %x
  ", fs32_to_cpu(sb, cg->cg_magic));
  	printk("  time:         %u
  ", fs32_to_cpu(sb, cg->cg_time));
  	printk("  cgx:          %u
  ", fs32_to_cpu(sb, cg->cg_cgx));
  	printk("  ncyl:         %u
  ", fs16_to_cpu(sb, cg->cg_ncyl));
  	printk("  niblk:        %u
  ", fs16_to_cpu(sb, cg->cg_niblk));
  	printk("  ndblk:        %u
  ", fs32_to_cpu(sb, cg->cg_ndblk));
  	printk("  cs_ndir:      %u
  ", fs32_to_cpu(sb, cg->cg_cs.cs_ndir));
  	printk("  cs_nbfree:    %u
  ", fs32_to_cpu(sb, cg->cg_cs.cs_nbfree));
  	printk("  cs_nifree:    %u
  ", fs32_to_cpu(sb, cg->cg_cs.cs_nifree));
  	printk("  cs_nffree:    %u
  ", fs32_to_cpu(sb, cg->cg_cs.cs_nffree));
  	printk("  rotor:        %u
  ", fs32_to_cpu(sb, cg->cg_rotor));
  	printk("  frotor:       %u
  ", fs32_to_cpu(sb, cg->cg_frotor));
  	printk("  irotor:       %u
  ", fs32_to_cpu(sb, cg->cg_irotor));
  	printk("  frsum:        %u, %u, %u, %u, %u, %u, %u, %u
  ",
  	    fs32_to_cpu(sb, cg->cg_frsum[0]), fs32_to_cpu(sb, cg->cg_frsum[1]),
  	    fs32_to_cpu(sb, cg->cg_frsum[2]), fs32_to_cpu(sb, cg->cg_frsum[3]),
  	    fs32_to_cpu(sb, cg->cg_frsum[4]), fs32_to_cpu(sb, cg->cg_frsum[5]),
  	    fs32_to_cpu(sb, cg->cg_frsum[6]), fs32_to_cpu(sb, cg->cg_frsum[7]));
  	printk("  btotoff:      %u
  ", fs32_to_cpu(sb, cg->cg_btotoff));
  	printk("  boff:         %u
  ", fs32_to_cpu(sb, cg->cg_boff));
  	printk("  iuseoff:      %u
  ", fs32_to_cpu(sb, cg->cg_iusedoff));
  	printk("  freeoff:      %u
  ", fs32_to_cpu(sb, cg->cg_freeoff));
  	printk("  nextfreeoff:  %u
  ", fs32_to_cpu(sb, cg->cg_nextfreeoff));
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
338
339
340
341
342
343
344
345
346
  	printk("  clustersumoff %u
  ",
  	       fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clustersumoff));
  	printk("  clusteroff    %u
  ",
  	       fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clusteroff));
  	printk("  nclusterblks  %u
  ",
  	       fs32_to_cpu(sb, cg->cg_u.cg_44.cg_nclusterblks));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
348
349
  	printk("
  ");
  }
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
350
  #else
3313e2926   Evgeniy Dushistov   [PATCH] ufs2 writ...
351
  #  define ufs_print_super_stuff(sb, usb1, usb2, usb3) /**/
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
352
  #  define ufs_print_cylinder_stuff(sb, cg) /**/
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
353
  #endif /* CONFIG_UFS_DEBUG */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354

ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
355
  static const struct super_operations ufs_super_ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
357
358
359
360
361
362
363
364
365
366
  
  static char error_buf[1024];
  
  void ufs_error (struct super_block * sb, const char * function,
  	const char * fmt, ...)
  {
  	struct ufs_sb_private_info * uspi;
  	struct ufs_super_block_first * usb1;
  	va_list args;
  
  	uspi = UFS_SB(sb)->s_uspi;
7b4ee73e2   Evgeniy   [PATCH] ufs cleanup
367
  	usb1 = ubh_get_usb_first(uspi);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
369
370
  	
  	if (!(sb->s_flags & MS_RDONLY)) {
  		usb1->fs_clean = UFS_FSBAD;
9695ef16e   Evgeniy Dushistov   [PATCH] ufs: wron...
371
  		ubh_mark_buffer_dirty(USPI_UBH(uspi));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
373
374
375
  		sb->s_dirt = 1;
  		sb->s_flags |= MS_RDONLY;
  	}
  	va_start (args, fmt);
4a6e617a4   Alexey Dobriyan   [PATCH] fs/*: tri...
376
  	vsnprintf (error_buf, sizeof(error_buf), fmt, args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
  	va_end (args);
  	switch (UFS_SB(sb)->s_mount_opt & UFS_MOUNT_ONERROR) {
  	case UFS_MOUNT_ONERROR_PANIC:
  		panic ("UFS-fs panic (device %s): %s: %s
  ", 
  			sb->s_id, function, error_buf);
  
  	case UFS_MOUNT_ONERROR_LOCK:
  	case UFS_MOUNT_ONERROR_UMOUNT:
  	case UFS_MOUNT_ONERROR_REPAIR:
  		printk (KERN_CRIT "UFS-fs error (device %s): %s: %s
  ",
  			sb->s_id, function, error_buf);
  	}		
  }
  
  void ufs_panic (struct super_block * sb, const char * function,
  	const char * fmt, ...)
  {
  	struct ufs_sb_private_info * uspi;
  	struct ufs_super_block_first * usb1;
  	va_list args;
  	
  	uspi = UFS_SB(sb)->s_uspi;
7b4ee73e2   Evgeniy   [PATCH] ufs cleanup
401
  	usb1 = ubh_get_usb_first(uspi);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
403
404
  	
  	if (!(sb->s_flags & MS_RDONLY)) {
  		usb1->fs_clean = UFS_FSBAD;
9695ef16e   Evgeniy Dushistov   [PATCH] ufs: wron...
405
  		ubh_mark_buffer_dirty(USPI_UBH(uspi));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
407
408
  		sb->s_dirt = 1;
  	}
  	va_start (args, fmt);
4a6e617a4   Alexey Dobriyan   [PATCH] fs/*: tri...
409
  	vsnprintf (error_buf, sizeof(error_buf), fmt, args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
411
412
413
414
415
416
417
418
419
420
421
422
  	va_end (args);
  	sb->s_flags |= MS_RDONLY;
  	printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s
  ",
  		sb->s_id, function, error_buf);
  }
  
  void ufs_warning (struct super_block * sb, const char * function,
  	const char * fmt, ...)
  {
  	va_list args;
  
  	va_start (args, fmt);
4a6e617a4   Alexey Dobriyan   [PATCH] fs/*: tri...
423
  	vsnprintf (error_buf, sizeof(error_buf), fmt, args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424
425
426
427
428
429
430
  	va_end (args);
  	printk (KERN_WARNING "UFS-fs warning (device %s): %s: %s
  ",
  		sb->s_id, function, error_buf);
  }
  
  enum {
2a9807c0d   Evgeniy Dushistov   ufs: implement sh...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
         Opt_type_old = UFS_MOUNT_UFSTYPE_OLD,
         Opt_type_sunx86 = UFS_MOUNT_UFSTYPE_SUNx86,
         Opt_type_sun = UFS_MOUNT_UFSTYPE_SUN,
         Opt_type_sunos = UFS_MOUNT_UFSTYPE_SUNOS,
         Opt_type_44bsd = UFS_MOUNT_UFSTYPE_44BSD,
         Opt_type_ufs2 = UFS_MOUNT_UFSTYPE_UFS2,
         Opt_type_hp = UFS_MOUNT_UFSTYPE_HP,
         Opt_type_nextstepcd = UFS_MOUNT_UFSTYPE_NEXTSTEP_CD,
         Opt_type_nextstep = UFS_MOUNT_UFSTYPE_NEXTSTEP,
         Opt_type_openstep = UFS_MOUNT_UFSTYPE_OPENSTEP,
         Opt_onerror_panic = UFS_MOUNT_ONERROR_PANIC,
         Opt_onerror_lock = UFS_MOUNT_ONERROR_LOCK,
         Opt_onerror_umount = UFS_MOUNT_ONERROR_UMOUNT,
         Opt_onerror_repair = UFS_MOUNT_ONERROR_REPAIR,
         Opt_err
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
  };
a447c0932   Steven Whitehouse   vfs: Use const fo...
447
  static const match_table_t tokens = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
449
450
  	{Opt_type_old, "ufstype=old"},
  	{Opt_type_sunx86, "ufstype=sunx86"},
  	{Opt_type_sun, "ufstype=sun"},
252e211e9   Mark   Add in SunOS 4.1....
451
  	{Opt_type_sunos, "ufstype=sunos"},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
452
453
454
455
456
457
458
  	{Opt_type_44bsd, "ufstype=44bsd"},
  	{Opt_type_ufs2, "ufstype=ufs2"},
  	{Opt_type_ufs2, "ufstype=5xbsd"},
  	{Opt_type_hp, "ufstype=hp"},
  	{Opt_type_nextstepcd, "ufstype=nextstep-cd"},
  	{Opt_type_nextstep, "ufstype=nextstep"},
  	{Opt_type_openstep, "ufstype=openstep"},
2a9807c0d   Evgeniy Dushistov   ufs: implement sh...
459
  /*end of possible ufs types */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
461
462
463
464
465
466
467
468
469
470
  	{Opt_onerror_panic, "onerror=panic"},
  	{Opt_onerror_lock, "onerror=lock"},
  	{Opt_onerror_umount, "onerror=umount"},
  	{Opt_onerror_repair, "onerror=repair"},
  	{Opt_err, NULL}
  };
  
  static int ufs_parse_options (char * options, unsigned * mount_options)
  {
  	char * p;
  	
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
471
472
  	UFSD("ENTER
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
  	
  	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_type_old:
  			ufs_clear_opt (*mount_options, UFSTYPE);
  			ufs_set_opt (*mount_options, UFSTYPE_OLD);
  			break;
  		case Opt_type_sunx86:
  			ufs_clear_opt (*mount_options, UFSTYPE);
  			ufs_set_opt (*mount_options, UFSTYPE_SUNx86);
  			break;
  		case Opt_type_sun:
  			ufs_clear_opt (*mount_options, UFSTYPE);
  			ufs_set_opt (*mount_options, UFSTYPE_SUN);
  			break;
252e211e9   Mark   Add in SunOS 4.1....
497
498
499
500
  		case Opt_type_sunos:
  			ufs_clear_opt(*mount_options, UFSTYPE);
  			ufs_set_opt(*mount_options, UFSTYPE_SUNOS);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
  		case Opt_type_44bsd:
  			ufs_clear_opt (*mount_options, UFSTYPE);
  			ufs_set_opt (*mount_options, UFSTYPE_44BSD);
  			break;
  		case Opt_type_ufs2:
  			ufs_clear_opt(*mount_options, UFSTYPE);
  			ufs_set_opt(*mount_options, UFSTYPE_UFS2);
  			break;
  		case Opt_type_hp:
  			ufs_clear_opt (*mount_options, UFSTYPE);
  			ufs_set_opt (*mount_options, UFSTYPE_HP);
  			break;
  		case Opt_type_nextstepcd:
  			ufs_clear_opt (*mount_options, UFSTYPE);
  			ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP_CD);
  			break;
  		case Opt_type_nextstep:
  			ufs_clear_opt (*mount_options, UFSTYPE);
  			ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP);
  			break;
  		case Opt_type_openstep:
  			ufs_clear_opt (*mount_options, UFSTYPE);
  			ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);
  			break;
  		case Opt_onerror_panic:
  			ufs_clear_opt (*mount_options, ONERROR);
  			ufs_set_opt (*mount_options, ONERROR_PANIC);
  			break;
  		case Opt_onerror_lock:
  			ufs_clear_opt (*mount_options, ONERROR);
  			ufs_set_opt (*mount_options, ONERROR_LOCK);
  			break;
  		case Opt_onerror_umount:
  			ufs_clear_opt (*mount_options, ONERROR);
  			ufs_set_opt (*mount_options, ONERROR_UMOUNT);
  			break;
  		case Opt_onerror_repair:
  			printk("UFS-fs: Unable to do repair on error, "
  				"will lock lock instead
  ");
  			ufs_clear_opt (*mount_options, ONERROR);
  			ufs_set_opt (*mount_options, ONERROR_REPAIR);
  			break;
  		default:
  			printk("UFS-fs: Invalid option: \"%s\" "
  					"or missing value
  ", p);
  			return 0;
  		}
  	}
  	return 1;
  }
  
  /*
25985edce   Lucas De Marchi   Fix common misspe...
555
556
557
   * Different types of UFS hold fs_cstotal in different
   * places, and use different data structure for it.
   * To make things simpler we just copy fs_cstotal to ufs_sb_private_info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
   */
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
559
  static void ufs_setup_cstotal(struct super_block *sb)
e295cfcb2   Evgeniy Dushistov   [PATCH] ufs: fix ...
560
  {
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
561
562
  	struct ufs_sb_info *sbi = UFS_SB(sb);
  	struct ufs_sb_private_info *uspi = sbi->s_uspi;
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
563
564
  	struct ufs_super_block_first *usb1;
  	struct ufs_super_block_second *usb2;
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
565
  	struct ufs_super_block_third *usb3;
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
  	unsigned mtype = sbi->s_mount_opt & UFS_MOUNT_UFSTYPE;
  
  	UFSD("ENTER, mtype=%u
  ", mtype);
  	usb1 = ubh_get_usb_first(uspi);
  	usb2 = ubh_get_usb_second(uspi);
  	usb3 = ubh_get_usb_third(uspi);
  
  	if ((mtype == UFS_MOUNT_UFSTYPE_44BSD &&
  	     (usb1->fs_flags & UFS_FLAGS_UPDATED)) ||
  	    mtype == UFS_MOUNT_UFSTYPE_UFS2) {
  		/*we have statistic in different place, then usual*/
  		uspi->cs_total.cs_ndir = fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_ndir);
  		uspi->cs_total.cs_nbfree = fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree);
  		uspi->cs_total.cs_nifree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree);
  		uspi->cs_total.cs_nffree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree);
  	} else {
  		uspi->cs_total.cs_ndir = fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir);
  		uspi->cs_total.cs_nbfree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree);
  		uspi->cs_total.cs_nifree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree);
  		uspi->cs_total.cs_nffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree);
  	}
  	UFSD("EXIT
  ");
  }
  
  /*
   * Read on-disk structures associated with cylinder groups
   */
  static int ufs_read_cylinder_structures(struct super_block *sb)
  {
  	struct ufs_sb_info *sbi = UFS_SB(sb);
  	struct ufs_sb_private_info *uspi = sbi->s_uspi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
599
600
601
  	struct ufs_buffer_head * ubh;
  	unsigned char * base, * space;
  	unsigned size, blks, i;
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
602
  	struct ufs_super_block_third *usb3;
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
603
604
  	UFSD("ENTER
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
605

ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
606
  	usb3 = ubh_get_usb_third(uspi);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
608
609
610
611
612
  	/*
  	 * Read cs structures from (usually) first data block
  	 * on the device. 
  	 */
  	size = uspi->s_cssize;
  	blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
788257d61   Arnd Bergmann   ufs: remove the BKL
613
  	base = space = kmalloc(size, GFP_NOFS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
614
615
  	if (!base)
  		goto failed; 
e295cfcb2   Evgeniy Dushistov   [PATCH] ufs: fix ...
616
  	sbi->s_csp = (struct ufs_csum *)space;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
617
618
619
620
  	for (i = 0; i < blks; i += uspi->s_fpb) {
  		size = uspi->s_bsize;
  		if (i + uspi->s_fpb > blks)
  			size = (blks - i) * uspi->s_fsize;
3313e2926   Evgeniy Dushistov   [PATCH] ufs2 writ...
621
  		ubh = ubh_bread(sb, uspi->s_csaddr + i, size);
7b4ee73e2   Evgeniy   [PATCH] ufs cleanup
622
623
624
625
626
  		
  		if (!ubh)
  			goto failed;
  
  		ubh_ubhcpymem (space, ubh, size);
7b4ee73e2   Evgeniy   [PATCH] ufs cleanup
627

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
629
630
631
632
633
634
635
636
  		space += size;
  		ubh_brelse (ubh);
  		ubh = NULL;
  	}
  
  	/*
  	 * Read cylinder group (we read only first fragment from block
  	 * at this time) and prepare internal data structures for cg caching.
  	 */
788257d61   Arnd Bergmann   ufs: remove the BKL
637
  	if (!(sbi->s_ucg = kmalloc (sizeof(struct buffer_head *) * uspi->s_ncg, GFP_NOFS)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
639
640
641
642
643
644
645
  		goto failed;
  	for (i = 0; i < uspi->s_ncg; i++) 
  		sbi->s_ucg[i] = NULL;
  	for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {
  		sbi->s_ucpi[i] = NULL;
  		sbi->s_cgno[i] = UFS_CGNO_EMPTY;
  	}
  	for (i = 0; i < uspi->s_ncg; i++) {
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
646
647
  		UFSD("read cg %u
  ", i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
648
649
650
651
  		if (!(sbi->s_ucg[i] = sb_bread(sb, ufs_cgcmin(i))))
  			goto failed;
  		if (!ufs_cg_chkmagic (sb, (struct ufs_cylinder_group *) sbi->s_ucg[i]->b_data))
  			goto failed;
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
652

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
653
  		ufs_print_cylinder_stuff(sb, (struct ufs_cylinder_group *) sbi->s_ucg[i]->b_data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
655
  	}
  	for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {
788257d61   Arnd Bergmann   ufs: remove the BKL
656
  		if (!(sbi->s_ucpi[i] = kmalloc (sizeof(struct ufs_cg_private_info), GFP_NOFS)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
657
658
659
660
  			goto failed;
  		sbi->s_cgno[i] = UFS_CGNO_EMPTY;
  	}
  	sbi->s_cg_loaded = 0;
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
661
662
  	UFSD("EXIT
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
663
664
665
  	return 1;
  
  failed:
f99d49adf   Jesper Juhl   [PATCH] kfree cle...
666
  	kfree (base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
667
668
  	if (sbi->s_ucg) {
  		for (i = 0; i < uspi->s_ncg; i++)
f99d49adf   Jesper Juhl   [PATCH] kfree cle...
669
670
  			if (sbi->s_ucg[i])
  				brelse (sbi->s_ucg[i]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
671
672
  		kfree (sbi->s_ucg);
  		for (i = 0; i < UFS_MAX_GROUP_LOADED; i++)
f99d49adf   Jesper Juhl   [PATCH] kfree cle...
673
  			kfree (sbi->s_ucpi[i]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
  	}
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
675
676
  	UFSD("EXIT (FAILED)
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
677
678
679
680
  	return 0;
  }
  
  /*
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
681
   * Sync our internal copy of fs_cstotal with disk
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
682
   */
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
683
  static void ufs_put_cstotal(struct super_block *sb)
e295cfcb2   Evgeniy Dushistov   [PATCH] ufs: fix ...
684
  {
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
  	unsigned mtype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE;
  	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
  	struct ufs_super_block_first *usb1;
  	struct ufs_super_block_second *usb2;
  	struct ufs_super_block_third *usb3;
  
  	UFSD("ENTER
  ");
  	usb1 = ubh_get_usb_first(uspi);
  	usb2 = ubh_get_usb_second(uspi);
  	usb3 = ubh_get_usb_third(uspi);
  
  	if ((mtype == UFS_MOUNT_UFSTYPE_44BSD &&
  	     (usb1->fs_flags & UFS_FLAGS_UPDATED)) ||
  	    mtype == UFS_MOUNT_UFSTYPE_UFS2) {
  		/*we have statistic in different place, then usual*/
  		usb2->fs_un.fs_u2.cs_ndir =
  			cpu_to_fs64(sb, uspi->cs_total.cs_ndir);
  		usb2->fs_un.fs_u2.cs_nbfree =
  			cpu_to_fs64(sb, uspi->cs_total.cs_nbfree);
  		usb3->fs_un1.fs_u2.cs_nifree =
  			cpu_to_fs64(sb, uspi->cs_total.cs_nifree);
  		usb3->fs_un1.fs_u2.cs_nffree =
  			cpu_to_fs64(sb, uspi->cs_total.cs_nffree);
  	} else {
  		usb1->fs_cstotal.cs_ndir =
  			cpu_to_fs32(sb, uspi->cs_total.cs_ndir);
  		usb1->fs_cstotal.cs_nbfree =
  			cpu_to_fs32(sb, uspi->cs_total.cs_nbfree);
  		usb1->fs_cstotal.cs_nifree =
  			cpu_to_fs32(sb, uspi->cs_total.cs_nifree);
  		usb1->fs_cstotal.cs_nffree =
  			cpu_to_fs32(sb, uspi->cs_total.cs_nffree);
  	}
  	ubh_mark_buffer_dirty(USPI_UBH(uspi));
3313e2926   Evgeniy Dushistov   [PATCH] ufs2 writ...
720
  	ufs_print_super_stuff(sb, usb1, usb2, usb3);
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
721
722
723
724
725
726
727
728
729
730
731
732
733
734
  	UFSD("EXIT
  ");
  }
  
  /**
   * ufs_put_super_internal() - put on-disk intrenal structures
   * @sb: pointer to super_block structure
   * Put on-disk structures associated with cylinder groups
   * and write them back to disk, also update cs_total on disk
   */
  static void ufs_put_super_internal(struct super_block *sb)
  {
  	struct ufs_sb_info *sbi = UFS_SB(sb);
  	struct ufs_sb_private_info *uspi = sbi->s_uspi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
735
736
737
  	struct ufs_buffer_head * ubh;
  	unsigned char * base, * space;
  	unsigned blks, size, i;
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
738

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739
  	
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
740
741
  	UFSD("ENTER
  ");
6cfd01484   Christoph Hellwig   push BKL down int...
742

ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
743
  	ufs_put_cstotal(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
744
745
  	size = uspi->s_cssize;
  	blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
e295cfcb2   Evgeniy Dushistov   [PATCH] ufs: fix ...
746
  	base = space = (char*) sbi->s_csp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
747
748
749
750
  	for (i = 0; i < blks; i += uspi->s_fpb) {
  		size = uspi->s_bsize;
  		if (i + uspi->s_fpb > blks)
  			size = (blks - i) * uspi->s_fsize;
3313e2926   Evgeniy Dushistov   [PATCH] ufs2 writ...
751

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
  		ubh = ubh_bread(sb, uspi->s_csaddr + i, size);
3313e2926   Evgeniy Dushistov   [PATCH] ufs2 writ...
753

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
  		ubh_memcpyubh (ubh, space, size);
  		space += size;
  		ubh_mark_buffer_uptodate (ubh, 1);
  		ubh_mark_buffer_dirty (ubh);
  		ubh_brelse (ubh);
  	}
  	for (i = 0; i < sbi->s_cg_loaded; i++) {
  		ufs_put_cylinder (sb, i);
  		kfree (sbi->s_ucpi[i]);
  	}
  	for (; i < UFS_MAX_GROUP_LOADED; i++) 
  		kfree (sbi->s_ucpi[i]);
  	for (i = 0; i < uspi->s_ncg; i++) 
  		brelse (sbi->s_ucg[i]);
  	kfree (sbi->s_ucg);
  	kfree (base);
6cfd01484   Christoph Hellwig   push BKL down int...
770

abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
771
772
  	UFSD("EXIT
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
773
774
775
776
777
778
779
780
781
  }
  
  static int ufs_fill_super(struct super_block *sb, void *data, int silent)
  {
  	struct ufs_sb_info * sbi;
  	struct ufs_sb_private_info * uspi;
  	struct ufs_super_block_first * usb1;
  	struct ufs_super_block_second * usb2;
  	struct ufs_super_block_third * usb3;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
782
783
784
785
  	struct ufs_buffer_head * ubh;	
  	struct inode *inode;
  	unsigned block_size, super_block_size;
  	unsigned flags;
7b4ee73e2   Evgeniy   [PATCH] ufs cleanup
786
  	unsigned super_block_offset;
9e6766cc8   Duane Griffin   ufs: validate max...
787
  	unsigned maxsymlen;
b55c460da   David Howells   iget: stop UFS fr...
788
  	int ret = -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
789
790
791
792
793
  
  	uspi = NULL;
  	ubh = NULL;
  	flags = 0;
  	
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
794
795
  	UFSD("ENTER
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
  		
f8314dc60   Panagiotis Issaris   [PATCH] fs: Conve...
797
  	sbi = kzalloc(sizeof(struct ufs_sb_info), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798
799
800
  	if (!sbi)
  		goto failed_nomem;
  	sb->s_fs_info = sbi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
801

abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
802
803
  	UFSD("flag %u
  ", (int)(sb->s_flags & MS_RDONLY));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
804
805
806
807
808
809
810
811
812
  	
  #ifndef CONFIG_UFS_FS_WRITE
  	if (!(sb->s_flags & MS_RDONLY)) {
  		printk("ufs was compiled with read-only support, "
  		"can't be mounted as read-write
  ");
  		goto failed;
  	}
  #endif
788257d61   Arnd Bergmann   ufs: remove the BKL
813
  	mutex_init(&sbi->mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
  	/*
  	 * Set default mount options
  	 * Parse mount options
  	 */
  	sbi->s_mount_opt = 0;
  	ufs_set_opt (sbi->s_mount_opt, ONERROR_LOCK);
  	if (!ufs_parse_options ((char *) data, &sbi->s_mount_opt)) {
  		printk("wrong mount options
  ");
  		goto failed;
  	}
  	if (!(sbi->s_mount_opt & UFS_MOUNT_UFSTYPE)) {
  		if (!silent)
  			printk("You didn't specify the type of your ufs filesystem
  
  "
  			"mount -t ufs -o ufstype="
c690a7225   Michael Owen   typo patch for fs...
831
832
833
  			"sun|sunx86|44bsd|ufs2|5xbsd|old|hp|nextstep|nextstep-cd|openstep ...
  
  "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
834
835
836
837
838
  			">>>WARNING<<< Wrong ufstype may corrupt your filesystem, "
  			"default is ufstype=old
  ");
  		ufs_set_opt (sbi->s_mount_opt, UFSTYPE_OLD);
  	}
252e211e9   Mark   Add in SunOS 4.1....
839
840
  	uspi = kzalloc(sizeof(struct ufs_sb_private_info), GFP_KERNEL);
  	sbi->s_uspi = uspi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841
842
  	if (!uspi)
  		goto failed;
f336953bf   Evgeniy Dushistov   [PATCH] ufs: rest...
843
  	uspi->s_dirblksize = UFS_SECTOR_SIZE;
7b4ee73e2   Evgeniy   [PATCH] ufs cleanup
844
  	super_block_offset=UFS_SBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
846
847
  	/* Keep 2Gig file limit. Some UFS variants need to override 
  	   this but as I don't know which I'll let those in the know loosen
  	   the rules */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
848
849
  	switch (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) {
  	case UFS_MOUNT_UFSTYPE_44BSD:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
850
851
  		UFSD("ufstype=44bsd
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
852
853
854
855
856
857
858
859
  		uspi->s_fsize = block_size = 512;
  		uspi->s_fmask = ~(512 - 1);
  		uspi->s_fshift = 9;
  		uspi->s_sbsize = super_block_size = 1536;
  		uspi->s_sbbase = 0;
  		flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
  		break;
  	case UFS_MOUNT_UFSTYPE_UFS2:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
860
861
  		UFSD("ufstype=ufs2
  ");
7b4ee73e2   Evgeniy   [PATCH] ufs cleanup
862
  		super_block_offset=SBLOCK_UFS2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
864
865
866
867
868
  		uspi->s_fsize = block_size = 512;
  		uspi->s_fmask = ~(512 - 1);
  		uspi->s_fshift = 9;
  		uspi->s_sbsize = super_block_size = 1536;
  		uspi->s_sbbase =  0;
  		flags |= UFS_TYPE_UFS2 | UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
869
870
871
  		break;
  		
  	case UFS_MOUNT_UFSTYPE_SUN:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
872
873
  		UFSD("ufstype=sun
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874
875
876
877
878
  		uspi->s_fsize = block_size = 1024;
  		uspi->s_fmask = ~(1024 - 1);
  		uspi->s_fshift = 10;
  		uspi->s_sbsize = super_block_size = 2048;
  		uspi->s_sbbase = 0;
252e211e9   Mark   Add in SunOS 4.1....
879
  		uspi->s_maxsymlinklen = 0; /* Not supported on disk */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
880
881
  		flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUN | UFS_CG_SUN;
  		break;
252e211e9   Mark   Add in SunOS 4.1....
882
883
884
885
886
887
888
889
890
891
892
893
  	case UFS_MOUNT_UFSTYPE_SUNOS:
  		UFSD(("ufstype=sunos
  "))
  		uspi->s_fsize = block_size = 1024;
  		uspi->s_fmask = ~(1024 - 1);
  		uspi->s_fshift = 10;
  		uspi->s_sbsize = 2048;
  		super_block_size = 2048;
  		uspi->s_sbbase = 0;
  		uspi->s_maxsymlinklen = 0; /* Not supported on disk */
  		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_SUNOS | UFS_CG_SUN;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
894
  	case UFS_MOUNT_UFSTYPE_SUNx86:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
895
896
  		UFSD("ufstype=sunx86
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
897
898
899
900
901
  		uspi->s_fsize = block_size = 1024;
  		uspi->s_fmask = ~(1024 - 1);
  		uspi->s_fshift = 10;
  		uspi->s_sbsize = super_block_size = 2048;
  		uspi->s_sbbase = 0;
252e211e9   Mark   Add in SunOS 4.1....
902
  		uspi->s_maxsymlinklen = 0; /* Not supported on disk */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
903
904
905
906
  		flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUNx86 | UFS_CG_SUN;
  		break;
  
  	case UFS_MOUNT_UFSTYPE_OLD:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
907
908
  		UFSD("ufstype=old
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
  		uspi->s_fsize = block_size = 1024;
  		uspi->s_fmask = ~(1024 - 1);
  		uspi->s_fshift = 10;
  		uspi->s_sbsize = super_block_size = 2048;
  		uspi->s_sbbase = 0;
  		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
  		if (!(sb->s_flags & MS_RDONLY)) {
  			if (!silent)
  				printk(KERN_INFO "ufstype=old is supported read-only
  ");
  			sb->s_flags |= MS_RDONLY;
  		}
  		break;
  	
  	case UFS_MOUNT_UFSTYPE_NEXTSTEP:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
924
925
  		UFSD("ufstype=nextstep
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
926
927
928
929
930
  		uspi->s_fsize = block_size = 1024;
  		uspi->s_fmask = ~(1024 - 1);
  		uspi->s_fshift = 10;
  		uspi->s_sbsize = super_block_size = 2048;
  		uspi->s_sbbase = 0;
0c664f974   Evgeniy Dushistov   ufs: fix nexstep ...
931
  		uspi->s_dirblksize = 1024;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
932
933
934
935
936
937
938
939
940
941
  		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
  		if (!(sb->s_flags & MS_RDONLY)) {
  			if (!silent)
  				printk(KERN_INFO "ufstype=nextstep is supported read-only
  ");
  			sb->s_flags |= MS_RDONLY;
  		}
  		break;
  	
  	case UFS_MOUNT_UFSTYPE_NEXTSTEP_CD:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
942
943
  		UFSD("ufstype=nextstep-cd
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
944
945
946
947
948
  		uspi->s_fsize = block_size = 2048;
  		uspi->s_fmask = ~(2048 - 1);
  		uspi->s_fshift = 11;
  		uspi->s_sbsize = super_block_size = 2048;
  		uspi->s_sbbase = 0;
0c664f974   Evgeniy Dushistov   ufs: fix nexstep ...
949
  		uspi->s_dirblksize = 1024;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
950
951
952
953
954
955
956
957
958
959
  		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
  		if (!(sb->s_flags & MS_RDONLY)) {
  			if (!silent)
  				printk(KERN_INFO "ufstype=nextstep-cd is supported read-only
  ");
  			sb->s_flags |= MS_RDONLY;
  		}
  		break;
  	
  	case UFS_MOUNT_UFSTYPE_OPENSTEP:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
960
961
  		UFSD("ufstype=openstep
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
962
963
964
965
966
  		uspi->s_fsize = block_size = 1024;
  		uspi->s_fmask = ~(1024 - 1);
  		uspi->s_fshift = 10;
  		uspi->s_sbsize = super_block_size = 2048;
  		uspi->s_sbbase = 0;
f336953bf   Evgeniy Dushistov   [PATCH] ufs: rest...
967
  		uspi->s_dirblksize = 1024;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
968
969
970
971
972
973
974
975
976
977
  		flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
  		if (!(sb->s_flags & MS_RDONLY)) {
  			if (!silent)
  				printk(KERN_INFO "ufstype=openstep is supported read-only
  ");
  			sb->s_flags |= MS_RDONLY;
  		}
  		break;
  	
  	case UFS_MOUNT_UFSTYPE_HP:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
978
979
  		UFSD("ufstype=hp
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
  		uspi->s_fsize = block_size = 1024;
  		uspi->s_fmask = ~(1024 - 1);
  		uspi->s_fshift = 10;
  		uspi->s_sbsize = super_block_size = 2048;
  		uspi->s_sbbase = 0;
  		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
  		if (!(sb->s_flags & MS_RDONLY)) {
  			if (!silent)
  				printk(KERN_INFO "ufstype=hp is supported read-only
  ");
  			sb->s_flags |= MS_RDONLY;
   		}
   		break;
  	default:
  		if (!silent)
  			printk("unknown ufstype
  ");
  		goto failed;
  	}
  	
  again:	
  	if (!sb_set_blocksize(sb, block_size)) {
  		printk(KERN_ERR "UFS: failed to set blocksize
  ");
  		goto failed;
  	}
  
  	/*
  	 * read ufs super block from device
  	 */
7b4ee73e2   Evgeniy   [PATCH] ufs cleanup
1010
1011
1012
  
  	ubh = ubh_bread_uspi(uspi, sb, uspi->s_sbbase + super_block_offset/block_size, super_block_size);
  	
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1013
1014
  	if (!ubh) 
              goto failed;
7b4ee73e2   Evgeniy   [PATCH] ufs cleanup
1015
1016
1017
  	usb1 = ubh_get_usb_first(uspi);
  	usb2 = ubh_get_usb_second(uspi);
  	usb3 = ubh_get_usb_third(uspi);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1018

252e211e9   Mark   Add in SunOS 4.1....
1019
1020
1021
1022
1023
1024
1025
  	/* Sort out mod used on SunOS 4.1.3 for fs_state */
  	uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat);
  	if (((flags & UFS_ST_MASK) == UFS_ST_SUNOS) &&
  	    (uspi->s_postblformat != UFS_42POSTBLFMT)) {
  		flags &= ~UFS_ST_MASK;
  		flags |=  UFS_ST_SUN;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1026
1027
1028
1029
1030
1031
  	/*
  	 * Check ufs magic number
  	 */
  	sbi->s_bytesex = BYTESEX_LE;
  	switch ((uspi->fs_magic = fs32_to_cpu(sb, usb3->fs_magic))) {
  		case UFS_MAGIC:
d27d7a9a7   Thomas Stewart   ufs: permit mount...
1032
  		case UFS_MAGIC_BW:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
1034
1035
1036
1037
1038
1039
1040
1041
  		case UFS2_MAGIC:
  		case UFS_MAGIC_LFN:
  	        case UFS_MAGIC_FEA:
  	        case UFS_MAGIC_4GB:
  			goto magic_found;
  	}
  	sbi->s_bytesex = BYTESEX_BE;
  	switch ((uspi->fs_magic = fs32_to_cpu(sb, usb3->fs_magic))) {
  		case UFS_MAGIC:
d27d7a9a7   Thomas Stewart   ufs: permit mount...
1042
  		case UFS_MAGIC_BW:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
  		case UFS2_MAGIC:
  		case UFS_MAGIC_LFN:
  	        case UFS_MAGIC_FEA:
  	        case UFS_MAGIC_4GB:
  			goto magic_found;
  	}
  
  	if ((((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP) 
  	  || ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP_CD) 
  	  || ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_OPENSTEP)) 
  	  && uspi->s_sbbase < 256) {
  		ubh_brelse_uspi(uspi);
  		ubh = NULL;
  		uspi->s_sbbase += 8;
  		goto again;
  	}
  	if (!silent)
  		printk("ufs_read_super: bad magic number
  ");
  	goto failed;
  
  magic_found:
  	/*
  	 * Check block and fragment sizes
  	 */
  	uspi->s_bsize = fs32_to_cpu(sb, usb1->fs_bsize);
  	uspi->s_fsize = fs32_to_cpu(sb, usb1->fs_fsize);
  	uspi->s_sbsize = fs32_to_cpu(sb, usb1->fs_sbsize);
  	uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
  	uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
9e8c4273e   vignesh babu   is_power_of_2: uf...
1073
  	if (!is_power_of_2(uspi->s_fsize)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
  		printk(KERN_ERR "ufs_read_super: fragment size %u is not a power of 2
  ",
  			uspi->s_fsize);
  			goto failed;
  	}
  	if (uspi->s_fsize < 512) {
  		printk(KERN_ERR "ufs_read_super: fragment size %u is too small
  ",
  			uspi->s_fsize);
  		goto failed;
  	}
  	if (uspi->s_fsize > 4096) {
  		printk(KERN_ERR "ufs_read_super: fragment size %u is too large
  ",
  			uspi->s_fsize);
  		goto failed;
  	}
9e8c4273e   vignesh babu   is_power_of_2: uf...
1091
  	if (!is_power_of_2(uspi->s_bsize)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
  		printk(KERN_ERR "ufs_read_super: block size %u is not a power of 2
  ",
  			uspi->s_bsize);
  		goto failed;
  	}
  	if (uspi->s_bsize < 4096) {
  		printk(KERN_ERR "ufs_read_super: block size %u is too small
  ",
  			uspi->s_bsize);
  		goto failed;
  	}
  	if (uspi->s_bsize / uspi->s_fsize > 8) {
  		printk(KERN_ERR "ufs_read_super: too many fragments per block (%u)
  ",
  			uspi->s_bsize / uspi->s_fsize);
  		goto failed;
  	}
  	if (uspi->s_fsize != block_size || uspi->s_sbsize != super_block_size) {
  		ubh_brelse_uspi(uspi);
  		ubh = NULL;
  		block_size = uspi->s_fsize;
  		super_block_size = uspi->s_sbsize;
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1114
1115
  		UFSD("another value of block_size or super_block_size %u, %u
  ", block_size, super_block_size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1116
1117
  		goto again;
  	}
f664f1f9b   Andrew Morton   revert "ufs: Fix ...
1118
  	sbi->s_flags = flags;/*after that line some functions use s_flags*/
3313e2926   Evgeniy Dushistov   [PATCH] ufs2 writ...
1119
  	ufs_print_super_stuff(sb, usb1, usb2, usb3);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1120
1121
1122
1123
1124
  
  	/*
  	 * Check, if file system was correctly unmounted.
  	 * If not, make it read only.
  	 */
f664f1f9b   Andrew Morton   revert "ufs: Fix ...
1125
1126
1127
1128
1129
1130
  	if (((flags & UFS_ST_MASK) == UFS_ST_44BSD) ||
  	  ((flags & UFS_ST_MASK) == UFS_ST_OLD) ||
  	  (((flags & UFS_ST_MASK) == UFS_ST_SUN ||
  	    (flags & UFS_ST_MASK) == UFS_ST_SUNOS ||
  	  (flags & UFS_ST_MASK) == UFS_ST_SUNx86) &&
  	  (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time))))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1131
1132
  		switch(usb1->fs_clean) {
  		case UFS_FSCLEAN:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1133
1134
  			UFSD("fs is clean
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1135
1136
  			break;
  		case UFS_FSSTABLE:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1137
1138
  			UFSD("fs is stable
  ");
b3a0fd4d8   Alex Viskovatoff   fs/ufs: recognize...
1139
1140
1141
1142
  			break;
  		case UFS_FSLOG:
  			UFSD("fs is logging fs
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1143
1144
  			break;
  		case UFS_FSOSF1:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1145
1146
  			UFSD("fs is DEC OSF/1
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
  			break;
  		case UFS_FSACTIVE:
  			printk("ufs_read_super: fs is active
  ");
  			sb->s_flags |= MS_RDONLY;
  			break;
  		case UFS_FSBAD:
  			printk("ufs_read_super: fs is bad
  ");
  			sb->s_flags |= MS_RDONLY;
  			break;
  		default:
  			printk("ufs_read_super: can't grok fs_clean 0x%x
  ", usb1->fs_clean);
  			sb->s_flags |= MS_RDONLY;
  			break;
  		}
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
1164
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1165
1166
1167
1168
1169
1170
1171
1172
1173
  		printk("ufs_read_super: fs needs fsck
  ");
  		sb->s_flags |= MS_RDONLY;
  	}
  
  	/*
  	 * Read ufs_super_block into internal data structures
  	 */
  	sb->s_op = &ufs_super_ops;
f3e2a520f   Alexey Dobriyan   ufs: NFS support
1174
  	sb->s_export_op = &ufs_export_ops;
123e9caf1   Christoph Hellwig   quota: explicitly...
1175

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
  	sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic);
  
  	uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno);
  	uspi->s_cblkno = fs32_to_cpu(sb, usb1->fs_cblkno);
  	uspi->s_iblkno = fs32_to_cpu(sb, usb1->fs_iblkno);
  	uspi->s_dblkno = fs32_to_cpu(sb, usb1->fs_dblkno);
  	uspi->s_cgoffset = fs32_to_cpu(sb, usb1->fs_cgoffset);
  	uspi->s_cgmask = fs32_to_cpu(sb, usb1->fs_cgmask);
  
  	if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
1186
1187
1188
  		uspi->s_u2_size  = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size);
  		uspi->s_u2_dsize = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize);
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
  		uspi->s_size  =  fs32_to_cpu(sb, usb1->fs_size);
  		uspi->s_dsize =  fs32_to_cpu(sb, usb1->fs_dsize);
  	}
  
  	uspi->s_ncg = fs32_to_cpu(sb, usb1->fs_ncg);
  	/* s_bsize already set */
  	/* s_fsize already set */
  	uspi->s_fpb = fs32_to_cpu(sb, usb1->fs_frag);
  	uspi->s_minfree = fs32_to_cpu(sb, usb1->fs_minfree);
  	uspi->s_bmask = fs32_to_cpu(sb, usb1->fs_bmask);
  	uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
  	uspi->s_bshift = fs32_to_cpu(sb, usb1->fs_bshift);
  	uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1202
1203
  	UFSD("uspi->s_bshift = %d,uspi->s_fshift = %d", uspi->s_bshift,
  		uspi->s_fshift);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
  	uspi->s_fpbshift = fs32_to_cpu(sb, usb1->fs_fragshift);
  	uspi->s_fsbtodb = fs32_to_cpu(sb, usb1->fs_fsbtodb);
  	/* s_sbsize already set */
  	uspi->s_csmask = fs32_to_cpu(sb, usb1->fs_csmask);
  	uspi->s_csshift = fs32_to_cpu(sb, usb1->fs_csshift);
  	uspi->s_nindir = fs32_to_cpu(sb, usb1->fs_nindir);
  	uspi->s_inopb = fs32_to_cpu(sb, usb1->fs_inopb);
  	uspi->s_nspf = fs32_to_cpu(sb, usb1->fs_nspf);
  	uspi->s_npsect = ufs_get_fs_npsect(sb, usb1, usb3);
  	uspi->s_interleave = fs32_to_cpu(sb, usb1->fs_interleave);
  	uspi->s_trackskew = fs32_to_cpu(sb, usb1->fs_trackskew);
3313e2926   Evgeniy Dushistov   [PATCH] ufs2 writ...
1215
1216
1217
1218
1219
  
  	if (uspi->fs_magic == UFS2_MAGIC)
  		uspi->s_csaddr = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_csaddr);
  	else
  		uspi->s_csaddr = fs32_to_cpu(sb, usb1->fs_csaddr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1220
1221
1222
1223
1224
1225
1226
  	uspi->s_cssize = fs32_to_cpu(sb, usb1->fs_cssize);
  	uspi->s_cgsize = fs32_to_cpu(sb, usb1->fs_cgsize);
  	uspi->s_ntrak = fs32_to_cpu(sb, usb1->fs_ntrak);
  	uspi->s_nsect = fs32_to_cpu(sb, usb1->fs_nsect);
  	uspi->s_spc = fs32_to_cpu(sb, usb1->fs_spc);
  	uspi->s_ipg = fs32_to_cpu(sb, usb1->fs_ipg);
  	uspi->s_fpg = fs32_to_cpu(sb, usb1->fs_fpg);
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
1227
1228
  	uspi->s_cpc = fs32_to_cpu(sb, usb2->fs_un.fs_u1.fs_cpc);
  	uspi->s_contigsumsize = fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_contigsumsize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1229
1230
  	uspi->s_qbmask = ufs_get_fs_qbmask(sb, usb3);
  	uspi->s_qfmask = ufs_get_fs_qfmask(sb, usb3);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1231
1232
1233
1234
1235
1236
1237
1238
  	uspi->s_nrpos = fs32_to_cpu(sb, usb3->fs_nrpos);
  	uspi->s_postbloff = fs32_to_cpu(sb, usb3->fs_postbloff);
  	uspi->s_rotbloff = fs32_to_cpu(sb, usb3->fs_rotbloff);
  
  	/*
  	 * Compute another frequently used values
  	 */
  	uspi->s_fpbmask = uspi->s_fpb - 1;
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1239
  	if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1240
  		uspi->s_apbshift = uspi->s_bshift - 3;
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1241
  	else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1242
  		uspi->s_apbshift = uspi->s_bshift - 2;
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1243

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
  	uspi->s_2apbshift = uspi->s_apbshift * 2;
  	uspi->s_3apbshift = uspi->s_apbshift * 3;
  	uspi->s_apb = 1 << uspi->s_apbshift;
  	uspi->s_2apb = 1 << uspi->s_2apbshift;
  	uspi->s_3apb = 1 << uspi->s_3apbshift;
  	uspi->s_apbmask = uspi->s_apb - 1;
  	uspi->s_nspfshift = uspi->s_fshift - UFS_SECTOR_BITS;
  	uspi->s_nspb = uspi->s_nspf << uspi->s_fpbshift;
  	uspi->s_inopf = uspi->s_inopb >> uspi->s_fpbshift;
  	uspi->s_bpf = uspi->s_fsize << 3;
  	uspi->s_bpfshift = uspi->s_fshift + 3;
  	uspi->s_bpfmask = uspi->s_bpf - 1;
90b315af1   Evgeniy Dushistov   ufs: fix symlink ...
1256
1257
  	if ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_44BSD ||
  	    (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_UFS2)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1258
  		uspi->s_maxsymlinklen =
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
1259
  		    fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1260

9e6766cc8   Duane Griffin   ufs: validate max...
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
  	if (uspi->fs_magic == UFS2_MAGIC)
  		maxsymlen = 2 * 4 * (UFS_NDADDR + UFS_NINDIR);
  	else
  		maxsymlen = 4 * (UFS_NDADDR + UFS_NINDIR);
  	if (uspi->s_maxsymlinklen > maxsymlen) {
  		ufs_warning(sb, __func__, "ufs_read_super: excessive maximum "
  			    "fast symlink size (%u)
  ", uspi->s_maxsymlinklen);
  		uspi->s_maxsymlinklen = maxsymlen;
  	}
b55c460da   David Howells   iget: stop UFS fr...
1271
1272
1273
  	inode = ufs_iget(sb, UFS_ROOTINO);
  	if (IS_ERR(inode)) {
  		ret = PTR_ERR(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1274
  		goto failed;
b55c460da   David Howells   iget: stop UFS fr...
1275
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1276
  	sb->s_root = d_alloc_root(inode);
b55c460da   David Howells   iget: stop UFS fr...
1277
1278
  	if (!sb->s_root) {
  		ret = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1279
  		goto dalloc_failed;
b55c460da   David Howells   iget: stop UFS fr...
1280
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1281

ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
1282
  	ufs_setup_cstotal(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1283
1284
1285
1286
1287
1288
  	/*
  	 * Read cylinder group structures
  	 */
  	if (!(sb->s_flags & MS_RDONLY))
  		if (!ufs_read_cylinder_structures(sb))
  			goto failed;
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1289
1290
  	UFSD("EXIT
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1291
1292
1293
1294
1295
  	return 0;
  
  dalloc_failed:
  	iput(inode);
  failed:
f99d49adf   Jesper Juhl   [PATCH] kfree cle...
1296
1297
1298
1299
  	if (ubh)
  		ubh_brelse_uspi (uspi);
  	kfree (uspi);
  	kfree(sbi);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1300
  	sb->s_fs_info = NULL;
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1301
1302
  	UFSD("EXIT (FAILED)
  ");
b55c460da   David Howells   iget: stop UFS fr...
1303
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1304
1305
  
  failed_nomem:
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1306
1307
  	UFSD("EXIT (NOMEM)
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1308
1309
  	return -ENOMEM;
  }
8c8006564   Christoph Hellwig   ufs: add ->sync_fs
1310
  static int ufs_sync_fs(struct super_block *sb, int wait)
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
1311
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1312
1313
1314
1315
  	struct ufs_sb_private_info * uspi;
  	struct ufs_super_block_first * usb1;
  	struct ufs_super_block_third * usb3;
  	unsigned flags;
788257d61   Arnd Bergmann   ufs: remove the BKL
1316
  	lock_ufs(sb);
ebc1ac164   Christoph Hellwig   ->write_super loc...
1317
  	lock_super(sb);
8c8006564   Christoph Hellwig   ufs: add ->sync_fs
1318

abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1319
1320
  	UFSD("ENTER
  ");
8c8006564   Christoph Hellwig   ufs: add ->sync_fs
1321

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1322
1323
  	flags = UFS_SB(sb)->s_flags;
  	uspi = UFS_SB(sb)->s_uspi;
7b4ee73e2   Evgeniy   [PATCH] ufs cleanup
1324
1325
  	usb1 = ubh_get_usb_first(uspi);
  	usb3 = ubh_get_usb_third(uspi);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1326

8c8006564   Christoph Hellwig   ufs: add ->sync_fs
1327
1328
1329
1330
1331
1332
1333
  	usb1->fs_time = cpu_to_fs32(sb, get_seconds());
  	if ((flags & UFS_ST_MASK) == UFS_ST_SUN  ||
  	    (flags & UFS_ST_MASK) == UFS_ST_SUNOS ||
  	    (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
  		ufs_set_fs_state(sb, usb1, usb3,
  				UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
  	ufs_put_cstotal(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1334
  	sb->s_dirt = 0;
8c8006564   Christoph Hellwig   ufs: add ->sync_fs
1335

abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1336
1337
  	UFSD("EXIT
  ");
ebc1ac164   Christoph Hellwig   ->write_super loc...
1338
  	unlock_super(sb);
788257d61   Arnd Bergmann   ufs: remove the BKL
1339
  	unlock_ufs(sb);
8c8006564   Christoph Hellwig   ufs: add ->sync_fs
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
  
  	return 0;
  }
  
  static void ufs_write_super(struct super_block *sb)
  {
  	if (!(sb->s_flags & MS_RDONLY))
  		ufs_sync_fs(sb, 1);
  	else
  		sb->s_dirt = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1350
  }
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1351
  static void ufs_put_super(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1352
1353
1354
  {
  	struct ufs_sb_info * sbi = UFS_SB(sb);
  		
abf5d15fd   Evgeniy Dushistov   [PATCH] ufs: easy...
1355
1356
  	UFSD("ENTER
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1357

8c85e1251   Christoph Hellwig   remove ->write_su...
1358
1359
  	if (sb->s_dirt)
  		ufs_write_super(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1360
  	if (!(sb->s_flags & MS_RDONLY))
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
1361
  		ufs_put_super_internal(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1362
1363
1364
1365
1366
  	
  	ubh_brelse_uspi (sbi->s_uspi);
  	kfree (sbi->s_uspi);
  	kfree (sbi);
  	sb->s_fs_info = NULL;
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
1367
1368
  	UFSD("EXIT
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
  	return;
  }
  
  
  static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
  {
  	struct ufs_sb_private_info * uspi;
  	struct ufs_super_block_first * usb1;
  	struct ufs_super_block_third * usb3;
  	unsigned new_mount_opt, ufstype;
  	unsigned flags;
337eb00a2   Alessio Igor Bogani   Push BKL down int...
1380

788257d61   Arnd Bergmann   ufs: remove the BKL
1381
  	lock_ufs(sb);
bbd6851a3   Al Viro   Push lock_super()...
1382
  	lock_super(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1383
1384
  	uspi = UFS_SB(sb)->s_uspi;
  	flags = UFS_SB(sb)->s_flags;
7b4ee73e2   Evgeniy   [PATCH] ufs cleanup
1385
1386
  	usb1 = ubh_get_usb_first(uspi);
  	usb3 = ubh_get_usb_third(uspi);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1387
1388
1389
1390
1391
1392
1393
1394
  	
  	/*
  	 * Allow the "check" option to be passed as a remount option.
  	 * It is not possible to change ufstype option during remount
  	 */
  	ufstype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE;
  	new_mount_opt = 0;
  	ufs_set_opt (new_mount_opt, ONERROR_LOCK);
bbd6851a3   Al Viro   Push lock_super()...
1395
1396
  	if (!ufs_parse_options (data, &new_mount_opt)) {
  		unlock_super(sb);
788257d61   Arnd Bergmann   ufs: remove the BKL
1397
  		unlock_ufs(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1398
  		return -EINVAL;
bbd6851a3   Al Viro   Push lock_super()...
1399
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1400
1401
  	if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) {
  		new_mount_opt |= ufstype;
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
1402
  	} else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1403
1404
  		printk("ufstype can't be changed during remount
  ");
bbd6851a3   Al Viro   Push lock_super()...
1405
  		unlock_super(sb);
788257d61   Arnd Bergmann   ufs: remove the BKL
1406
  		unlock_ufs(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1407
1408
1409
1410
1411
  		return -EINVAL;
  	}
  
  	if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
  		UFS_SB(sb)->s_mount_opt = new_mount_opt;
bbd6851a3   Al Viro   Push lock_super()...
1412
  		unlock_super(sb);
788257d61   Arnd Bergmann   ufs: remove the BKL
1413
  		unlock_ufs(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1414
1415
1416
1417
1418
1419
1420
  		return 0;
  	}
  	
  	/*
  	 * fs was mouted as rw, remounting ro
  	 */
  	if (*mount_flags & MS_RDONLY) {
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
1421
  		ufs_put_super_internal(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1422
1423
  		usb1->fs_time = cpu_to_fs32(sb, get_seconds());
  		if ((flags & UFS_ST_MASK) == UFS_ST_SUN
252e211e9   Mark   Add in SunOS 4.1....
1424
  		  || (flags & UFS_ST_MASK) == UFS_ST_SUNOS
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1425
1426
1427
  		  || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) 
  			ufs_set_fs_state(sb, usb1, usb3,
  				UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
9695ef16e   Evgeniy Dushistov   [PATCH] ufs: wron...
1428
  		ubh_mark_buffer_dirty (USPI_UBH(uspi));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1429
1430
  		sb->s_dirt = 0;
  		sb->s_flags |= MS_RDONLY;
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
1431
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1432
1433
1434
  	/*
  	 * fs was mounted as ro, remounting rw
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1435
1436
1437
1438
  #ifndef CONFIG_UFS_FS_WRITE
  		printk("ufs was compiled with read-only support, "
  		"can't be mounted as read-write
  ");
bbd6851a3   Al Viro   Push lock_super()...
1439
  		unlock_super(sb);
788257d61   Arnd Bergmann   ufs: remove the BKL
1440
  		unlock_ufs(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1441
1442
1443
  		return -EINVAL;
  #else
  		if (ufstype != UFS_MOUNT_UFSTYPE_SUN && 
252e211e9   Mark   Add in SunOS 4.1....
1444
  		    ufstype != UFS_MOUNT_UFSTYPE_SUNOS &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1445
  		    ufstype != UFS_MOUNT_UFSTYPE_44BSD &&
cbcae39fa   Evgeniy Dushistov   [PATCH] ufs2 writ...
1446
1447
  		    ufstype != UFS_MOUNT_UFSTYPE_SUNx86 &&
  		    ufstype != UFS_MOUNT_UFSTYPE_UFS2) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448
1449
  			printk("this ufstype is read-only supported
  ");
bbd6851a3   Al Viro   Push lock_super()...
1450
  			unlock_super(sb);
788257d61   Arnd Bergmann   ufs: remove the BKL
1451
  			unlock_ufs(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1452
1453
  			return -EINVAL;
  		}
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
1454
  		if (!ufs_read_cylinder_structures(sb)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1455
1456
  			printk("failed during remounting
  ");
bbd6851a3   Al Viro   Push lock_super()...
1457
  			unlock_super(sb);
788257d61   Arnd Bergmann   ufs: remove the BKL
1458
  			unlock_ufs(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1459
1460
1461
1462
1463
1464
  			return -EPERM;
  		}
  		sb->s_flags &= ~MS_RDONLY;
  #endif
  	}
  	UFS_SB(sb)->s_mount_opt = new_mount_opt;
bbd6851a3   Al Viro   Push lock_super()...
1465
  	unlock_super(sb);
788257d61   Arnd Bergmann   ufs: remove the BKL
1466
  	unlock_ufs(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1467
1468
  	return 0;
  }
34c80b1d9   Al Viro   vfs: switch ->sho...
1469
  static int ufs_show_options(struct seq_file *seq, struct dentry *root)
2a9807c0d   Evgeniy Dushistov   ufs: implement sh...
1470
  {
34c80b1d9   Al Viro   vfs: switch ->sho...
1471
  	struct ufs_sb_info *sbi = UFS_SB(root->d_sb);
2a9807c0d   Evgeniy Dushistov   ufs: implement sh...
1472
  	unsigned mval = sbi->s_mount_opt & UFS_MOUNT_UFSTYPE;
a447c0932   Steven Whitehouse   vfs: Use const fo...
1473
  	const struct match_token *tp = tokens;
2a9807c0d   Evgeniy Dushistov   ufs: implement sh...
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
  
  	while (tp->token != Opt_onerror_panic && tp->token != mval)
  		++tp;
  	BUG_ON(tp->token == Opt_onerror_panic);
  	seq_printf(seq, ",%s", tp->pattern);
  
  	mval = sbi->s_mount_opt & UFS_MOUNT_ONERROR;
  	while (tp->token != Opt_err && tp->token != mval)
  		++tp;
  	BUG_ON(tp->token == Opt_err);
  	seq_printf(seq, ",%s", tp->pattern);
  
  	return 0;
  }
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
1488
  static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1489
  {
726c33422   David Howells   [PATCH] VFS: Perm...
1490
  	struct super_block *sb = dentry->d_sb;
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
1491
1492
1493
1494
1495
  	struct ufs_sb_private_info *uspi= UFS_SB(sb)->s_uspi;
  	unsigned  flags = UFS_SB(sb)->s_flags;
  	struct ufs_super_block_first *usb1;
  	struct ufs_super_block_second *usb2;
  	struct ufs_super_block_third *usb3;
41d577aa3   Coly Li   fs/ufs: return f_...
1496
  	u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1497

788257d61   Arnd Bergmann   ufs: remove the BKL
1498
  	lock_ufs(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1499

647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
1500
1501
1502
  	usb1 = ubh_get_usb_first(uspi);
  	usb2 = ubh_get_usb_second(uspi);
  	usb3 = ubh_get_usb_third(uspi);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1503
  	
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1504
1505
  	if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
  		buf->f_type = UFS2_MAGIC;
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
1506
  		buf->f_blocks = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize);
647b7e87b   Evgeniy Dushistov   [PATCH] ufs: one ...
1507
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1508
1509
  		buf->f_type = UFS_MAGIC;
  		buf->f_blocks = uspi->s_dsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1510
  	}
ee3ffd6c1   Evgeniy Dushistov   [PATCH] ufs: make...
1511
1512
1513
  	buf->f_bfree = ufs_blkstofrags(uspi->cs_total.cs_nbfree) +
  		uspi->cs_total.cs_nffree;
  	buf->f_ffree = uspi->cs_total.cs_nifree;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1514
1515
1516
1517
1518
  	buf->f_bsize = sb->s_blocksize;
  	buf->f_bavail = (buf->f_bfree > (((long)buf->f_blocks / 100) * uspi->s_minfree))
  		? (buf->f_bfree - (((long)buf->f_blocks / 100) * uspi->s_minfree)) : 0;
  	buf->f_files = uspi->s_ncg * uspi->s_ipg;
  	buf->f_namelen = UFS_MAXNAMLEN;
41d577aa3   Coly Li   fs/ufs: return f_...
1519
1520
  	buf->f_fsid.val[0] = (u32)id;
  	buf->f_fsid.val[1] = (u32)(id >> 32);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1521

788257d61   Arnd Bergmann   ufs: remove the BKL
1522
  	unlock_ufs(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1523
1524
1525
  
  	return 0;
  }
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
1526
  static struct kmem_cache * ufs_inode_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1527
1528
1529
1530
  
  static struct inode *ufs_alloc_inode(struct super_block *sb)
  {
  	struct ufs_inode_info *ei;
788257d61   Arnd Bergmann   ufs: remove the BKL
1531
  	ei = (struct ufs_inode_info *)kmem_cache_alloc(ufs_inode_cachep, GFP_NOFS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1532
1533
1534
1535
1536
  	if (!ei)
  		return NULL;
  	ei->vfs_inode.i_version = 1;
  	return &ei->vfs_inode;
  }
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
1537
  static void ufs_i_callback(struct rcu_head *head)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1538
  {
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
1539
  	struct inode *inode = container_of(head, struct inode, i_rcu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1540
1541
  	kmem_cache_free(ufs_inode_cachep, UFS_I(inode));
  }
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
1542
1543
1544
1545
  static void ufs_destroy_inode(struct inode *inode)
  {
  	call_rcu(&inode->i_rcu, ufs_i_callback);
  }
51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
1546
  static void init_once(void *foo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1547
1548
  {
  	struct ufs_inode_info *ei = (struct ufs_inode_info *) foo;
a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
1549
  	inode_init_once(&ei->vfs_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1550
  }
20c2df83d   Paul Mundt   mm: Remove slab d...
1551

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1552
1553
1554
1555
  static int init_inodecache(void)
  {
  	ufs_inode_cachep = kmem_cache_create("ufs_inode_cache",
  					     sizeof(struct ufs_inode_info),
fffb60f93   Paul Jackson   [PATCH] cpuset me...
1556
1557
  					     0, (SLAB_RECLAIM_ACCOUNT|
  						SLAB_MEM_SPREAD),
20c2df83d   Paul Mundt   mm: Remove slab d...
1558
  					     init_once);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1559
1560
1561
1562
1563
1564
1565
  	if (ufs_inode_cachep == NULL)
  		return -ENOMEM;
  	return 0;
  }
  
  static void destroy_inodecache(void)
  {
1a1d92c10   Alexey Dobriyan   [PATCH] Really ig...
1566
  	kmem_cache_destroy(ufs_inode_cachep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1567
  }
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
1568
  static const struct super_operations ufs_super_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1569
1570
  	.alloc_inode	= ufs_alloc_inode,
  	.destroy_inode	= ufs_destroy_inode,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1571
  	.write_inode	= ufs_write_inode,
58e8268c7   Al Viro   switch ufs to ->e...
1572
  	.evict_inode	= ufs_evict_inode,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1573
1574
  	.put_super	= ufs_put_super,
  	.write_super	= ufs_write_super,
8c8006564   Christoph Hellwig   ufs: add ->sync_fs
1575
  	.sync_fs	= ufs_sync_fs,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1576
1577
  	.statfs		= ufs_statfs,
  	.remount_fs	= ufs_remount,
2a9807c0d   Evgeniy Dushistov   ufs: implement sh...
1578
  	.show_options   = ufs_show_options,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1579
  };
152a08366   Al Viro   new helper: mount...
1580
1581
  static struct dentry *ufs_mount(struct file_system_type *fs_type,
  	int flags, const char *dev_name, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1582
  {
152a08366   Al Viro   new helper: mount...
1583
  	return mount_bdev(fs_type, flags, dev_name, data, ufs_fill_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1584
1585
1586
1587
1588
  }
  
  static struct file_system_type ufs_fs_type = {
  	.owner		= THIS_MODULE,
  	.name		= "ufs",
152a08366   Al Viro   new helper: mount...
1589
  	.mount		= ufs_mount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
  	.kill_sb	= kill_block_super,
  	.fs_flags	= FS_REQUIRES_DEV,
  };
  
  static int __init init_ufs_fs(void)
  {
  	int err = init_inodecache();
  	if (err)
  		goto out1;
  	err = register_filesystem(&ufs_fs_type);
  	if (err)
  		goto out;
  	return 0;
  out:
  	destroy_inodecache();
  out1:
  	return err;
  }
  
  static void __exit exit_ufs_fs(void)
  {
  	unregister_filesystem(&ufs_fs_type);
  	destroy_inodecache();
  }
  
  module_init(init_ufs_fs)
  module_exit(exit_ufs_fs)
  MODULE_LICENSE("GPL");