-
Notifications
You must be signed in to change notification settings - Fork 0
/
f2label.c
105 lines (82 loc) · 2.54 KB
/
f2label.c
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
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define VERSION_NO "0.0.1"
static void
print_message_and_die(const char* format, ...)
{
va_list argptr;
va_start(argptr, format);
vfprintf(stderr, format, argptr);
va_end(argptr);
exit(1);
}
int
main(int argc, char* argv[])
{
int ret;
if (geteuid() != 0) print_message_and_die("ERROR: must be root\n");
if (argc != 3) {
print_message_and_die("usage: %s <f2fs filepath> <new label>\n", argv[0]);
}
printf("f2label v.%s\n", VERSION_NO);
const char* const filepath = argv[1];
const char* const new_label = argv[2];
if (strlen(new_label) >= FSLABEL_MAX) {
print_message_and_die("ERROR: new label is too long; max %d chars\n", FSLABEL_MAX - 1);
}
// determine if path is a directory or file
struct stat filepath_stat;
ret = stat(filepath, &filepath_stat);
if (ret == -1) {
print_message_and_die("ERROR: couldn't stat() filepath\n");
}
bool path_is_dir = S_ISDIR(filepath_stat.st_mode);
int fd;
if (path_is_dir) {
DIR* dir = opendir(filepath);
fd = dirfd(dir);
}
else {
fd = open(filepath, O_RDWR);
}
if (fd == -1) {
print_message_and_die("ERROR: could not open filepath (%s)\n", strerror(errno));
}
ret = ioctl(fd, FS_IOC_SETFSLABEL, new_label);
if (ret == -1) {
fprintf(stderr, "%s\n", strerror(errno));
print_message_and_die("ERROR: ioctl() failed (%s)\n", strerror(errno));
}
// confirm that it actually worked
char buf[FSLABEL_MAX];
ret = ioctl(fd, FS_IOC_GETFSLABEL, buf);
if (strcmp(buf, new_label)) {
print_message_and_die("ERROR: did not actually set label\n");
}
fprintf(stderr, "new label is: %s\n", buf);
// TODO call BLKRRPART (partprobe) to force kernel to re-load the partition table
/*
int devfd = open("/dev/sdb", O_RDONLY);
if (devfd == -1) {
print_message_and_die("ERROR: could not open devfd\n");
}
ret = ioctl(devfd, BLKRRPART);
if (ret != 0) {
print_message_and_die("could not reload partition table\n");
}
*/
fprintf(stderr, "NOTE: you may need to run 'sudo partprobe /dev/sdX', where 'sdX' is the underlying device, for the kernel to pick up the new label.\n");
fprintf(stderr, "done.\n");
return 0;
}