]> git.neil.brown.name Git - lafs-utils.git/blob - lib/lafs_new_segment.c
FORMAT CHANGE use 32bit block counts in segment usage file.
[lafs-utils.git] / lib / lafs_new_segment.c
1
2 /* allocate a new segment at assign it to a lafs_cluster
3  */
4
5 #include <lafs/lafs.h>
6
7 static void cluster_reset(struct lafs *fs, struct lafs_cluster *wc)
8 {
9         wc->remaining = dev_by_num(fs, wc->seg.dev)->segment_size;
10         wc->chead_blocks = 1;
11         wc->remaining--;
12         wc->chead_size = sizeof(struct cluster_head);
13 }
14
15 static void set_youth(struct lafs *fs, int dev, loff_t seg, int youth)
16 {
17         struct lafs_device *dv;
18         struct lafs_dblk *db;
19         uint16_t *p;
20         loff_t addr;
21
22         dv = dev_by_num(fs, dev);
23         addr = seg / (fs->blocksize >> YOUTH_SHIFT);
24
25         db = lafs_dblk(dv->segsum, addr);
26         lafs_load_dblk(db);
27         p = (void*)db->b.data;
28         p[seg % (fs->blocksize >> YOUTH_SHIFT)] = __cpu_to_le16(youth);
29         lafs_sched_blk(&db->b);
30 }
31
32 int lafs_new_segment(struct lafs *fs, int cnum)
33 {
34         int dev;
35         loff_t seg;
36         struct lafs_cluster *wc = &fs->wc[cnum];
37
38         if (fs->free_head == fs->free_tail) {
39                 /* list is empty */
40                 lafs_find_free(fs);
41                 if (fs->free_head == fs->free_tail)
42                         return 0;
43         }
44         dev = fs->freelist[fs->free_head].dev;
45         seg = fs->freelist[fs->free_head].seg;
46
47         fs->free_head++;
48         if (fs->free_head > 128)
49                 fs->free_head -= 128;
50
51         wc->seg.dev = dev;
52         wc->seg.num = seg;
53         wc->seg.st_table = 0;
54         wc->seg.st_row = 0;
55         wc->seg.table = wc->seg.nxt_table = wc->seg.st_table;
56         wc->seg.row = wc->seg.nxt_row = wc->seg.st_row;
57         wc->seg.col = 0;
58
59         cluster_reset(fs, wc);
60
61         /* Need to set the youth for this segment */
62         set_youth(fs, dev, seg, fs->youth_next++);
63         return 1;
64 }