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; }
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; }
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; }