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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/fs/fat/file.c
  3.  *
  4.  *  Written 1992,1993 by Werner Almesberger
  5.  *
  6.  *  regular file handling primitives for fat-based filesystems
  7.  */
  8. #include <linux/sched.h>
  9. #include <linux/locks.h>
  10. #include <linux/fs.h>
  11. #include <linux/msdos_fs.h>
  12. #include <linux/errno.h>
  13. #include <linux/fcntl.h>
  14. #include <linux/stat.h>
  15. #include <linux/string.h>
  16. #include <linux/pagemap.h>
  17. #include <linux/fat_cvf.h>
  18. #include <asm/uaccess.h>
  19. #include <asm/system.h>
  20. #define PRINTK(x)
  21. #define Printk(x) printk x
  22. struct file_operations fat_file_operations = {
  23. llseek: generic_file_llseek,
  24. read: fat_file_read,
  25. write: fat_file_write,
  26. mmap: generic_file_mmap,
  27. fsync: file_fsync,
  28. };
  29. struct inode_operations fat_file_inode_operations = {
  30. truncate: fat_truncate,
  31. setattr: fat_notify_change,
  32. };
  33. ssize_t fat_file_read(
  34. struct file *filp,
  35. char *buf,
  36. size_t count,
  37. loff_t *ppos)
  38. {
  39. struct inode *inode = filp->f_dentry->d_inode;
  40. return MSDOS_SB(inode->i_sb)->cvf_format
  41. ->cvf_file_read(filp,buf,count,ppos);
  42. }
  43. int fat_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
  44. {
  45. struct super_block *sb = inode->i_sb;
  46. unsigned long phys;
  47. phys = fat_bmap(inode, iblock);
  48. if (phys) {
  49. bh_result->b_dev = inode->i_dev;
  50. bh_result->b_blocknr = phys;
  51. bh_result->b_state |= (1UL << BH_Mapped);
  52. return 0;
  53. }
  54. if (!create)
  55. return 0;
  56. if (iblock << sb->s_blocksize_bits != MSDOS_I(inode)->mmu_private) {
  57. BUG();
  58. return -EIO;
  59. }
  60. if (!(iblock % MSDOS_SB(inode->i_sb)->cluster_size)) {
  61. if (fat_add_cluster(inode) < 0)
  62. return -ENOSPC;
  63. }
  64. MSDOS_I(inode)->mmu_private += sb->s_blocksize;
  65. phys = fat_bmap(inode, iblock);
  66. if (!phys)
  67. BUG();
  68. bh_result->b_dev = inode->i_dev;
  69. bh_result->b_blocknr = phys;
  70. bh_result->b_state |= (1UL << BH_Mapped);
  71. bh_result->b_state |= (1UL << BH_New);
  72. return 0;
  73. }
  74. ssize_t fat_file_write(
  75. struct file *filp,
  76. const char *buf,
  77. size_t count,
  78. loff_t *ppos)
  79. {
  80. struct inode *inode = filp->f_dentry->d_inode;
  81. struct super_block *sb = inode->i_sb;
  82. return MSDOS_SB(sb)->cvf_format
  83. ->cvf_file_write(filp,buf,count,ppos);
  84. }
  85. ssize_t default_fat_file_write(
  86. struct file *filp,
  87. const char *buf,
  88. size_t count,
  89. loff_t *ppos)
  90. {
  91. struct inode *inode = filp->f_dentry->d_inode;
  92. int retval;
  93. retval = generic_file_write(filp, buf, count, ppos);
  94. if (retval > 0) {
  95. inode->i_mtime = inode->i_ctime = CURRENT_TIME;
  96. MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
  97. mark_inode_dirty(inode);
  98. }
  99. return retval;
  100. }
  101. void fat_truncate(struct inode *inode)
  102. {
  103. struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
  104. int cluster;
  105. /* Why no return value?  Surely the disk could fail... */
  106. if (IS_RDONLY (inode))
  107. return /* -EPERM */;
  108. if (IS_IMMUTABLE(inode))
  109. return /* -EPERM */;
  110. cluster = 1 << sbi->cluster_bits;
  111. /* 
  112.  * This protects against truncating a file bigger than it was then
  113.  * trying to write into the hole.
  114.  */
  115. if (MSDOS_I(inode)->mmu_private > inode->i_size)
  116. MSDOS_I(inode)->mmu_private = inode->i_size;
  117. fat_free(inode, (inode->i_size + (cluster - 1)) >> sbi->cluster_bits);
  118. MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
  119. inode->i_ctime = inode->i_mtime = CURRENT_TIME;
  120. mark_inode_dirty(inode);
  121. }