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/qnx4/fsync.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  * QNX4 file system, Linux implementation.
    3  * 
    4  * Version : 0.1
    5  * 
    6  * Using parts of the xiafs filesystem.
    7  * 
    8  * History :
    9  * 
   10  * 24-03-1998 by Richard Frowijn : first release.
   11  */
   12 
   13 #include <linux/config.h>
   14 #include <linux/errno.h>
   15 #include <linux/sched.h>
   16 #include <linux/stat.h>
   17 #include <linux/fcntl.h>
   18 #include <linux/locks.h>
   19 #include <linux/smp_lock.h>
   20 
   21 #include <linux/fs.h>
   22 #include <linux/qnx4_fs.h>
   23 
   24 #include <asm/segment.h>
   25 #include <asm/system.h>
   26 
   27 /*
   28  * The functions for qnx4 fs file synchronization.
   29  */
   30 
   31 #ifdef CONFIG_QNX4FS_RW
   32 
   33 static int sync_block(struct inode *inode, unsigned short *block, int wait)
   34 {
   35         struct buffer_head *bh;
   36         unsigned short tmp;
   37 
   38         if (!*block)
   39                 return 0;
   40         tmp = *block;
   41         bh = sb_get_hash_table(inode->i_sb, *block);
   42         if (!bh)
   43                 return 0;
   44         if (*block != tmp) {
   45                 brelse(bh);
   46                 return 1;
   47         }
   48         if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
   49                 brelse(bh);
   50                 return -1;
   51         }
   52         if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
   53                 brelse(bh);
   54                 return 0;
   55         }
   56         ll_rw_block(WRITE, 1, &bh);
   57         atomic_dec(&bh->b_count);
   58         return 0;
   59 }
   60 
   61 #ifdef WTF
   62 static int sync_iblock(struct inode *inode, unsigned short *iblock,
   63                        struct buffer_head **bh, int wait)
   64 {
   65         int rc;
   66         unsigned short tmp;
   67 
   68         *bh = NULL;
   69         tmp = *iblock;
   70         if (!tmp)
   71                 return 0;
   72         rc = sync_block(inode, iblock, wait);
   73         if (rc)
   74                 return rc;
   75         *bh = sb_bread(inode->i_sb, tmp);
   76         if (tmp != *iblock) {
   77                 brelse(*bh);
   78                 *bh = NULL;
   79                 return 1;
   80         }
   81         if (!*bh)
   82                 return -1;
   83         return 0;
   84 }
   85 #endif
   86 
   87 static int sync_direct(struct inode *inode, int wait)
   88 {
   89         int i;
   90         int rc, err = 0;
   91 
   92         for (i = 0; i < 7; i++) {
   93                 rc = sync_block(inode,
   94                                 (unsigned short *) inode->u.qnx4_i.i_first_xtnt.xtnt_blk + i, wait);
   95                 if (rc > 0)
   96                         break;
   97                 if (rc)
   98                         err = rc;
   99         }
  100         return err;
  101 }
  102 
  103 #ifdef WTF
  104 static int sync_indirect(struct inode *inode, unsigned short *iblock, int wait)
  105 {
  106         int i;
  107         struct buffer_head *ind_bh;
  108         int rc, err = 0;
  109 
  110         rc = sync_iblock(inode, iblock, &ind_bh, wait);
  111         if (rc || !ind_bh)
  112                 return rc;
  113 
  114         for (i = 0; i < 512; i++) {
  115                 rc = sync_block(inode,
  116                                 ((unsigned short *) ind_bh->b_data) + i,
  117                                 wait);
  118                 if (rc > 0)
  119                         break;
  120                 if (rc)
  121                         err = rc;
  122         }
  123         brelse(ind_bh);
  124         return err;
  125 }
  126 
  127 static int sync_dindirect(struct inode *inode, unsigned short *diblock,
  128                           int wait)
  129 {
  130         int i;
  131         struct buffer_head *dind_bh;
  132         int rc, err = 0;
  133 
  134         rc = sync_iblock(inode, diblock, &dind_bh, wait);
  135         if (rc || !dind_bh)
  136                 return rc;
  137 
  138         for (i = 0; i < 512; i++) {
  139                 rc = sync_indirect(inode,
  140                                 ((unsigned short *) dind_bh->b_data) + i,
  141                                    wait);
  142                 if (rc > 0)
  143                         break;
  144                 if (rc)
  145                         err = rc;
  146         }
  147         brelse(dind_bh);
  148         return err;
  149 }
  150 #endif
  151 
  152 int qnx4_sync_file(struct file *file, struct dentry *dentry, int unused)
  153 {
  154         struct inode *inode = dentry->d_inode;
  155         int wait, err = 0;
  156         
  157         (void) file;
  158         if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
  159               S_ISLNK(inode->i_mode)))
  160                 return -EINVAL;
  161 
  162         lock_kernel();
  163         for (wait = 0; wait <= 1; wait++) {
  164                 err |= sync_direct(inode, wait);
  165         }
  166         err |= qnx4_sync_inode(inode);
  167         unlock_kernel();
  168         return (err < 0) ? -EIO : 0;
  169 }
  170 
  171 #endif

Cache object: 9d5cab02a66a0e6565a343e274f34f16


[ 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.