iput(ino);
dprintk("start processing list\n");
list_for_each_entry_safe(b, tmp, &tc->cleaning, cleaning) {
- struct block *cb;
+ struct block *cb = NULL;
int err = lafs_find_block_async(b);
dprintk("find_async gives %d %s\n", err, strblk(&b->b));
if (err == -EAGAIN)
continue;
- if (err) {
+ if (err)
/* Eeek, what do I do?? */
- list_del_init(&b->cleaning);
- ino = b->b.inode;
- putdref(b, MKREF(cleaning));
- iput(ino);
- continue;
- }
+ goto done_cleaning;
+
cb = first_in_seg(&b->b, fs, tc->dev, tc->seg, MKREF(clean2));
if (cb == NULL) {
/* Moved, don't want this. */
dprintk("Not in seg\n");
- list_del_init(&b->cleaning);
- ino = b->b.inode;
- putdref(b, MKREF(cleaning));
- iput(ino);
- continue;
+ goto done_cleaning;
}
err = lafs_load_block(cb, NULL);
- if (err) {
- list_del_init(&b->cleaning);
- ino = b->b.inode;
- putdref(b, MKREF(cleaning));
- putref(cb, MKREF(clean2));
- iput(ino);
- continue;
- }
+ if (err)
+ goto done_cleaning;
+
err = lafs_wait_block_async(cb);
if (err == -EAGAIN) {
putref(cb, MKREF(clean2));
continue;
}
-
- if (err) {
- list_del_init(&b->cleaning);
- ino = b->b.inode;
- putref(cb, MKREF(clean2));
- putdref(b, MKREF(cleaning));
- iput(ino);
- continue;
- }
+ if (err)
+ goto done_cleaning;
err = mark_cleaning(cb);
dprintk("Want to clean %s (%d)\n",
strblk(cb), err);
+ if (err)
+ rv = -1;
/* as cb is B_Pinned, it holds an effective
* ref on the inode, so it is safe to drop our
* ref now
*/
+ done_cleaning:
list_del_init(&b->cleaning);
ino = b->b.inode;
putdref(b, MKREF(cleaning));
putref(cb, MKREF(clean2));
iput(ino);
- rv = -1;
- if (err)
+ if (rv)
goto out;
}
rv = tc->ch == NULL && tc->ss == 0 &&
static inline void _putref(struct block *b)
{
+ if (!b)
+ return;
BUG_ON(atomic_read(&b->refcnt)==0);
lafs_refile(b, 1);
}
#if DEBUG_REF == 0
#define _reflog(c,blk,ref,add) (c(blk))
#else
-#define _reflog(c,blk,ref,add) ({ add? add_ref(blk,ref,__FILE__,__LINE__) : \
+#define _reflog(c,blk,ref,add) ({ !blk ? 0 : \
+ add? add_ref(blk,ref,__FILE__,__LINE__) : \
del_ref(blk,ref, __FILE__,__LINE__); c(blk); })
#endif
#define getref(blk, r) ( ({BUG_ON((blk) && ! atomic_read(&(blk)->refcnt));}), _reflog(_getref, blk,r,1))