The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/reiserfs/file.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: e9a5b465d32437996200da24a7142417


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.