super.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:30k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/fs/ufs/super.c
  3.  *
  4.  * Copyright (C) 1998
  5.  * Daniel Pirkl <daniel.pirkl@email.cz>
  6.  * Charles University, Faculty of Mathematics and Physics
  7.  */
  8. /* Derived from
  9.  *
  10.  *  linux/fs/ext2/super.c
  11.  *
  12.  * Copyright (C) 1992, 1993, 1994, 1995
  13.  * Remy Card (card@masi.ibp.fr)
  14.  * Laboratoire MASI - Institut Blaise Pascal
  15.  * Universite Pierre et Marie Curie (Paris VI)
  16.  *
  17.  *  from
  18.  *
  19.  *  linux/fs/minix/inode.c
  20.  *
  21.  *  Copyright (C) 1991, 1992  Linus Torvalds
  22.  *
  23.  *  Big-endian to little-endian byte-swapping/bitmaps by
  24.  *        David S. Miller (davem@caip.rutgers.edu), 1995
  25.  */
  26.  
  27. /*
  28.  * Inspired by
  29.  *
  30.  *  linux/fs/ufs/super.c
  31.  *
  32.  * Copyright (C) 1996
  33.  * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
  34.  * Laboratory for Computer Science Research Computing Facility
  35.  * Rutgers, The State University of New Jersey
  36.  *
  37.  * Copyright (C) 1996  Eddie C. Dost  (ecd@skynet.be)
  38.  *
  39.  * Kernel module support added on 96/04/26 by
  40.  * Stefan Reinauer <stepan@home.culture.mipt.ru>
  41.  *
  42.  * Module usage counts added on 96/04/29 by
  43.  * Gertjan van Wingerde <gertjan@cs.vu.nl>
  44.  *
  45.  * Clean swab support on 19970406 by
  46.  * Francois-Rene Rideau <fare@tunes.org>
  47.  *
  48.  * 4.4BSD (FreeBSD) support added on February 1st 1998 by
  49.  * Niels Kristian Bech Jensen <nkbj@image.dk> partially based
  50.  * on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>.
  51.  *
  52.  * NeXTstep support added on February 5th 1998 by
  53.  * Niels Kristian Bech Jensen <nkbj@image.dk>.
  54.  *
  55.  * write support Daniel Pirkl <daniel.pirkl@email.cz> 1998
  56.  * 
  57.  * HP/UX hfs filesystem support added by
  58.  * Martin K. Petersen <mkp@mkp.net>, August 1999
  59.  *
  60.  */
  61. #include <linux/config.h>
  62. #include <linux/module.h>
  63. #include <stdarg.h>
  64. #include <asm/bitops.h>
  65. #include <asm/uaccess.h>
  66. #include <asm/system.h>
  67. #include <linux/errno.h>
  68. #include <linux/fs.h>
  69. #include <linux/ufs_fs.h>
  70. #include <linux/slab.h>
  71. #include <linux/sched.h>
  72. #include <linux/stat.h>
  73. #include <linux/string.h>
  74. #include <linux/locks.h>
  75. #include <linux/blkdev.h>
  76. #include <linux/init.h>
  77. #include "swab.h"
  78. #include "util.h"
  79. #undef UFS_SUPER_DEBUG
  80. #undef UFS_SUPER_DEBUG_MORE
  81. #ifdef UFS_SUPER_DEBUG
  82. #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x;
  83. #else
  84. #define UFSD(x)
  85. #endif
  86. #ifdef UFS_SUPER_DEBUG_MORE
  87. /*
  88.  * Print contents of ufs_super_block, useful for debugging
  89.  */
  90. void ufs_print_super_stuff(struct super_block *sb,
  91. struct ufs_super_block_first * usb1,
  92. struct ufs_super_block_second * usb2, 
  93. struct ufs_super_block_third * usb3)
  94. {
  95. printk("ufs_print_super_stuffn");
  96. printk("size of usb:     %un", sizeof(struct ufs_super_block));
  97. printk("  magic:         0x%xn", fs32_to_cpu(sb, usb3->fs_magic));
  98. printk("  sblkno:        %un", fs32_to_cpu(sb, usb1->fs_sblkno));
  99. printk("  cblkno:        %un", fs32_to_cpu(sb, usb1->fs_cblkno));
  100. printk("  iblkno:        %un", fs32_to_cpu(sb, usb1->fs_iblkno));
  101. printk("  dblkno:        %un", fs32_to_cpu(sb, usb1->fs_dblkno));
  102. printk("  cgoffset:      %un", fs32_to_cpu(sb, usb1->fs_cgoffset));
  103. printk("  ~cgmask:       0x%xn", ~fs32_to_cpu(sb, usb1->fs_cgmask));
  104. printk("  size:          %un", fs32_to_cpu(sb, usb1->fs_size));
  105. printk("  dsize:         %un", fs32_to_cpu(sb, usb1->fs_dsize));
  106. printk("  ncg:           %un", fs32_to_cpu(sb, usb1->fs_ncg));
  107. printk("  bsize:         %un", fs32_to_cpu(sb, usb1->fs_bsize));
  108. printk("  fsize:         %un", fs32_to_cpu(sb, usb1->fs_fsize));
  109. printk("  frag:          %un", fs32_to_cpu(sb, usb1->fs_frag));
  110. printk("  fragshift:     %un", fs32_to_cpu(sb, usb1->fs_fragshift));
  111. printk("  ~fmask:        %un", ~fs32_to_cpu(sb, usb1->fs_fmask));
  112. printk("  fshift:        %un", fs32_to_cpu(sb, usb1->fs_fshift));
  113. printk("  sbsize:        %un", fs32_to_cpu(sb, usb1->fs_sbsize));
  114. printk("  spc:           %un", fs32_to_cpu(sb, usb1->fs_spc));
  115. printk("  cpg:           %un", fs32_to_cpu(sb, usb1->fs_cpg));
  116. printk("  ipg:           %un", fs32_to_cpu(sb, usb1->fs_ipg));
  117. printk("  fpg:           %un", fs32_to_cpu(sb, usb1->fs_fpg));
  118. printk("  csaddr:        %un", fs32_to_cpu(sb, usb1->fs_csaddr));
  119. printk("  cssize:        %un", fs32_to_cpu(sb, usb1->fs_cssize));
  120. printk("  cgsize:        %un", fs32_to_cpu(sb, usb1->fs_cgsize));
  121. printk("  fstodb:        %un", fs32_to_cpu(sb, usb1->fs_fsbtodb));
  122. printk("  contigsumsize: %dn", fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_contigsumsize));
  123. printk("  postblformat:  %un", fs32_to_cpu(sb, usb3->fs_postblformat));
  124. printk("  nrpos:         %un", fs32_to_cpu(sb, usb3->fs_nrpos));
  125. printk("  ndir           %un", fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir));
  126. printk("  nifree         %un", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree));
  127. printk("  nbfree         %un", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree));
  128. printk("  nffree         %un", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree));
  129. printk("n");
  130. }
  131. /*
  132.  * Print contents of ufs_cylinder_group, useful for debugging
  133.  */
  134. void ufs_print_cylinder_stuff(struct super_block *sb, struct ufs_cylinder_group *cg)
  135. {
  136. printk("nufs_print_cylinder_stuffn");
  137. printk("size of ucg: %un", sizeof(struct ufs_cylinder_group));
  138. printk("  magic:        %xn", fs32_to_cpu(sb, cg->cg_magic));
  139. printk("  time:         %un", fs32_to_cpu(sb, cg->cg_time));
  140. printk("  cgx:          %un", fs32_to_cpu(sb, cg->cg_cgx));
  141. printk("  ncyl:         %un", fs16_to_cpu(sb, cg->cg_ncyl));
  142. printk("  niblk:        %un", fs16_to_cpu(sb, cg->cg_niblk));
  143. printk("  ndblk:        %un", fs32_to_cpu(sb, cg->cg_ndblk));
  144. printk("  cs_ndir:      %un", fs32_to_cpu(sb, cg->cg_cs.cs_ndir));
  145. printk("  cs_nbfree:    %un", fs32_to_cpu(sb, cg->cg_cs.cs_nbfree));
  146. printk("  cs_nifree:    %un", fs32_to_cpu(sb, cg->cg_cs.cs_nifree));
  147. printk("  cs_nffree:    %un", fs32_to_cpu(sb, cg->cg_cs.cs_nffree));
  148. printk("  rotor:        %un", fs32_to_cpu(sb, cg->cg_rotor));
  149. printk("  frotor:       %un", fs32_to_cpu(sb, cg->cg_frotor));
  150. printk("  irotor:       %un", fs32_to_cpu(sb, cg->cg_irotor));
  151. printk("  frsum:        %u, %u, %u, %u, %u, %u, %u, %un",
  152.     fs32_to_cpu(sb, cg->cg_frsum[0]), fs32_to_cpu(sb, cg->cg_frsum[1]),
  153.     fs32_to_cpu(sb, cg->cg_frsum[2]), fs32_to_cpu(sb, cg->cg_frsum[3]),
  154.     fs32_to_cpu(sb, cg->cg_frsum[4]), fs32_to_cpu(sb, cg->cg_frsum[5]),
  155.     fs32_to_cpu(sb, cg->cg_frsum[6]), fs32_to_cpu(sb, cg->cg_frsum[7]));
  156. printk("  btotoff:      %un", fs32_to_cpu(sb, cg->cg_btotoff));
  157. printk("  boff:         %un", fs32_to_cpu(sb, cg->cg_boff));
  158. printk("  iuseoff:      %un", fs32_to_cpu(sb, cg->cg_iusedoff));
  159. printk("  freeoff:      %un", fs32_to_cpu(sb, cg->cg_freeoff));
  160. printk("  nextfreeoff:  %un", fs32_to_cpu(sb, cg->cg_nextfreeoff));
  161. printk("  clustersumoff %un", fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clustersumoff));
  162. printk("  clusteroff    %un", fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clusteroff));
  163. printk("  nclusterblks  %un", fs32_to_cpu(sb, cg->cg_u.cg_44.cg_nclusterblks));
  164. printk("n");
  165. }
  166. #endif /* UFS_SUPER_DEBUG_MORE */
  167. static struct super_operations ufs_super_ops;
  168. static char error_buf[1024];
  169. void ufs_error (struct super_block * sb, const char * function,
  170. const char * fmt, ...)
  171. {
  172. struct ufs_sb_private_info * uspi;
  173. struct ufs_super_block_first * usb1;
  174. va_list args;
  175. uspi = sb->u.ufs_sb.s_uspi;
  176. usb1 = ubh_get_usb_first(USPI_UBH);
  177. if (!(sb->s_flags & MS_RDONLY)) {
  178. usb1->fs_clean = UFS_FSBAD;
  179. ubh_mark_buffer_dirty(USPI_UBH);
  180. sb->s_dirt = 1;
  181. sb->s_flags |= MS_RDONLY;
  182. }
  183. va_start (args, fmt);
  184. vsprintf (error_buf, fmt, args);
  185. va_end (args);
  186. switch (sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_ONERROR) {
  187. case UFS_MOUNT_ONERROR_PANIC:
  188. panic ("UFS-fs panic (device %s): %s: %sn", 
  189. kdevname(sb->s_dev), function, error_buf);
  190. case UFS_MOUNT_ONERROR_LOCK:
  191. case UFS_MOUNT_ONERROR_UMOUNT:
  192. case UFS_MOUNT_ONERROR_REPAIR:
  193. printk (KERN_CRIT "UFS-fs error (device %s): %s: %sn",
  194. kdevname(sb->s_dev), function, error_buf);
  195. }
  196. }
  197. void ufs_panic (struct super_block * sb, const char * function,
  198. const char * fmt, ...)
  199. {
  200. struct ufs_sb_private_info * uspi;
  201. struct ufs_super_block_first * usb1;
  202. va_list args;
  203. uspi = sb->u.ufs_sb.s_uspi;
  204. usb1 = ubh_get_usb_first(USPI_UBH);
  205. if (!(sb->s_flags & MS_RDONLY)) {
  206. usb1->fs_clean = UFS_FSBAD;
  207. ubh_mark_buffer_dirty(USPI_UBH);
  208. sb->s_dirt = 1;
  209. }
  210. va_start (args, fmt);
  211. vsprintf (error_buf, fmt, args);
  212. va_end (args);
  213. sb->s_flags |= MS_RDONLY;
  214. printk (KERN_CRIT "UFS-fs panic (device %s): %s: %sn",
  215. kdevname(sb->s_dev), function, error_buf);
  216. }
  217. void ufs_warning (struct super_block * sb, const char * function,
  218. const char * fmt, ...)
  219. {
  220. va_list args;
  221. va_start (args, fmt);
  222. vsprintf (error_buf, fmt, args);
  223. va_end (args);
  224. printk (KERN_WARNING "UFS-fs warning (device %s): %s: %sn",
  225. kdevname(sb->s_dev), function, error_buf);
  226. }
  227. static int ufs_parse_options (char * options, unsigned * mount_options)
  228. {
  229. char * this_char;
  230. char * value;
  231. UFSD(("ENTERn"))
  232. if (!options)
  233. return 1;
  234. for (this_char = strtok (options, ",");
  235.      this_char != NULL;
  236.      this_char = strtok (NULL, ",")) {
  237.      
  238. if ((value = strchr (this_char, '=')) != NULL)
  239. *value++ = 0;
  240. if (!strcmp (this_char, "ufstype")) {
  241. ufs_clear_opt (*mount_options, UFSTYPE);
  242. if (!strcmp (value, "old"))
  243. ufs_set_opt (*mount_options, UFSTYPE_OLD);
  244. else if (!strcmp (value, "sun"))
  245. ufs_set_opt (*mount_options, UFSTYPE_SUN);
  246. else if (!strcmp (value, "44bsd"))
  247. ufs_set_opt (*mount_options, UFSTYPE_44BSD);
  248. else if (!strcmp (value, "nextstep"))
  249. ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP);
  250. else if (!strcmp (value, "nextstep-cd"))
  251. ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP_CD);
  252. else if (!strcmp (value, "openstep"))
  253. ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);
  254. else if (!strcmp (value, "sunx86"))
  255. ufs_set_opt (*mount_options, UFSTYPE_SUNx86);
  256. else if (!strcmp (value, "hp"))
  257. ufs_set_opt (*mount_options, UFSTYPE_HP);
  258. else {
  259. printk ("UFS-fs: Invalid type option: %sn", value);
  260. return 0;
  261. }
  262. }
  263. else if (!strcmp (this_char, "onerror")) {
  264. ufs_clear_opt (*mount_options, ONERROR);
  265. if (!strcmp (value, "panic"))
  266. ufs_set_opt (*mount_options, ONERROR_PANIC);
  267. else if (!strcmp (value, "lock"))
  268. ufs_set_opt (*mount_options, ONERROR_LOCK);
  269. else if (!strcmp (value, "umount"))
  270. ufs_set_opt (*mount_options, ONERROR_UMOUNT);
  271. else if (!strcmp (value, "repair")) {
  272. printk("UFS-fs: Unable to do repair on error, "
  273. "will lock lock instead n");
  274. ufs_set_opt (*mount_options, ONERROR_REPAIR);
  275. }
  276. else {
  277. printk ("UFS-fs: Invalid action onerror: %sn", value);
  278. return 0;
  279. }
  280. }
  281. else {
  282. printk("UFS-fs: Invalid option: %sn", this_char);
  283. return 0;
  284. }
  285. }
  286. return 1;
  287. }
  288. /*
  289.  * Read on-disk structures associated with cylinder groups
  290.  */
  291. int ufs_read_cylinder_structures (struct super_block * sb) {
  292. struct ufs_sb_private_info * uspi;
  293. struct ufs_buffer_head * ubh;
  294. unsigned char * base, * space;
  295. unsigned size, blks, i;
  296. UFSD(("ENTERn"))
  297. uspi = sb->u.ufs_sb.s_uspi;
  298. /*
  299.  * Read cs structures from (usually) first data block
  300.  * on the device. 
  301.  */
  302. size = uspi->s_cssize;
  303. blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
  304. base = space = kmalloc(size, GFP_KERNEL);
  305. if (!base)
  306. goto failed; 
  307. for (i = 0; i < blks; i += uspi->s_fpb) {
  308. size = uspi->s_bsize;
  309. if (i + uspi->s_fpb > blks)
  310. size = (blks - i) * uspi->s_fsize;
  311. ubh = ubh_bread(sb, uspi->s_csaddr + i, size);
  312. if (!ubh)
  313. goto failed;
  314. ubh_ubhcpymem (space, ubh, size);
  315. sb->u.ufs_sb.s_csp[ufs_fragstoblks(i)] = (struct ufs_csum *)space;
  316. space += size;
  317. ubh_brelse (ubh);
  318. ubh = NULL;
  319. }
  320. /*
  321.  * Read cylinder group (we read only first fragment from block
  322.  * at this time) and prepare internal data structures for cg caching.
  323.  */
  324. if (!(sb->u.ufs_sb.s_ucg = kmalloc (sizeof(struct buffer_head *) * uspi->s_ncg, GFP_KERNEL)))
  325. goto failed;
  326. for (i = 0; i < uspi->s_ncg; i++) 
  327. sb->u.ufs_sb.s_ucg[i] = NULL;
  328. for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {
  329. sb->u.ufs_sb.s_ucpi[i] = NULL;
  330. sb->u.ufs_sb.s_cgno[i] = UFS_CGNO_EMPTY;
  331. }
  332. for (i = 0; i < uspi->s_ncg; i++) {
  333. UFSD(("read cg %un", i))
  334. if (!(sb->u.ufs_sb.s_ucg[i] = sb_bread(sb, ufs_cgcmin(i))))
  335. goto failed;
  336. if (!ufs_cg_chkmagic (sb, (struct ufs_cylinder_group *) sb->u.ufs_sb.s_ucg[i]->b_data))
  337. goto failed;
  338. #ifdef UFS_SUPER_DEBUG_MORE
  339. ufs_print_cylinder_stuff(sb, (struct ufs_cylinder_group *) sb->u.ufs_sb.s_ucg[i]->b_data);
  340. #endif
  341. }
  342. for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {
  343. if (!(sb->u.ufs_sb.s_ucpi[i] = kmalloc (sizeof(struct ufs_cg_private_info), GFP_KERNEL)))
  344. goto failed;
  345. sb->u.ufs_sb.s_cgno[i] = UFS_CGNO_EMPTY;
  346. }
  347. sb->u.ufs_sb.s_cg_loaded = 0;
  348. UFSD(("EXITn"))
  349. return 1;
  350. failed:
  351. if (base) kfree (base);
  352. if (sb->u.ufs_sb.s_ucg) {
  353. for (i = 0; i < uspi->s_ncg; i++)
  354. if (sb->u.ufs_sb.s_ucg[i]) brelse (sb->u.ufs_sb.s_ucg[i]);
  355. kfree (sb->u.ufs_sb.s_ucg);
  356. for (i = 0; i < UFS_MAX_GROUP_LOADED; i++)
  357. if (sb->u.ufs_sb.s_ucpi[i]) kfree (sb->u.ufs_sb.s_ucpi[i]);
  358. }
  359. UFSD(("EXIT (FAILED)n"))
  360. return 0;
  361. }
  362. /*
  363.  * Put on-disk structures associated with cylinder groups and 
  364.  * write them back to disk
  365.  */
  366. void ufs_put_cylinder_structures (struct super_block * sb) {
  367. struct ufs_sb_private_info * uspi;
  368. struct ufs_buffer_head * ubh;
  369. unsigned char * base, * space;
  370. unsigned blks, size, i;
  371. UFSD(("ENTERn"))
  372. uspi = sb->u.ufs_sb.s_uspi;
  373. size = uspi->s_cssize;
  374. blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
  375. base = space = (char*) sb->u.ufs_sb.s_csp[0];
  376. for (i = 0; i < blks; i += uspi->s_fpb) {
  377. size = uspi->s_bsize;
  378. if (i + uspi->s_fpb > blks)
  379. size = (blks - i) * uspi->s_fsize;
  380. ubh = ubh_bread(sb, uspi->s_csaddr + i, size);
  381. ubh_memcpyubh (ubh, space, size);
  382. space += size;
  383. ubh_mark_buffer_uptodate (ubh, 1);
  384. ubh_mark_buffer_dirty (ubh);
  385. ubh_brelse (ubh);
  386. }
  387. for (i = 0; i < sb->u.ufs_sb.s_cg_loaded; i++) {
  388. ufs_put_cylinder (sb, i);
  389. kfree (sb->u.ufs_sb.s_ucpi[i]);
  390. }
  391. for (; i < UFS_MAX_GROUP_LOADED; i++) 
  392. kfree (sb->u.ufs_sb.s_ucpi[i]);
  393. for (i = 0; i < uspi->s_ncg; i++) 
  394. brelse (sb->u.ufs_sb.s_ucg[i]);
  395. kfree (sb->u.ufs_sb.s_ucg);
  396. kfree (base);
  397. UFSD(("EXITn"))
  398. }
  399. struct super_block * ufs_read_super (struct super_block * sb, void * data,
  400. int silent)
  401. {
  402. struct ufs_sb_private_info * uspi;
  403. struct ufs_super_block_first * usb1;
  404. struct ufs_super_block_second * usb2;
  405. struct ufs_super_block_third * usb3;
  406. struct ufs_buffer_head * ubh;
  407. struct inode *inode;
  408. unsigned block_size, super_block_size;
  409. unsigned flags;
  410. uspi = NULL;
  411. ubh = NULL;
  412. flags = 0;
  413. UFSD(("ENTERn"))
  414. UFSD(("flag %un", (int)(sb->s_flags & MS_RDONLY)))
  415. #ifndef CONFIG_UFS_FS_WRITE
  416. if (!(sb->s_flags & MS_RDONLY)) {
  417. printk("ufs was compiled with read-only support, "
  418. "can't be mounted as read-writen");
  419. goto failed;
  420. }
  421. #endif
  422. /*
  423.  * Set default mount options
  424.  * Parse mount options
  425.  */
  426. sb->u.ufs_sb.s_mount_opt = 0;
  427. ufs_set_opt (sb->u.ufs_sb.s_mount_opt, ONERROR_LOCK);
  428. if (!ufs_parse_options ((char *) data, &sb->u.ufs_sb.s_mount_opt)) {
  429. printk("wrong mount optionsn");
  430. goto failed;
  431. }
  432. if (!(sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE)) {
  433. printk("You didn't specify the type of your ufs filesystemnn"
  434. "mount -t ufs -o ufstype="
  435. "sun|sunx86|44bsd|old|hp|nextstep|netxstep-cd|openstep ...nn"
  436. ">>>WARNING<<< Wrong ufstype may corrupt your filesystem, "
  437. "default is ufstype=oldn");
  438. ufs_set_opt (sb->u.ufs_sb.s_mount_opt, UFSTYPE_OLD);
  439. }
  440. sb->u.ufs_sb.s_uspi = uspi =
  441. kmalloc (sizeof(struct ufs_sb_private_info), GFP_KERNEL);
  442. if (!uspi)
  443. goto failed;
  444. /* Keep 2Gig file limit. Some UFS variants need to override 
  445.    this but as I don't know which I'll let those in the know loosen
  446.    the rules */
  447.    
  448. switch (sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) {
  449. case UFS_MOUNT_UFSTYPE_44BSD:
  450. UFSD(("ufstype=44bsdn"))
  451. uspi->s_fsize = block_size = 512;
  452. uspi->s_fmask = ~(512 - 1);
  453. uspi->s_fshift = 9;
  454. uspi->s_sbsize = super_block_size = 1536;
  455. uspi->s_sbbase = 0;
  456. flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
  457. break;
  458. case UFS_MOUNT_UFSTYPE_SUN:
  459. UFSD(("ufstype=sunn"))
  460. uspi->s_fsize = block_size = 1024;
  461. uspi->s_fmask = ~(1024 - 1);
  462. uspi->s_fshift = 10;
  463. uspi->s_sbsize = super_block_size = 2048;
  464. uspi->s_sbbase = 0;
  465. uspi->s_maxsymlinklen = 56;
  466. flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUN | UFS_CG_SUN;
  467. break;
  468. case UFS_MOUNT_UFSTYPE_SUNx86:
  469. UFSD(("ufstype=sunx86n"))
  470. uspi->s_fsize = block_size = 1024;
  471. uspi->s_fmask = ~(1024 - 1);
  472. uspi->s_fshift = 10;
  473. uspi->s_sbsize = super_block_size = 2048;
  474. uspi->s_sbbase = 0;
  475. uspi->s_maxsymlinklen = 56;
  476. flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUNx86 | UFS_CG_SUN;
  477. break;
  478. case UFS_MOUNT_UFSTYPE_OLD:
  479. UFSD(("ufstype=oldn"))
  480. uspi->s_fsize = block_size = 1024;
  481. uspi->s_fmask = ~(1024 - 1);
  482. uspi->s_fshift = 10;
  483. uspi->s_sbsize = super_block_size = 2048;
  484. uspi->s_sbbase = 0;
  485. flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
  486. if (!(sb->s_flags & MS_RDONLY)) {
  487. printk(KERN_INFO "ufstype=old is supported read-onlyn"); 
  488. sb->s_flags |= MS_RDONLY;
  489. }
  490. break;
  491. case UFS_MOUNT_UFSTYPE_NEXTSTEP:
  492. UFSD(("ufstype=nextstepn"))
  493. uspi->s_fsize = block_size = 1024;
  494. uspi->s_fmask = ~(1024 - 1);
  495. uspi->s_fshift = 10;
  496. uspi->s_sbsize = super_block_size = 2048;
  497. uspi->s_sbbase = 0;
  498. flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
  499. if (!(sb->s_flags & MS_RDONLY)) {
  500. printk(KERN_INFO "ufstype=nextstep is supported read-onlyn");
  501. sb->s_flags |= MS_RDONLY;
  502. }
  503. break;
  504. case UFS_MOUNT_UFSTYPE_NEXTSTEP_CD:
  505. UFSD(("ufstype=nextstep-cdn"))
  506. uspi->s_fsize = block_size = 2048;
  507. uspi->s_fmask = ~(2048 - 1);
  508. uspi->s_fshift = 11;
  509. uspi->s_sbsize = super_block_size = 2048;
  510. uspi->s_sbbase = 0;
  511. flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
  512. if (!(sb->s_flags & MS_RDONLY)) {
  513. printk(KERN_INFO "ufstype=nextstep-cd is supported read-onlyn");
  514. sb->s_flags |= MS_RDONLY;
  515. }
  516. break;
  517. case UFS_MOUNT_UFSTYPE_OPENSTEP:
  518. UFSD(("ufstype=openstepn"))
  519. uspi->s_fsize = block_size = 1024;
  520. uspi->s_fmask = ~(1024 - 1);
  521. uspi->s_fshift = 10;
  522. uspi->s_sbsize = super_block_size = 2048;
  523. uspi->s_sbbase = 0;
  524. flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
  525. if (!(sb->s_flags & MS_RDONLY)) {
  526. printk(KERN_INFO "ufstype=openstep is supported read-onlyn");
  527. sb->s_flags |= MS_RDONLY;
  528. }
  529. break;
  530. case UFS_MOUNT_UFSTYPE_HP:
  531. UFSD(("ufstype=hpn"))
  532. uspi->s_fsize = block_size = 1024;
  533. uspi->s_fmask = ~(1024 - 1);
  534. uspi->s_fshift = 10;
  535. uspi->s_sbsize = super_block_size = 2048;
  536. uspi->s_sbbase = 0;
  537. flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
  538. if (!(sb->s_flags & MS_RDONLY)) {
  539. printk(KERN_INFO "ufstype=hp is supported read-onlyn");
  540. sb->s_flags |= MS_RDONLY;
  541.   }
  542.   break;
  543. default:
  544. printk("unknown ufstypen");
  545. goto failed;
  546. }
  547. again:
  548. if (set_blocksize (sb->s_dev, block_size)) {
  549. printk(KERN_ERR "UFS: failed to set blocksizen");
  550. goto failed;
  551. }
  552. sb->s_blocksize = block_size;
  553. /*
  554.  * read ufs super block from device
  555.  */
  556. ubh = ubh_bread_uspi (uspi, sb, uspi->s_sbbase + UFS_SBLOCK/block_size, super_block_size);
  557. if (!ubh) 
  558. goto failed;
  559. usb1 = ubh_get_usb_first(USPI_UBH);
  560. usb2 = ubh_get_usb_second(USPI_UBH);
  561. usb3 = ubh_get_usb_third(USPI_UBH);
  562. /*
  563.  * Check ufs magic number
  564.  */
  565. switch (__constant_le32_to_cpu(usb3->fs_magic)) {
  566. case UFS_MAGIC:
  567. case UFS_MAGIC_LFN:
  568.         case UFS_MAGIC_FEA:
  569.         case UFS_MAGIC_4GB:
  570. sb->u.ufs_sb.s_bytesex = BYTESEX_LE;
  571. goto magic_found;
  572. }
  573. switch (__constant_be32_to_cpu(usb3->fs_magic)) {
  574. case UFS_MAGIC:
  575. case UFS_MAGIC_LFN:
  576.         case UFS_MAGIC_FEA:
  577.         case UFS_MAGIC_4GB:
  578. sb->u.ufs_sb.s_bytesex = BYTESEX_BE;
  579. goto magic_found;
  580. }
  581. if ((((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP) 
  582.   || ((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP_CD) 
  583.   || ((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_OPENSTEP)) 
  584.   && uspi->s_sbbase < 256) {
  585. ubh_brelse_uspi(uspi);
  586. ubh = NULL;
  587. uspi->s_sbbase += 8;
  588. goto again;
  589. }
  590. printk("ufs_read_super: bad magic numbern");
  591. goto failed;
  592. magic_found:
  593. /*
  594.  * Check block and fragment sizes
  595.  */
  596. uspi->s_bsize = fs32_to_cpu(sb, usb1->fs_bsize);
  597. uspi->s_fsize = fs32_to_cpu(sb, usb1->fs_fsize);
  598. uspi->s_sbsize = fs32_to_cpu(sb, usb1->fs_sbsize);
  599. uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
  600. uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
  601. if (uspi->s_fsize & (uspi->s_fsize - 1)) {
  602. printk(KERN_ERR "ufs_read_super: fragment size %u is not a power of 2n",
  603. uspi->s_fsize);
  604. goto failed;
  605. }
  606. if (uspi->s_fsize < 512) {
  607. printk(KERN_ERR "ufs_read_super: fragment size %u is too smalln",
  608. uspi->s_fsize);
  609. goto failed;
  610. }
  611. if (uspi->s_fsize > 4096) {
  612. printk(KERN_ERR "ufs_read_super: fragment size %u is too largen",
  613. uspi->s_fsize);
  614. goto failed;
  615. }
  616. if (uspi->s_bsize & (uspi->s_bsize - 1)) {
  617. printk(KERN_ERR "ufs_read_super: block size %u is not a power of 2n",
  618. uspi->s_bsize);
  619. goto failed;
  620. }
  621. if (uspi->s_bsize < 4096) {
  622. printk(KERN_ERR "ufs_read_super: block size %u is too smalln",
  623. uspi->s_bsize);
  624. goto failed;
  625. }
  626. if (uspi->s_bsize / uspi->s_fsize > 8) {
  627. printk(KERN_ERR "ufs_read_super: too many fragments per block (%u)n",
  628. uspi->s_bsize / uspi->s_fsize);
  629. goto failed;
  630. }
  631. if (uspi->s_fsize != block_size || uspi->s_sbsize != super_block_size) {
  632. ubh_brelse_uspi(uspi);
  633. ubh = NULL;
  634. block_size = uspi->s_fsize;
  635. super_block_size = uspi->s_sbsize;
  636. UFSD(("another value of block_size or super_block_size %u, %un", block_size, super_block_size))
  637. goto again;
  638. }
  639. #ifdef UFS_SUPER_DEBUG_MORE
  640. ufs_print_super_stuff(sb, usb1, usb2, usb3);
  641. #endif
  642. /*
  643.  * Check, if file system was correctly unmounted.
  644.  * If not, make it read only.
  645.  */
  646. if (((flags & UFS_ST_MASK) == UFS_ST_44BSD) ||
  647.   ((flags & UFS_ST_MASK) == UFS_ST_OLD) ||
  648.   (((flags & UFS_ST_MASK) == UFS_ST_SUN || 
  649.   (flags & UFS_ST_MASK) == UFS_ST_SUNx86) && 
  650.   (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time))))) {
  651. switch(usb1->fs_clean) {
  652. case UFS_FSCLEAN:
  653. UFSD(("fs is cleann"))
  654. break;
  655. case UFS_FSSTABLE:
  656. UFSD(("fs is stablen"))
  657. break;
  658. case UFS_FSOSF1:
  659. UFSD(("fs is DEC OSF/1n"))
  660. break;
  661. case UFS_FSACTIVE:
  662. printk("ufs_read_super: fs is activen");
  663. sb->s_flags |= MS_RDONLY;
  664. break;
  665. case UFS_FSBAD:
  666. printk("ufs_read_super: fs is badn");
  667. sb->s_flags |= MS_RDONLY;
  668. break;
  669. default:
  670. printk("ufs_read_super: can't grok fs_clean 0x%xn", usb1->fs_clean);
  671. sb->s_flags |= MS_RDONLY;
  672. break;
  673. }
  674. }
  675. else {
  676. printk("ufs_read_super: fs needs fsckn");
  677. sb->s_flags |= MS_RDONLY;
  678. }
  679. /*
  680.  * Read ufs_super_block into internal data structures
  681.  */
  682. sb->s_blocksize = fs32_to_cpu(sb, usb1->fs_fsize);
  683. sb->s_blocksize_bits = fs32_to_cpu(sb, usb1->fs_fshift);
  684. sb->s_op = &ufs_super_ops;
  685. sb->dq_op = NULL; /***/
  686. sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic);
  687. uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno);
  688. uspi->s_cblkno = fs32_to_cpu(sb, usb1->fs_cblkno);
  689. uspi->s_iblkno = fs32_to_cpu(sb, usb1->fs_iblkno);
  690. uspi->s_dblkno = fs32_to_cpu(sb, usb1->fs_dblkno);
  691. uspi->s_cgoffset = fs32_to_cpu(sb, usb1->fs_cgoffset);
  692. uspi->s_cgmask = fs32_to_cpu(sb, usb1->fs_cgmask);
  693. uspi->s_size = fs32_to_cpu(sb, usb1->fs_size);
  694. uspi->s_dsize = fs32_to_cpu(sb, usb1->fs_dsize);
  695. uspi->s_ncg = fs32_to_cpu(sb, usb1->fs_ncg);
  696. /* s_bsize already set */
  697. /* s_fsize already set */
  698. uspi->s_fpb = fs32_to_cpu(sb, usb1->fs_frag);
  699. uspi->s_minfree = fs32_to_cpu(sb, usb1->fs_minfree);
  700. uspi->s_bmask = fs32_to_cpu(sb, usb1->fs_bmask);
  701. uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
  702. uspi->s_bshift = fs32_to_cpu(sb, usb1->fs_bshift);
  703. uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
  704. uspi->s_fpbshift = fs32_to_cpu(sb, usb1->fs_fragshift);
  705. uspi->s_fsbtodb = fs32_to_cpu(sb, usb1->fs_fsbtodb);
  706. /* s_sbsize already set */
  707. uspi->s_csmask = fs32_to_cpu(sb, usb1->fs_csmask);
  708. uspi->s_csshift = fs32_to_cpu(sb, usb1->fs_csshift);
  709. uspi->s_nindir = fs32_to_cpu(sb, usb1->fs_nindir);
  710. uspi->s_inopb = fs32_to_cpu(sb, usb1->fs_inopb);
  711. uspi->s_nspf = fs32_to_cpu(sb, usb1->fs_nspf);
  712. uspi->s_npsect = ufs_get_fs_npsect(sb, usb1, usb3);
  713. uspi->s_interleave = fs32_to_cpu(sb, usb1->fs_interleave);
  714. uspi->s_trackskew = fs32_to_cpu(sb, usb1->fs_trackskew);
  715. uspi->s_csaddr = fs32_to_cpu(sb, usb1->fs_csaddr);
  716. uspi->s_cssize = fs32_to_cpu(sb, usb1->fs_cssize);
  717. uspi->s_cgsize = fs32_to_cpu(sb, usb1->fs_cgsize);
  718. uspi->s_ntrak = fs32_to_cpu(sb, usb1->fs_ntrak);
  719. uspi->s_nsect = fs32_to_cpu(sb, usb1->fs_nsect);
  720. uspi->s_spc = fs32_to_cpu(sb, usb1->fs_spc);
  721. uspi->s_ipg = fs32_to_cpu(sb, usb1->fs_ipg);
  722. uspi->s_fpg = fs32_to_cpu(sb, usb1->fs_fpg);
  723. uspi->s_cpc = fs32_to_cpu(sb, usb2->fs_cpc);
  724. uspi->s_contigsumsize = fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_contigsumsize);
  725. uspi->s_qbmask = ufs_get_fs_qbmask(sb, usb3);
  726. uspi->s_qfmask = ufs_get_fs_qfmask(sb, usb3);
  727. uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat);
  728. uspi->s_nrpos = fs32_to_cpu(sb, usb3->fs_nrpos);
  729. uspi->s_postbloff = fs32_to_cpu(sb, usb3->fs_postbloff);
  730. uspi->s_rotbloff = fs32_to_cpu(sb, usb3->fs_rotbloff);
  731. /*
  732.  * Compute another frequently used values
  733.  */
  734. uspi->s_fpbmask = uspi->s_fpb - 1;
  735. uspi->s_apbshift = uspi->s_bshift - 2;
  736. uspi->s_2apbshift = uspi->s_apbshift * 2;
  737. uspi->s_3apbshift = uspi->s_apbshift * 3;
  738. uspi->s_apb = 1 << uspi->s_apbshift;
  739. uspi->s_2apb = 1 << uspi->s_2apbshift;
  740. uspi->s_3apb = 1 << uspi->s_3apbshift;
  741. uspi->s_apbmask = uspi->s_apb - 1;
  742. uspi->s_nspfshift = uspi->s_fshift - UFS_SECTOR_BITS;
  743. uspi->s_nspb = uspi->s_nspf << uspi->s_fpbshift;
  744. uspi->s_inopf = uspi->s_inopb >> uspi->s_fpbshift;
  745. uspi->s_bpf = uspi->s_fsize << 3;
  746. uspi->s_bpfshift = uspi->s_fshift + 3;
  747. uspi->s_bpfmask = uspi->s_bpf - 1;
  748. if ((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) ==
  749.     UFS_MOUNT_UFSTYPE_44BSD)
  750. uspi->s_maxsymlinklen =
  751.     fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_maxsymlinklen);
  752. sb->u.ufs_sb.s_flags = flags;
  753. inode = iget(sb, UFS_ROOTINO);
  754. if (!inode || is_bad_inode(inode))
  755. goto failed;
  756. sb->s_root = d_alloc_root(inode);
  757. if (!sb->s_root)
  758. goto dalloc_failed;
  759. /*
  760.  * Read cylinder group structures
  761.  */
  762. if (!(sb->s_flags & MS_RDONLY))
  763. if (!ufs_read_cylinder_structures(sb))
  764. goto failed;
  765. UFSD(("EXITn"))
  766. return(sb);
  767. dalloc_failed:
  768. iput(inode);
  769. failed:
  770. if (ubh) ubh_brelse_uspi (uspi);
  771. if (uspi) kfree (uspi);
  772. UFSD(("EXIT (FAILED)n"))
  773. return(NULL);
  774. }
  775. void ufs_write_super (struct super_block * sb) {
  776. struct ufs_sb_private_info * uspi;
  777. struct ufs_super_block_first * usb1;
  778. struct ufs_super_block_third * usb3;
  779. unsigned flags;
  780. UFSD(("ENTERn"))
  781. flags = sb->u.ufs_sb.s_flags;
  782. uspi = sb->u.ufs_sb.s_uspi;
  783. usb1 = ubh_get_usb_first(USPI_UBH);
  784. usb3 = ubh_get_usb_third(USPI_UBH);
  785. if (!(sb->s_flags & MS_RDONLY)) {
  786. usb1->fs_time = cpu_to_fs32(sb, CURRENT_TIME);
  787. if ((flags & UFS_ST_MASK) == UFS_ST_SUN 
  788.   || (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
  789. ufs_set_fs_state(sb, usb1, usb3,
  790. UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
  791. ubh_mark_buffer_dirty (USPI_UBH);
  792. }
  793. sb->s_dirt = 0;
  794. UFSD(("EXITn"))
  795. }
  796. void ufs_put_super (struct super_block * sb)
  797. {
  798. struct ufs_sb_private_info * uspi;
  799. UFSD(("ENTERn"))
  800. uspi = sb->u.ufs_sb.s_uspi;
  801. if (!(sb->s_flags & MS_RDONLY))
  802. ufs_put_cylinder_structures (sb);
  803. ubh_brelse_uspi (uspi);
  804. kfree (sb->u.ufs_sb.s_uspi);
  805. return;
  806. }
  807. int ufs_remount (struct super_block * sb, int * mount_flags, char * data)
  808. {
  809. struct ufs_sb_private_info * uspi;
  810. struct ufs_super_block_first * usb1;
  811. struct ufs_super_block_third * usb3;
  812. unsigned new_mount_opt, ufstype;
  813. unsigned flags;
  814. uspi = sb->u.ufs_sb.s_uspi;
  815. flags = sb->u.ufs_sb.s_flags;
  816. usb1 = ubh_get_usb_first(USPI_UBH);
  817. usb3 = ubh_get_usb_third(USPI_UBH);
  818. /*
  819.  * Allow the "check" option to be passed as a remount option.
  820.  * It is not possible to change ufstype option during remount
  821.  */
  822. ufstype = sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE;
  823. new_mount_opt = 0;
  824. ufs_set_opt (new_mount_opt, ONERROR_LOCK);
  825. if (!ufs_parse_options (data, &new_mount_opt))
  826. return -EINVAL;
  827. if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) {
  828. new_mount_opt |= ufstype;
  829. }
  830. else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
  831. printk("ufstype can't be changed during remountn");
  832. return -EINVAL;
  833. }
  834. if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
  835. sb->u.ufs_sb.s_mount_opt = new_mount_opt;
  836. return 0;
  837. }
  838. /*
  839.  * fs was mouted as rw, remounting ro
  840.  */
  841. if (*mount_flags & MS_RDONLY) {
  842. ufs_put_cylinder_structures(sb);
  843. usb1->fs_time = cpu_to_fs32(sb, CURRENT_TIME);
  844. if ((flags & UFS_ST_MASK) == UFS_ST_SUN
  845.   || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) 
  846. ufs_set_fs_state(sb, usb1, usb3,
  847. UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
  848. ubh_mark_buffer_dirty (USPI_UBH);
  849. sb->s_dirt = 0;
  850. sb->s_flags |= MS_RDONLY;
  851. }
  852. /*
  853.  * fs was mounted as ro, remounting rw
  854.  */
  855. else {
  856. #ifndef CONFIG_UFS_FS_WRITE
  857. printk("ufs was compiled with read-only support, "
  858. "can't be mounted as read-writen");
  859. return -EINVAL;
  860. #else
  861. if (ufstype != UFS_MOUNT_UFSTYPE_SUN && 
  862.     ufstype != UFS_MOUNT_UFSTYPE_44BSD &&
  863.     ufstype != UFS_MOUNT_UFSTYPE_SUNx86) {
  864. printk("this ufstype is read-only supportedn");
  865. return -EINVAL;
  866. }
  867. if (!ufs_read_cylinder_structures (sb)) {
  868. printk("failed during remountingn");
  869. return -EPERM;
  870. }
  871. sb->s_flags &= ~MS_RDONLY;
  872. #endif
  873. }
  874. sb->u.ufs_sb.s_mount_opt = new_mount_opt;
  875. return 0;
  876. }
  877. int ufs_statfs (struct super_block * sb, struct statfs * buf)
  878. {
  879. struct ufs_sb_private_info * uspi;
  880. struct ufs_super_block_first * usb1;
  881. uspi = sb->u.ufs_sb.s_uspi;
  882. usb1 = ubh_get_usb_first (USPI_UBH);
  883. buf->f_type = UFS_MAGIC;
  884. buf->f_bsize = sb->s_blocksize;
  885. buf->f_blocks = uspi->s_dsize;
  886. buf->f_bfree = ufs_blkstofrags(fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree)) +
  887. fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree);
  888. buf->f_bavail = (buf->f_bfree > ((buf->f_blocks / 100) * uspi->s_minfree))
  889. ? (buf->f_bfree - ((buf->f_blocks / 100) * uspi->s_minfree)) : 0;
  890. buf->f_files = uspi->s_ncg * uspi->s_ipg;
  891. buf->f_ffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree);
  892. buf->f_namelen = UFS_MAXNAMLEN;
  893. return 0;
  894. }
  895. static struct super_operations ufs_super_ops = {
  896. read_inode: ufs_read_inode,
  897. write_inode: ufs_write_inode,
  898. delete_inode: ufs_delete_inode,
  899. put_super: ufs_put_super,
  900. write_super: ufs_write_super,
  901. statfs: ufs_statfs,
  902. remount_fs: ufs_remount,
  903. };
  904. static DECLARE_FSTYPE_DEV(ufs_fs_type, "ufs", ufs_read_super);
  905. static int __init init_ufs_fs(void)
  906. {
  907. return register_filesystem(&ufs_fs_type);
  908. }
  909. static void __exit exit_ufs_fs(void)
  910. {
  911. unregister_filesystem(&ufs_fs_type);
  912. }
  913. EXPORT_NO_SYMBOLS;
  914. module_init(init_ufs_fs)
  915. module_exit(exit_ufs_fs)
  916. MODULE_LICENSE("GPL");