root/fs/minix/fsync.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sync_block
  2. sync_iblock
  3. sync_direct
  4. sync_indirect
  5. sync_dindirect
  6. minix_sync_file

   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 #include <asm/segment.h>
  12 #include <asm/system.h>
  13 
  14 #include <linux/errno.h>
  15 #include <linux/sched.h>
  16 #include <linux/tty.h>
  17 #include <linux/stat.h>
  18 #include <linux/fcntl.h>
  19 #include <linux/locks.h>
  20 
  21 #include <linux/fs.h>
  22 #include <linux/minix_fs.h>
  23 
  24 
  25 #define blocksize BLOCK_SIZE
  26 #define addr_per_block 512
  27 
  28 static int sync_block (struct inode * inode, unsigned short * block, int wait)
     /* [previous][next][first][last][top][bottom][index][help] */
  29 {
  30         struct buffer_head * bh;
  31         unsigned short tmp;
  32         
  33         if (!*block)
  34                 return 0;
  35         tmp = *block;
  36         bh = get_hash_table(inode->i_dev, *block, blocksize);
  37         if (!bh)
  38                 return 0;
  39         if (*block != tmp) {
  40                 brelse (bh);
  41                 return 1;
  42         }
  43         if (wait && bh->b_req && !bh->b_uptodate) {
  44                 brelse(bh);
  45                 return -1;
  46         }
  47         if (wait || !bh->b_uptodate || !bh->b_dirt)
  48         {
  49                 brelse(bh);
  50                 return 0;
  51         }
  52         ll_rw_block(WRITE, 1, &bh);
  53         bh->b_count--;
  54         return 0;
  55 }
  56 
  57 static int sync_iblock (struct inode * inode, unsigned short * iblock, 
     /* [previous][next][first][last][top][bottom][index][help] */
  58                         struct buffer_head **bh, int wait) 
  59 {
  60         int rc;
  61         unsigned short 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)
     /* [previous][next][first][last][top][bottom][index][help] */
  83 {
  84         int i;
  85         int rc, err = 0;
  86 
  87         for (i = 0; i < 7; i++) {
  88                 rc = sync_block (inode, inode->u.minix_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 short *iblock, int wait)
     /* [previous][next][first][last][top][bottom][index][help] */
  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 short *) 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 short *diblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 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 short *) 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 minix_sync_file(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 
 152         for (wait=0; wait<=1; wait++)
 153         {
 154                 err |= sync_direct(inode, wait);
 155                 err |= sync_indirect(inode, inode->u.minix_i.i_data+7, wait);
 156                 err |= sync_dindirect(inode, inode->u.minix_i.i_data+8, wait);
 157         }
 158         err |= minix_sync_inode (inode);
 159         return (err < 0) ? -EIO : 0;
 160 }

/* [previous][next][first][last][top][bottom][index][help] */