return addr;
}
+static void cluster_reset(struct fs *fs, struct wc *wc)
+{
+ int blocksize = fs->prime_sb->s_blocksize;
+ if (wc->seg.dev < 0) {
+ wc->remaining = 0;
+ wc->chead = NULL;
+ wc->chead_size = 0;
+ return;
+ }
+ wc->remaining = seg_remainder(fs, &wc->seg);
+ wc->chead_blocks = 1;
+ wc->remaining--;
+ wc->cluster_space = blocksize - sizeof(struct cluster_head);
+ wc->chead_size = sizeof(struct cluster_head);
+
+ wc->pending_next = (wc->pending_next+1) % 4;
+ wc->chead = page_address(wc->page[wc->pending_next]);
+
+}
+
static int new_segment(struct fs *fs, int cnum)
{
/* new_segment can fail if cnum > 0 and there is no
lafs_seg_deref(fs, p + 1, 0);
wc->seg.dev = -1;
}
- wc->remaining = 0;
if (cnum &&
fs->clean_reserved < fs->max_segment)
return -ENOSPC;
/* This gets a reference on the 'segsum' */
lafs_free_get(fs, &dev, &seg, 0);
- wc->seg.dev = dev;
- wc->seg.num = seg;
seg_setpos(fs, &wc->seg, segtovirt(fs, dev, seg));
+ BUG_ON(wc->seg.dev != dev);
+ BUG_ON(wc->seg.num != seg);
- wc->remaining = seg_remainder(fs, &wc->seg);
return 0;
}
mutex_unlock(&wc->lock);
return -ENOSPC;
}
+ cluster_reset(fs, wc);
}
}
dprintk("D %d\n", wake);
/* now re-initialise the cluster information */
- wc->chead_blocks = 1;
- wc->remaining--;
- wc->cluster_space = sb->s_blocksize - sizeof(struct cluster_head);
- wc->chead_size = sizeof(struct cluster_head);
-
- wc->pending_next = (wc->pending_next+1) % 4;
- wc->chead = page_address(wc->page[wc->pending_next]);
+ cluster_reset(fs, wc);
wait_event(wc->pending_wait,
atomic_read(&wc->pending_cnt[wc->pending_next]) == 0);
int lafs_cluster_init(struct fs *fs, int cnum, u64 addr, u64 prev, u64 seq)
{
- int blocksize = fs->prime_sb->s_blocksize;
struct wc *wc = &fs->wc[cnum];
int i;
}
return -ENOMEM;
}
- wc->pending_next = 0;
- wc->chead = page_address(wc->page[wc->pending_next]);
-
- wc->chead_blocks = 1;
- wc->cluster_space = blocksize - sizeof(struct cluster_head);
- wc->chead_size = sizeof(struct cluster_head);
-
+ wc->pending_next = -1;
wc->cluster_seq = seq;
wc->prev_addr = prev;
- seg_setpos(fs, &wc->seg, addr);
- if (cnum)
- wc->remaining = 0;
- else
- wc->remaining = seg_remainder(fs, &wc->seg) - 1;/*1 for header*/
- if (prev && cnum == 0) {
- /* if prev == 0 this is a brand new segment for cleaning */
+
+ if (addr) {
+ seg_setpos(fs, &wc->seg, addr);
+ cluster_reset(fs, wc);
+ BUG_ON(cnum);
spin_lock(&fs->lock);
fs->free_blocks += wc->remaining+1;
spin_unlock(&fs->lock);