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 / minix / fsync.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-23  |  2.9 KB  |  164 lines

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