Ejemplo n.º 1
0
int qnx4_is_free(struct super_block *sb, long block)
{
	int start = le32_to_cpu(qnx4_sb(sb)->BitMap->di_first_xtnt.xtnt_blk) - 1;
	int size = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size);
	struct buffer_head *bh;
	const char *g;
	int ret = -EIO;

	start += block / (QNX4_BLOCK_SIZE * 8);
	QNX4DEBUG(("qnx4: is_free requesting block [%lu], bitmap in block [%lu]\n",
		   (unsigned long) block, (unsigned long) start));
	(void) size;		/* CHECKME */
	bh = sb_bread(sb, start);
	if (bh == NULL) {
		return -EIO;
	}
	g = bh->b_data + (block % QNX4_BLOCK_SIZE);
	if (((*g) & (1 << (block % 8))) == 0) {
		QNX4DEBUG(("qnx4: is_free -> block is free\n"));
		ret = 1;
	} else {
		QNX4DEBUG(("qnx4: is_free -> block is busy\n"));
		ret = 0;
	}
	brelse(bh);

	return ret;
}
Ejemplo n.º 2
0
static int qnx4_readlink(struct dentry *dentry, char *buffer, int buflen)
{
	struct inode *inode = dentry->d_inode;
	struct buffer_head *bh;
	int i;
	char c;

	QNX4DEBUG(("qnx4: qnx4_readlink() called\n"));

	if (buffer == NULL || inode == NULL || !S_ISLNK(inode->i_mode)) {
		return -EINVAL;
	}
	if (buflen > 1023) {
		buflen = 1023;
	}
	bh = qnx4_bread( inode, 0, 0 );
	if (bh == NULL) {
		QNX4DEBUG(("qnx4: NULL symlink bh\n"));
		return 0;
	}
	QNX4DEBUG(("qnx4: qnx4_bread sym called -> [%s]\n",
		   bh->b_data));
	i = 0;
	while (i < buflen && (c = bh->b_data[i])) {
		i++;
		put_user(c, buffer++);
	}
	brelse(bh);
	return i;
}
/*
 * Check the root directory of the filesystem to make sure
 * it really _is_ a qnx4 filesystem, and to check the size
 * of the directory entry.
 */
