aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorXiaoming Ni <nixiaoming@huawei.com>2022-12-13 13:13:23 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2022-12-13 14:26:20 +0100
commita1856934ba795f81546f5dd9a14ba4faa757ce52 (patch)
tree8d81c51e88ba4390440be5a63d29524be1dc4765 /libbb
parent7dc76c9f210b3c66a9c89e6690af7b49f6c540a8 (diff)
downloadbusybox-w32-a1856934ba795f81546f5dd9a14ba4faa757ce52.tar.gz
busybox-w32-a1856934ba795f81546f5dd9a14ba4faa757ce52.tar.bz2
busybox-w32-a1856934ba795f81546f5dd9a14ba4faa757ce52.zip
loop: refactor: extract subfunction set_loopdev_params()
Extract subfunction set_loop_info() from set_loop() function old new delta set_loop 760 784 +24 Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r--libbb/loop.c90
1 files changed, 51 insertions, 39 deletions
diff --git a/libbb/loop.c b/libbb/loop.c
index 256b7ac90..424c39216 100644
--- a/libbb/loop.c
+++ b/libbb/loop.c
@@ -110,6 +110,51 @@ static int get_next_free_loop(char *dev, int id)
110 return loopdevno; 110 return loopdevno;
111} 111}
112 112
113static int set_loopdev_params(int ffd,
114 int lfd, const char *file,
115 unsigned long long offset,
116 unsigned long long sizelimit,
117 unsigned flags)
118{
119 int rc;
120 bb_loop_info loopinfo;
121
122 rc = ioctl(lfd, BB_LOOP_GET_STATUS, &loopinfo);
123
124 /* If device is free, try to claim it */
125 if (rc && errno == ENXIO) {
126 /* Associate free loop device with file */
127 rc = ioctl(lfd, LOOP_SET_FD, ffd);
128 if (rc != 0) {
129 /* Ouch... race: the device already has a fd */
130 return -1;
131 }
132 memset(&loopinfo, 0, sizeof(loopinfo));
133 safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE);
134 loopinfo.lo_offset = offset;
135 loopinfo.lo_sizelimit = sizelimit;
136 /*
137 * Used by mount to set LO_FLAGS_AUTOCLEAR.
138 * LO_FLAGS_READ_ONLY is not set because RO is controlled by open type of the file.
139 * Note that closing LO_FLAGS_AUTOCLEARed lfd before mount
140 * is wrong (would free the loop device!)
141 */
142 loopinfo.lo_flags = (flags & ~BB_LO_FLAGS_READ_ONLY);
143 rc = ioctl(lfd, BB_LOOP_SET_STATUS, &loopinfo);
144 if (rc != 0 && (loopinfo.lo_flags & BB_LO_FLAGS_AUTOCLEAR)) {
145 /* Old kernel, does not support LO_FLAGS_AUTOCLEAR? */
146 /* (this code path is not tested) */
147 loopinfo.lo_flags -= BB_LO_FLAGS_AUTOCLEAR;
148 rc = ioctl(lfd, BB_LOOP_SET_STATUS, &loopinfo);
149 }
150 if (rc == 0)
151 return rc; /* SUCCESS! */
152 /* failure, undo LOOP_SET_FD */
153 ioctl(lfd, LOOP_CLR_FD, 0); // actually, 0 param is unnecessary
154 }
155 return -1;
156}
157
113/* Returns opened fd to the loop device, <0 on error. 158/* Returns opened fd to the loop device, <0 on error.
114 * *device is loop device to use, or if *device==NULL finds a loop device to 159 * *device is loop device to use, or if *device==NULL finds a loop device to
115 * mount it on and sets *device to a strdup of that loop device name. 160 * mount it on and sets *device to a strdup of that loop device name.
@@ -119,7 +164,6 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse
119{ 164{
120 char dev[LOOP_NAMESIZE]; 165 char dev[LOOP_NAMESIZE];
121 char *try; 166 char *try;
122 bb_loop_info loopinfo;
123 struct stat statbuf; 167 struct stat statbuf;
124 int i, lfd, ffd, mode, rc; 168 int i, lfd, ffd, mode, rc;
125 169
@@ -183,45 +227,13 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse
183 goto try_next_loopN; 227 goto try_next_loopN;
184 } 228 }
185 229
186 rc = ioctl(lfd, BB_LOOP_GET_STATUS, &loopinfo); 230 rc = set_loopdev_params(ffd, lfd, file, offset, sizelimit, flags);
187 231 if (rc == 0) {
188 /* If device is free, try to claim it */ 232 /* SUCCESS! */
189 if (rc && errno == ENXIO) { 233 if (!*device)
190 /* Associate free loop device with file */ 234 *device = xstrdup(dev);
191 rc = ioctl(lfd, LOOP_SET_FD, ffd); 235 break;
192 if (rc != 0) {
193 /* Ouch... race: the device already has a fd */
194 goto close_and_try_next_loopN;
195 }
196 memset(&loopinfo, 0, sizeof(loopinfo));
197 safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE);
198 loopinfo.lo_offset = offset;
199 loopinfo.lo_sizelimit = sizelimit;
200 /*
201 * Used by mount to set LO_FLAGS_AUTOCLEAR.
202 * LO_FLAGS_READ_ONLY is not set because RO is controlled by open type of the file.
203 * Note that closing LO_FLAGS_AUTOCLEARed lfd before mount
204 * is wrong (would free the loop device!)
205 */
206 loopinfo.lo_flags = (flags & ~BB_LO_FLAGS_READ_ONLY);
207 rc = ioctl(lfd, BB_LOOP_SET_STATUS, &loopinfo);
208 if (rc != 0 && (loopinfo.lo_flags & BB_LO_FLAGS_AUTOCLEAR)) {
209 /* Old kernel, does not support LO_FLAGS_AUTOCLEAR? */
210 /* (this code path is not tested) */
211 loopinfo.lo_flags -= BB_LO_FLAGS_AUTOCLEAR;
212 rc = ioctl(lfd, BB_LOOP_SET_STATUS, &loopinfo);
213 }
214 if (rc == 0) {
215 /* SUCCESS! */
216 if (!*device) /* was looping in search of free "/dev/loopN"? */
217 *device = xstrdup(dev);
218 rc = lfd; /* return this */
219 break;
220 }
221 /* failure, undo LOOP_SET_FD */
222 ioctl(lfd, LOOP_CLR_FD, 0); // actually, 0 param is unnecessary
223 } 236 }
224 close_and_try_next_loopN:
225 close(lfd); 237 close(lfd);
226 try_next_loopN: 238 try_next_loopN:
227 rc = -1; 239 rc = -1;