lafs_checkpoint_unlock(fs);
}
-static struct mutex *orphan_mutex(struct datablock *db)
+static struct inode *orphan_inode(struct datablock *db)
{
switch (LAFSI(db->b.inode)->type) {
case TypeInodeFile:
- if (db->my_inode == NULL)
- return NULL;
- return &db->my_inode->i_mutex;
+ if (db->my_inode &&
+ test_bit(I_Deleting, &LAFSI(db->my_inode)->iflags))
+ return db->my_inode;
+ return igrab(db->my_inode);
case TypeDir:
- return &db->b.inode->i_mutex;
+ return igrab(db->b.inode);
default:
BUG();
}
}
+static void orphan_iput(struct inode *ino)
+{
+ if (!ino)
+ return;
+ if (test_bit(I_Deleting, &LAFSI(ino)->iflags))
+ return;
+ iput(ino);
+}
+
long lafs_run_orphans(struct fs *fs)
{
struct datablock *db;
set_bit(OrphansRunning, &fs->fsstate);
spin_lock(&fs->lock);
while (!list_empty(&fs->pending_orphans)) {
- struct mutex *mx;
+ struct inode *ino;
db = list_entry(fs->pending_orphans.next,
struct datablock,
orphans);
list_move(&db->orphans, &done);
- mx = orphan_mutex(db);
- if (!mx && !test_bit(B_Claimed, &db->b.flags))
- /* OK not to have a mutex */;
- else if (!mx || !mutex_trylock(mx)) {
+ ino = orphan_inode(db);
+ if (!ino && !test_bit(B_Claimed, &db->b.flags))
+ /* OK not to have an inode */;
+ else if (!ino || !mutex_trylock(&ino->i_mutex)) {
/* we cannot get a wakeup when mutex
* is unlocked, so we need timeout
* FIXME this is unfortunate
*/
+ orphan_iput(ino);
timeout = msecs_to_jiffies(500);
continue;
}
getdref(db, MKREF(run_orphans));
spin_unlock(&fs->lock);
- if (!mx)
+ if (!ino)
lafs_orphan_release(fs, db);
else {
int err = -ERESTARTSYS;
if (err == -ENOMEM)
timeout = msecs_to_jiffies(500);
}
- mutex_unlock(mx);
+ mutex_unlock(&ino->i_mutex);
}
+ orphan_iput(ino);
putdref(db, MKREF(run_orphans));
spin_lock(&fs->lock);
}
* It must be IOlocked, and this call must not come
* from lafs_run_orphans.
*/
- struct mutex *mx = orphan_mutex(db);
- BUG_ON(mx && !mutex_is_locked(mx));
+ struct inode *ino = orphan_inode(db);
+
+ BUG_ON(ino && !mutex_is_locked(&ino->i_mutex));
+ orphan_iput(ino);
+
if (test_bit(B_Orphan, &db->b.flags))
return 0;
spin_lock(&fs->lock);