]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libdisk/md.c
libxfs-apply: ensure guilt import retains commit messages
[thirdparty/xfsprogs-dev.git] / libdisk / md.c
CommitLineData
f937adac 1/*
da23017d
NS
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
dfc130f3 4 *
da23017d
NS
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
f937adac 7 * published by the Free Software Foundation.
dfc130f3 8 *
da23017d
NS
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
dfc130f3 13 *
da23017d
NS
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
f937adac
NS
17 */
18
9440d84d 19#include "drivers.h"
f937adac
NS
20#include "md.h"
21
d5dca43b 22int
a400ab25 23mnt_is_md_subvol(
25b4e3c2
BN
24 dev_t dev,
25 enum md_type *type)
d5dca43b 26{
25b4e3c2 27 *type = MD_TYPE_MD;
d90395e8
ES
28 if (major(dev) == MD_MAJOR)
29 return 1;
25b4e3c2
BN
30 if (get_driver_block_major("md", major(dev)))
31 return 1;
32 *type = MD_TYPE_MDP;
33 if (get_driver_block_major("mdp", major(dev)))
34 return 1;
35 return 0;
d5dca43b
NS
36}
37
f937adac
NS
38int
39md_get_subvol_stripe(
40 char *dfile,
41 sv_type_t type,
42 int *sunit,
43 int *swidth,
c22b5fdf 44 int *sectalign,
f937adac
NS
45 struct stat64 *sb)
46{
25b4e3c2
BN
47 char *pc;
48 char *dfile2 = NULL;
49 enum md_type md_type;
50
51 if (mnt_is_md_subvol(sb->st_rdev, &md_type)) {
d90395e8 52 struct md_array_info md;
836f654f 53 int fd;
f937adac 54
25b4e3c2
BN
55 if (md_type == MD_TYPE_MDP) {
56 pc = strrchr(dfile, 'd');
57 if (pc)
58 pc = strchr(pc, 'p');
59 if (!pc) {
60 fprintf(stderr,
61 _("Error getting MD array device from %s\n"),
62 dfile);
63 exit(1);
64 }
65 dfile2 = malloc(pc - dfile + 1);
66 if (dfile2 == NULL) {
67 fprintf(stderr,
68 _("Couldn't malloc device string\n"));
69 exit(1);
70 }
71 strncpy(dfile2, dfile, pc - dfile);
72 dfile2[pc - dfile + 1] = '\0';
73 }
f937adac 74 /* Open device */
25b4e3c2
BN
75 fd = open(dfile2 ? dfile2 : dfile, O_RDONLY);
76 if (fd == -1) {
77 free(dfile2);
f937adac 78 return 0;
25b4e3c2 79 }
f937adac
NS
80
81 /* Is this thing on... */
82 if (ioctl(fd, GET_ARRAY_INFO, &md)) {
9440d84d
NS
83 fprintf(stderr,
84 _("Error getting MD array info from %s\n"),
25b4e3c2 85 dfile2 ? dfile2 : dfile);
f937adac
NS
86 exit(1);
87 }
836f654f 88 close(fd);
25b4e3c2 89 free(dfile2);
f937adac 90
5ad6fbfa
NS
91 /*
92 * Ignore levels we don't want aligned (e.g. linear)
93 * and deduct disk(s) from stripe width on RAID4/5/6
94 */
95 switch (md.level) {
96 case 6:
8dd34538 97 md.raid_disks--;
5ad6fbfa
NS
98 /* fallthrough */
99 case 5:
100 case 4:
8dd34538 101 md.raid_disks--;
5ad6fbfa
NS
102 /* fallthrough */
103 case 1:
104 case 0:
105 case 10:
106 break;
107 default:
108 return 0;
109 }
f937adac
NS
110
111 /* Update sizes */
112 *sunit = md.chunk_size >> 9;
8dd34538 113 *swidth = *sunit * md.raid_disks;
c22b5fdf 114 *sectalign = (md.level == 4 || md.level == 5 || md.level == 6);
f937adac
NS
115
116 return 1;
117 }
118 return 0;
119}