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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/fs/hfs/super.c
  3.  *
  4.  * Copyright (C) 1995-1997  Paul H. Hargrove
  5.  * This file may be distributed under the terms of the GNU General Public License.
  6.  *
  7.  * This file contains hfs_read_super(), some of the super_ops and
  8.  * init_module() and cleanup_module(). The remaining super_ops are in
  9.  * inode.c since they deal with inodes.
  10.  *
  11.  * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds
  12.  *
  13.  * "XXX" in a comment is a note to myself to consider changing something.
  14.  *
  15.  * In function preconditions the term "valid" applied to a pointer to
  16.  * a structure means that the pointer is non-NULL and the structure it
  17.  * points to has all fields initialized to consistent values.
  18.  *
  19.  * The code in this file initializes some structures which contain
  20.  * pointers by calling memset(&foo, 0, sizeof(foo)).
  21.  * This produces the desired behavior only due to the non-ANSI
  22.  * assumption that the machine representation of NULL is all zeros.
  23.  */
  24. #include "hfs.h"
  25. #include <linux/hfs_fs_sb.h>
  26. #include <linux/hfs_fs_i.h>
  27. #include <linux/hfs_fs.h>
  28. #include <linux/config.h> /* for CONFIG_MAC_PARTITION */
  29. #include <linux/blkdev.h>
  30. #include <linux/module.h>
  31. #include <linux/init.h>
  32. MODULE_LICENSE("GPL");
  33. /*================ Forward declarations ================*/
  34. static void hfs_read_inode(struct inode *);
  35. static void hfs_put_super(struct super_block *);
  36. static int hfs_statfs(struct super_block *, struct statfs *);
  37. static void hfs_write_super(struct super_block *);
  38. /*================ Global variables ================*/
  39. static struct super_operations hfs_super_operations = { 
  40. read_inode: hfs_read_inode,
  41. put_inode: hfs_put_inode,
  42. put_super: hfs_put_super,
  43. write_super: hfs_write_super,
  44. statfs: hfs_statfs,
  45. };
  46. /*================ File-local variables ================*/
  47. static DECLARE_FSTYPE_DEV(hfs_fs, "hfs", hfs_read_super);
  48. /*================ File-local functions ================*/
  49. /* 
  50.  * hfs_read_inode()
  51.  *
  52.  * this doesn't actually do much. hfs_iget actually fills in the 
  53.  * necessary inode information.
  54.  */
  55. static void hfs_read_inode(struct inode *inode)
  56. {
  57.   inode->i_mode = 0;
  58. }
  59. /*
  60.  * hfs_write_super()
  61.  *
  62.  * Description:
  63.  *   This function is called by the VFS only. When the filesystem
  64.  *   is mounted r/w it updates the MDB on disk.
  65.  * Input Variable(s):
  66.  *   struct super_block *sb: Pointer to the hfs superblock
  67.  * Output Variable(s):
  68.  *   NONE
  69.  * Returns:
  70.  *   void
  71.  * Preconditions:
  72.  *   'sb' points to a "valid" (struct super_block).
  73.  * Postconditions:
  74.  *   The MDB is marked 'unsuccessfully unmounted' by clearing bit 8 of drAtrb
  75.  *   (hfs_put_super() must set this flag!). Some MDB fields are updated
  76.  *   and the MDB buffer is written to disk by calling hfs_mdb_commit().
  77.  */
  78. static void hfs_write_super(struct super_block *sb)
  79. {
  80. struct hfs_mdb *mdb = HFS_SB(sb)->s_mdb;
  81. /* is this a valid hfs superblock? */
  82. if (!sb || sb->s_magic != HFS_SUPER_MAGIC) {
  83. return;
  84. }
  85. if (!(sb->s_flags & MS_RDONLY)) {
  86. /* sync everything to the buffers */
  87. hfs_mdb_commit(mdb, 0);
  88. }
  89. sb->s_dirt = 0;
  90. }
  91. /*
  92.  * hfs_put_super()
  93.  *
  94.  * This is the put_super() entry in the super_operations structure for
  95.  * HFS filesystems.  The purpose is to release the resources
  96.  * associated with the superblock sb.
  97.  */
  98. static void hfs_put_super(struct super_block *sb)
  99. {
  100. struct hfs_mdb *mdb = HFS_SB(sb)->s_mdb;
  101.  
  102. if (!(sb->s_flags & MS_RDONLY)) {
  103. hfs_mdb_commit(mdb, 0);
  104. sb->s_dirt = 0;
  105. }
  106. /* release the MDB's resources */
  107. hfs_mdb_put(mdb, sb->s_flags & MS_RDONLY);
  108. /* restore default blocksize for the device */
  109. set_blocksize(sb->s_dev, BLOCK_SIZE);
  110. }
  111. /*
  112.  * hfs_statfs()
  113.  *
  114.  * This is the statfs() entry in the super_operations structure for
  115.  * HFS filesystems.  The purpose is to return various data about the
  116.  * filesystem.
  117.  *
  118.  * changed f_files/f_ffree to reflect the fs_ablock/free_ablocks.
  119.  */
  120. static int hfs_statfs(struct super_block *sb, struct statfs *buf)
  121. {
  122. struct hfs_mdb *mdb = HFS_SB(sb)->s_mdb;
  123. buf->f_type = HFS_SUPER_MAGIC;
  124. buf->f_bsize = HFS_SECTOR_SIZE;
  125. buf->f_blocks = mdb->alloc_blksz * mdb->fs_ablocks;
  126. buf->f_bfree = mdb->alloc_blksz * mdb->free_ablocks;
  127. buf->f_bavail = buf->f_bfree;
  128. buf->f_files = mdb->fs_ablocks;  
  129. buf->f_ffree = mdb->free_ablocks;
  130. buf->f_namelen = HFS_NAMELEN;
  131. return 0;
  132. }
  133. /*
  134.  * parse_options()
  135.  * 
  136.  * adapted from linux/fs/msdos/inode.c written 1992,93 by Werner Almesberger
  137.  * This function is called by hfs_read_super() to parse the mount options.
  138.  */
  139. static int parse_options(char *options, struct hfs_sb_info *hsb, int *part)
  140. {
  141. char *this_char, *value;
  142. char names, fork;
  143. /* initialize the sb with defaults */
  144. memset(hsb, 0, sizeof(*hsb));
  145. hsb->magic = HFS_SB_MAGIC;
  146. hsb->s_uid   = current->uid;
  147. hsb->s_gid   = current->gid;
  148. hsb->s_umask = current->fs->umask;
  149. hsb->s_type    = 0x3f3f3f3f; /* == '????' */
  150. hsb->s_creator = 0x3f3f3f3f; /* == '????' */
  151. hsb->s_lowercase = 0;
  152. hsb->s_quiet     = 0;
  153. hsb->s_afpd      = 0;
  154.         /* default version. 0 just selects the defaults */
  155. hsb->s_version   = 0; 
  156. hsb->s_conv = 'b';
  157. names = '?';
  158. fork = '?';
  159. *part = 0;
  160. if (!options) {
  161. goto done;
  162. }
  163. for (this_char = strtok(options,","); this_char;
  164.      this_char = strtok(NULL,",")) {
  165. if ((value = strchr(this_char,'=')) != NULL) {
  166. *value++ = 0;
  167. }
  168. /* Numeric-valued options */
  169. if (!strcmp(this_char, "version")) {
  170. if (!value || !*value) {
  171. return 0;
  172. }
  173. hsb->s_version = simple_strtoul(value,&value,0);
  174. if (*value) {
  175. return 0;
  176. }
  177. } else if (!strcmp(this_char,"uid")) {
  178. if (!value || !*value) {
  179. return 0;
  180. }
  181. hsb->s_uid = simple_strtoul(value,&value,0);
  182. if (*value) {
  183. return 0;
  184. }
  185. } else if (!strcmp(this_char,"gid")) {
  186. if (!value || !*value) {
  187. return 0;
  188. }
  189. hsb->s_gid = simple_strtoul(value,&value,0);
  190. if (*value) {
  191. return 0;
  192. }
  193. } else if (!strcmp(this_char,"umask")) {
  194. if (!value || !*value) {
  195. return 0;
  196. }
  197. hsb->s_umask = simple_strtoul(value,&value,8);
  198. if (*value) {
  199. return 0;
  200. }
  201. } else if (!strcmp(this_char,"part")) {
  202. if (!value || !*value) {
  203. return 0;
  204. }
  205. *part = simple_strtoul(value,&value,0);
  206. if (*value) {
  207. return 0;
  208. }
  209. /* String-valued options */
  210. } else if (!strcmp(this_char,"type") && value) {
  211. if (strlen(value) != 4) {
  212. return 0;
  213. }
  214. hsb->s_type = hfs_get_nl(value);
  215. } else if (!strcmp(this_char,"creator") && value) {
  216. if (strlen(value) != 4) {
  217. return 0;
  218. }
  219. hsb->s_creator = hfs_get_nl(value);
  220. /* Boolean-valued options */
  221. } else if (!strcmp(this_char,"quiet")) {
  222. if (value) {
  223. return 0;
  224. }
  225. hsb->s_quiet = 1;
  226. } else if (!strcmp(this_char,"afpd")) {
  227. if (value) {
  228. return 0;
  229. }
  230. hsb->s_afpd = 1;
  231. /* Multiple choice options */
  232. } else if (!strcmp(this_char,"names") && value) {
  233. if ((*value && !value[1] && strchr("ntal78c",*value)) ||
  234.     !strcmp(value,"netatalk") ||
  235.     !strcmp(value,"trivial") ||
  236.     !strcmp(value,"alpha") ||
  237.     !strcmp(value,"latin") ||
  238.     !strcmp(value,"7bit") ||
  239.     !strcmp(value,"8bit") ||
  240.     !strcmp(value,"cap")) {
  241. names = *value;
  242. } else {
  243. return 0;
  244. }
  245. } else if (!strcmp(this_char,"fork") && value) {
  246. if ((*value && !value[1] && strchr("nsdc",*value)) ||
  247.     !strcmp(value,"netatalk") ||
  248.     !strcmp(value,"single") ||
  249.     !strcmp(value,"double") ||
  250.     !strcmp(value,"cap")) {
  251. fork = *value;
  252. } else {
  253. return 0;
  254. }
  255. } else if (!strcmp(this_char,"case") && value) {
  256. if ((*value && !value[1] && strchr("la",*value)) ||
  257.     !strcmp(value,"lower") ||
  258.     !strcmp(value,"asis")) {
  259. hsb->s_lowercase = (*value == 'l');
  260. } else {
  261. return 0;
  262. }
  263. } else if (!strcmp(this_char,"conv") && value) {
  264. if ((*value && !value[1] && strchr("bta",*value)) ||
  265.     !strcmp(value,"binary") ||
  266.     !strcmp(value,"text") ||
  267.     !strcmp(value,"auto")) {
  268. hsb->s_conv = *value;
  269. } else {
  270. return 0;
  271. }
  272. } else {
  273. return 0;
  274. }
  275. }
  276. done:
  277. /* Parse the "fork" and "names" options */
  278. if (fork == '?') {
  279. fork = hsb->s_afpd ? 'n' : 'c';
  280. }
  281. switch (fork) {
  282. default:
  283. case 'c':
  284. hsb->s_ifill = hfs_cap_ifill;
  285. hsb->s_reserved1 = hfs_cap_reserved1;
  286. hsb->s_reserved2 = hfs_cap_reserved2;
  287. break;
  288. case 's':
  289. hfs_warn("hfs_fs: AppleSingle not yet implemented.n");
  290. return 0;
  291. /* break; */
  292. case 'd':
  293. hsb->s_ifill = hfs_dbl_ifill;
  294. hsb->s_reserved1 = hfs_dbl_reserved1;
  295. hsb->s_reserved2 = hfs_dbl_reserved2;
  296. break;
  297. case 'n':
  298. hsb->s_ifill = hfs_nat_ifill;
  299. hsb->s_reserved1 = hfs_nat_reserved1;
  300. hsb->s_reserved2 = hfs_nat_reserved2;
  301. break;
  302. }
  303. if (names == '?') {
  304. names = fork;
  305. }
  306. switch (names) {
  307. default:
  308. case 'n':
  309. hsb->s_nameout = hfs_colon2mac;
  310. hsb->s_namein = hfs_mac2nat;
  311. break;
  312. case 'c':
  313. hsb->s_nameout = hfs_colon2mac;
  314. hsb->s_namein = hfs_mac2cap;
  315. break;
  316. case 't':
  317. hsb->s_nameout = hfs_triv2mac;
  318. hsb->s_namein = hfs_mac2triv;
  319. break;
  320. case '7':
  321. hsb->s_nameout = hfs_prcnt2mac;
  322. hsb->s_namein = hfs_mac2seven;
  323. break;
  324. case '8':
  325. hsb->s_nameout = hfs_prcnt2mac;
  326. hsb->s_namein = hfs_mac2eight;
  327. break;
  328. case 'l':
  329. hsb->s_nameout = hfs_latin2mac;
  330. hsb->s_namein = hfs_mac2latin;
  331. break;
  332.   case 'a': /* 's' and 'd' are unadvertised aliases for 'alpha', */
  333.   case 's': /* since 'alpha' is the default if fork=s or fork=d. */
  334.   case 'd': /* (It is also helpful for poor typists!)           */
  335. hsb->s_nameout = hfs_prcnt2mac;
  336. hsb->s_namein = hfs_mac2alpha;
  337. break;
  338. }
  339. return 1;
  340. }
  341. /*================ Global functions ================*/
  342. /*
  343.  * hfs_read_super()
  344.  *
  345.  * This is the function that is responsible for mounting an HFS
  346.  * filesystem. It performs all the tasks necessary to get enough data
  347.  * from the disk to read the root inode.  This includes parsing the
  348.  * mount options, dealing with Macintosh partitions, reading the
  349.  * superblock and the allocation bitmap blocks, calling
  350.  * hfs_btree_init() to get the necessary data about the extents and
  351.  * catalog B-trees and, finally, reading the root inode into memory.
  352.  */
  353. struct super_block *hfs_read_super(struct super_block *s, void *data,
  354.    int silent)
  355. {
  356. struct hfs_mdb *mdb;
  357. struct hfs_cat_key key;
  358. kdev_t dev = s->s_dev;
  359. hfs_s32 part_size, part_start;
  360. struct inode *root_inode;
  361. int part;
  362. if (!parse_options((char *)data, HFS_SB(s), &part)) {
  363. hfs_warn("hfs_fs: unable to parse mount options.n");
  364. goto bail3;
  365. }
  366. /* set the device driver to 512-byte blocks */
  367. set_blocksize(dev, HFS_SECTOR_SIZE);
  368. s->s_blocksize_bits = HFS_SECTOR_SIZE_BITS;
  369. s->s_blocksize = HFS_SECTOR_SIZE;
  370. #ifdef CONFIG_MAC_PARTITION
  371. /* check to see if we're in a partition */
  372. mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, 0);
  373. /* erk. try parsing the partition table ourselves */
  374. if (!mdb) {
  375. if (hfs_part_find(s, part, silent, &part_size, &part_start)) {
  376.      goto bail2;
  377.    }
  378.    mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, part_start);
  379. }
  380. #else
  381. if (hfs_part_find(s, part, silent, &part_size, &part_start)) {
  382. goto bail2;
  383. }
  384. mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, part_start);
  385. #endif
  386. if (!mdb) {
  387. if (!silent) {
  388. hfs_warn("VFS: Can't find a HFS filesystem on dev %s.n",
  389.        kdevname(dev));
  390. }
  391. goto bail2;
  392. }
  393. HFS_SB(s)->s_mdb = mdb;
  394. if (HFS_ITYPE(mdb->next_id) != 0) {
  395. hfs_warn("hfs_fs: too many files.n");
  396. goto bail1;
  397. }
  398. s->s_magic = HFS_SUPER_MAGIC;
  399. s->s_op = &hfs_super_operations;
  400. /* try to get the root inode */
  401. hfs_cat_build_key(htonl(HFS_POR_CNID),
  402.   (struct hfs_name *)(mdb->vname), &key);
  403. root_inode = hfs_iget(hfs_cat_get(mdb, &key), HFS_ITYPE_NORM, NULL);
  404. if (!root_inode) 
  405. goto bail_no_root;
  406.   
  407. s->s_root = d_alloc_root(root_inode);
  408. if (!s->s_root) 
  409. goto bail_no_root;
  410. /* fix up pointers. */
  411. HFS_I(root_inode)->entry->sys_entry[HFS_ITYPE_TO_INT(HFS_ITYPE_NORM)] =
  412.   s->s_root;
  413. s->s_root->d_op = &hfs_dentry_operations;
  414. /* everything's okay */
  415. return s;
  416. bail_no_root: 
  417. hfs_warn("hfs_fs: get root inode failed.n");
  418. iput(root_inode);
  419. bail1:
  420. hfs_mdb_put(mdb, s->s_flags & MS_RDONLY);
  421. bail2:
  422. set_blocksize(dev, BLOCK_SIZE);
  423. bail3:
  424. return NULL;
  425. }
  426. static int __init init_hfs_fs(void)
  427. {
  428.         hfs_cat_init();
  429. return register_filesystem(&hfs_fs);
  430. }
  431. static void __exit exit_hfs_fs(void) {
  432. hfs_cat_free();
  433. unregister_filesystem(&hfs_fs);
  434. }
  435. module_init(init_hfs_fs)
  436. module_exit(exit_hfs_fs)
  437. #if defined(DEBUG_ALL) || defined(DEBUG_MEM)
  438. long int hfs_alloc = 0;
  439. #endif