* wait for any pending IO to complete (so page can be freed)
*/
for (i=0; i<(1<<bits); i++) {
- if (start >= size) {
- if (test_bit(B_Dirty, &b[i].b.flags) ||
- test_bit(B_Realloc, &b[i].b.flags) ||
- test_bit(B_Uninc, &b[i].b.flags) ||
- test_bit(B_PinPending, &b[i].b.flags))
- lafs_erase_dblock(&b[i]);
- } else if (b_start >= offset) {
+ if (start >= size)
+ /* Remove block from mapping and file */
+ lafs_erase_dblock(&b[i]);
+ else if (b_start >= offset) {
+ /* Just remove block from mapping */
lafs_iolock_block(&b[i].b);
BUG_ON(test_bit(B_Dirty, &b[i].b.flags));
BUG_ON(test_bit(B_Realloc, &b[i].b.flags));
lafs_erase_dblock(struct datablock *b)
{
struct fs *fs = fs_from_inode(b->b.inode);
- if (!b->b.parent) {
- printk("erase with no parent: %s\n", strblk(&b->b));
- BUG();
- /* We have indirect ref on ->iblock so it can be de-refed */
- }
+
dprintk("Eraseblock for %s\n", strblk(&b->b));
if (b->b.physaddr == 0 &&
b->b.fileaddr == 0 &&
LAFSI(b->b.inode)->depth == 0) {
-#if 0
- /* This lives in the inode, so we cannot drop the
- * block, we have to zero it.
- */
- char *buf = map_dblock(b);
- memset(buf, 0, (1<<b->b.inode->i_blkbits));
- unmap_dblock(b, buf);
- return;
-#else
/* We need to clear out the index block that this
* block lives in.
+ * Need private_lock to be allowed to dereference ->iblock
*/
- BUG_ON(LAFSI(b->b.inode)->depth != LAFSI(b->b.inode)->iblock->depth);
- lafs_clear_index(LAFSI(b->b.inode)->iblock);
- clear_bit(B_PhysValid, &b->b.flags);
-#endif
+ spin_lock(&b->b.inode->i_data.private_lock);
+ if (LAFSI(b->b.inode)->iblock) {
+ BUG_ON(LAFSI(b->b.inode)->depth !=
+ LAFSI(b->b.inode)->iblock->depth);
+ lafs_clear_index(LAFSI(b->b.inode)->iblock);
+ clear_bit(B_PhysValid, &b->b.flags);
+ }
+ spin_unlock(&b->b.inode->i_data.private_lock);
}
-#if 0
- /* We aren't dirtying the block, but we do need to write it,
- * so moving ICredit to UnincCredit for consistency.
- * It won't be needed, so maybe I shouldn't need to bother?
- */
- if (!test_and_set_bit(B_UnincCredit, &b->b.flags))
- if (!test_and_clear_bit(B_ICredit, &b->b.flags))
- BUG(); // ICredit should be set before we dirty a block.
-#endif
lafs_iolock_block(&b->b);
if (LAFSI(b->b.inode)->type == TypeInodeFile &&
} else
spin_unlock(&fs->lock);
- if (b->b.physaddr)
+ if (b->b.parent == NULL)
+ /* Erasing a block that isn't in the indexing tree only
+ * happens when truncating and lafs_invalidate_page is called
+ * on some clean page.
+ * So we don't clear out physaddr here, but instead leave that
+ * to the core truncate code.
+ * Just remove B_PhysValid to avoid confusion.
+ */
+ clear_bit(B_PhysValid, &b->b.flags);
+ else if (b->b.physaddr)
lafs_allocated_block(fs, &b->b, 0);
- else {
+ else
if (test_and_clear_bit(B_UnincCredit, &b->b.flags))
lafs_space_return(fs, 1);
- }
+
lafs_iounlock_block(&b->b, 0);
}