/* * called when an entry is deleted, need to clear the bits in the * bitmaps. */ static void omfs_delete_inode(struct inode *inode) { truncate_inode_pages(&inode->i_data, 0); if (S_ISREG(inode->i_mode)) { inode->i_size = 0; omfs_shrink_inode(inode); } omfs_clear_range(inode->i_sb, inode->i_ino, 2); clear_inode(inode); }
/* * called when an entry is deleted, need to clear the bits in the * bitmaps. */ static void omfs_evict_inode(struct inode *inode) { truncate_inode_pages_final(&inode->i_data); clear_inode(inode); if (inode->i_nlink) return; if (S_ISREG(inode->i_mode)) { inode->i_size = 0; omfs_shrink_inode(inode); } omfs_clear_range(inode->i_sb, inode->i_ino, 2); }
int omfs_shrink_inode(struct inode *inode) { struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); struct omfs_extent *oe; struct omfs_extent_entry *entry; struct buffer_head *bh; u64 next, last; u32 extent_count; u32 max_extents; int ret; /* traverse extent table, freeing each entry that is greater * than inode->i_size; */ next = inode->i_ino; /* only support truncate -> 0 for now */ ret = -EIO; if (inode->i_size != 0) goto out; bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); if (!bh) goto out; oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]); max_extents = omfs_max_extents(sbi, OMFS_EXTENT_START); for (;;) { if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next)) goto out_brelse; extent_count = be32_to_cpu(oe->e_extent_count); if (extent_count > max_extents) goto out_brelse; last = next; next = be64_to_cpu(oe->e_next); entry = &oe->e_entry; /* ignore last entry as it is the terminator */ for (; extent_count > 1; extent_count--) { u64 start, count; start = be64_to_cpu(entry->e_cluster); count = be64_to_cpu(entry->e_blocks); omfs_clear_range(inode->i_sb, start, (int) count); entry++; } omfs_make_empty_table(bh, (char *) oe - bh->b_data); mark_buffer_dirty(bh); brelse(bh); if (last != inode->i_ino) omfs_clear_range(inode->i_sb, last, sbi->s_mirrors); if (next == ~0) break; bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); if (!bh) goto out; oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); max_extents = omfs_max_extents(sbi, OMFS_EXTENT_CONT); } ret = 0; out: return ret; out_brelse: brelse(bh); return ret; }