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

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