コード例 #1
0
ファイル: ext2_inode.c プロジェクト: JasonFord53/freebsd
/*
 *	discard preallocated blocks
 */
int
ext2_inactive(struct vop_inactive_args *ap)
{
	struct vnode *vp = ap->a_vp;
	struct inode *ip = VTOI(vp);
	struct thread *td = ap->a_td;
	int mode, error = 0;

	/*
	 * Ignore inodes related to stale file handles.
	 */
	if (ip->i_mode == 0)
		goto out;
	if (ip->i_nlink <= 0) {
		error = ext2_truncate(vp, (off_t)0, 0, NOCRED, td);
		ip->i_rdev = 0;
		mode = ip->i_mode;
		ip->i_mode = 0;
		ip->i_flag |= IN_CHANGE | IN_UPDATE;
		ext2_vfree(vp, ip->i_number, mode);
	}
	if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE))
		ext2_update(vp, 0);
out:
	/*
	 * If we are done with the inode, reclaim it
	 * so that it can be reused immediately.
	 */
	if (ip->i_mode == 0)
		vrecycle(vp);
	return (error);
}
コード例 #2
0
ファイル: ext2_alloc.c プロジェクト: jamesbjackson/src
/*
 * Allocate an inode in the filesystem.
 *
 */
int
ext2_valloc(struct vnode *pvp, int mode, struct ucred *cred, struct vnode **vpp)
{
    struct timespec ts;
    struct inode *pip;
    struct m_ext2fs *fs;
    struct inode *ip;
    struct ext2mount *ump;
    ino_t ino, ipref;
    int i, error, cg;

    *vpp = NULL;
    pip = VTOI(pvp);
    fs = pip->i_e2fs;
    ump = pip->i_ump;

    EXT2_LOCK(ump);
    if (fs->e2fs->e2fs_ficount == 0)
        goto noinodes;
    /*
     * If it is a directory then obtain a cylinder group based on
     * ext2_dirpref else obtain it using ino_to_cg. The preferred inode is
     * always the next inode.
     */
    if ((mode & IFMT) == IFDIR) {
        cg = ext2_dirpref(pip);
        if (fs->e2fs_contigdirs[cg] < 255)
            fs->e2fs_contigdirs[cg]++;
    } else {
        cg = ino_to_cg(fs, pip->i_number);
        if (fs->e2fs_contigdirs[cg] > 0)
            fs->e2fs_contigdirs[cg]--;
    }
    ipref = cg * fs->e2fs->e2fs_ipg + 1;
    ino = (ino_t)ext2_hashalloc(pip, cg, (long)ipref, mode, ext2_nodealloccg);

    if (ino == 0)
        goto noinodes;
    error = VFS_VGET(pvp->v_mount, ino, LK_EXCLUSIVE, vpp);
    if (error) {
        ext2_vfree(pvp, ino, mode);
        return (error);
    }
    ip = VTOI(*vpp);

    /*
     * The question is whether using VGET was such good idea at all:
     * Linux doesn't read the old inode in when it is allocating a
     * new one. I will set at least i_size and i_blocks to zero.
     */
    ip->i_size = 0;
    ip->i_blocks = 0;
    ip->i_mode = 0;
    ip->i_flags = 0;
    /* now we want to make sure that the block pointers are zeroed out */
    for (i = 0; i < NDADDR; i++)
        ip->i_db[i] = 0;
    for (i = 0; i < NIADDR; i++)
        ip->i_ib[i] = 0;

    /*
     * Set up a new generation number for this inode.
     * XXX check if this makes sense in ext2
     */
    if (ip->i_gen == 0 || ++ip->i_gen == 0)
        ip->i_gen = random() / 2 + 1;

    vfs_timestamp(&ts);
    ip->i_birthtime = ts.tv_sec;
    ip->i_birthnsec = ts.tv_nsec;

    /*
    printf("ext2_valloc: allocated inode %d\n", ino);
    */
    return (0);
noinodes:
    EXT2_UNLOCK(ump);
    ext2_fserr(fs, cred->cr_uid, "out of inodes");
    uprintf("\n%s: create/symlink failed, no inodes free\n", fs->e2fs_fsmnt);
    return (ENOSPC);
}