return err;
}
-static void orphan_abort(struct fs *fs);
-static void orphan_commit(struct fs *fs, struct datablock *b, struct datablock *ob);
-static int orphan_pin(struct fs *fs, struct datablock *b)
+static struct datablock *orphan_pin(struct fs *fs, struct datablock *b)
{
struct orphan_md *om = &LAFSI(fs->orphans)->md.orphan;
u32 slot;
u32 bnum;
struct datablock *ob;
- mutex_lock_nested(&fs->orphans->i_mutex, I_MUTEX_QUOTA);
slot = om->nextfree;
bnum = slot >> (fs->prime_sb->s_blocksize_bits-4);
dprintk("slot=%d bnum=%d\n", slot, bnum);
lafs_phase_wait(&ob->b);
err = lafs_pin_dblock(ob);
if (err) {
- if (err != -EAGAIN)
- orphan_abort(fs);
- mutex_unlock(&fs->orphans->i_mutex);
putdref(ob, MKREF(orphan));
- return err;
+ return ERR_PTR(err);
}
- orphan_commit(fs, b, ob);
- mutex_unlock(&fs->orphans->i_mutex);
- return 0;
+ return ob;
}
static void orphan_commit(struct fs *fs, struct datablock *b, struct datablock *ob)
int lafs_make_orphan(struct fs *fs, struct datablock *db)
{
int err;
+ struct datablock *ob;
if (test_bit(B_Orphan, &db->b.flags))
return 0;
return err;
retry:
lafs_checkpoint_lock(fs);
- err = orphan_pin(fs, db);
- if (err == -EAGAIN) {
+ mutex_lock_nested(&fs->orphans->i_mutex, I_MUTEX_QUOTA);
+ ob = orphan_pin(fs, db);
+ if (IS_ERR(ob) && PTR_ERR(ob) == -EAGAIN) {
+ mutex_unlock(&fs->orphans->i_mutex);
lafs_checkpoint_unlock_wait(fs);
goto retry;
}
- /* there is no 'commit' - 'pin' did all the work */
+ if (IS_ERR(ob)) {
+ orphan_abort(fs);
+ err = PTR_ERR(ob);
+ } else
+ orphan_commit(fs, db, ob);
+ mutex_unlock(&fs->orphans->i_mutex);
lafs_checkpoint_unlock(fs);
return err;
}