lafs_cluster_flush(fs, 1);
}
-static int try_clean(struct fs *fs, struct toclean *tc)
+static void cleaner_load(struct fs *fs, struct toclean *tc)
+{
+ /* Need to read in the cluster header */
+ int err;
+ err = lafs_load_page_async(fs, tc->chead,
+ tc->haddr,
+ (PAGE_SIZE /
+ fs->blocksize),
+ &tc->ac);
+
+ BUG_ON(err && err != -EAGAIN && err != -EIO);
+
+ if (err == -EAGAIN)
+ return;
+ if (err)
+ //printk("CLEANER got IO error !!\n");
+ // FIXME adjust youth to so as not to touch this again
+ goto bad_header;
+
+ tc->ch = page_address(tc->chead);
+ if (memcmp(tc->ch->idtag, "LaFSHead", 8) != 0)
+ goto bad_header;
+ if (memcmp(tc->ch->uuid, fs->state->uuid, 16) != 0)
+ goto bad_header;
+ if (tc->seq == 0)
+ tc->seq = le64_to_cpu(tc->ch->seq);
+ else {
+ tc->seq++;
+ if (tc->seq != le64_to_cpu(tc->ch->seq)) {
+ printk("Bad seq number\n");
+ goto bad_header;
+ }
+ }
+ tc->gh = tc->ch->groups;
+ tc->desc = tc->gh->u.desc;
+ if (lafs_calc_cluster_csum(tc->ch) != tc->ch->checksum) {
+ //printk("Cluster header checksum is wrong!!\n");
+ goto bad_header;
+ }
+ dprintk("try_clean: got header %d\n", (int)tc->haddr);
+ return;
+
+bad_header:
+ tc->ac.state = 0;
+ tc->have_addr = 0;
+}
+
+static void cleaner_parse(struct fs *fs, struct toclean *tc)
{
- /* return 1 if everything has been found, -ve if we need to flush */
- int again = 0;
u32 bnum;
int bcnt;
u32 inum, fsnum;
struct inode *ino = NULL;
- struct datablock *b, *tmp;
- int rv = 0;
- mutex_lock(&fs->cleaner.lock);
- dprintk("try_clean: state = %d\n", tc->ac.state);
- if (tc->ch == NULL && tc->have_addr) {
- /* Need to read in the cluster header */
- int err;
- err = lafs_load_page_async(fs, tc->chead,
- tc->haddr,
- (PAGE_SIZE /
- fs->blocksize),
- &tc->ac);
-
- rv = 0;
- if (err == -EAGAIN)
- goto out;
- if (err == -EIO) {
- //printk("CLEANER got IO error !!\n");
- // FIXME adjust youth to so as not to touch this again
- bad_header:
- tc->ac.state = 0;
- tc->have_addr = 0;
- rv = 0;
- goto out;
- }
- BUG_ON(err);
- tc->ch = page_address(tc->chead);
- if (memcmp(tc->ch->idtag, "LaFSHead", 8) != 0)
- goto bad_header;
- if (memcmp(tc->ch->uuid, fs->state->uuid, 16) != 0)
- goto bad_header;
- if (tc->seq == 0)
- tc->seq = le64_to_cpu(tc->ch->seq);
- else {
- tc->seq++;
- if (tc->seq != le64_to_cpu(tc->ch->seq)) {
- printk("Bad seq number\n");
- goto bad_header;
- }
- }
- tc->gh = tc->ch->groups;
- tc->desc = tc->gh->u.desc;
- if (lafs_calc_cluster_csum(tc->ch) != tc->ch->checksum) {
- //printk("Cluster header checksum is wrong!!\n");
- goto bad_header;
- }
- dprintk("try_clean: got header %d\n", (int)tc->haddr);
- }
+ int again = 0;
while (tc->ch && again < 16) {
/* Load the index block for each described data or index block.
* For data blocks, get the address and possibly load the
}
break;
} else {
+ struct datablock *b;
dprintk("got the inode\n");
/* Minor optimisation for files that have shrunk */
/* Actually this is critical for handling truncation
}
if (ino)
iput(ino);
+}
+
+static int cleaner_process(struct fs *fs, struct toclean *tc)
+{
+ struct datablock *b, *tmp;
+ int rv = 0;
+ struct inode *ino;
+
dprintk("start processing list\n");
list_for_each_entry_safe(b, tmp, &tc->cleaning, cleaning) {
struct block *cb = NULL;
iput(ino);
putref(cb, MKREF(clean2));
if (rv)
- goto out;
+ break;
}
- rv = tc->ch == NULL && !tc->have_addr &&
- list_empty(&tc->cleaning);
-out:
+ return rv;
+}
+
+static int try_clean(struct fs *fs, struct toclean *tc)
+{
+ /* return 1 if everything has been found, -ve if we need to flush */
+ int rv = 0;
+
+ mutex_lock(&fs->cleaner.lock);
+ dprintk("try_clean: state = %d\n", tc->ac.state);
+ if (tc->ch == NULL && tc->have_addr)
+ cleaner_load(fs, tc);
+
+ if (tc->ch)
+ cleaner_parse(fs, tc);
+
+ if (!list_empty(&tc->cleaning))
+ rv = cleaner_process(fs, tc);
+ if (!rv)
+ rv = (tc->ch == NULL && !tc->have_addr &&
+ list_empty(&tc->cleaning));
mutex_unlock(&fs->cleaner.lock);
return rv;
}