44 |
} bb_loop_info; |
} bb_loop_info; |
45 |
#endif |
#endif |
46 |
|
|
47 |
char *query_loop(const char *device) |
char* FAST_FUNC query_loop(const char *device) |
48 |
{ |
{ |
49 |
int fd; |
int fd; |
50 |
bb_loop_info loopinfo; |
bb_loop_info loopinfo; |
61 |
} |
} |
62 |
|
|
63 |
|
|
64 |
int del_loop(const char *device) |
int FAST_FUNC del_loop(const char *device) |
65 |
{ |
{ |
66 |
int fd, rc; |
int fd, rc; |
67 |
|
|
79 |
search will re-use an existing loop device already bound to that |
search will re-use an existing loop device already bound to that |
80 |
file/offset if it finds one. |
file/offset if it finds one. |
81 |
*/ |
*/ |
82 |
int set_loop(char **device, const char *file, unsigned long long offset) |
int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset) |
83 |
{ |
{ |
84 |
char dev[20], *try; |
char dev[LOOP_NAMESIZE]; |
85 |
|
char *try; |
86 |
bb_loop_info loopinfo; |
bb_loop_info loopinfo; |
87 |
struct stat statbuf; |
struct stat statbuf; |
88 |
int i, dfd, ffd, mode, rc=-1; |
int i, dfd, ffd, mode, rc = -1; |
89 |
|
|
90 |
/* Open the file. Barf if this doesn't work. */ |
/* Open the file. Barf if this doesn't work. */ |
91 |
mode = O_RDWR; |
mode = O_RDWR; |
99 |
|
|
100 |
/* Find a loop device. */ |
/* Find a loop device. */ |
101 |
try = *device ? : dev; |
try = *device ? : dev; |
102 |
for (i=0;rc;i++) { |
for (i = 0; rc; i++) { |
103 |
sprintf(dev, LOOP_FORMAT, i); |
sprintf(dev, LOOP_FORMAT, i); |
104 |
|
|
105 |
/* Ran out of block devices, return failure. */ |
/* Ran out of block devices, return failure. */ |
106 |
if (stat(try, &statbuf) || !S_ISBLK(statbuf.st_mode)) { |
if (stat(try, &statbuf) || !S_ISBLK(statbuf.st_mode)) { |
107 |
rc=-ENOENT; |
rc = -ENOENT; |
108 |
break; |
break; |
109 |
} |
} |
110 |
/* Open the sucker and check its loopiness. */ |
/* Open the sucker and check its loopiness. */ |
113 |
mode = O_RDONLY; |
mode = O_RDONLY; |
114 |
dfd = open(try, mode); |
dfd = open(try, mode); |
115 |
} |
} |
116 |
if (dfd < 0) goto try_again; |
if (dfd < 0) |
117 |
|
goto try_again; |
118 |
|
|
119 |
rc = ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo); |
rc = ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo); |
120 |
|
|
121 |
/* If device free, claim it. */ |
/* If device is free, claim it. */ |
122 |
if (rc && errno == ENXIO) { |
if (rc && errno == ENXIO) { |
123 |
memset(&loopinfo, 0, sizeof(loopinfo)); |
memset(&loopinfo, 0, sizeof(loopinfo)); |
124 |
safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE); |
safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE); |
125 |
loopinfo.lo_offset = offset; |
loopinfo.lo_offset = offset; |
126 |
/* Associate free loop device with file. */ |
/* Associate free loop device with file. */ |
127 |
if (!ioctl(dfd, LOOP_SET_FD, ffd)) { |
if (!ioctl(dfd, LOOP_SET_FD, ffd)) { |
128 |
if (!ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo)) rc = 0; |
if (!ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo)) |
129 |
else ioctl(dfd, LOOP_CLR_FD, 0); |
rc = 0; |
130 |
|
else |
131 |
|
ioctl(dfd, LOOP_CLR_FD, 0); |
132 |
} |
} |
133 |
|
|
134 |
/* If this block device already set up right, re-use it. |
/* If this block device already set up right, re-use it. |
136 |
file isn't pretty either. In general, mounting the same file twice |
file isn't pretty either. In general, mounting the same file twice |
137 |
without using losetup manually is problematic.) |
without using losetup manually is problematic.) |
138 |
*/ |
*/ |
139 |
} else if (strcmp(file,(char *)loopinfo.lo_file_name) |
} else if (strcmp(file, (char *)loopinfo.lo_file_name) != 0 |
140 |
|| offset != loopinfo.lo_offset) { |
|| offset != loopinfo.lo_offset) { |
141 |
rc = -1; |
rc = -1; |
142 |
} |
} |
143 |
close(dfd); |
close(dfd); |
144 |
try_again: |
try_again: |
145 |
if (*device) break; |
if (*device) break; |
146 |
} |
} |
147 |
close(ffd); |
close(ffd); |
148 |
if (!rc) { |
if (!rc) { |
149 |
if (!*device) *device = xstrdup(dev); |
if (!*device) |
150 |
return mode==O_RDONLY ? 1 : 0; |
*device = xstrdup(dev); |
151 |
|
return (mode == O_RDONLY); /* 1:ro, 0:rw */ |
152 |
} |
} |
153 |
return rc; |
return rc; |
154 |
} |
} |