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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * QNX4 file system, Linux implementation.
  3.  *
  4.  * Version : 0.2.1
  5.  *
  6.  * Using parts of the xiafs filesystem.
  7.  *
  8.  * History :
  9.  *
  10.  * 01-06-1998 by Richard Frowijn : first release.
  11.  * 20-06-1998 by Frank Denis : Linux 2.1.99+ support, boot signature, misc.
  12.  * 30-06-1998 by Frank Denis : first step to write inodes.
  13.  */
  14. #include <linux/config.h>
  15. #include <linux/module.h>
  16. #include <linux/types.h>
  17. #include <linux/string.h>
  18. #include <linux/errno.h>
  19. #include <linux/slab.h>
  20. #include <linux/qnx4_fs.h>
  21. #include <linux/fs.h>
  22. #include <linux/locks.h>
  23. #include <linux/init.h>
  24. #include <linux/highuid.h>
  25. #include <linux/smp_lock.h>
  26. #include <asm/uaccess.h>
  27. #define QNX4_VERSION  4
  28. #define QNX4_BMNAME   ".bitmap"
  29. static struct super_operations qnx4_sops;
  30. #ifdef CONFIG_QNX4FS_RW
  31. int qnx4_sync_inode(struct inode *inode)
  32. {
  33. int err = 0;
  34. # if 0
  35. struct buffer_head *bh;
  36.     bh = qnx4_update_inode(inode);
  37. if (bh && buffer_dirty(bh))
  38. {
  39. ll_rw_block(WRITE, 1, &bh);
  40. wait_on_buffer(bh);
  41. if (buffer_req(bh) && !buffer_uptodate(bh))
  42. {
  43. printk ("IO error syncing qnx4 inode [%s:%08lx]n",
  44. kdevname(inode->i_dev), inode->i_ino);
  45. err = -1;
  46. }
  47.         brelse (bh);
  48. } else if (!bh) {
  49. err = -1;
  50. }
  51. # endif
  52. return err;
  53. }
  54. static void qnx4_delete_inode(struct inode *inode)
  55. {
  56. QNX4DEBUG(("qnx4: deleting inode [%lu]n", (unsigned long) inode->i_ino));
  57. lock_kernel();
  58. inode->i_size = 0;
  59. qnx4_truncate(inode);
  60. qnx4_free_inode(inode);
  61. unlock_kernel();
  62. }
  63. static void qnx4_write_super(struct super_block *sb)
  64. {
  65. QNX4DEBUG(("qnx4: write_supern"));
  66. sb->s_dirt = 0;
  67. }
  68. static void qnx4_write_inode(struct inode *inode, int unused)
  69. {
  70. struct qnx4_inode_entry *raw_inode;
  71. int block, ino;
  72. struct buffer_head *bh;
  73. ino = inode->i_ino;
  74. QNX4DEBUG(("qnx4: write inode 1.n"));
  75. if (inode->i_nlink == 0) {
  76. return;
  77. }
  78. if (!ino) {
  79. printk("qnx4: bad inode number on dev %s: %d is out of rangen",
  80.        kdevname(inode->i_dev), ino);
  81. return;
  82. }
  83. QNX4DEBUG(("qnx4: write inode 2.n"));
  84. block = ino / QNX4_INODES_PER_BLOCK;
  85. lock_kernel();
  86. if (!(bh = sb_bread(inode->i_sb, block))) {
  87. printk("qnx4: major problem: unable to read inode from dev "
  88.        "%sn", kdevname(inode->i_dev));
  89. unlock_kernel();
  90. return;
  91. }
  92. raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
  93.     (ino % QNX4_INODES_PER_BLOCK);
  94. raw_inode->di_mode  = cpu_to_le16(inode->i_mode);
  95. raw_inode->di_uid   = cpu_to_le16(fs_high2lowuid(inode->i_uid));
  96. raw_inode->di_gid   = cpu_to_le16(fs_high2lowgid(inode->i_gid));
  97. raw_inode->di_nlink = cpu_to_le16(inode->i_nlink);
  98. raw_inode->di_size  = cpu_to_le32(inode->i_size);
  99. raw_inode->di_mtime = cpu_to_le32(inode->i_mtime);
  100. raw_inode->di_atime = cpu_to_le32(inode->i_atime);
  101. raw_inode->di_ctime = cpu_to_le32(inode->i_ctime);
  102. raw_inode->di_first_xtnt.xtnt_size = cpu_to_le32(inode->i_blocks);
  103. mark_buffer_dirty(bh);
  104. brelse(bh);
  105. unlock_kernel();
  106. }
  107. #endif
  108. static struct super_block *qnx4_read_super(struct super_block *, void *, int);
  109. static void qnx4_put_super(struct super_block *sb);
  110. static void qnx4_read_inode(struct inode *);
  111. static int qnx4_remount(struct super_block *sb, int *flags, char *data);
  112. static int qnx4_statfs(struct super_block *, struct statfs *);
  113. static struct super_operations qnx4_sops =
  114. {
  115. read_inode: qnx4_read_inode,
  116. #ifdef CONFIG_QNX4FS_RW
  117. write_inode: qnx4_write_inode,
  118. delete_inode: qnx4_delete_inode,
  119. #endif
  120. put_super: qnx4_put_super,
  121. #ifdef CONFIG_QNX4FS_RW
  122. write_super: qnx4_write_super,
  123. #endif
  124. statfs: qnx4_statfs,
  125. remount_fs: qnx4_remount,
  126. };
  127. static int qnx4_remount(struct super_block *sb, int *flags, char *data)
  128. {
  129. struct qnx4_sb_info *qs;
  130. qs = &sb->u.qnx4_sb;
  131. qs->Version = QNX4_VERSION;
  132. if (*flags & MS_RDONLY) {
  133. return 0;
  134. }
  135. mark_buffer_dirty(qs->sb_buf);
  136. return 0;
  137. }
  138. struct buffer_head *qnx4_getblk(struct inode *inode, int nr,
  139.  int create)
  140. {
  141. struct buffer_head *result = NULL;
  142. if ( nr >= 0 )
  143. nr = qnx4_block_map( inode, nr );
  144. if (nr) {
  145. result = sb_getblk(inode->i_sb, nr);
  146. return result;
  147. }
  148. if (!create) {
  149. return NULL;
  150. }
  151. #if 0
  152. tmp = qnx4_new_block(inode->i_sb);
  153. if (!tmp) {
  154. return NULL;
  155. }
  156. result = sb_getblk(inode->i_sb, tmp);
  157. if (tst) {
  158. qnx4_free_block(inode->i_sb, tmp);
  159. brelse(result);
  160. goto repeat;
  161. }
  162. tst = tmp;
  163. #endif
  164. inode->i_ctime = CURRENT_TIME;
  165. mark_inode_dirty(inode);
  166. return result;
  167. }
  168. struct buffer_head *qnx4_bread(struct inode *inode, int block, int create)
  169. {
  170. struct buffer_head *bh;
  171. bh = qnx4_getblk(inode, block, create);
  172. if (!bh || buffer_uptodate(bh)) {
  173. return bh;
  174. }
  175. ll_rw_block(READ, 1, &bh);
  176. wait_on_buffer(bh);
  177. if (buffer_uptodate(bh)) {
  178. return bh;
  179. }
  180. brelse(bh);
  181. return NULL;
  182. }
  183. int qnx4_get_block( struct inode *inode, long iblock, struct buffer_head *bh, int create )
  184. {
  185. unsigned long phys;
  186. QNX4DEBUG(("qnx4: qnx4_get_block inode=[%ld] iblock=[%ld]n",inode->i_ino,iblock));
  187. phys = qnx4_block_map( inode, iblock );
  188. if ( phys ) {
  189. // logical block is before EOF
  190. bh->b_dev     = inode->i_dev;
  191. bh->b_blocknr = phys;
  192. bh->b_state  |= (1UL << BH_Mapped);
  193. } else if ( create ) {
  194. // to be done.
  195. }
  196. return 0;
  197. }
  198. unsigned long qnx4_block_map( struct inode *inode, long iblock )
  199. {
  200. int ix;
  201. long offset, i_xblk;
  202. unsigned long block = 0;
  203. struct buffer_head *bh = 0;
  204. struct qnx4_xblk *xblk = 0;
  205. struct qnx4_inode_info *qnx4_inode = &inode->u.qnx4_i;
  206. qnx4_nxtnt_t nxtnt = le16_to_cpu(qnx4_inode->i_num_xtnts);
  207. if ( iblock < le32_to_cpu(qnx4_inode->i_first_xtnt.xtnt_size) ) {
  208. // iblock is in the first extent. This is easy.
  209. block = le32_to_cpu(qnx4_inode->i_first_xtnt.xtnt_blk) + iblock - 1;
  210. } else {
  211. // iblock is beyond first extent. We have to follow the extent chain.
  212. i_xblk = le32_to_cpu(qnx4_inode->i_xblk);
  213. offset = iblock - le32_to_cpu(qnx4_inode->i_first_xtnt.xtnt_size);
  214. ix = 0;
  215. while ( --nxtnt > 0 ) {
  216. if ( ix == 0 ) {
  217. // read next xtnt block.
  218. bh = sb_bread(inode->i_sb, i_xblk - 1);
  219. if ( !bh ) {
  220. QNX4DEBUG(("qnx4: I/O error reading xtnt block [%ld])n", i_xblk - 1));
  221. return -EIO;
  222. }
  223. xblk = (struct qnx4_xblk*)bh->b_data;
  224. if ( memcmp( xblk->xblk_signature, "IamXblk", 7 ) ) {
  225. QNX4DEBUG(("qnx4: block at %ld is not a valid xtntn", qnx4_inode->i_xblk));
  226. return -EIO;
  227. }
  228. }
  229. if ( offset < le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size) ) {
  230. // got it!
  231. block = le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_blk) + offset - 1;
  232. break;
  233. }
  234. offset -= le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size);
  235. if ( ++ix >= xblk->xblk_num_xtnts ) {
  236. i_xblk = le32_to_cpu(xblk->xblk_next_xblk);
  237. ix = 0;
  238. brelse( bh );
  239. bh = 0;
  240. }
  241. }
  242. if ( bh )
  243. brelse( bh );
  244. }
  245. QNX4DEBUG(("qnx4: mapping block %ld of inode %ld = %ldn",iblock,inode->i_ino,block));
  246. return block;
  247. }
  248. static int qnx4_statfs(struct super_block *sb, struct statfs *buf)
  249. {
  250. buf->f_type    = sb->s_magic;
  251. buf->f_bsize   = sb->s_blocksize;
  252. buf->f_blocks  = le32_to_cpu(sb->u.qnx4_sb.BitMap->di_size) * 8;
  253. buf->f_bfree   = qnx4_count_free_blocks(sb);
  254. buf->f_bavail  = buf->f_bfree;
  255. buf->f_namelen = QNX4_NAME_MAX;
  256. return 0;
  257. }
  258. /*
  259.  * Check the root directory of the filesystem to make sure
  260.  * it really _is_ a qnx4 filesystem, and to check the size
  261.  * of the directory entry.
  262.  */
  263. static const char *qnx4_checkroot(struct super_block *sb)
  264. {
  265. struct buffer_head *bh;
  266. struct qnx4_inode_entry *rootdir;
  267. int rd, rl;
  268. int i, j;
  269. int found = 0;
  270. if (*(sb->u.qnx4_sb.sb->RootDir.di_fname) != '/') {
  271. return "no qnx4 filesystem (no root dir).";
  272. } else {
  273. QNX4DEBUG(("QNX4 filesystem found on dev %s.n", kdevname(sb->s_dev)));
  274. rd = le32_to_cpu(sb->u.qnx4_sb.sb->RootDir.di_first_xtnt.xtnt_blk) - 1;
  275. rl = le32_to_cpu(sb->u.qnx4_sb.sb->RootDir.di_first_xtnt.xtnt_size);
  276. for (j = 0; j < rl; j++) {
  277. bh = sb_bread(sb, rd + j); /* root dir, first block */
  278. if (bh == NULL) {
  279. return "unable to read root entry.";
  280. }
  281. for (i = 0; i < QNX4_INODES_PER_BLOCK; i++) {
  282. rootdir = (struct qnx4_inode_entry *) (bh->b_data + i * QNX4_DIR_ENTRY_SIZE);
  283. if (rootdir->di_fname != NULL) {
  284. QNX4DEBUG(("Rootdir entry found : [%s]n", rootdir->di_fname));
  285. if (!strncmp(rootdir->di_fname, QNX4_BMNAME, sizeof QNX4_BMNAME)) {
  286. found = 1;
  287. sb->u.qnx4_sb.BitMap = kmalloc( sizeof( struct qnx4_inode_entry ), GFP_KERNEL );
  288. if (!sb->u.qnx4_sb.BitMap) {
  289. brelse (bh);
  290. return "not enough memory for bitmap inode";
  291. }
  292. memcpy( sb->u.qnx4_sb.BitMap, rootdir, sizeof( struct qnx4_inode_entry ) ); /* keep bitmap inode known */
  293. break;
  294. }
  295. }
  296. }
  297. brelse(bh);
  298. if (found != 0) {
  299. break;
  300. }
  301. }
  302. if (found == 0) {
  303. return "bitmap file not found.";
  304. }
  305. }
  306. return NULL;
  307. }
  308. static struct super_block *qnx4_read_super(struct super_block *s,
  309.    void *data, int silent)
  310. {
  311. struct buffer_head *bh;
  312. kdev_t dev = s->s_dev;
  313. struct inode *root;
  314. const char *errmsg;
  315. set_blocksize(dev, QNX4_BLOCK_SIZE);
  316. s->s_blocksize = QNX4_BLOCK_SIZE;
  317. s->s_blocksize_bits = QNX4_BLOCK_SIZE_BITS;
  318. /* Check the boot signature. Since the qnx4 code is
  319.    dangerous, we should leave as quickly as possible
  320.    if we don't belong here... */
  321. bh = sb_bread(s, 0);
  322. if (!bh) {
  323. printk("qnx4: unable to read the boot sectorn");
  324. goto outnobh;
  325. }
  326. if ( memcmp( (char*)bh->b_data + 4, "QNX4FS", 6 ) ) {
  327. if (!silent)
  328. printk("qnx4: wrong fsid in boot sector.n");
  329. goto out;
  330. }
  331. brelse(bh);
  332. bh = sb_bread(s, 1);
  333. if (!bh) {
  334. printk("qnx4: unable to read the superblockn");
  335. goto outnobh;
  336. }
  337. s->s_op = &qnx4_sops;
  338. s->s_magic = QNX4_SUPER_MAGIC;
  339. #ifndef CONFIG_QNX4FS_RW
  340. s->s_flags |= MS_RDONLY; /* Yup, read-only yet */
  341. #endif
  342. s->u.qnx4_sb.sb_buf = bh;
  343. s->u.qnx4_sb.sb = (struct qnx4_super_block *) bh->b_data;
  344.   /* check before allocating dentries, inodes, .. */
  345. errmsg = qnx4_checkroot(s);
  346. if (errmsg != NULL) {
  347.   if (!silent)
  348.   printk("qnx4: %sn", errmsg);
  349. goto out;
  350. }
  351.   /* does root not have inode number QNX4_ROOT_INO ?? */
  352.   root = iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK);
  353.   if (!root) {
  354.   printk("qnx4: get inode failedn");
  355.   goto out;
  356.   }
  357.   s->s_root = d_alloc_root(root);
  358.   if (s->s_root == NULL)
  359.   goto outi;
  360. brelse(bh);
  361. return s;
  362.       outi:
  363. iput(root);
  364.       out:
  365. brelse(bh);
  366.       outnobh:
  367. return NULL;
  368. }
  369. static void qnx4_put_super(struct super_block *sb)
  370. {
  371. kfree( sb->u.qnx4_sb.BitMap );
  372. return;
  373. }
  374. static int qnx4_writepage(struct page *page)
  375. {
  376. return block_write_full_page(page,qnx4_get_block);
  377. }
  378. static int qnx4_readpage(struct file *file, struct page *page)
  379. {
  380. return block_read_full_page(page,qnx4_get_block);
  381. }
  382. static int qnx4_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
  383. {
  384. return cont_prepare_write(page,from,to,qnx4_get_block,
  385. &page->mapping->host->u.qnx4_i.mmu_private);
  386. }
  387. static int qnx4_bmap(struct address_space *mapping, long block)
  388. {
  389. return generic_block_bmap(mapping,block,qnx4_get_block);
  390. }
  391. struct address_space_operations qnx4_aops = {
  392. readpage: qnx4_readpage,
  393. writepage: qnx4_writepage,
  394. sync_page: block_sync_page,
  395. prepare_write: qnx4_prepare_write,
  396. commit_write: generic_commit_write,
  397. bmap: qnx4_bmap
  398. };
  399. static void qnx4_read_inode(struct inode *inode)
  400. {
  401. struct buffer_head *bh;
  402. struct qnx4_inode_entry *raw_inode;
  403. int block, ino;
  404. ino = inode->i_ino;
  405. inode->i_mode = 0;
  406. QNX4DEBUG(("Reading inode : [%d]n", ino));
  407. if (!ino) {
  408. printk("qnx4: bad inode number on dev %s: %d is out of rangen",
  409.        kdevname(inode->i_dev), ino);
  410. return;
  411. }
  412. block = ino / QNX4_INODES_PER_BLOCK;
  413. if (!(bh = sb_bread(inode->i_sb, block))) {
  414. printk("qnx4: major problem: unable to read inode from dev "
  415.        "%sn", kdevname(inode->i_dev));
  416. return;
  417. }
  418. raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
  419.     (ino % QNX4_INODES_PER_BLOCK);
  420. inode->i_mode    = le16_to_cpu(raw_inode->di_mode);
  421. inode->i_uid     = (uid_t)le16_to_cpu(raw_inode->di_uid);
  422. inode->i_gid     = (gid_t)le16_to_cpu(raw_inode->di_gid);
  423. inode->i_nlink   = le16_to_cpu(raw_inode->di_nlink);
  424. inode->i_size    = le32_to_cpu(raw_inode->di_size);
  425. inode->i_mtime   = le32_to_cpu(raw_inode->di_mtime);
  426. inode->i_atime   = le32_to_cpu(raw_inode->di_atime);
  427. inode->i_ctime   = le32_to_cpu(raw_inode->di_ctime);
  428. inode->i_blocks  = le32_to_cpu(raw_inode->di_first_xtnt.xtnt_size);
  429. inode->i_blksize = QNX4_DIR_ENTRY_SIZE;
  430. memcpy(&inode->u.qnx4_i, (struct qnx4_inode_info *) raw_inode, QNX4_DIR_ENTRY_SIZE);
  431. if (S_ISREG(inode->i_mode)) {
  432. inode->i_op = &qnx4_file_inode_operations;
  433. inode->i_fop = &qnx4_file_operations;
  434. inode->i_mapping->a_ops = &qnx4_aops;
  435. inode->u.qnx4_i.mmu_private = inode->i_size;
  436. } else if (S_ISDIR(inode->i_mode)) {
  437. inode->i_op = &qnx4_dir_inode_operations;
  438. inode->i_fop = &qnx4_dir_operations;
  439. } else if (S_ISLNK(inode->i_mode)) {
  440. inode->i_op = &page_symlink_inode_operations;
  441. inode->i_mapping->a_ops = &qnx4_aops;
  442. inode->u.qnx4_i.mmu_private = inode->i_size;
  443. } else
  444. printk("qnx4: bad inode %d on dev %sn",ino,kdevname(inode->i_dev));
  445. brelse(bh);
  446. }
  447. static DECLARE_FSTYPE_DEV(qnx4_fs_type, "qnx4", qnx4_read_super);
  448. static int __init init_qnx4_fs(void)
  449. {
  450. printk("QNX4 filesystem 0.2.2 registered.n");
  451. return register_filesystem(&qnx4_fs_type);
  452. }
  453. static void __exit exit_qnx4_fs(void)
  454. {
  455. unregister_filesystem(&qnx4_fs_type);
  456. }
  457. EXPORT_NO_SYMBOLS;
  458. module_init(init_qnx4_fs)
  459. module_exit(exit_qnx4_fs)
  460. MODULE_LICENSE("GPL");