]> git.neil.brown.name Git - mdadm.git/blob - raid5extend.c
Release mdadm-4.0
[mdadm.git] / raid5extend.c
1
2 int phys2log(int phys, int stripe, int n, int layout)
3 {
4     /* In an 'n' disk array using 'layout',
5      * in stripe 'stripe', the physical disc 'phys'
6      * stores what logical chunk?
7      * -1 mean parity.
8      *
9      */
10     switch(layout) {
11     case ALGORITHM_LEFT_ASYMMETRIC:
12         pd = (n-1) - (stripe % n);
13         if (phys < pd)
14             return phys;
15         else if (phys == pd)
16             return -1;
17         else return phys-1;
18
19     case ALGORITHM_RIGHT_ASYMMETRIC:
20         pd = stripe % n;
21         if (phys < pd)
22             return phys;
23         else if (phys == pd)
24             return -1;
25         else return phys-1;
26
27     case ALGORITHM_LEFT_SYMMETRIC:
28         pd = (n-1) - (stripe %n);
29         if (phys < pd)
30             return phys+ n-1-pd;
31         else if (phys == pd)
32             return -1;
33         else return phys-pd-1;
34
35     case ALGORITHM_RIGHT_SYMMETRIC:
36         pd = stripe % n;
37         if (phys < pd)
38             return phys+ n-1-pd;
39         else if (phys == pd)
40             return -1;
41         else return phys-pd-1;
42     }
43     return -2;
44 }
45
46 raid5_extend(unsigned long len, int chunksize, int layout, int n, int m, int rfds[], int wfds[])
47 {
48
49     static char buf[4096];
50
51     unsigned long blocks = len/4;
52     unsigned int blocksperchunk= chunksize/4096;
53
54     unsigned long b;
55
56     for (b=0; b<blocks; b++) {
57         unsigned long stripe = b / blocksperchunk;
58         unsigned int offset = b - (stripe*blocksperchunk);
59         unsigned long chunk = stripe * (n-1);
60         int src;
61         for (src=0; src<n; src++) {
62             int dnum, snum;
63             if (read(rfds[src], buf, sizeof(buf)) != sizeof(buf)) {
64                 error();
65                 return 0;
66             }
67
68             snum = phys2log(src, stripe, n, layout);
69
70             if (snum == -1)
71                 continue;
72             chunk = stripe*(n-1)+snum;
73
74             dstripe = chunk/(m-1);
75             dnum = log2phys(chunk-(stripe*(m-1)), dstripe, m, layout);
76             llseek(wfds[dnum], dstripe*chunksize+(offset*4096), 0);
77             write(wfds[dnum], buf, sizeof(buf));
78         }
79     }
80 }