super.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:30k
源码类别:

嵌入式Linux

开发平台:

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. set_blocksize (sb->s_dev, block_size);
  549. sb->s_blocksize = block_size;
  550. /*
  551.  * read ufs super block from device
  552.  */
  553. ubh = ubh_bread_uspi (uspi, sb, uspi->s_sbbase + UFS_SBLOCK/block_size, super_block_size);
  554. if (!ubh) 
  555. goto failed;
  556. usb1 = ubh_get_usb_first(USPI_UBH);
  557. usb2 = ubh_get_usb_second(USPI_UBH);
  558. usb3 = ubh_get_usb_third(USPI_UBH);
  559. /*
  560.  * Check ufs magic number
  561.  */
  562. switch (__constant_le32_to_cpu(usb3->fs_magic)) {
  563. case UFS_MAGIC:
  564. case UFS_MAGIC_LFN:
  565.         case UFS_MAGIC_FEA:
  566.         case UFS_MAGIC_4GB:
  567. sb->u.ufs_sb.s_bytesex = BYTESEX_LE;
  568. goto magic_found;
  569. }
  570. switch (__constant_be32_to_cpu(usb3->fs_magic)) {
  571. case UFS_MAGIC:
  572. case UFS_MAGIC_LFN:
  573.         case UFS_MAGIC_FEA:
  574.         case UFS_MAGIC_4GB:
  575. sb->u.ufs_sb.s_bytesex = BYTESEX_BE;
  576. goto magic_found;
  577. }
  578. if ((((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP) 
  579.   || ((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP_CD) 
  580.   || ((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_OPENSTEP)) 
  581.   && uspi->s_sbbase < 256) {
  582. ubh_brelse_uspi(uspi);
  583. ubh = NULL;
  584. uspi->s_sbbase += 8;
  585. goto again;
  586. }
  587. printk("ufs_read_super: bad magic numbern");
  588. goto failed;
  589. magic_found:
  590. /*
  591.  * Check block and fragment sizes
  592.  */
  593. uspi->s_bsize = fs32_to_cpu(sb, usb1->fs_bsize);
  594. uspi->s_fsize = fs32_to_cpu(sb, usb1->fs_fsize);
  595. uspi->s_sbsize = fs32_to_cpu(sb, usb1->fs_sbsize);
  596. uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
  597. uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
  598. if (uspi->s_bsize != 4096 && uspi->s_bsize != 8192 
  599.   && uspi->s_bsize != 32768) {
  600. printk("ufs_read_super: fs_bsize %u != {4096, 8192, 32768}n", uspi->s_bsize);
  601. goto failed;
  602. }
  603. if (uspi->s_fsize != 512 && uspi->s_fsize != 1024 
  604.   && uspi->s_fsize != 2048 && uspi->s_fsize != 4096) {
  605. printk("ufs_read_super: fs_fsize %u != {512, 1024, 2048. 4096}n", uspi->s_fsize);
  606. goto failed;
  607. }
  608. if (uspi->s_fsize != block_size || uspi->s_sbsize != super_block_size) {
  609. ubh_brelse_uspi(uspi);
  610. ubh = NULL;
  611. block_size = uspi->s_fsize;
  612. super_block_size = uspi->s_sbsize;
  613. UFSD(("another value of block_size or super_block_size %u, %un", block_size, super_block_size))
  614. goto again;
  615. }
  616. #ifdef UFS_SUPER_DEBUG_MORE
  617. ufs_print_super_stuff(sb, usb1, usb2, usb3);
  618. #endif
  619. /*
  620.  * Check, if file system was correctly unmounted.
  621.  * If not, make it read only.
  622.  */
  623. if (((flags & UFS_ST_MASK) == UFS_ST_44BSD) ||
  624.   ((flags & UFS_ST_MASK) == UFS_ST_OLD) ||
  625.   (((flags & UFS_ST_MASK) == UFS_ST_SUN || 
  626.   (flags & UFS_ST_MASK) == UFS_ST_SUNx86) && 
  627.   (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time))))) {
  628. switch(usb1->fs_clean) {
  629. case UFS_FSCLEAN:
  630. UFSD(("fs is cleann"))
  631. break;
  632. case UFS_FSSTABLE:
  633. UFSD(("fs is stablen"))
  634. break;
  635. case UFS_FSOSF1:
  636. UFSD(("fs is DEC OSF/1n"))
  637. break;
  638. case UFS_FSACTIVE:
  639. printk("ufs_read_super: fs is activen");
  640. sb->s_flags |= MS_RDONLY;
  641. break;
  642. case UFS_FSBAD:
  643. printk("ufs_read_super: fs is badn");
  644. sb->s_flags |= MS_RDONLY;
  645. break;
  646. default:
  647. printk("ufs_read_super: can't grok fs_clean 0x%xn", usb1->fs_clean);
  648. sb->s_flags |= MS_RDONLY;
  649. break;
  650. }
  651. }
  652. else {
  653. printk("ufs_read_super: fs needs fsckn");
  654. sb->s_flags |= MS_RDONLY;
  655. }
  656. /*
  657.  * Read ufs_super_block into internal data structures
  658.  */
  659. sb->s_blocksize = fs32_to_cpu(sb, usb1->fs_fsize);
  660. sb->s_blocksize_bits = fs32_to_cpu(sb, usb1->fs_fshift);
  661. sb->s_op = &ufs_super_ops;
  662. sb->dq_op = NULL; /***/
  663. sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic);
  664. uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno);
  665. uspi->s_cblkno = fs32_to_cpu(sb, usb1->fs_cblkno);
  666. uspi->s_iblkno = fs32_to_cpu(sb, usb1->fs_iblkno);
  667. uspi->s_dblkno = fs32_to_cpu(sb, usb1->fs_dblkno);
  668. uspi->s_cgoffset = fs32_to_cpu(sb, usb1->fs_cgoffset);
  669. uspi->s_cgmask = fs32_to_cpu(sb, usb1->fs_cgmask);
  670. uspi->s_size = fs32_to_cpu(sb, usb1->fs_size);
  671. uspi->s_dsize = fs32_to_cpu(sb, usb1->fs_dsize);
  672. uspi->s_ncg = fs32_to_cpu(sb, usb1->fs_ncg);
  673. /* s_bsize already set */
  674. /* s_fsize already set */
  675. uspi->s_fpb = fs32_to_cpu(sb, usb1->fs_frag);
  676. uspi->s_minfree = fs32_to_cpu(sb, usb1->fs_minfree);
  677. uspi->s_bmask = fs32_to_cpu(sb, usb1->fs_bmask);
  678. uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
  679. uspi->s_bshift = fs32_to_cpu(sb, usb1->fs_bshift);
  680. uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
  681. uspi->s_fpbshift = fs32_to_cpu(sb, usb1->fs_fragshift);
  682. uspi->s_fsbtodb = fs32_to_cpu(sb, usb1->fs_fsbtodb);
  683. /* s_sbsize already set */
  684. uspi->s_csmask = fs32_to_cpu(sb, usb1->fs_csmask);
  685. uspi->s_csshift = fs32_to_cpu(sb, usb1->fs_csshift);
  686. uspi->s_nindir = fs32_to_cpu(sb, usb1->fs_nindir);
  687. uspi->s_inopb = fs32_to_cpu(sb, usb1->fs_inopb);
  688. uspi->s_nspf = fs32_to_cpu(sb, usb1->fs_nspf);
  689. uspi->s_npsect = ufs_get_fs_npsect(sb, usb1, usb3);
  690. uspi->s_interleave = fs32_to_cpu(sb, usb1->fs_interleave);
  691. uspi->s_trackskew = fs32_to_cpu(sb, usb1->fs_trackskew);
  692. uspi->s_csaddr = fs32_to_cpu(sb, usb1->fs_csaddr);
  693. uspi->s_cssize = fs32_to_cpu(sb, usb1->fs_cssize);
  694. uspi->s_cgsize = fs32_to_cpu(sb, usb1->fs_cgsize);
  695. uspi->s_ntrak = fs32_to_cpu(sb, usb1->fs_ntrak);
  696. uspi->s_nsect = fs32_to_cpu(sb, usb1->fs_nsect);
  697. uspi->s_spc = fs32_to_cpu(sb, usb1->fs_spc);
  698. uspi->s_ipg = fs32_to_cpu(sb, usb1->fs_ipg);
  699. uspi->s_fpg = fs32_to_cpu(sb, usb1->fs_fpg);
  700. uspi->s_cpc = fs32_to_cpu(sb, usb2->fs_cpc);
  701. uspi->s_contigsumsize = fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_contigsumsize);
  702. uspi->s_qbmask = ufs_get_fs_qbmask(sb, usb3);
  703. uspi->s_qfmask = ufs_get_fs_qfmask(sb, usb3);
  704. uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat);
  705. uspi->s_nrpos = fs32_to_cpu(sb, usb3->fs_nrpos);
  706. uspi->s_postbloff = fs32_to_cpu(sb, usb3->fs_postbloff);
  707. uspi->s_rotbloff = fs32_to_cpu(sb, usb3->fs_rotbloff);
  708. /*
  709.  * Compute another frequently used values
  710.  */
  711. uspi->s_fpbmask = uspi->s_fpb - 1;
  712. uspi->s_apbshift = uspi->s_bshift - 2;
  713. uspi->s_2apbshift = uspi->s_apbshift * 2;
  714. uspi->s_3apbshift = uspi->s_apbshift * 3;
  715. uspi->s_apb = 1 << uspi->s_apbshift;
  716. uspi->s_2apb = 1 << uspi->s_2apbshift;
  717. uspi->s_3apb = 1 << uspi->s_3apbshift;
  718. uspi->s_apbmask = uspi->s_apb - 1;
  719. uspi->s_nspfshift = uspi->s_fshift - UFS_SECTOR_BITS;
  720. uspi->s_nspb = uspi->s_nspf << uspi->s_fpbshift;
  721. uspi->s_inopf = uspi->s_inopb >> uspi->s_fpbshift;
  722. uspi->s_bpf = uspi->s_fsize << 3;
  723. uspi->s_bpfshift = uspi->s_fshift + 3;
  724. uspi->s_bpfmask = uspi->s_bpf - 1;
  725. if ((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) ==
  726.     UFS_MOUNT_UFSTYPE_44BSD)
  727. uspi->s_maxsymlinklen =
  728.     fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_maxsymlinklen);
  729. sb->u.ufs_sb.s_flags = flags;
  730. inode = iget(sb, UFS_ROOTINO);
  731. if (!inode || is_bad_inode(inode))
  732. goto failed;
  733. sb->s_root = d_alloc_root(inode);
  734. if (!sb->s_root)
  735. goto dalloc_failed;
  736. /*
  737.  * Read cylinder group structures
  738.  */
  739. if (!(sb->s_flags & MS_RDONLY))
  740. if (!ufs_read_cylinder_structures(sb))
  741. goto failed;
  742. UFSD(("EXITn"))
  743. return(sb);
  744. dalloc_failed:
  745. iput(inode);
  746. failed:
  747. if (ubh) ubh_brelse_uspi (uspi);
  748. if (uspi) kfree (uspi);
  749. UFSD(("EXIT (FAILED)n"))
  750. return(NULL);
  751. }
  752. void ufs_write_super (struct super_block * sb) {
  753. struct ufs_sb_private_info * uspi;
  754. struct ufs_super_block_first * usb1;
  755. struct ufs_super_block_third * usb3;
  756. unsigned flags;
  757. UFSD(("ENTERn"))
  758. flags = sb->u.ufs_sb.s_flags;
  759. uspi = sb->u.ufs_sb.s_uspi;
  760. usb1 = ubh_get_usb_first(USPI_UBH);
  761. usb3 = ubh_get_usb_third(USPI_UBH);
  762. if (!(sb->s_flags & MS_RDONLY)) {
  763. usb1->fs_time = cpu_to_fs32(sb, CURRENT_TIME);
  764. if ((flags & UFS_ST_MASK) == UFS_ST_SUN 
  765.   || (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
  766. ufs_set_fs_state(sb, usb1, usb3,
  767. UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
  768. ubh_mark_buffer_dirty (USPI_UBH);
  769. }
  770. sb->s_dirt = 0;
  771. UFSD(("EXITn"))
  772. }
  773. void ufs_put_super (struct super_block * sb)
  774. {
  775. struct ufs_sb_private_info * uspi;
  776. UFSD(("ENTERn"))
  777. uspi = sb->u.ufs_sb.s_uspi;
  778. if (!(sb->s_flags & MS_RDONLY))
  779. ufs_put_cylinder_structures (sb);
  780. ubh_brelse_uspi (uspi);
  781. kfree (sb->u.ufs_sb.s_uspi);
  782. return;
  783. }
  784. int ufs_remount (struct super_block * sb, int * mount_flags, char * data)
  785. {
  786. struct ufs_sb_private_info * uspi;
  787. struct ufs_super_block_first * usb1;
  788. struct ufs_super_block_third * usb3;
  789. unsigned new_mount_opt, ufstype;
  790. unsigned flags;
  791. uspi = sb->u.ufs_sb.s_uspi;
  792. flags = sb->u.ufs_sb.s_flags;
  793. usb1 = ubh_get_usb_first(USPI_UBH);
  794. usb3 = ubh_get_usb_third(USPI_UBH);
  795. /*
  796.  * Allow the "check" option to be passed as a remount option.
  797.  * It is not possible to change ufstype option during remount
  798.  */
  799. ufstype = sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE;
  800. new_mount_opt = 0;
  801. ufs_set_opt (new_mount_opt, ONERROR_LOCK);
  802. if (!ufs_parse_options (data, &new_mount_opt))
  803. return -EINVAL;
  804. if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) {
  805. new_mount_opt |= ufstype;
  806. }
  807. else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
  808. printk("ufstype can't be changed during remountn");
  809. return -EINVAL;
  810. }
  811. if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
  812. sb->u.ufs_sb.s_mount_opt = new_mount_opt;
  813. return 0;
  814. }
  815. /*
  816.  * fs was mouted as rw, remounting ro
  817.  */
  818. if (*mount_flags & MS_RDONLY) {
  819. ufs_put_cylinder_structures(sb);
  820. usb1->fs_time = cpu_to_fs32(sb, CURRENT_TIME);
  821. if ((flags & UFS_ST_MASK) == UFS_ST_SUN
  822.   || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) 
  823. ufs_set_fs_state(sb, usb1, usb3,
  824. UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
  825. ubh_mark_buffer_dirty (USPI_UBH);
  826. sb->s_dirt = 0;
  827. sb->s_flags |= MS_RDONLY;
  828. }
  829. /*
  830.  * fs was mounted as ro, remounting rw
  831.  */
  832. else {
  833. #ifndef CONFIG_UFS_FS_WRITE
  834. printk("ufs was compiled with read-only support, "
  835. "can't be mounted as read-writen");
  836. return -EINVAL;
  837. #else
  838. if (ufstype != UFS_MOUNT_UFSTYPE_SUN && 
  839.     ufstype != UFS_MOUNT_UFSTYPE_44BSD &&
  840.     ufstype != UFS_MOUNT_UFSTYPE_SUNx86) {
  841. printk("this ufstype is read-only supportedn");
  842. return -EINVAL;
  843. }
  844. if (!ufs_read_cylinder_structures (sb)) {
  845. printk("failed during remountingn");
  846. return -EPERM;
  847. }
  848. sb->s_flags &= ~MS_RDONLY;
  849. #endif
  850. }
  851. sb->u.ufs_sb.s_mount_opt = new_mount_opt;
  852. return 0;
  853. }
  854. int ufs_statfs (struct super_block * sb, struct statfs * buf)
  855. {
  856. struct ufs_sb_private_info * uspi;
  857. struct ufs_super_block_first * usb1;
  858. uspi = sb->u.ufs_sb.s_uspi;
  859. usb1 = ubh_get_usb_first (USPI_UBH);
  860. buf->f_type = UFS_MAGIC;
  861. buf->f_bsize = sb->s_blocksize;
  862. buf->f_blocks = uspi->s_dsize;
  863. buf->f_bfree = ufs_blkstofrags(fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree)) +
  864. fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree);
  865. buf->f_bavail = (buf->f_bfree > ((buf->f_blocks / 100) * uspi->s_minfree))
  866. ? (buf->f_bfree - ((buf->f_blocks / 100) * uspi->s_minfree)) : 0;
  867. buf->f_files = uspi->s_ncg * uspi->s_ipg;
  868. buf->f_ffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree);
  869. buf->f_namelen = UFS_MAXNAMLEN;
  870. return 0;
  871. }
  872. static struct super_operations ufs_super_ops = {
  873. read_inode: ufs_read_inode,
  874. write_inode: ufs_write_inode,
  875. delete_inode: ufs_delete_inode,
  876. put_super: ufs_put_super,
  877. write_super: ufs_write_super,
  878. statfs: ufs_statfs,
  879. remount_fs: ufs_remount,
  880. };
  881. static DECLARE_FSTYPE_DEV(ufs_fs_type, "ufs", ufs_read_super);
  882. static int __init init_ufs_fs(void)
  883. {
  884. return register_filesystem(&ufs_fs_type);
  885. }
  886. static void __exit exit_ufs_fs(void)
  887. {
  888. unregister_filesystem(&ufs_fs_type);
  889. }
  890. EXPORT_NO_SYMBOLS;
  891. module_init(init_ufs_fs)
  892. module_exit(exit_ufs_fs)
  893. MODULE_LICENSE("GPL");