static const char *qnx4_checkroot(struct super_block *sb)
{
	struct buffer_head *bh;
	struct qnx4_inode_entry *rootdir;
	int rd, rl;
	int i, j;

	if (*(qnx4_sb(sb)->sb->RootDir.di_fname) != '/')
		return "no qnx4 filesystem (no root dir).";
	QNX4DEBUG((KERN_NOTICE "QNX4 filesystem found on dev %s.\n", sb->s_id));
	rd = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_blk) - 1;
	rl = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_size);
	for (j = 0; j < rl; j++) {
		bh = sb_bread(sb, rd + j);	/* root dir, first block */
		if (bh == NULL)
			return "unable to read root entry.";
		rootdir = (struct qnx4_inode_entry *) bh->b_data;
		for (i = 0; i < QNX4_INODES_PER_BLOCK; i++, rootdir++) {
			QNX4DEBUG((KERN_INFO "rootdir entry found : [%s]\n", rootdir->di_fname));
			if (strcmp(rootdir->di_fname, QNX4_BMNAME) != 0)
				continue;
			qnx4_sb(sb)->BitMap = kmemdup(rootdir,
						      sizeof(struct qnx4_inode_entry),
						      GFP_KERNEL);
			brelse(bh);
			if (!qnx4_sb(sb)->BitMap)
				return "not enough memory for bitmap inode";
			/* keep bitmap inode known */
			return NULL;
		}
		brelse(bh);
	}
	return "bitmap file not found.";
}
Ejemplo n.º 4
0
unsigned long qnx4_block_map( struct inode *inode, long iblock )
{
	int ix;
	long offset, i_xblk;
	unsigned long block = 0;
	struct buffer_head *bh = NULL;
	struct qnx4_xblk *xblk = NULL;
	struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode);
	u16 nxtnt = le16_to_cpu(qnx4_inode->di_num_xtnts);

	if ( iblock < le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size) ) {
		// iblock is in the first extent. This is easy.
		block = le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_blk) + iblock - 1;
	} else {
		// iblock is beyond first extent. We have to follow the extent chain.
		i_xblk = le32_to_cpu(qnx4_inode->di_xblk);
		offset = iblock - le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size);
		ix = 0;
		while ( --nxtnt > 0 ) {
			if ( ix == 0 ) {
				// read next xtnt block.
				bh = sb_bread(inode->i_sb, i_xblk - 1);
				if ( !bh ) {
					QNX4DEBUG((KERN_ERR "qnx4: I/O error reading xtnt block [%ld])\n", i_xblk - 1));
					return -EIO;
				}
				xblk = (struct qnx4_xblk*)bh->b_data;
				if ( memcmp( xblk->xblk_signature, "IamXblk", 7 ) ) {
					QNX4DEBUG((KERN_ERR "qnx4: block at %ld is not a valid xtnt\n", qnx4_inode->i_xblk));
					return -EIO;
				}
			}
			if ( offset < le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size) ) {
				// got it!
				block = le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_blk) + offset - 1;
				break;
			}
			offset -= le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size);
			if ( ++ix >= xblk->xblk_num_xtnts ) {
				i_xblk = le32_to_cpu(xblk->xblk_next_xblk);
				ix = 0;
				brelse( bh );
				bh = NULL;
			}
		}
		if ( bh )
			brelse( bh );
	}

	QNX4DEBUG((KERN_INFO "qnx4: mapping block %ld of inode %ld = %ld\n",iblock,inode->i_ino,block));
	return block;
}
Ejemplo n.º 5
0
int qnx4_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct buffer_head *bh;
	struct qnx4_inode_entry *de;
	struct inode *inode;
	int retval;
	int ino;

	QNX4DEBUG(("qnx4: qnx4_rmdir [%s]\n", dentry->d_name.name));
	lock_kernel();
	bh = qnx4_find_entry(dentry->d_name.len, dir, dentry->d_name.name,
			     &de, &ino);
	if (bh == NULL) {
		unlock_kernel();
		return -ENOENT;
	}
	inode = dentry->d_inode;
	if (inode->i_ino != ino) {
		retval = -EIO;
		goto end_rmdir;
	}
#if 0
	if (!empty_dir(inode)) {
		retval = -ENOTEMPTY;
		goto end_rmdir;
	}
#endif
	if (inode->i_nlink != 2) {
		QNX4DEBUG(("empty directory has nlink!=2 (%d)\n", inode->i_nlink));
	}
	QNX4DEBUG(("qnx4: deleting directory\n"));
	de->di_status = 0;
	memset(de->di_fname, 0, sizeof de->di_fname);
	de->di_mode = 0;
	mark_buffer_dirty(bh);
	inode->i_nlink = 0;
	mark_inode_dirty(inode);
	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
	dir->i_nlink--;
	mark_inode_dirty(dir);
	retval = 0;

      end_rmdir:
	brelse(bh);

	unlock_kernel();
	return retval;
}
Ejemplo n.º 6
0
int qnx4_set_bitmap(struct super_block *sb, long block, int busy)
{
	int start = le32_to_cpu(qnx4_sb(sb)->BitMap->di_first_xtnt.xtnt_blk) - 1;
	int size = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size);
	struct buffer_head *bh;
	char *g;

	start += block / (QNX4_BLOCK_SIZE * 8);
	QNX4DEBUG(("qnx4: set_bitmap requesting block [%lu], bitmap in block [%lu]\n",
		   (unsigned long) block, (unsigned long) start));
	(void) size;		/* CHECKME */
	bh = sb_bread(sb, start);
	if (bh == NULL) {
		return -EIO;
	}
	g = bh->b_data + (block % QNX4_BLOCK_SIZE);
	if (busy == 0) {
		(*g) &= ~(1 << (block % 8));
	} else {
		(*g) |= (1 << (block % 8));
	}
	mark_buffer_dirty(bh);
	brelse(bh);

	return 0;
}
Ejemplo n.º 7
0
struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
{
    int ino;
    struct qnx4_inode_entry *de;
    struct qnx4_link_info *lnk;
    struct buffer_head *bh;
    const char *name = dentry->d_name.name;
    int len = dentry->d_name.len;
    struct inode *foundinode = NULL;

    lock_kernel();
    if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino)))
        goto out;
    /* The entry is linked, let's get the real info */
    if ((de->di_status & QNX4_FILE_LINK) == QNX4_FILE_LINK) {
        lnk = (struct qnx4_link_info *) de;
        ino = (le32_to_cpu(lnk->dl_inode_blk) - 1) *
              QNX4_INODES_PER_BLOCK +
              lnk->dl_inode_ndx;
    }
    brelse(bh);

    foundinode = qnx4_iget(dir->i_sb, ino);
    if (IS_ERR(foundinode)) {
        unlock_kernel();
        QNX4DEBUG(("qnx4: lookup->iget -> error %ld\n",
                   PTR_ERR(foundinode)));
        return ERR_CAST(foundinode);
    }
