示例#1
0
struct inode *sysv_iget(struct super_block *sb, unsigned int ino)
{
	struct sysv_sb_info * sbi = SYSV_SB(sb);
	struct buffer_head * bh;
	struct sysv_inode * raw_inode;
	struct sysv_inode_info * si;
	struct inode *inode;
	unsigned int block;

	if (!ino || ino > sbi->s_ninodes) {
		printk("Bad inode number on dev %s: %d is out of range\n",
		       sb->s_id, ino);
		return ERR_PTR(-EIO);
	}

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

	raw_inode = sysv_raw_inode(sb, ino, &bh);
	if (!raw_inode) {
		printk("Major problem: unable to read inode from dev %s\n",
		       inode->i_sb->s_id);
		goto bad_inode;
	}
	/* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */
	inode->i_mode = fs16_to_cpu(sbi, raw_inode->i_mode);
	inode->i_uid = (uid_t)fs16_to_cpu(sbi, raw_inode->i_uid);
	inode->i_gid = (gid_t)fs16_to_cpu(sbi, raw_inode->i_gid);
	set_nlink(inode, fs16_to_cpu(sbi, raw_inode->i_nlink));
	inode->i_size = fs32_to_cpu(sbi, raw_inode->i_size);
	inode->i_atime.tv_sec = fs32_to_cpu(sbi, raw_inode->i_atime);
	inode->i_mtime.tv_sec = fs32_to_cpu(sbi, raw_inode->i_mtime);
	inode->i_ctime.tv_sec = fs32_to_cpu(sbi, raw_inode->i_ctime);
	inode->i_ctime.tv_nsec = 0;
	inode->i_atime.tv_nsec = 0;
	inode->i_mtime.tv_nsec = 0;
	inode->i_blocks = 0;

	si = SYSV_I(inode);
	for (block = 0; block < 10+1+1+1; block++)
		read3byte(sbi, &raw_inode->i_data[3*block],
				(u8 *)&si->i_data[block]);
	brelse(bh);
	si->i_dir_start_lookup = 0;
	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
		sysv_set_inode(inode,
			       old_decode_dev(fs32_to_cpu(sbi, si->i_data[0])));
	else
		sysv_set_inode(inode, 0);
	unlock_new_inode(inode);
	return inode;

bad_inode:
	iget_failed(inode);
	return ERR_PTR(-EIO);
}
示例#2
0
static int sysv_symlink(struct inode * dir, struct dentry * dentry,
                        const char * symname)
{
    int err = -ENAMETOOLONG;
    int l = strlen(symname)+1;
    struct inode * inode;

    if (l > dir->i_sb->s_blocksize)
        goto out;

    inode = sysv_new_inode(dir, S_IFLNK|0777);
    err = PTR_ERR(inode);
    if (IS_ERR(inode))
        goto out;

    sysv_set_inode(inode, 0);
    err = page_symlink(inode, symname, l);
    if (err)
        goto out_fail;

    mark_inode_dirty(inode);
    err = add_nondir(dentry, inode);
out:
    return err;

out_fail:
    inode_dec_link_count(inode);
    iput(inode);
    goto out;
}
示例#3
0
static int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev)
{
	struct inode * inode = sysv_new_inode(dir, mode);
	int err = PTR_ERR(inode);

	if (!IS_ERR(inode)) {
		sysv_set_inode(inode, rdev);
		mark_inode_dirty(inode);
		err = add_nondir(dentry, inode);
	}
	return err;
}
示例#4
0
文件: namei.c 项目: 19Dan01/linux
static int sysv_mknod(struct inode * dir, struct dentry * dentry, umode_t mode, dev_t rdev)
{
	struct inode * inode;
	int err;

	if (!old_valid_dev(rdev))
		return -EINVAL;

	inode = sysv_new_inode(dir, mode);
	err = PTR_ERR(inode);

	if (!IS_ERR(inode)) {
		sysv_set_inode(inode, rdev);
		mark_inode_dirty(inode);
		err = add_nondir(dentry, inode);
	}
	return err;
}
示例#5
0
static void sysv_read_inode(struct inode *inode)
{
	struct super_block * sb = inode->i_sb;
	struct buffer_head * bh;
	struct sysv_inode * raw_inode;
	unsigned int block, ino;
	dev_t rdev = 0;

	ino = inode->i_ino;
	if (!ino || ino > sb->sv_ninodes) {
		printk("Bad inode number on dev %s: %d is out of range\n",
		       inode->i_sb->s_id, ino);
		goto bad_inode;
	}
	raw_inode = sysv_raw_inode(sb, ino, &bh);
	if (!raw_inode) {
		printk("Major problem: unable to read inode from dev %s\n",
		       inode->i_sb->s_id);
		goto bad_inode;
	}
	/* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */
	inode->i_mode = fs16_to_cpu(sb, raw_inode->i_mode);
	inode->i_uid = (uid_t)fs16_to_cpu(sb, raw_inode->i_uid);
	inode->i_gid = (gid_t)fs16_to_cpu(sb, raw_inode->i_gid);
	inode->i_nlink = fs16_to_cpu(sb, raw_inode->i_nlink);
	inode->i_size = fs32_to_cpu(sb, raw_inode->i_size);
	inode->i_atime = fs32_to_cpu(sb, raw_inode->i_atime);
	inode->i_mtime = fs32_to_cpu(sb, raw_inode->i_mtime);
	inode->i_ctime = fs32_to_cpu(sb, raw_inode->i_ctime);
	inode->i_blocks = inode->i_blksize = 0;
	for (block = 0; block < 10+1+1+1; block++)
		read3byte(sb, &raw_inode->i_a.i_addb[3*block],
			(unsigned char*)&inode->u.sysv_i.i_data[block]);
	brelse(bh);
	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
		rdev = (u16)fs32_to_cpu(sb, inode->u.sysv_i.i_data[0]);
	inode->u.sysv_i.i_dir_start_lookup = 0;
	sysv_set_inode(inode, rdev);
	return;

bad_inode:
	make_bad_inode(inode);
	return;
}
示例#6
0
static int sysv_mkdir(struct inode * dir, struct dentry *dentry, int mode)
{
    struct inode * inode;
    int err = -EMLINK;

    if (dir->i_nlink >= SYSV_SB(dir->i_sb)->s_link_max)
        goto out;
    inode_inc_link_count(dir);

    inode = sysv_new_inode(dir, S_IFDIR|mode);
    err = PTR_ERR(inode);
    if (IS_ERR(inode))
        goto out_dir;

    sysv_set_inode(inode, 0);

    inode_inc_link_count(inode);

    err = sysv_make_empty(inode, dir);
    if (err)
        goto out_fail;

    err = sysv_add_link(dentry, inode);
    if (err)
        goto out_fail;

    d_instantiate(dentry, inode);
out:
    return err;

out_fail:
    inode_dec_link_count(inode);
    inode_dec_link_count(inode);
    iput(inode);
out_dir:
    inode_dec_link_count(dir);
    goto out;
}