root/fs/minix/fsync.c

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

DEFINITIONS

This source file includes following definitions.
  1. V1_sync_block
  2. V1_sync_iblock
  3. V1_sync_direct
  4. V1_sync_indirect
  5. V1_sync_dindirect
  6. V1_minix_sync_file
  7. V2_sync_block
  8. V2_sync_iblock
  9. V2_sync_direct
  10. V2_sync_indirect
  11. V2_sync_dindirect
  12. V2_sync_tindirect
  13. V2_minix_sync_file
  14. 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  *  Copyright (C) 1996 Gertjan van Wingerde (gertjan@cs.vu.nl)
   9  *      Minix V2 fs support
  10  *
  11  *  minix fsync primitive
  12  */
  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 #include <asm/segment.h>
  24 #include <asm/system.h>
  25 
  26 #define blocksize BLOCK_SIZE
  27 
  28 /*
  29  * The functions for minix V1 fs file synchronization.
  30  */
  31 static int V1_sync_block (struct inode * inode, unsigned short * block, int wait)
     /* [previous][next][first][last][top][bottom][index][help] */
  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 && buffer_req(bh) && !buffer_uptodate(bh)) {
  47                 brelse(bh);
  48                 return -1;
  49         }
  50         if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
  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 V1_sync_iblock (struct inode * inode, unsigned short * iblock, 
     /* [previous][next][first][last][top][bottom][index][help] */
  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 = V1_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 static int V1_sync_direct(struct inode *inode, int wait)
     /* [previous][next][first][last][top][bottom][index][help] */
  85 {
  86         int i;
  87         int rc, err = 0;
  88 
  89         for (i = 0; i < 7; i++) {
  90                 rc = V1_sync_block (inode, 
  91                      (unsigned short *) inode->u.minix_i.u.i1_data + i, wait);
  92                 if (rc > 0)
  93                         break;
  94                 if (rc)
  95                         err = rc;
  96         }
  97         return err;
  98 }
  99 
 100 static int V1_sync_indirect(struct inode *inode, unsigned short *iblock, int wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102         int i;
 103         struct buffer_head * ind_bh;
 104         int rc, err = 0;
 105 
 106         rc = V1_sync_iblock (inode, iblock, &ind_bh, wait);
 107         if (rc || !ind_bh)
 108                 return rc;
 109 
 110         for (i = 0; i < 512; i++) {
 111                 rc = V1_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 V1_sync_dindirect(struct inode *inode, unsigned short *diblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 124                           int wait)
 125 {
 126         int i;
 127         struct buffer_head * dind_bh;
 128         int rc, err = 0;
 129 
 130         rc = V1_sync_iblock (inode, diblock, &dind_bh, wait);
 131         if (rc || !dind_bh)
 132                 return rc;
 133 
 134         for (i = 0; i < 512; i++) {
 135                 rc = V1_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 V1_minix_sync_file(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 |= V1_sync_direct(inode, wait);
 158                 err |= V1_sync_indirect(inode, inode->u.minix_i.u.i1_data + 7, wait);
 159                 err |= V1_sync_dindirect(inode, inode->u.minix_i.u.i1_data + 8, wait);
 160         }
 161         err |= minix_sync_inode (inode);
 162         return (err < 0) ? -EIO : 0;
 163 }
 164 
 165 /* 
 166  * The functions for minix V2 fs file synchronization.
 167  */
 168 static int V2_sync_block (struct inode * inode, unsigned long * block, int wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 169 {
 170         struct buffer_head * bh;
 171         unsigned long tmp;
 172         
 173         if (!*block)
 174                 return 0;
 175         tmp = *block;
 176         bh = get_hash_table(inode->i_dev, *block, blocksize);
 177         if (!bh)
 178                 return 0;
 179         if (*block != tmp) {
 180                 brelse (bh);
 181                 return 1;
 182         }
 183         if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
 184                 brelse(bh);
 185                 return -1;
 186         }
 187         if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
 188         {
 189                 brelse(bh);
 190                 return 0;
 191         }
 192         ll_rw_block(WRITE, 1, &bh);
 193         bh->b_count--;
 194         return 0;
 195 }
 196 
 197 static int V2_sync_iblock (struct inode * inode, unsigned long * iblock, 
     /* [previous][next][first][last][top][bottom][index][help] */
 198                         struct buffer_head **bh, int wait) 
 199 {
 200         int rc;
 201         unsigned long tmp;
 202         
 203         *bh = NULL;
 204         tmp = *iblock;
 205         if (!tmp)
 206                 return 0;
 207         rc = V2_sync_block (inode, iblock, wait);
 208         if (rc)
 209                 return rc;
 210         *bh = bread(inode->i_dev, tmp, blocksize);
 211         if (tmp != *iblock) {
 212                 brelse(*bh);
 213                 *bh = NULL;
 214                 return 1;
 215         }
 216         if (!*bh)
 217                 return -1;
 218         return 0;
 219 }
 220 
 221 static int V2_sync_direct(struct inode *inode, int wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 222 {
 223         int i;
 224         int rc, err = 0;
 225 
 226         for (i = 0; i < 7; i++) {
 227                 rc = V2_sync_block (inode, 
 228                         (unsigned long *)inode->u.minix_i.u.i2_data + i, wait);
 229                 if (rc > 0)
 230                         break;
 231                 if (rc)
 232                         err = rc;
 233         }
 234         return err;
 235 }
 236 
 237 static int V2_sync_indirect(struct inode *inode, unsigned long *iblock, int wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 238 {
 239         int i;
 240         struct buffer_head * ind_bh;
 241         int rc, err = 0;
 242 
 243         rc = V2_sync_iblock (inode, iblock, &ind_bh, wait);
 244         if (rc || !ind_bh)
 245                 return rc;
 246 
 247         for (i = 0; i < 256; i++) {
 248                 rc = V2_sync_block (inode, 
 249                                     ((unsigned long *) ind_bh->b_data) + i, 
 250                                     wait);
 251                 if (rc > 0)
 252                         break;
 253                 if (rc)
 254                         err = rc;
 255         }
 256         brelse(ind_bh);
 257         return err;
 258 }
 259 
 260 static int V2_sync_dindirect(struct inode *inode, unsigned long *diblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 261                           int wait)
 262 {
 263         int i;
 264         struct buffer_head * dind_bh;
 265         int rc, err = 0;
 266 
 267         rc = V2_sync_iblock (inode, diblock, &dind_bh, wait);
 268         if (rc || !dind_bh)
 269                 return rc;
 270 
 271         for (i = 0; i < 256; i++) {
 272                 rc = V2_sync_indirect (inode,
 273                                        ((unsigned long *) dind_bh->b_data) + i, 
 274                                        wait);
 275                 if (rc > 0)
 276                         break;
 277                 if (rc)
 278                         err = rc;
 279         }
 280         brelse(dind_bh);
 281         return err;
 282 }
 283 
 284 static int V2_sync_tindirect(struct inode *inode, unsigned long *tiblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 285                           int wait)
 286 {
 287         int i;
 288         struct buffer_head * tind_bh;
 289         int rc, err = 0;
 290 
 291         rc = V2_sync_iblock (inode, tiblock, &tind_bh, wait);
 292         if (rc || !tind_bh)
 293                 return rc;
 294 
 295         for (i = 0; i < 256; i++) {
 296                 rc = V2_sync_dindirect (inode,
 297                                         ((unsigned long *) tind_bh->b_data) + i, 
 298                                         wait);
 299                 if (rc > 0)
 300                         break;
 301                 if (rc)
 302                         err = rc;
 303         }
 304         brelse(tind_bh);
 305         return err;
 306 }
 307 
 308 int V2_minix_sync_file(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
 309 {
 310         int wait, err = 0;
 311         
 312         if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
 313              S_ISLNK(inode->i_mode)))
 314                 return -EINVAL;
 315 
 316         for (wait=0; wait<=1; wait++)
 317         {
 318                 err |= V2_sync_direct(inode, wait);
 319                 err |= V2_sync_indirect(inode, 
 320                       (unsigned long *) inode->u.minix_i.u.i2_data + 7, wait);
 321                 err |= V2_sync_dindirect(inode, 
 322                       (unsigned long *) inode->u.minix_i.u.i2_data + 8, wait);
 323                 err |= V2_sync_tindirect(inode, 
 324                       (unsigned long *) inode->u.minix_i.u.i2_data + 9, wait);
 325         }
 326         err |= minix_sync_inode (inode);
 327         return (err < 0) ? -EIO : 0;
 328 }
 329 
 330 /*
 331  * The function which is called for file synchronization.
 332  */
 333 int minix_sync_file(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
 334 {
 335         if (INODE_VERSION(inode) == MINIX_V1)
 336                 return V1_minix_sync_file(inode, file);
 337         else
 338                 return V2_minix_sync_file(inode, file);
 339 }

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