static void free_branches(struct inode *inode, block_t *p, block_t *q, int depth)
{
	struct buffer_head * bh;
	unsigned long nr;

	if (depth--) {
		for ( ; p < q ; p++) {
			nr = block_to_cpu(*p);
			if (!nr)
				continue;
			*p = 0;
			bh = sb_bread(inode->i_sb, nr);
			if (!bh)
				continue;
			free_branches(inode, (block_t*)bh->b_data,
				      block_end(bh), depth);
			bforget(bh);
			minix_free_block(inode, nr);
			mark_inode_dirty(inode);
		}
	} else
		free_data(inode, p, q);
}
static inline int splice_branch(struct inode *inode,
				     Indirect chain[DEPTH],
				     Indirect *where,
				     int num)
{
	int i;

	write_lock(&pointers_lock);

	/*                                                                */
	if (!verify_chain(chain, where-1) || *where->p)
		goto changed;

	*where->p = where->key;

	write_unlock(&pointers_lock);

	/*                                                                */

	inode->i_ctime = CURRENT_TIME_SEC;

	/*                                        */
	if (where->bh)
		mark_buffer_dirty_inode(where->bh, inode);

	mark_inode_dirty(inode);
	return 0;

changed:
	write_unlock(&pointers_lock);
	for (i = 1; i < num; i++)
		bforget(where[i].bh);
	for (i = 0; i < num; i++)
		minix_free_block(inode, block_to_cpu(where[i].key));
	return -EAGAIN;
}
Exemplo n.º 3
0
static inline int splice_branch(struct inode *inode,
				     Indirect chain[DEPTH],
				     Indirect *where,
				     int num)
{
	int i;

	write_lock(&pointers_lock);

	/* Verify that place we are splicing to is still there and vacant */
	if (!verify_chain(chain, where-1) || *where->p)
		goto changed;

	*where->p = where->key;

	write_unlock(&pointers_lock);

	/* We are done with atomic stuff, now do the rest of housekeeping */

	inode->i_ctime = CURRENT_TIME_SEC;

	/* had we spliced it onto indirect block? */
	if (where->bh)
		mark_buffer_dirty_inode(where->bh, inode);

	mark_inode_dirty(inode);
	return 0;

changed:
	write_unlock(&pointers_lock);
	for (i = 1; i < num; i++)
		bforget(where[i].bh);
	for (i = 0; i < num; i++)
		minix_free_block(inode, block_to_cpu(where[i].key));
	return -EAGAIN;
}
Exemplo n.º 4
0
static int V1_trunc_indirect(register struct inode *inode,
			     int offset, unsigned short *p)
{
    struct buffer_head *bh;
    int i;
    unsigned short tmp;
    register struct buffer_head *ind_bh;
    unsigned short *ind;
    int retry = 0;

    tmp = *p;
    if (!tmp)
	return 0;
    ind_bh = bread(inode->i_dev, (block_t) tmp);
    if (tmp != *p) {
	brelse(ind_bh);
	return 1;
    }
    if (!ind_bh) {
	*p = 0;
	return 0;
    }
    map_buffer(ind_bh);
  repeat:
    for (i = INDIRECT_BLOCK(offset); i < 512; i++) {
	if (i < 0) {
	    i = 0;
	} else if (i < INDIRECT_BLOCK(offset)) {
	    goto repeat;
	}
	ind = i + (unsigned short *) ind_bh->b_data;
	tmp = *ind;
	if (!tmp)
	    continue;
	bh = get_hash_table(inode->i_dev, (block_t) tmp);
	if (i < INDIRECT_BLOCK(offset)) {
	    brelse(bh);
	    goto repeat;
	}
	if ((bh && bh->b_count != 1) || tmp != *ind) {
	    retry = 1;
	    brelse(bh);
	    continue;
	}
	*ind = 0;
	mark_buffer_dirty(ind_bh, 1);
	brelse(bh);
	minix_free_block(inode->i_sb, tmp);
    }
    ind = (unsigned short *) ind_bh->b_data;
    for (i = 0; i < 512; i++)
	if (*(ind++))
	    break;
    if (i >= 512)
	if (ind_bh->b_count != 1)
	    retry = 1;
	else {
	    tmp = *p;
	    *p = 0;
	    minix_free_block(inode->i_sb, tmp);
	}
    unmap_brelse(ind_bh);
    return retry;
}