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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
  3.  */
  4. #include <linux/sched.h>
  5. #include <linux/reiserfs_fs.h>
  6. #include <linux/smp_lock.h>
  7. /*
  8. ** We pack the tails of files on file close, not at the time they are written.
  9. ** This implies an unnecessary copy of the tail and an unnecessary indirect item
  10. ** insertion/balancing, for files that are written in one write.
  11. ** It avoids unnecessary tail packings (balances) for files that are written in
  12. ** multiple writes and are small enough to have tails.
  13. ** 
  14. ** file_release is called by the VFS layer when the file is closed.  If
  15. ** this is the last open file descriptor, and the file
  16. ** small enough to have a tail, and the tail is currently in an
  17. ** unformatted node, the tail is converted back into a direct item.
  18. ** 
  19. ** We use reiserfs_truncate_file to pack the tail, since it already has
  20. ** all the conditions coded.  
  21. */
  22. static int reiserfs_file_release (struct inode * inode, struct file * filp)
  23. {
  24.     struct reiserfs_transaction_handle th ;
  25.     int windex ;
  26.     if (!S_ISREG (inode->i_mode))
  27. BUG ();
  28.     /* fast out for when nothing needs to be done */
  29.     if ((atomic_read(&inode->i_count) > 1 ||
  30.          !(inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) || 
  31.          !tail_has_to_be_packed(inode))       && 
  32. inode->u.reiserfs_i.i_prealloc_count <= 0) {
  33. return 0;
  34.     }    
  35.     
  36.     lock_kernel() ;
  37.     down (&inode->i_sem); 
  38.     journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
  39.     reiserfs_update_inode_transaction(inode) ;
  40. #ifdef REISERFS_PREALLOCATE
  41.     reiserfs_discard_prealloc (&th, inode);
  42. #endif
  43.     journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
  44.     if (atomic_read(&inode->i_count) <= 1 &&
  45. (inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) &&
  46.         tail_has_to_be_packed (inode)) {
  47. /* if regular file is released by last holder and it has been
  48.    appended (we append by unformatted node only) or its direct
  49.    item(s) had to be converted, then it may have to be
  50.    indirect2direct converted */
  51. windex = push_journal_writer("file_release") ;
  52. reiserfs_truncate_file(inode, 0) ;
  53. pop_journal_writer(windex) ;
  54.     }
  55.     up (&inode->i_sem); 
  56.     unlock_kernel() ;
  57.     return 0;
  58. }
  59. static void reiserfs_vfs_truncate_file(struct inode *inode) {
  60.     reiserfs_truncate_file(inode, 1) ;
  61. }
  62. /* Sync a reiserfs file. */
  63. static int reiserfs_sync_file(
  64.       struct file   * p_s_filp,
  65.       struct dentry * p_s_dentry,
  66.       int datasync
  67.       ) {
  68.   struct inode * p_s_inode = p_s_dentry->d_inode;
  69.   int n_err;
  70.   lock_kernel() ;
  71.   if (!S_ISREG(p_s_inode->i_mode))
  72.       BUG ();
  73.   n_err = fsync_inode_buffers(p_s_inode) ;
  74.   n_err |= fsync_inode_data_buffers(p_s_inode);
  75.   reiserfs_commit_for_inode(p_s_inode) ;
  76.   unlock_kernel() ;
  77.   return ( n_err < 0 ) ? -EIO : 0;
  78. }
  79. static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
  80.     struct inode *inode = dentry->d_inode ;
  81.     int error ;
  82.     if (attr->ia_valid & ATTR_SIZE) {
  83. /* version 2 items will be caught by the s_maxbytes check
  84. ** done for us in vmtruncate
  85. */
  86. if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
  87.     attr->ia_size > MAX_NON_LFS)
  88.             return -EFBIG ;
  89. /* fill in hole pointers in the expanding truncate case. */
  90.         if (attr->ia_size > inode->i_size) {
  91.     error = generic_cont_expand(inode, attr->ia_size) ;
  92.     if (inode->u.reiserfs_i.i_prealloc_count > 0) {
  93. struct reiserfs_transaction_handle th ;
  94. /* we're changing at most 2 bitmaps, inode + super */
  95. journal_begin(&th, inode->i_sb, 4) ;
  96. reiserfs_discard_prealloc (&th, inode);
  97. journal_end(&th, inode->i_sb, 4) ;
  98.     }
  99.     if (error)
  100.         return error ;
  101. }
  102.     }
  103.     if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
  104.  ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
  105. (get_inode_sd_version (inode) == STAT_DATA_V1))
  106. /* stat data of format v3.5 has 16 bit uid and gid */
  107.     return -EINVAL;
  108.     error = inode_change_ok(inode, attr) ;
  109.     if (!error)
  110.         inode_setattr(inode, attr) ;
  111.     return error ;
  112. }
  113. struct file_operations reiserfs_file_operations = {
  114.     read: generic_file_read,
  115.     write: generic_file_write,
  116.     ioctl: reiserfs_ioctl,
  117.     mmap: generic_file_mmap,
  118.     release: reiserfs_file_release,
  119.     fsync: reiserfs_sync_file,
  120. };
  121. struct  inode_operations reiserfs_file_inode_operations = {
  122.     truncate: reiserfs_vfs_truncate_file,
  123.     setattr:    reiserfs_setattr,
  124. };