2 * Parse command line, get partition information
4 * Written by Cai Zhiyong <caizhiyong@huawei.com>
7 #include <linux/export.h>
8 #include <linux/cmdline-parser.h>
10 static int parse_subpart(struct cmdline_subpart
**subpart
, char *partdef
)
13 struct cmdline_subpart
*new_subpart
;
17 new_subpart
= kzalloc(sizeof(struct cmdline_subpart
), GFP_KERNEL
);
21 if (*partdef
== '-') {
22 new_subpart
->size
= (sector_t
)(~0ULL);
25 new_subpart
->size
= (sector_t
)memparse(partdef
, &partdef
);
26 if (new_subpart
->size
< (sector_t
)PAGE_SIZE
) {
27 pr_warn("cmdline partition size is invalid.");
33 if (*partdef
== '@') {
35 new_subpart
->from
= (sector_t
)memparse(partdef
, &partdef
);
37 new_subpart
->from
= (sector_t
)(~0ULL);
40 if (*partdef
== '(') {
42 char *next
= strchr(++partdef
, ')');
45 pr_warn("cmdline partition format is invalid.");
50 length
= min_t(int, next
- partdef
,
51 sizeof(new_subpart
->name
) - 1);
52 strncpy(new_subpart
->name
, partdef
, length
);
53 new_subpart
->name
[length
] = '\0';
57 new_subpart
->name
[0] = '\0';
59 new_subpart
->flags
= 0;
61 if (!strncmp(partdef
, "ro", 2)) {
62 new_subpart
->flags
|= PF_RDONLY
;
66 if (!strncmp(partdef
, "lk", 2)) {
67 new_subpart
->flags
|= PF_POWERUP_LOCK
;
71 *subpart
= new_subpart
;
78 static void free_subpart(struct cmdline_parts
*parts
)
80 struct cmdline_subpart
*subpart
;
82 while (parts
->subpart
) {
83 subpart
= parts
->subpart
;
84 parts
->subpart
= subpart
->next_subpart
;
89 static int parse_parts(struct cmdline_parts
**parts
, const char *bdevdef
)
94 struct cmdline_subpart
**next_subpart
;
95 struct cmdline_parts
*newparts
;
96 char buf
[BDEVNAME_SIZE
+ 32 + 4];
100 newparts
= kzalloc(sizeof(struct cmdline_parts
), GFP_KERNEL
);
104 next
= strchr(bdevdef
, ':');
106 pr_warn("cmdline partition has no block device.");
110 length
= min_t(int, next
- bdevdef
, sizeof(newparts
->name
) - 1);
111 strncpy(newparts
->name
, bdevdef
, length
);
112 newparts
->name
[length
] = '\0';
113 newparts
->nr_subparts
= 0;
115 next_subpart
= &newparts
->subpart
;
117 while (next
&& *(++next
)) {
119 next
= strchr(bdevdef
, ',');
121 length
= (!next
) ? (sizeof(buf
) - 1) :
122 min_t(int, next
- bdevdef
, sizeof(buf
) - 1);
124 strncpy(buf
, bdevdef
, length
);
127 ret
= parse_subpart(next_subpart
, buf
);
131 newparts
->nr_subparts
++;
132 next_subpart
= &(*next_subpart
)->next_subpart
;
135 if (!newparts
->subpart
) {
136 pr_warn("cmdline partition has no valid partition.");
145 free_subpart(newparts
);
150 void cmdline_parts_free(struct cmdline_parts
**parts
)
152 struct cmdline_parts
*next_parts
;
155 next_parts
= (*parts
)->next_parts
;
156 free_subpart(*parts
);
161 EXPORT_SYMBOL(cmdline_parts_free
);
163 int cmdline_parts_parse(struct cmdline_parts
**parts
, const char *cmdline
)
169 struct cmdline_parts
**next_parts
;
173 next
= pbuf
= buf
= kstrdup(cmdline
, GFP_KERNEL
);
179 while (next
&& *pbuf
) {
180 next
= strchr(pbuf
, ';');
184 ret
= parse_parts(next_parts
, pbuf
);
191 next_parts
= &(*next_parts
)->next_parts
;
195 pr_warn("cmdline partition has no valid partition.");
206 cmdline_parts_free(parts
);
209 EXPORT_SYMBOL(cmdline_parts_parse
);
211 struct cmdline_parts
*cmdline_parts_find(struct cmdline_parts
*parts
,
214 while (parts
&& strncmp(bdev
, parts
->name
, sizeof(parts
->name
)))
215 parts
= parts
->next_parts
;
218 EXPORT_SYMBOL(cmdline_parts_find
);
223 * 1 can not add so many partitions.
225 int cmdline_parts_set(struct cmdline_parts
*parts
, sector_t disk_size
,
227 int (*add_part
)(int, struct cmdline_subpart
*, void *),
231 struct cmdline_subpart
*subpart
;
233 for (subpart
= parts
->subpart
; subpart
;
234 subpart
= subpart
->next_subpart
, slot
++) {
235 if (subpart
->from
== (sector_t
)(~0ULL))
236 subpart
->from
= from
;
238 from
= subpart
->from
;
240 if (from
>= disk_size
)
243 if (subpart
->size
> (disk_size
- from
))
244 subpart
->size
= disk_size
- from
;
246 from
+= subpart
->size
;
248 if (add_part(slot
, subpart
, param
))
254 EXPORT_SYMBOL(cmdline_parts_set
);