i_size_write(ino, 0);
truncate_inode_pages(&ino->i_data, 0);
LAFSI(ino)->trunc_next = 0;
+ set_bit(I_Deleting, &LAFSI(ino)->iflags);
set_bit(I_Trunc, &LAFSI(ino)->iflags);
+ lafs_igrab_fs(ino);
- set_bit(I_Deleting, &LAFSI(ino)->iflags);
if (!IS_ERR(b)) {
set_bit(B_Claimed, &b->b.flags);
lafs_add_orphan(fs, b);
/* must be finished */
LAFS_BUG(test_bit(B_Dirty, &ib->b.flags), &ib->b);
clear_bit(I_Trunc, &LAFSI(ino)->iflags);
- if (!test_bit(I_Deleting, &LAFSI(ino)->iflags))
- iput(ino);
+ lafs_iput_fs(ino);
wake_up(&fs->trunc_wait);
err = -ERESTARTSYS;
goto out2;
/* Must be all done */
spin_unlock(&ib->b.inode->i_data.private_lock);
clear_bit(I_Trunc, &LAFSI(ino)->iflags);
- if (!test_bit(I_Deleting, &LAFSI(ino)->iflags))
- iput(ino);
+ lafs_iput_fs(ino);
wake_up(&fs->trunc_wait);
err = -ERESTARTSYS;
goto out2;
if (LAFSI(ino)->depth == 0) {
/* Nothing to truncate */
clear_bit(I_Trunc, &LAFSI(ino)->iflags);
- if (!test_bit(I_Deleting, &LAFSI(ino)->iflags))
- iput(ino);
+ lafs_iput_fs(ino);
if (test_bit(B_Pinned, &ib->b.flags))
/* Need to move the dirtiness which keeps this
* pinned to the data block.
lafs_make_orphan(fs, db);
if (!test_and_set_bit(I_Trunc, &LAFSI(ino)->iflags))
- igrab(ino);
+ lafs_igrab_fs(ino);
if (trunc_block == 0)
LAFSI(ino)->trunc_gen++;
LAFSI(ino)->trunc_next = trunc_block;
static inline void lafs_iput_fs(struct inode *ino)
{
struct super_block *sb = ino->i_sb;
- iput(ino);
+ if (!test_bit(I_Deleting, &LAFSI(ino)->iflags))
+ iput(ino);
deactivate_super(sb);
}
static inline void lafs_igrab_fs(struct inode *ino)
{
- igrab(ino);
+ if (igrab(ino) == NULL &&
+ !test_bit(I_Deleting, &LAFSI(ino)->iflags))
+ BUG();
atomic_inc(&ino->i_sb->s_active);
}