home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / fs / xiafs / fsync.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-23  |  3.0 KB  |  164 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. #ifdef MODULE
  12. #include <linux/module.h>
  13. #endif
  14.  
  15. #include <asm/segment.h>
  16. #include <asm/system.h>
  17.  
  18. #include <linux/errno.h>
  19. #include <linux/sched.h>
  20. #include <linux/stat.h>
  21. #include <linux/fcntl.h>
  22. #include <linux/locks.h>
  23.  
  24. #include <linux/fs.h>
  25. #include <linux/xia_fs.h>
  26.  
  27. #include "xiafs_mac.h"
  28.  
  29.  
  30. #define blocksize (XIAFS_ZSIZE(inode->i_sb))
  31. #define addr_per_block (XIAFS_ADDRS_PER_Z(inode->i_sb))
  32.  
  33. static int sync_block (struct inode * inode, unsigned long * block, int wait)
  34. {
  35.     struct buffer_head * bh;
  36.     int tmp;
  37.     
  38.     if (!*block)
  39.         return 0;
  40.     tmp = *block;
  41.     bh = get_hash_table(inode->i_dev, *block, blocksize);
  42.     if (!bh)
  43.         return 0;
  44.     if (*block != tmp) {
  45.         brelse (bh);
  46.         return 1;
  47.     }
  48.     if (wait && bh->b_req && !bh->b_uptodate) {
  49.         brelse(bh);
  50.         return -1;
  51.     }
  52.     if (wait || !bh->b_uptodate || !bh->b_dirt)
  53.     {
  54.         brelse(bh);
  55.         return 0;
  56.     }
  57.     ll_rw_block(WRITE, 1, &bh);
  58.     bh->b_count--;
  59.     return 0;
  60. }
  61.  
  62. static int sync_iblock (struct inode * inode, unsigned long * iblock, 
  63.             struct buffer_head **bh, int wait) 
  64. {
  65.     int rc, tmp;
  66.     
  67.     *bh = NULL;
  68.     tmp = *iblock;
  69.     if (!tmp)
  70.         return 0;
  71.     rc = sync_block (inode, iblock, wait);
  72.     if (rc)
  73.         return rc;
  74.     *bh = bread(inode->i_dev, tmp, blocksize);
  75.     if (tmp != *iblock) {
  76.         brelse(*bh);
  77.         *bh = NULL;
  78.         return 1;
  79.     }
  80.     if (!*bh)
  81.         return -1;
  82.     return 0;
  83. }
  84.  
  85.  
  86. static int sync_direct(struct inode *inode, int wait)
  87. {
  88.     int i;
  89.     int rc, err = 0;
  90.  
  91.     for (i = 0; i < 8; i++) {
  92.         rc = sync_block (inode, inode->u.ext_i.i_data + i, wait);
  93.         if (rc > 0)
  94.             break;
  95.         if (rc)
  96.             err = rc;
  97.     }
  98.     return err;
  99. }
  100.  
  101. static int sync_indirect(struct inode *inode, unsigned long *iblock, int wait)
  102. {
  103.     int i;
  104.     struct buffer_head * ind_bh;
  105.     int rc, err = 0;
  106.  
  107.     rc = sync_iblock (inode, iblock, &ind_bh, wait);
  108.     if (rc || !ind_bh)
  109.         return rc;
  110.     
  111.     for (i = 0; i < addr_per_block; i++) {
  112.         rc = sync_block (inode, 
  113.                  ((unsigned long *) ind_bh->b_data) + i,
  114.                  wait);
  115.         if (rc > 0)
  116.             break;
  117.         if (rc)
  118.             err = rc;
  119.     }
  120.     brelse(ind_bh);
  121.     return err;
  122. }
  123.  
  124. static int sync_dindirect(struct inode *inode, unsigned long *diblock,
  125.               int wait)
  126. {
  127.     int i;
  128.     struct buffer_head * dind_bh;
  129.     int rc, err = 0;
  130.  
  131.     rc = sync_iblock (inode, diblock, &dind_bh, wait);
  132.     if (rc || !dind_bh)
  133.         return rc;
  134.     
  135.     for (i = 0; i < addr_per_block; i++) {
  136.         rc = sync_indirect (inode,
  137.                     ((unsigned long *) dind_bh->b_data) + i,
  138.                     wait);
  139.         if (rc > 0)
  140.             break;
  141.         if (rc)
  142.             err = rc;
  143.     }
  144.     brelse(dind_bh);
  145.     return err;
  146. }
  147.  
  148. int xiafs_sync_file(struct inode * inode, struct file * file)
  149. {
  150.     int wait, err = 0;
  151.     
  152.     if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
  153.          S_ISLNK(inode->i_mode)))
  154.         return -EINVAL;
  155.     for (wait=0; wait<=1; wait++)
  156.     {
  157.         err |= sync_direct(inode, wait);
  158.         err |= sync_indirect(inode, &inode->u.xiafs_i.i_ind_zone, wait);
  159.         err |= sync_dindirect(inode, &inode->u.xiafs_i.i_dind_zone, wait);
  160.     }
  161.     err |= xiafs_sync_inode (inode);
  162.     return (err < 0) ? -EIO : 0;
  163. }
  164.