out:
    unlock_kernel();
    d_add(dentry, foundinode);

    return NULL;
}
Ejemplo n.º 8
0
static void qnx4_write_super(struct super_block *sb)
{
	lock_kernel();
	QNX4DEBUG(("qnx4: write_super\n"));
	sb->s_dirt = 0;
	unlock_kernel();
}
Ejemplo n.º 9
0
struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
{
	int ino;
	struct qnx4_inode_entry *de;
	struct qnx4_link_info *lnk;
	struct buffer_head *bh;
	const char *name = dentry->d_name.name;
	int len = dentry->d_name.len;
	struct inode *foundinode = NULL;

	if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino)))
		goto out;
	/* The entry is linked, let's get the real info */
	if ((de->di_status & QNX4_FILE_LINK) == QNX4_FILE_LINK) {
		lnk = (struct qnx4_link_info *) de;
		ino = (le32_to_cpu(lnk->dl_inode_blk) - 1) *
                    QNX4_INODES_PER_BLOCK +
		    lnk->dl_inode_ndx;
	}
	brelse(bh);

	foundinode = qnx4_iget(dir->i_sb, ino);
	if (IS_ERR(foundinode))
		QNX4DEBUG((KERN_ERR "qnx4: lookup->iget -> error %ld\n",
			   PTR_ERR(foundinode)));
out:
	return d_splice_alias(foundinode, dentry);
}
Ejemplo n.º 10
0
static void qnx4_write_super(struct super_block *sb)
{
	lock_kernel();
	QNX4DEBUG(("qnx4: write_super\n"));
	mark_sb_clean(sb);
	unlock_kernel();
}
Ejemplo n.º 11
0
/*
 * Check the root directory of the filesystem to make sure
 * it really _is_ a qnx4 filesystem, and to check the size
 * of the directory entry.
 */
