void minix_truncate(register struct inode *inode) { int retry; if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) return; while (1) { retry = V1_trunc_direct(inode); retry |= V1_trunc_indirect(inode, 7, &inode->i_zone[7]); retry |= V1_trunc_dindirect(inode, 7 + 512, &inode->i_zone[8]); if (!retry) break; schedule(); } inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_dirt = 1; }
static int V1_trunc_dindirect(register struct inode *inode, int offset, unsigned short *p) { int i; unsigned short tmp; register struct buffer_head *dind_bh; unsigned short *dind; int retry = 0; if (!(tmp = *p)) return 0; dind_bh = bread(inode->i_dev, (block_t) tmp); if (tmp != *p) { brelse(dind_bh); return 1; } if (!dind_bh) { *p = 0; return 0; } map_buffer(dind_bh); repeat: for (i = DINDIRECT_BLOCK(offset); i < 512; i++) { if (i < 0) i = 0; if (i < DINDIRECT_BLOCK(offset)) goto repeat; dind = i + (unsigned short *) dind_bh->b_data; retry |= V1_trunc_indirect(inode, offset + (i << 9), dind); mark_buffer_dirty(dind_bh, 1); } dind = (unsigned short *) dind_bh->b_data; for (i = 0; i < 512; i++) if (*(dind++)) break; if (i >= 512) if (dind_bh->b_count != 1) retry = 1; else { tmp = *p; *p = 0; inode->i_dirt = 1; minix_free_block(inode->i_sb, tmp); } unmap_brelse(dind_bh); return retry; }