linux/fs/qnx4/fsync.c
<<
>>
Prefs
   1/* 
   2 * QNX4 file system, Linux implementation.
   3 * 
   4 * Version : 0.1
   5 * 
   6 * Using parts of the xiafs filesystem.
   7 * 
   8 * History :
   9 * 
  10 * 24-03-1998 by Richard Frowijn : first release.
  11 */
  12
  13#include <linux/errno.h>
  14#include <linux/time.h>
  15#include <linux/stat.h>
  16#include <linux/fcntl.h>
  17#include <linux/smp_lock.h>
  18#include <linux/buffer_head.h>
  19
  20#include <linux/fs.h>
  21#include <linux/qnx4_fs.h>
  22
  23#include <asm/system.h>
  24
  25/*
  26 * The functions for qnx4 fs file synchronization.
  27 */
  28
  29#ifdef CONFIG_QNX4FS_RW
  30
  31static int sync_block(struct inode *inode, unsigned short *block, int wait)
  32{
  33        struct buffer_head *bh;
  34        unsigned short tmp;
  35
  36        if (!*block)
  37                return 0;
  38        tmp = *block;
  39        bh = sb_find_get_block(inode->i_sb, *block);
  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                brelse(bh);
  52                return 0;
  53        }
  54        ll_rw_block(WRITE, 1, &bh);
  55        atomic_dec(&bh->b_count);
  56        return 0;
  57}
  58
  59#ifdef WTF
  60static int sync_iblock(struct inode *inode, unsigned short *iblock,
  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 = sync_block(inode, iblock, wait);
  71        if (rc)
  72                return rc;
  73        *bh = sb_bread(inode->i_sb, tmp);
  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#endif
  84
  85static int sync_direct(struct inode *inode, int wait)
  86{
  87        int i;
  88        int rc, err = 0;
  89
  90        for (i = 0; i < 7; i++) {
  91                rc = sync_block(inode,
  92                                (unsigned short *) qnx4_raw_inode(inode)->di_first_xtnt.xtnt_blk + i, wait);
  93                if (rc > 0)
  94                        break;
  95                if (rc)
  96                        err = rc;
  97        }
  98        return err;
  99}
 100
 101#ifdef WTF
 102static int sync_indirect(struct inode *inode, unsigned short *iblock, int wait)
 103{
 104        int i;
 105        struct buffer_head *ind_bh;
 106        int rc, err = 0;
 107
 108        rc = sync_iblock(inode, iblock, &ind_bh, wait);
 109        if (rc || !ind_bh)
 110                return rc;
 111
 112        for (i = 0; i < 512; i++) {
 113                rc = sync_block(inode,
 114                                ((unsigned short *) ind_bh->b_data) + i,
 115                                wait);
 116                if (rc > 0)
 117                        break;
 118                if (rc)
 119                        err = rc;
 120        }
 121        brelse(ind_bh);
 122        return err;
 123}
 124
 125static int sync_dindirect(struct inode *inode, unsigned short *diblock,
 126                          int wait)
 127{
 128        int i;
 129        struct buffer_head *dind_bh;
 130        int rc, err = 0;
 131
 132        rc = sync_iblock(inode, diblock, &dind_bh, wait);
 133        if (rc || !dind_bh)
 134                return rc;
 135
 136        for (i = 0; i < 512; i++) {
 137                rc = sync_indirect(inode,
 138                                ((unsigned short *) dind_bh->b_data) + i,
 139                                   wait);
 140                if (rc > 0)
 141                        break;
 142                if (rc)
 143                        err = rc;
 144        }
 145        brelse(dind_bh);
 146        return err;
 147}
 148#endif
 149
 150int qnx4_sync_file(struct file *file, struct dentry *dentry, int unused)
 151{
 152        struct inode *inode = dentry->d_inode;
 153        int wait, err = 0;
 154        
 155        (void) file;
 156        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
 157              S_ISLNK(inode->i_mode)))
 158                return -EINVAL;
 159
 160        lock_kernel();
 161        for (wait = 0; wait <= 1; wait++) {
 162                err |= sync_direct(inode, wait);
 163        }
 164        err |= qnx4_sync_inode(inode);
 165        unlock_kernel();
 166        return (err < 0) ? -EIO : 0;
 167}
 168
 169#endif
 170
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.