static const char *qnx4_checkroot(struct super_block *sb)
{
	struct buffer_head *bh;
	struct qnx4_inode_entry *rootdir;
	int rd, rl;
	int i, j;
	int found = 0;

	if (*(qnx4_sb(sb)->sb->RootDir.di_fname) != '/') {
		return "no qnx4 filesystem (no root dir).";
	} else {
		QNX4DEBUG(("QNX4 filesystem found on dev %s.\n", sb->s_id));
		rd = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_blk) - 1;
		rl = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_size);
		for (j = 0; j < rl; j++) {
			bh = sb_bread(sb, rd + j);	/* root dir, first block */
			if (bh == NULL) {
				return "unable to read root entry.";
			}
			for (i = 0; i < QNX4_INODES_PER_BLOCK; i++) {
				rootdir = (struct qnx4_inode_entry *) (bh->b_data + i * QNX4_DIR_ENTRY_SIZE);
				if (rootdir->di_fname != NULL) {
					QNX4DEBUG(("Rootdir entry found : [%s]\n", rootdir->di_fname));
					if (!strncmp(rootdir->di_fname, QNX4_BMNAME, sizeof QNX4_BMNAME)) {
						found = 1;
						qnx4_sb(sb)->BitMap = kmalloc( sizeof( struct qnx4_inode_entry ), GFP_KERNEL );
						if (!qnx4_sb(sb)->BitMap) {
							brelse (bh);
							return "not enough memory for bitmap inode";
						}
						memcpy( qnx4_sb(sb)->BitMap, rootdir, sizeof( struct qnx4_inode_entry ) );	/* keep bitmap inode known */
						break;
					}
				}
			}
			brelse(bh);
			if (found != 0) {
				break;
			}
		}
		if (found == 0) {
			return "bitmap file not found.";
		}
	}
	return NULL;
}
Ejemplo n.º 12
0
static void qnx4_read_inode(struct inode *inode)
{
	struct buffer_head *bh;
	struct qnx4_inode_entry *raw_inode;
	int block, ino;
	struct super_block *sb = inode->i_sb;
	struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode);

	ino = inode->i_ino;
	inode->i_mode = 0;

	QNX4DEBUG(("Reading inode : [%d]\n", ino));
	if (!ino) {
		printk("qnx4: bad inode number on dev %s: %d is out of range\n",
		       sb->s_id, ino);
		return;
	}
	block = ino / QNX4_INODES_PER_BLOCK;

	if (!(bh = sb_bread(sb, block))) {
		printk("qnx4: major problem: unable to read inode from dev "
		       "%s\n", sb->s_id);
		return;
	}
	raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
	    (ino % QNX4_INODES_PER_BLOCK);

	inode->i_mode    = le16_to_cpu(raw_inode->di_mode);
	inode->i_uid     = (uid_t)le16_to_cpu(raw_inode->di_uid);
	inode->i_gid     = (gid_t)le16_to_cpu(raw_inode->di_gid);
	inode->i_nlink   = le16_to_cpu(raw_inode->di_nlink);
	inode->i_size    = le32_to_cpu(raw_inode->di_size);
	inode->i_mtime.tv_sec   = le32_to_cpu(raw_inode->di_mtime);
	inode->i_mtime.tv_nsec = 0;
	inode->i_atime.tv_sec   = le32_to_cpu(raw_inode->di_atime);
	inode->i_atime.tv_nsec = 0;
	inode->i_ctime.tv_sec   = le32_to_cpu(raw_inode->di_ctime);
	inode->i_ctime.tv_nsec = 0;
	inode->i_blocks  = le32_to_cpu(raw_inode->di_first_xtnt.xtnt_size);
	inode->i_blksize = QNX4_DIR_ENTRY_SIZE;

	memcpy(qnx4_inode, raw_inode, QNX4_DIR_ENTRY_SIZE);
	if (S_ISREG(inode->i_mode)) {
		inode->i_op = &qnx4_file_inode_operations;
		inode->i_fop = &qnx4_file_operations;
		inode->i_mapping->a_ops = &qnx4_aops;
		qnx4_i(inode)->mmu_private = inode->i_size;
	} else if (S_ISDIR(inode->i_mode)) {
		inode->i_op = &qnx4_dir_inode_operations;
		inode->i_fop = &qnx4_dir_operations;
	} else if (S_ISLNK(inode->i_mode)) {
		inode->i_op = &page_symlink_inode_operations;
		inode->i_mapping->a_ops = &qnx4_aops;
		qnx4_i(inode)->mmu_private = inode->i_size;
	} else
		printk("qnx4: bad inode %d on dev %s\n",ino,sb->s_id);
	brelse(bh);
}
Ejemplo n.º 13
0
int qnx4_unlink(struct inode *dir, struct dentry *dentry)
{
	struct buffer_head *bh;
	struct qnx4_inode_entry *de;
	struct inode *inode;
	int retval;
	int ino;

	QNX4DEBUG(("qnx4: qnx4_unlink [%s]\n", dentry->d_name.name));
	lock_kernel();
	bh = qnx4_find_entry(dentry->d_name.len, dir, dentry->d_name.name,
			     &de, &ino);
	if (bh == NULL) {
		unlock_kernel();
		return -ENOENT;
	}
	inode = dentry->d_inode;
	if (inode->i_ino != ino) {
		retval = -EIO;
		goto end_unlink;
	}
	retval = -EPERM;
	if (!inode->i_nlink) {
		QNX4DEBUG(("Deleting nonexistent file (%s:%lu), %d\n",
			   inode->i_sb->s_id,
			   inode->i_ino, inode->i_nlink));
		inode->i_nlink = 1;
	}
	de->di_status = 0;
	memset(de->di_fname, 0, sizeof de->di_fname);
	de->di_mode = 0;
	mark_buffer_dirty(bh);
	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
	mark_inode_dirty(dir);
	inode->i_nlink--;
	inode->i_ctime = dir->i_ctime;
	mark_inode_dirty(inode);
	retval = 0;

end_unlink:
	unlock_kernel();
	brelse(bh);

	return retval;
}
Ejemplo n.º 14
0
int qnx4_create(struct inode *dir, struct dentry *dentry, int mode,
                struct nameidata *nd)
{
    QNX4DEBUG(("qnx4: qnx4_create\n"));
    if (dir == NULL) {
        return -ENOENT;
    }
    return -ENOSPC;
}
Ejemplo n.º 15
0
static void qnx4_delete_inode(struct inode *inode)
{
	QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino));
	truncate_inode_pages(&inode->i_data, 0);
	inode->i_size = 0;
	qnx4_truncate(inode);
	lock_kernel();
	qnx4_free_inode(inode);
	unlock_kernel();
}
Ejemplo n.º 16
0
static int qnx4_write_inode(struct inode *inode, int unused)
{
	struct qnx4_inode_entry *raw_inode;
	int block, ino;
	struct buffer_head *bh;
	ino = inode->i_ino;

	QNX4DEBUG(("qnx4: write inode 1.\n"));
	if (inode->i_nlink == 0) {
		return 0;
	}
	if (!ino) {
		printk("qnx4: bad inode number on dev %s: %d is out of range\n",
		       inode->i_sb->s_id, ino);
		return -EIO;
	}
	QNX4DEBUG(("qnx4: write inode 2.\n"));
	block = ino / QNX4_INODES_PER_BLOCK;
	lock_kernel();
	if (!(bh = sb_bread(inode->i_sb, block))) {
		printk("qnx4: major problem: unable to read inode from dev "
		       "%s\n", inode->i_sb->s_id);
		unlock_kernel();
		return -EIO;
	}
	raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
	    (ino % QNX4_INODES_PER_BLOCK);
	raw_inode->di_mode  = cpu_to_le16(inode->i_mode);
	raw_inode->di_uid   = cpu_to_le16(fs_high2lowuid(inode->i_uid));
	raw_inode->di_gid   = cpu_to_le16(fs_high2lowgid(inode->i_gid));
	raw_inode->di_nlink = cpu_to_le16(inode->i_nlink);
	raw_inode->di_size  = cpu_to_le32(inode->i_size);
	raw_inode->di_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
	raw_inode->di_atime = cpu_to_le32(inode->i_atime.tv_sec);
	raw_inode->di_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
	raw_inode->di_first_xtnt.xtnt_size = cpu_to_le32(inode->i_blocks);
	mark_buffer_dirty(bh);
	brelse(bh);
	unlock_kernel();
	return 0;
}
Ejemplo n.º 17
0
static int qnx4_get_block( struct inode *inode, sector_t iblock, struct buffer_head *bh, int create )
{
	unsigned long phys;

	QNX4DEBUG((KERN_INFO "qnx4: qnx4_get_block inode=[%ld] iblock=[%ld]\n",inode->i_ino,iblock));

	phys = qnx4_block_map( inode, iblock );
	if ( phys ) {
		// logical block is before EOF
		map_bh(bh, inode->i_sb, phys);
	}
	return 0;
}
Ejemplo n.º 18
0
void qnx4_truncate(struct inode *inode)
{
	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
	      S_ISLNK(inode->i_mode))) {
		return;
	}
	if (!(S_ISDIR(inode->i_mode))) {
		/* TODO */
	}
	QNX4DEBUG(("qnx4: qnx4_truncate called\n"));
	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
	mark_inode_dirty(inode);
}
Ejemplo n.º 19
0
struct inode *qnx4_iget(struct super_block *sb, unsigned long ino)
{
	struct buffer_head *bh;
	struct qnx4_inode_entry *raw_inode;
	int block;
	struct qnx4_inode_entry *qnx4_inode;
	struct inode *inode;

