We currently hold a refcount on the inodes of dir orphans.
We need the filesystem (super_block) as well.
Also, while we don't really need a similar refcount for inode orphans,
it doesn't hurt.
So simplify the tracking of whether we need to take such a refcount,
use iget_fs to grab the super_block as well, and also take a ref in
lafs_add_orphans, which was missing.
Signed-off-by: NeilBrown <neilb@suse.de>
unmap_dblock(dirblk, buf);
}
if (orphan)
- return lafs_make_orphan(fs, doh->dirent_block, dir);
+ return lafs_make_orphan(fs, doh->dirent_block);
return 0;
}
if (IS_ERR(inodb))
err = PTR_ERR(inodb);
if (last && !err)
- err = lafs_make_orphan(fs, inodb, NULL);
+ err = lafs_make_orphan(fs, inodb);
if (err)
goto abort;
lafs_iolock_block(&inodb->b);
if (IS_ERR(inodb))
err = PTR_ERR(inodb);
if (!err)
- err = lafs_make_orphan(fs, inodb, NULL);
+ err = lafs_make_orphan(fs, inodb);
if (err)
goto abort;
lafs_iolock_block(&inodb->b);
if (IS_ERR(newdb))
err = PTR_ERR(newdb);
if (last && !err)
- err = lafs_make_orphan(fs, newdb, NULL);
+ err = lafs_make_orphan(fs, newdb);
lafs_iolock_block(&newdb->b);
set_bit(B_PinPending, &newdb->b.flags);
lafs_iounlock_block(&newdb->b);
* space being tight.
* just try again
*/
- lafs_orphan_release(fs, b, dir);
+ lafs_orphan_release(fs, b);
err = 0;
goto abort;
}
if (lafs_dir_find(buf2, bits, seed, (hash-1) & MaxDirHash,
&piece) &&
lafs_dir_extract(buf2, bits, &de, piece, NULL)->target == 0)
- err = lafs_make_orphan_nb(fs, b2, dir);
+ err = lafs_make_orphan_nb(fs, b2);
unmap_dblock(b2, buf2);
putdref(b2, MKREF(dir_orphan));
b2 = NULL;
} else
unmap_dblock(b, buf);
- lafs_orphan_release(fs, b, dir);
+ lafs_orphan_release(fs, b);
err = 0;
abort:
LAFSI(ino)->ciblocks +
LAFSI(ino)->piblocks);
if (lafs_erase_dblock_async(b))
- lafs_orphan_release(fs, b, NULL);
+ lafs_orphan_release(fs, b);
} else if (ino->i_nlink || LAFSI(ino)->type == 0)
- lafs_orphan_release(fs, b, NULL);
+ lafs_orphan_release(fs, b);
else
lafs_orphan_forget(fs, b);
return 0;
clear_bit(B_Claimed, &imni->ib->b.flags);
clear_bit(B_PinPending, &imni->ib->b.flags);
lafs_orphan_release(fs_from_inode(imni->ib->b.inode),
- imni->ib, NULL);
+ imni->ib);
}
putdref(imni->ib, MKREF(cfi_ino));
if (imni->mb) {
err = lafs_cluster_update_prepare(&ui, fs, sizeof(struct la_inode))
?: err;
if (err == 0)
- err = lafs_make_orphan(fs, imni.ib, NULL);
+ err = lafs_make_orphan(fs, imni.ib);
if (err)
goto abort;
retry:
* If this doesn't get registered as an orphan .... maybe
* it will have to wait until something else truncates it.
*/
- lafs_make_orphan(fs, db, NULL);
+ lafs_make_orphan(fs, db);
if (!test_and_set_bit(I_Trunc, &LAFSI(ino)->iflags))
igrab(ino);
unsigned long lafs_do_checkpoint(struct fs *fs);
struct block *lafs_get_flushable(struct fs *fs, int phase);
-int lafs_make_orphan(struct fs *fs, struct datablock *db, struct inode *ino);
-int lafs_make_orphan_nb(struct fs *fs, struct datablock *db, struct inode *ino);
-void lafs_orphan_release(struct fs *fs, struct datablock *b, struct inode *ino);
+int lafs_make_orphan(struct fs *fs, struct datablock *db);
+int lafs_make_orphan_nb(struct fs *fs, struct datablock *db);
+void lafs_orphan_release(struct fs *fs, struct datablock *db);
long lafs_run_orphans(struct fs *fs);
void lafs_add_orphan(struct fs *fs, struct datablock *db);
void lafs_orphan_forget(struct fs *fs, struct datablock *db);
b->orphan_slot = om->nextfree++;
set_bit(B_Orphan, &b->b.flags);
getdref(b, MKREF(orphan_flag));
+ lafs_igrab_fs(b->b.inode);
lafs_add_orphan(fs, b);
dprintk("%p->orphan_slot=%d (%lu,%lu,%lu) %s\n", b, b->orphan_slot,
* For directories, i_mutex is used for this.
* For inodes, B_IOLock is used.
*/
-int lafs_make_orphan(struct fs *fs, struct datablock *db, struct inode *ino)
+int lafs_make_orphan(struct fs *fs, struct datablock *db)
{
int err;
struct datablock *ob;
if (IS_ERR(ob)) {
orphan_abort(fs);
err = PTR_ERR(ob);
- } else {
+ } else
orphan_commit(fs, db, ob);
- if (ino)
- igrab(ino);
- }
+
mutex_unlock(&fs->orphans->i_mutex);
lafs_checkpoint_unlock(fs);
return err;
}
/* non-blocking version of make_orphan */
-int lafs_make_orphan_nb(struct fs *fs, struct datablock *db, struct inode *ino)
+int lafs_make_orphan_nb(struct fs *fs, struct datablock *db)
{
int err;
struct datablock *ob;
if (IS_ERR(ob)) {
orphan_abort(fs);
err = PTR_ERR(ob);
- } else {
+ } else
orphan_commit(fs, db, ob);
- if (ino)
- igrab(ino);
- }
+
mutex_unlock(&fs->orphans->i_mutex);
lafs_checkpoint_unlock(fs);
return err;
* like a spinlock, and erase_dblock should not block as the block
* should be PinPending;
*/
-void lafs_orphan_release(struct fs *fs, struct datablock *b, struct inode *ino)
+void lafs_orphan_release(struct fs *fs, struct datablock *b)
{
struct datablock *ob1, *ob2;
int shift = b->b.inode->i_blkbits - 4;
om->nextfree--;
om->reserved++;
clear_bit(B_Orphan, &b->b.flags);
- iput(ino);
+ lafs_iput_fs(b->b.inode);
lafs_drop_orphan(fs, b);
putdref(b, MKREF(orphan_flag));
getdref(ob, MKREF(orphan_flag));
getdref(db, MKREF(orphan));
ob->orphan_slot = bslot + slot;
+ lafs_igrab_fs(ob->b.inode);
lafs_add_orphan(fs, ob);
} else
or[slot].type = 0;