home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / fs / xiafs / fsync.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-27  |  2.9 KB  |  160 lines

  1. /*
  2.  *  linux/fs/xiafs/fsync.c
  3.  *
  4.  *  Changes Copyright (C) 1993 Stephen Tweedie (sct@dcs.ed.ac.uk)
  5.  *  from
  6.  *  Copyright (C) 1991, 1992 Linus Torvalds
  7.  *
  8.  *  xiafs fsync primitive
  9.  */
  10.  
  11. #include <asm/segment.h>
  12. #include <asm/system.h>
  13.  
  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.  
  20. #include <linux/fs.h>
  21. #include <linux/xia_fs.h>
  22.  
  23. #include "xiafs_mac.h"
  24.  
  25.  
  26. #define blocksize (XIAFS_ZSIZE(inode->i_sb))
  27. #define addr_per_block (XIAFS_ADDRS_PER_Z(inode->i_sb))
  28.  
  29. static int sync_block (struct inode * inode, unsigned long * block, int wait)
  30. {
  31.     struct buffer_head * bh;
  32.     int tmp;
  33.     
  34.     if (!*block)
  35.         return 0;
  36.     tmp = *block;
  37.     bh = get_hash_table(inode->i_dev, *block, blocksize);
  38.     if (!bh)
  39.         return 0;
  40.     if (*block != tmp) {
  41.         brelse (bh);
  42.         return 1;
  43.     }
  44.     if (wait && bh->b_req && !bh->b_uptodate) {
  45.         brelse(bh);
  46.         return -1;
  47.     }
  48.     if (wait || !bh->b_uptodate || !bh->b_dirt)
  49.     {
  50.         brelse(bh);
  51.         return 0;
  52.     }
  53.     ll_rw_block(WRITE, 1, &bh);
  54.     bh->b_count--;
  55.     return 0;
  56. }
  57.  
  58. static int sync_iblock (struct inode * inode, unsigned long * iblock, 
  59.             struct buffer_head **bh, int wait) 
  60. {
  61.     int rc, tmp;
  62.     
  63.     *bh = NULL;
  64.     tmp = *iblock;
  65.     if (!tmp)
  66.         return 0;
  67.     rc = sync_block (inode, iblock, wait);
  68.     if (rc)
  69.         return rc;
  70.     *bh = bread(inode->i_dev, tmp, blocksize);
  71.     if (tmp != *iblock) {
  72.         brelse(*bh);
  73.         *bh = NULL;
  74.         return 1;
  75.     }
  76.     if (!*bh)
  77.         return -1;
  78.     return 0;
  79. }
  80.  
  81.  
  82. static int sync_direct(struct inode *inode, int wait)
  83. {
  84.     int i;
  85.     int rc, err = 0;
  86.  
  87.     for (i = 0; i < 8; i++) {
  88.         rc = sync_block (inode, inode->u.ext_i.i_data + i, wait);
  89.         if (rc > 0)
  90.             break;
  91.         if (rc)
  92.             err = rc;
  93.     }
  94.     return err;
  95. }
  96.  
  97. static int sync_indirect(struct inode *inode, unsigned long *iblock, int wait)
  98. {
  99.     int i;
  100.     struct buffer_head * ind_bh;
  101.     int rc, err = 0;
  102.  
  103.     rc = sync_iblock (inode, iblock, &ind_bh, wait);
  104.     if (rc || !ind_bh)
  105.         return rc;
  106.     
  107.     for (i = 0; i < addr_per_block; i++) {
  108.         rc = sync_block (inode, 
  109.                  ((unsigned long *) ind_bh->b_data) + i,
  110.                  wait);
  111.         if (rc > 0)
  112.             break;
  113.         if (rc)
  114.             err = rc;
  115.     }
  116.     brelse(ind_bh);
  117.     return err;
  118. }
  119.  
  120. static int sync_dindirect(struct inode *inode, unsigned long *diblock,
  121.               int wait)
  122. {
  123.     int i;
  124.     struct buffer_head * dind_bh;
  125.     int rc, err = 0;
  126.  
  127.     rc = sync_iblock (inode, diblock, &dind_bh, wait);
  128.     if (rc || !dind_bh)
  129.         return rc;
  130.     
  131.     for (i = 0; i < addr_per_block; i++) {
  132.         rc = sync_indirect (inode,
  133.                     ((unsigned long *) dind_bh->b_data) + i,
  134.                     wait);
  135.         if (rc > 0)
  136.             break;
  137.         if (rc)
  138.             err = rc;
  139.     }
  140.     brelse(dind_bh);
  141.     return err;
  142. }
  143.  
  144. int xiafs_sync_file(struct inode * inode, struct file * file)
  145. {
  146.     int wait, err = 0;
  147.     
  148.     if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
  149.          S_ISLNK(inode->i_mode)))
  150.         return -EINVAL;
  151.     for (wait=0; wait<=1; wait++)
  152.     {
  153.         err |= sync_direct(inode, wait);
  154.         err |= sync_indirect(inode, &inode->u.xiafs_i.i_ind_zone, wait);
  155.         err |= sync_dindirect(inode, &inode->u.xiafs_i.i_dind_zone, wait);
  156.     }
  157.     err |= xiafs_sync_inode (inode);
  158.     return (err < 0) ? -EIO : 0;
  159. }
  160.