	inode = iget_locked(sb, ino);
	if (!inode)
		return ERR_PTR(-ENOMEM);
	if (!(inode->i_state & I_NEW))
		return inode;

	qnx4_inode = qnx4_raw_inode(inode);
	inode->i_mode = 0;

	QNX4DEBUG((KERN_INFO "reading inode : [%d]\n", ino));
	if (!ino) {
		printk(KERN_ERR "qnx4: bad inode number on dev %s: %lu is "
				"out of range\n",
		       sb->s_id, ino);
		iget_failed(inode);
		return ERR_PTR(-EIO);
	}
	block = ino / QNX4_INODES_PER_BLOCK;

	if (!(bh = sb_bread(sb, block))) {
		printk(KERN_ERR "qnx4: major problem: unable to read inode from dev "
		       "%s\n", sb->s_id);
		iget_failed(inode);
		return ERR_PTR(-EIO);
	}
	raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
	    (ino % QNX4_INODES_PER_BLOCK);

	inode->i_mode    = le16_to_cpu(raw_inode->di_mode);
	inode->i_uid     = (uid_t)le16_to_cpu(raw_inode->di_uid);
	inode->i_gid     = (gid_t)le16_to_cpu(raw_inode->di_gid);
	inode->i_nlink   = le16_to_cpu(raw_inode->di_nlink);
	inode->i_size    = le32_to_cpu(raw_inode->di_size);
	inode->i_mtime.tv_sec   = le32_to_cpu(raw_inode->di_mtime);
	inode->i_mtime.tv_nsec = 0;
	inode->i_atime.tv_sec   = le32_to_cpu(raw_inode->di_atime);
	inode->i_atime.tv_nsec = 0;
	inode->i_ctime.tv_sec   = le32_to_cpu(raw_inode->di_ctime);
	inode->i_ctime.tv_nsec = 0;
	inode->i_blocks  = le32_to_cpu(raw_inode->di_first_xtnt.xtnt_size);

	memcpy(qnx4_inode, raw_inode, QNX4_DIR_ENTRY_SIZE);
	if (S_ISREG(inode->i_mode)) {
		inode->i_fop = &generic_ro_fops;
		inode->i_mapping->a_ops = &qnx4_aops;
		qnx4_i(inode)->mmu_private = inode->i_size;
	} else if (S_ISDIR(inode->i_mode)) {
		inode->i_op = &qnx4_dir_inode_operations;
		inode->i_fop = &qnx4_dir_operations;
	} else if (S_ISLNK(inode->i_mode)) {
		inode->i_op = &page_symlink_inode_operations;
		inode->i_mapping->a_ops = &qnx4_aops;
		qnx4_i(inode)->mmu_private = inode->i_size;
	} else {
		printk(KERN_ERR "qnx4: bad inode %lu on dev %s\n",
			ino, sb->s_id);
		iget_failed(inode);
		brelse(bh);
		return ERR_PTR(-EIO);
	}
	brelse(bh);
	unlock_new_inode(inode);
	return inode;
}