Exemplo n.º 1
0
/*
 * Free an inode.
 *
 * the maintenance of the actual bitmaps is again up to the linux code
 */
int
ext2_vfree(struct vnode *pvp, ino_t ino, int mode)
{
	struct ext2_sb_info *fs;
	struct inode *pip;
	mode_t save_i_mode;

	pip = VTOI(pvp);
	fs = pip->i_e2fs;
	if ((u_int)ino > fs->s_inodes_per_group * fs->s_groups_count)
		panic("ext2_vfree: range: dev = (%d, %d), ino = %"PRId64", fs = %s",
		    major(pip->i_dev), minor(pip->i_dev), ino, fs->fs_fsmnt);

/* ext2_debug("ext2_vfree (%d, %d) called\n", pip->i_number, mode);
 */
	ext2_discard_prealloc(pip);

	/* we need to make sure that ext2_free_inode can adjust the
	   used_dir_counts in the group summary information - I'd
	   really like to know what the rationale behind this
	   'set i_mode to zero to denote an unused inode' is
	 */
	save_i_mode = pip->i_mode;
	pip->i_mode = mode;
	ext2_free_inode(pip);
	pip->i_mode = save_i_mode;
	return (0);
}
Exemplo n.º 2
0
/**
 * Remove the target file or link
 */
void ext2_rm(struct ext2_disk *disk, const char *target_file_name) {
    // Read info about the containing directory
    char *last_segment;
    uint32_t container_inode;
    struct ext2_inode *containing_directory = ext2_traverse_path(disk, NULL, target_file_name, &last_segment, &container_inode);

    struct ext2_directory_entry *entry;
    if ((entry = ext2_read_entry_from_directory(disk, containing_directory, last_segment)) == NULL) {
        // File does not exist
        errx(1, "File with name %s does not exist", last_segment);
    } else if (IS_DIRECTORY(ext2_get_inode(disk, 0, entry->inode_addr))) {
        // Target is a directory
        errx(1, "Cannot remove directory %s", last_segment);
    } else {
        // Save the inode number
        uint32_t inode_addr = entry->inode_addr;

        // Remove the directory entry by clearing its fields
        entry->inode_addr = 0;
        entry->size = 0;
        entry->name_length = 0;
        entry->type_indicator = 0;
        entry->name = 0;

        // Decrement the hard link count
        if (--ext2_get_inode(disk, 0, inode_addr)->num_links == 0)
            // No more hard links point to the inode; free the inode and data blocks
            ext2_free_inode(disk, inode_addr);
    }
}
Exemplo n.º 3
0
/*
 * Called at the last iput() if i_nlink is zero.
 */
void ext2_delete_inode (struct inode * inode)
{
	if (is_bad_inode(inode))
		goto no_delete;
	EXT2_I(inode)->i_dtime	= get_seconds();
	mark_inode_dirty(inode);
	ext2_update_inode(inode, inode_needs_sync(inode));

	inode->i_size = 0;
	if (inode->i_blocks)
		ext2_truncate (inode);
	ext2_free_inode (inode);

	return;
no_delete:
	clear_inode(inode);	/* We must guarantee clearing of inode... */
}
/*
 * Called at the last iput() if i_nlink is zero.
 */
void ext2_delete_inode (struct inode * inode)
{
	lock_kernel();

	if (is_bad_inode(inode))
		goto no_delete;
	inode->u.ext2_i.i_dtime	= CURRENT_TIME;
	mark_inode_dirty(inode);
	ext2_update_inode(inode, IS_SYNC(inode));
	inode->i_size = 0;
	if (inode->i_blocks)
		ext2_truncate (inode);
	ext2_free_inode (inode);

	unlock_kernel();
	return;
no_delete:
	unlock_kernel();
	clear_inode(inode);	/* We must guarantee clearing of inode... */
}
Exemplo n.º 5
0
/*
 * Called at the last iput() if i_nlink is zero.
 */
void ext2_evict_inode(struct inode * inode)
{
	struct ext2_block_alloc_info *rsv;
	int want_delete = 0;

	if (!inode->i_nlink && !is_bad_inode(inode)) {
		want_delete = 1;
		dquot_initialize(inode);
	} else {
		dquot_drop(inode);
	}

	truncate_inode_pages_final(&inode->i_data);

	if (want_delete) {
		sb_start_intwrite(inode->i_sb);
		/* set dtime */
		EXT2_I(inode)->i_dtime	= get_seconds();
		mark_inode_dirty(inode);
		__ext2_write_inode(inode, inode_needs_sync(inode));
		/* truncate to 0 */
		inode->i_size = 0;
		if (inode->i_blocks)
			ext2_truncate_blocks(inode, 0);
		ext2_xattr_delete_inode(inode);
	}

	invalidate_inode_buffers(inode);
	clear_inode(inode);

	ext2_discard_reservation(inode);
	rsv = EXT2_I(inode)->i_block_alloc_info;
	EXT2_I(inode)->i_block_alloc_info = NULL;
	if (unlikely(rsv))
		kfree(rsv);

	if (want_delete) {
		ext2_free_inode(inode);
		sb_end_intwrite(inode->i_sb);
	}
}