/* Setting 'next' address for last cluster in
* a cleaner segment */
return 0;
+ if (seg->table > seg->nxt_table ||
+ (seg->table == seg->nxt_table &&
+ seg->row >= seg->nxt_row))
+ /* We have gone beyond the end of the cluster,
+ * must be bad data during roll-forward
+ */
+ return 0;
addr = seg->col * dv->stride;
addr += seg->row;
addr += seg->table * dv->rows_per_table;
{
/* step forward one block, returning the address of
* the block stepped over
+ * The write cluster can have three sections:
+ * - the tail end of one table
+ * - a number of complete tables
+ * - the head of one table
+ *
+ * For each table or partial table we want to talk a full
+ * column at a time, then go to the next column.
+ * So we step to the next row. If it is beyond the range of
+ * the current table, go to 'start' of next column, or to
+ * next table.
*/
struct fs_dev *dv = &fs->devs[seg->dev];
u64 addr = seg_addr(fs, seg);
+ if (!addr)
+ /* Beyond end of cluster */
+ return 0;
+
/* now step forward in column or table or seg */
- seg->col++;
- if (seg->col >= dv->width) {
- seg->col = 0;
- seg->row++;
- if (seg->row >= dv->rows_per_table) {
- seg->row = 0;
+ seg->row++;
+ if (seg->row >= dv->rows_per_table ||
+ (seg->table == seg->nxt_table
+ && seg->row >= seg->nxt_row)) {
+ seg->col++;
+ if (seg->col >= dv->width) {
+ seg->col = 0;
seg->table++;
}
+ if (seg->table == seg->st_table)
+ seg->row = seg->st_row;
+ else
+ seg->row = 0;
}
return addr;
}
current_block++;
cluster_incdesc(wc, desc_start, b, fs->blocksize_bits);
addr = lafs_seg_next(fs, &wc->seg);
+ BUG_ON(!addr);
if (cnum && test_bit(B_Dirty, &b->flags))
/* We are cleaning but this block is now dirty.
* Don't waste the UnincCredit on recording the
* response */
/* FIXME range check count */
while (!err && cnt--) {
+ if (bytes != DescHole &&
+ !baddr) {
+ /* We have fallen off the end of
+ * the write-cluster - something
+ * is wrong with the header
+ */
+ printk(KERN_WARNING "LAFS: cluster size is wrong\n");
+ return -EIO;
+ }
if (!flg && bytes != DescIndex)
err = roll_block(fs, fsnum, inum, trunc,
bnum, baddr,