ia64/linux-2.6.18-xen.hg

annotate fs/qnx4/fsync.c @ 524:7f8b544237bf

netfront: Allow netfront in domain 0.

This is useful if your physical network device is in a utility domain.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Apr 15 15:18:58 2008 +0100 (2008-04-15)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 * QNX4 file system, Linux implementation.
ian@0 3 *
ian@0 4 * Version : 0.1
ian@0 5 *
ian@0 6 * Using parts of the xiafs filesystem.
ian@0 7 *
ian@0 8 * History :
ian@0 9 *
ian@0 10 * 24-03-1998 by Richard Frowijn : first release.
ian@0 11 */
ian@0 12
ian@0 13 #include <linux/errno.h>
ian@0 14 #include <linux/time.h>
ian@0 15 #include <linux/stat.h>
ian@0 16 #include <linux/fcntl.h>
ian@0 17 #include <linux/smp_lock.h>
ian@0 18 #include <linux/buffer_head.h>
ian@0 19
ian@0 20 #include <linux/fs.h>
ian@0 21 #include <linux/qnx4_fs.h>
ian@0 22
ian@0 23 #include <asm/system.h>
ian@0 24
ian@0 25 /*
ian@0 26 * The functions for qnx4 fs file synchronization.
ian@0 27 */
ian@0 28
ian@0 29 #ifdef CONFIG_QNX4FS_RW
ian@0 30
ian@0 31 static int sync_block(struct inode *inode, unsigned short *block, int wait)
ian@0 32 {
ian@0 33 struct buffer_head *bh;
ian@0 34 unsigned short tmp;
ian@0 35
ian@0 36 if (!*block)
ian@0 37 return 0;
ian@0 38 tmp = *block;
ian@0 39 bh = sb_find_get_block(inode->i_sb, *block);
ian@0 40 if (!bh)
ian@0 41 return 0;
ian@0 42 if (*block != tmp) {
ian@0 43 brelse(bh);
ian@0 44 return 1;
ian@0 45 }
ian@0 46 if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
ian@0 47 brelse(bh);
ian@0 48 return -1;
ian@0 49 }
ian@0 50 if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
ian@0 51 brelse(bh);
ian@0 52 return 0;
ian@0 53 }
ian@0 54 ll_rw_block(WRITE, 1, &bh);
ian@0 55 atomic_dec(&bh->b_count);
ian@0 56 return 0;
ian@0 57 }
ian@0 58
ian@0 59 #ifdef WTF
ian@0 60 static int sync_iblock(struct inode *inode, unsigned short *iblock,
ian@0 61 struct buffer_head **bh, int wait)
ian@0 62 {
ian@0 63 int rc;
ian@0 64 unsigned short tmp;
ian@0 65
ian@0 66 *bh = NULL;
ian@0 67 tmp = *iblock;
ian@0 68 if (!tmp)
ian@0 69 return 0;
ian@0 70 rc = sync_block(inode, iblock, wait);
ian@0 71 if (rc)
ian@0 72 return rc;
ian@0 73 *bh = sb_bread(inode->i_sb, tmp);
ian@0 74 if (tmp != *iblock) {
ian@0 75 brelse(*bh);
ian@0 76 *bh = NULL;
ian@0 77 return 1;
ian@0 78 }
ian@0 79 if (!*bh)
ian@0 80 return -1;
ian@0 81 return 0;
ian@0 82 }
ian@0 83 #endif
ian@0 84
ian@0 85 static int sync_direct(struct inode *inode, int wait)
ian@0 86 {
ian@0 87 int i;
ian@0 88 int rc, err = 0;
ian@0 89
ian@0 90 for (i = 0; i < 7; i++) {
ian@0 91 rc = sync_block(inode,
ian@0 92 (unsigned short *) qnx4_raw_inode(inode)->di_first_xtnt.xtnt_blk + i, wait);
ian@0 93 if (rc > 0)
ian@0 94 break;
ian@0 95 if (rc)
ian@0 96 err = rc;
ian@0 97 }
ian@0 98 return err;
ian@0 99 }
ian@0 100
ian@0 101 #ifdef WTF
ian@0 102 static int sync_indirect(struct inode *inode, unsigned short *iblock, int wait)
ian@0 103 {
ian@0 104 int i;
ian@0 105 struct buffer_head *ind_bh;
ian@0 106 int rc, err = 0;
ian@0 107
ian@0 108 rc = sync_iblock(inode, iblock, &ind_bh, wait);
ian@0 109 if (rc || !ind_bh)
ian@0 110 return rc;
ian@0 111
ian@0 112 for (i = 0; i < 512; i++) {
ian@0 113 rc = sync_block(inode,
ian@0 114 ((unsigned short *) ind_bh->b_data) + i,
ian@0 115 wait);
ian@0 116 if (rc > 0)
ian@0 117 break;
ian@0 118 if (rc)
ian@0 119 err = rc;
ian@0 120 }
ian@0 121 brelse(ind_bh);
ian@0 122 return err;
ian@0 123 }
ian@0 124
ian@0 125 static int sync_dindirect(struct inode *inode, unsigned short *diblock,
ian@0 126 int wait)
ian@0 127 {
ian@0 128 int i;
ian@0 129 struct buffer_head *dind_bh;
ian@0 130 int rc, err = 0;
ian@0 131
ian@0 132 rc = sync_iblock(inode, diblock, &dind_bh, wait);
ian@0 133 if (rc || !dind_bh)
ian@0 134 return rc;
ian@0 135
ian@0 136 for (i = 0; i < 512; i++) {
ian@0 137 rc = sync_indirect(inode,
ian@0 138 ((unsigned short *) dind_bh->b_data) + i,
ian@0 139 wait);
ian@0 140 if (rc > 0)
ian@0 141 break;
ian@0 142 if (rc)
ian@0 143 err = rc;
ian@0 144 }
ian@0 145 brelse(dind_bh);
ian@0 146 return err;
ian@0 147 }
ian@0 148 #endif
ian@0 149
ian@0 150 int qnx4_sync_file(struct file *file, struct dentry *dentry, int unused)
ian@0 151 {
ian@0 152 struct inode *inode = dentry->d_inode;
ian@0 153 int wait, err = 0;
ian@0 154
ian@0 155 (void) file;
ian@0 156 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
ian@0 157 S_ISLNK(inode->i_mode)))
ian@0 158 return -EINVAL;
ian@0 159
ian@0 160 lock_kernel();
ian@0 161 for (wait = 0; wait <= 1; wait++) {
ian@0 162 err |= sync_direct(inode, wait);
ian@0 163 }
ian@0 164 err |= qnx4_sync_inode(inode);
ian@0 165 unlock_kernel();
ian@0 166 return (err < 0) ? -EIO : 0;
ian@0 167 }
ian@0 168
ian@0 169 #endif