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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/fs/ext3/file.c
  3.  *
  4.  * Copyright (C) 1992, 1993, 1994, 1995
  5.  * Remy Card (card@masi.ibp.fr)
  6.  * Laboratoire MASI - Institut Blaise Pascal
  7.  * Universite Pierre et Marie Curie (Paris VI)
  8.  *
  9.  *  from
  10.  *
  11.  *  linux/fs/minix/file.c
  12.  *
  13.  *  Copyright (C) 1991, 1992  Linus Torvalds
  14.  *
  15.  *  ext3 fs regular file handling primitives
  16.  *
  17.  *  64-bit file support on 64-bit platforms by Jakub Jelinek
  18.  * (jj@sunsite.ms.mff.cuni.cz)
  19.  */
  20. #include <linux/sched.h>
  21. #include <linux/fs.h>
  22. #include <linux/locks.h>
  23. #include <linux/jbd.h>
  24. #include <linux/ext3_fs.h>
  25. #include <linux/ext3_jbd.h>
  26. #include <linux/smp_lock.h>
  27. /*
  28.  * Called when an inode is released. Note that this is different
  29.  * from ext3_file_open: open gets called at every open, but release
  30.  * gets called only when /all/ the files are closed.
  31.  */
  32. static int ext3_release_file (struct inode * inode, struct file * filp)
  33. {
  34. if (filp->f_mode & FMODE_WRITE)
  35. ext3_discard_prealloc (inode);
  36. return 0;
  37. }
  38. /*
  39.  * Called when an inode is about to be opened.
  40.  * We use this to disallow opening RW large files on 32bit systems if
  41.  * the caller didn't specify O_LARGEFILE.  On 64bit systems we force
  42.  * on this flag in sys_open.
  43.  */
  44. static int ext3_open_file (struct inode * inode, struct file * filp)
  45. {
  46. if (!(filp->f_flags & O_LARGEFILE) &&
  47.     inode->i_size > 0x7FFFFFFFLL)
  48. return -EFBIG;
  49. return 0;
  50. }
  51. /*
  52.  * ext3_file_write().
  53.  *
  54.  * Most things are done in ext3_prepare_write() and ext3_commit_write().
  55.  */
  56. static ssize_t
  57. ext3_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
  58. {
  59. int ret, err;
  60. struct inode *inode = file->f_dentry->d_inode;
  61. ret = generic_file_write(file, buf, count, ppos);
  62. /* Skip file flushing code if there was an error, or if nothing
  63.    was written. */
  64. if (ret <= 0)
  65. return ret;
  66. /* If the inode is IS_SYNC, or is O_SYNC and we are doing
  67.            data-journaling, then we need to make sure that we force the
  68.            transaction to disk to keep all metadata uptodate
  69.            synchronously. */
  70. if (file->f_flags & O_SYNC) {
  71. /* If we are non-data-journaled, then the dirty data has
  72.                    already been flushed to backing store by
  73.                    generic_osync_inode, and the inode has been flushed
  74.                    too if there have been any modifications other than
  75.                    mere timestamp updates.
  76.    
  77.    Open question --- do we care about flushing
  78.    timestamps too if the inode is IS_SYNC? */
  79. if (!ext3_should_journal_data(inode))
  80. return ret;
  81. goto force_commit;
  82. }
  83. /* So we know that there has been no forced data flush.  If the
  84.            inode is marked IS_SYNC, we need to force one ourselves. */
  85. if (!IS_SYNC(inode))
  86. return ret;
  87. /* Open question #2 --- should we force data to disk here too?
  88.            If we don't, the only impact is that data=writeback
  89.            filesystems won't flush data to disk automatically on
  90.            IS_SYNC, only metadata (but historically, that is what ext2
  91.            has done.) */
  92. force_commit:
  93. err = ext3_force_commit(inode->i_sb);
  94. if (err) 
  95. return err;
  96. return ret;
  97. }
  98. struct file_operations ext3_file_operations = {
  99. llseek: generic_file_llseek, /* BKL held */
  100. read: generic_file_read, /* BKL not held.  Don't need */
  101. write: ext3_file_write, /* BKL not held.  Don't need */
  102. ioctl: ext3_ioctl, /* BKL held */
  103. mmap: generic_file_mmap,
  104. open: ext3_open_file, /* BKL not held.  Don't need */
  105. release: ext3_release_file, /* BKL not held.  Don't need */
  106. fsync: ext3_sync_file, /* BKL held */
  107. };
  108. struct inode_operations ext3_file_inode_operations = {
  109. truncate: ext3_truncate, /* BKL held */
  110. setattr: ext3_setattr, /* BKL held */
  111. };