root/fs/xiafs/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. xiafs_sync_file

   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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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, 
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 }

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