1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "defs.h"
/**
* open_ubi - open the libubi.
* @c: the UBIFS file-system description object
* @node: name of the UBI volume character device to fetch information about
*
* This function opens libubi, and initialize device & volume information
* according to @node. Returns %0 in case of success and %-1 in case of failure.
*/
int open_ubi(struct ubifs_info *c, const char *node)
{
struct stat st;
if (stat(node, &st) || !S_ISCHR(st.st_mode))
return -1;
c->libubi = libubi_open();
if (!c->libubi)
return -1;
if (ubi_get_vol_info(c->libubi, node, &c->vi))
goto out_err;
if (ubi_get_dev_info1(c->libubi, c->vi.dev_num, &c->di))
goto out_err;
return 0;
out_err:
close_ubi(c);
return -1;
}
void close_ubi(struct ubifs_info *c)
{
if (c->libubi) {
libubi_close(c->libubi);
c->libubi = NULL;
}
}
/**
* open_target - open the output target.
* @c: the UBIFS file-system description object
*
* Open the output target. The target can be an UBI volume
* or a file.
*
* Returns %0 in case of success and %-1 in case of failure.
*/
int open_target(struct ubifs_info *c)
{
if (c->libubi) {
c->dev_fd = open(c->dev_name, O_RDWR | O_EXCL);
if (c->dev_fd == -1)
return sys_errmsg("cannot open the UBI volume '%s'",
c->dev_name);
if (ubi_set_property(c->dev_fd, UBI_VOL_PROP_DIRECT_WRITE, 1)) {
close(c->dev_fd);
return sys_errmsg("ubi_set_property(set direct_write) failed");
}
} else {
c->dev_fd = open(c->dev_name, O_CREAT | O_RDWR | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
if (c->dev_fd == -1)
return sys_errmsg("cannot create output file '%s'",
c->dev_name);
}
return 0;
}
/**
* close_target - close the output target.
* @c: the UBIFS file-system description object
*
* Close the output target. If the target was an UBI
* volume, also close libubi.
*
* Returns %0 in case of success and %-1 in case of failure.
*/
int close_target(struct ubifs_info *c)
{
if (c->dev_fd >= 0) {
if (c->libubi && ubi_set_property(c->dev_fd, UBI_VOL_PROP_DIRECT_WRITE, 0))
return sys_errmsg("ubi_set_property(clear direct_write) failed");
if (close(c->dev_fd) == -1)
return sys_errmsg("cannot close the target '%s'", c->dev_name);
}
return 0;
}
/**
* check_volume_empty - check if the UBI volume is empty.
* @c: the UBIFS file-system description object
*
* This function checks if the UBI volume is empty by looking if its LEBs are
* mapped or not.
*
* Returns %0 in case of success, %1 is the volume is not empty,
* and a negative error code in case of failure.
*/
int check_volume_empty(struct ubifs_info *c)
{
int lnum, err;
for (lnum = 0; lnum < c->vi.rsvd_lebs; lnum++) {
err = ubi_is_mapped(c->dev_fd, lnum);
if (err < 0)
return err;
if (err == 1)
return 1;
}
return 0;
}
|