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

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