コード例 #1
0
/*
 * Allocate an inode in the file system.
 *
 * we leave the actual allocation strategy to the (modified)
 * ext2_new_inode(), to make sure we get the policies right
 */
int
ext2_valloc(struct vnode *pvp, int mode, struct ucred *cred, struct vnode **vpp)
{
	struct inode *pip;
	struct ext2_sb_info *fs;
	struct inode *ip;
	ino_t ino;
	int i, error;

	*vpp = NULL;
	pip = VTOI(pvp);
	fs = pip->i_e2fs;
	if (fs->s_es->s_free_inodes_count == 0)
		goto noinodes;

	/* call the Linux routine - it returns the inode number only */
	ino = ext2_new_inode(pip, mode);

	if (ino == 0)
		goto noinodes;
	error = VFS_VGET(pvp->v_mount, NULL, ino, 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's allocating a
	  new one. I will set at least i_size & i_blocks the zero.
	*/
	ip->i_mode = 0;
	ip->i_size = 0;
	ip->i_blocks = 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 = krandom() / 2 + 1;
/*
kprintf("ext2_valloc: allocated inode %d\n", ino);
*/
	return (0);
noinodes:
	ext2_fserr(fs, cred->cr_uid, "out of inodes");
	uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt);
	return (ENOSPC);
}
コード例 #2
0
/*
 * Last reference to an inode.  If necessary, write or delete it.
 *
 * ext2_inactive(struct vnode *a_vp)
 */
int
ext2_inactive(struct vop_inactive_args *ap)
{
    struct vnode *vp = ap->a_vp;
    struct inode *ip = VTOI(vp);
    int mode, error = 0;

    ext2_discard_prealloc(ip);
    if (prtactive && vp->v_sysref.refcnt > 1)
        vprint("ext2_inactive: pushing active", vp);

    /*
     * Ignore inodes related to stale file handles.
     */
    if (ip == NULL || ip->i_mode == 0)
        goto out;
    if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
#ifdef QUOTA
        if (!ext2_getinoquota(ip))
            (void)ext2_chkiq(ip, -1, NOCRED, FORCE);
#endif
        error = EXT2_TRUNCATE(vp, (off_t)0, 0, NOCRED);
        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 == NULL || ip->i_mode == 0)
        vrecycle(vp);
    return (error);
}