]> git.ipfire.org Git - thirdparty/util-linux.git/blame - lib/loopdev.c
Merge branch 'minor-improvement' of https://github.com/calestyo/util-linux
[thirdparty/util-linux.git] / lib / loopdev.c
CommitLineData
c444a71b 1
10ee5932 2/*
0f23ee0c
KZ
3 * No copyright is claimed. This code is in the public domain; do with
4 * it what you wish.
5 *
6 * Written by Karel Zak <kzak@redhat.com>
10ee5932
KZ
7 *
8 * -- based on mount/losetup.c
9 *
10 * Simple library for work with loop devices.
11 *
12 * - requires kernel 2.6.x
13 * - reads info from /sys/block/loop<N>/loop/<attr> (new kernels)
14 * - reads info by ioctl
15 * - supports *unlimited* number of loop devices
16 * - supports /dev/loop<N> as well as /dev/loop/<N>
17 * - minimize overhead (fd, loopinfo, ... are shared for all operations)
18 * - setup (associate device and backing file)
19 * - delete (dis-associate file)
20 * - old LOOP_{SET,GET}_STATUS (32bit) ioctls are unsupported
21 * - extendible
22 */
23#include <stdio.h>
24#include <stdint.h>
25#include <string.h>
26#include <ctype.h>
27#include <fcntl.h>
10ee5932
KZ
28#include <stdlib.h>
29#include <unistd.h>
30#include <sys/ioctl.h>
31#include <sys/stat.h>
32#include <sys/mman.h>
10ee5932
KZ
33#include <inttypes.h>
34#include <dirent.h>
10ee5932
KZ
35
36#include "linux_version.h"
37#include "c.h"
38#include "sysfs.h"
39#include "pathnames.h"
40#include "loopdev.h"
41#include "canonicalize.h"
293714c0 42#include "blkdev.h"
0bf03740 43#include "debug.h"
fbc2fe82 44#include "fileutils.h"
10ee5932 45
0ae7bb11
KZ
46#define LOOPDEV_MAX_TRIES 10
47
0bf03740
KZ
48/*
49 * Debug stuff (based on include/debug.h)
50 */
2ba641e5 51static UL_DEBUG_DEFINE_MASK(loopdev);
0bf03740 52UL_DEBUG_DEFINE_MASKNAMES(loopdev) = UL_DEBUG_EMPTY_MASKNAMES;
aee31ddc 53
0bf03740
KZ
54#define LOOPDEV_DEBUG_INIT (1 << 1)
55#define LOOPDEV_DEBUG_CXT (1 << 2)
56#define LOOPDEV_DEBUG_ITER (1 << 3)
57#define LOOPDEV_DEBUG_SETUP (1 << 4)
aee31ddc 58
0bf03740
KZ
59#define DBG(m, x) __UL_DBG(loopdev, LOOPDEV_DEBUG_, m, x)
60#define ON_DBG(m, x) __UL_DBG_CALL(loopdev, LOOPDEV_DEBUG_, m, x)
aee31ddc 61
6d00cfb2
KZ
62#define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(loopdev)
63#include "debugobj.h"
64
0bf03740 65static void loopdev_init_debug(void)
aee31ddc 66{
0bf03740
KZ
67 if (loopdev_debug_mask)
68 return;
a15dca2f 69 __UL_INIT_DEBUG_FROM_ENV(loopdev, LOOPDEV_DEBUG_, 0, LOOPDEV_DEBUG);
aee31ddc
KZ
70}
71
e4062c72
KZ
72/*
73 * see loopcxt_init()
74 */
10ee5932 75#define loopcxt_ioctl_enabled(_lc) (!((_lc)->flags & LOOPDEV_FL_NOIOCTL))
e4062c72
KZ
76#define loopcxt_sysfs_available(_lc) (!((_lc)->flags & LOOPDEV_FL_NOSYSFS)) \
77 && !loopcxt_ioctl_enabled(_lc)
10ee5932 78
9d5424c2
KZ
79/*
80 * Calls @x and repeat on EAGAIN
81 */
82#define repeat_on_eagain(x) __extension__ ({ \
83 int _c = 0, _e; \
84 do { \
85 errno = 0; \
86 _e = x; \
87 if (_e == 0 || errno != EAGAIN) \
88 break; \
89 if (_c >= LOOPDEV_MAX_TRIES) \
90 break; \
91 xusleep(250000); \
92 _c++; \
93 } while (1); \
94 _e == 0 ? 0 : errno ? -errno : -1; \
95 })
96
10ee5932
KZ
97/*
98 * @lc: context
99 * @device: device name, absolute device path or NULL to reset the current setting
100 *
101 * Sets device, absolute paths (e.g. "/dev/loop<N>") are unchanged, device
102 * names ("loop<N>") are converted to the path (/dev/loop<N> or to
103 * /dev/loop/<N>)
104 *
85794fb0
KZ
105 * This sets the device name, but does not check if the device exists!
106 *
10ee5932
KZ
107 * Returns: <0 on error, 0 on success
108 */
109int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
110{
111 if (!lc)
112 return -EINVAL;
113
f4bf9592 114 if (lc->fd >= 0) {
10ee5932 115 close(lc->fd);
0bf03740 116 DBG(CXT, ul_debugobj(lc, "closing old open fd"));
f4bf9592 117 }
10ee5932 118 lc->fd = -1;
a6ca0456
JB
119 lc->is_lost = 0;
120 lc->devno = 0;
ced1142d 121 lc->mode = O_RDONLY;
75d239ff 122 lc->blocksize = 0;
10ee5932 123 lc->has_info = 0;
6c224de1 124 lc->info_failed = 0;
10ee5932 125 *lc->device = '\0';
d5fd456c 126 memset(&lc->config, 0, sizeof(lc->config));
10ee5932
KZ
127
128 /* set new */
129 if (device) {
130 if (*device != '/') {
131 const char *dir = _PATH_DEV;
132
133 /* compose device name for /dev/loop<n> or /dev/loop/<n> */
134 if (lc->flags & LOOPDEV_FL_DEVSUBDIR) {
135 if (strlen(device) < 5)
136 return -1;
137 device += 4;
138 dir = _PATH_DEV_LOOP "/"; /* _PATH_DEV uses tailing slash */
139 }
140 snprintf(lc->device, sizeof(lc->device), "%s%s",
141 dir, device);
91072cd4
KZ
142 } else
143 xstrncpy(lc->device, device, sizeof(lc->device));
144
0bf03740 145 DBG(CXT, ul_debugobj(lc, "%s name assigned", device));
10ee5932
KZ
146 }
147
7604f85f
KZ
148 ul_unref_path(lc->sysfs);
149 lc->sysfs = NULL;
10ee5932
KZ
150 return 0;
151}
152
dab13032 153int loopcxt_has_device(struct loopdev_cxt *lc)
c7e0925d
KZ
154{
155 return lc && *lc->device;
156}
157
a6ca0456
JB
158dev_t loopcxt_get_devno(struct loopdev_cxt *lc)
159{
160 if (!lc || !loopcxt_has_device(lc))
161 return 0;
162 if (!lc->devno)
163 lc->devno = sysfs_devname_to_devno(lc->device);
164 return lc->devno;
165}
166
167int loopcxt_is_lost(struct loopdev_cxt *lc)
168{
169 if (!lc || !loopcxt_has_device(lc))
170 return 0;
171 if (lc->is_lost)
172 return 1;
173
174 lc->is_lost = access(lc->device, F_OK) != 0
175 && loopcxt_get_devno(lc) != 0;
176
177 return lc->is_lost;
178}
179
10ee5932
KZ
180/*
181 * @lc: context
182 * @flags: LOOPDEV_FL_* flags
183 *
3fd1f771 184 * Initialize loop handler.
10ee5932 185 *
fd7f0718
KZ
186 * We have two sets of the flags:
187 *
188 * * LOOPDEV_FL_* flags control loopcxt_* API behavior
189 *
190 * * LO_FLAGS_* are kernel flags used for LOOP_{SET,GET}_STAT64 ioctls
191 *
10ee5932
KZ
192 * Returns: <0 on error, 0 on success.
193 */
194int loopcxt_init(struct loopdev_cxt *lc, int flags)
195{
defa0710 196 int rc;
0b14bf7a 197 struct stat st;
6219c25e 198 struct loopdev_cxt dummy = UL_LOOPDEVCXT_EMPTY;
0b14bf7a 199
10ee5932
KZ
200 if (!lc)
201 return -EINVAL;
202
0bf03740
KZ
203 loopdev_init_debug();
204 DBG(CXT, ul_debugobj(lc, "initialize context"));
205
6219c25e 206 memcpy(lc, &dummy, sizeof(dummy));
10ee5932 207 lc->flags = flags;
defa0710
KZ
208
209 rc = loopcxt_set_device(lc, NULL);
210 if (rc)
211 return rc;
10ee5932 212
df0f2ad7
KZ
213 if (stat(_PATH_SYS_BLOCK, &st) || !S_ISDIR(st.st_mode)) {
214 lc->flags |= LOOPDEV_FL_NOSYSFS;
215 lc->flags &= ~LOOPDEV_FL_NOIOCTL;
0bf03740 216 DBG(CXT, ul_debugobj(lc, "init: disable /sys usage"));
df0f2ad7
KZ
217 }
218
82b4082e 219 if (!(lc->flags & LOOPDEV_FL_NOSYSFS) &&
f4bf9592 220 get_linux_version() >= KERNEL_VERSION(2,6,37)) {
10ee5932
KZ
221 /*
222 * Use only sysfs for basic information about loop devices
223 */
224 lc->flags |= LOOPDEV_FL_NOIOCTL;
0bf03740 225 DBG(CXT, ul_debugobj(lc, "init: ignore ioctls"));
f4bf9592 226 }
10ee5932 227
f4bf9592 228 if (!(lc->flags & LOOPDEV_FL_CONTROL) && !stat(_PATH_DEV_LOOPCTL, &st)) {
0b14bf7a 229 lc->flags |= LOOPDEV_FL_CONTROL;
0bf03740 230 DBG(CXT, ul_debugobj(lc, "init: loop-control detected "));
f4bf9592 231 }
0b14bf7a 232
10ee5932
KZ
233 return 0;
234}
235
236/*
237 * @lc: context
238 *
239 * Deinitialize loop context
240 */
241void loopcxt_deinit(struct loopdev_cxt *lc)
242{
82756a74
KZ
243 int errsv = errno;
244
10ee5932
KZ
245 if (!lc)
246 return;
247
0bf03740 248 DBG(CXT, ul_debugobj(lc, "de-initialize"));
aee31ddc 249
10ee5932
KZ
250 free(lc->filename);
251 lc->filename = NULL;
252
defa0710 253 ignore_result( loopcxt_set_device(lc, NULL) );
10ee5932 254 loopcxt_deinit_iterator(lc);
82756a74
KZ
255
256 errno = errsv;
10ee5932
KZ
257}
258
259/*
260 * @lc: context
261 *
262 * Returns newly allocated device path.
263 */
264char *loopcxt_strdup_device(struct loopdev_cxt *lc)
265{
cba69bb5 266 if (!lc || !*lc->device)
10ee5932
KZ
267 return NULL;
268 return strdup(lc->device);
269}
270
271/*
272 * @lc: context
273 *
274 * Returns pointer device name in the @lc struct.
275 */
276const char *loopcxt_get_device(struct loopdev_cxt *lc)
277{
cba69bb5 278 return lc && *lc->device ? lc->device : NULL;
10ee5932
KZ
279}
280
281/*
282 * @lc: context
283 *
284 * Returns pointer to the sysfs context (see lib/sysfs.c)
285 */
7604f85f 286static struct path_cxt *loopcxt_get_sysfs(struct loopdev_cxt *lc)
10ee5932
KZ
287{
288 if (!lc || !*lc->device || (lc->flags & LOOPDEV_FL_NOSYSFS))
289 return NULL;
290
7604f85f 291 if (!lc->sysfs) {
a6ca0456 292 dev_t devno = loopcxt_get_devno(lc);
aee31ddc 293 if (!devno) {
0bf03740 294 DBG(CXT, ul_debugobj(lc, "sysfs: failed devname to devno"));
10ee5932 295 return NULL;
aee31ddc 296 }
7604f85f
KZ
297
298 lc->sysfs = ul_new_sysfs_path(devno, NULL, NULL);
299 if (!lc->sysfs)
0bf03740 300 DBG(CXT, ul_debugobj(lc, "sysfs: init failed"));
10ee5932 301 }
aee31ddc 302
7604f85f 303 return lc->sysfs;
10ee5932
KZ
304}
305
ced1142d 306static int __loopcxt_get_fd(struct loopdev_cxt *lc, mode_t mode)
10ee5932 307{
ced1142d
KZ
308 int old = -1;
309
10ee5932 310 if (!lc || !*lc->device)
fd7f0718 311 return -EINVAL;
10ee5932 312
ced1142d
KZ
313 /* It's okay to return a FD with read-write permissions if someone
314 * asked for read-only, but you shouldn't do the opposite.
315 *
316 * (O_RDONLY is a widely usable default.)
317 */
318 if (lc->fd >= 0 && mode == O_RDWR && lc->mode == O_RDONLY) {
319 DBG(CXT, ul_debugobj(lc, "closing already open device (mode mismatch)"));
320 old = lc->fd;
321 lc->fd = -1;
322 }
323
fd7f0718 324 if (lc->fd < 0) {
ced1142d 325 lc->mode = mode;
b1fa3e22 326 lc->fd = open(lc->device, lc->mode | O_CLOEXEC);
0bf03740 327 DBG(CXT, ul_debugobj(lc, "open %s [%s]: %m", lc->device,
ced1142d
KZ
328 mode == O_RDONLY ? "ro" :
329 mode == O_RDWR ? "rw" : "??"));
330
331 if (lc->fd < 0 && old >= 0) {
332 /* restore original on error */
333 lc->fd = old;
334 old = -1;
335 }
fd7f0718 336 }
ced1142d
KZ
337
338 if (old >= 0)
339 close(old);
10ee5932
KZ
340 return lc->fd;
341}
342
ced1142d
KZ
343/* default is read-only file descriptor, it's enough for all ioctls */
344int loopcxt_get_fd(struct loopdev_cxt *lc)
345{
346 return __loopcxt_get_fd(lc, O_RDONLY);
347}
348
349int loopcxt_set_fd(struct loopdev_cxt *lc, int fd, mode_t mode)
fd7f0718
KZ
350{
351 if (!lc)
352 return -EINVAL;
353
354 lc->fd = fd;
355 lc->mode = mode;
356 return 0;
357}
358
10ee5932
KZ
359/*
360 * @lc: context
361 * @flags: LOOPITER_FL_* flags
362 *
29e204d1 363 * Iterator can be used to scan list of the free or used loop devices.
10ee5932
KZ
364 *
365 * Returns: <0 on error, 0 on success
366 */
367int loopcxt_init_iterator(struct loopdev_cxt *lc, int flags)
368{
369 struct loopdev_iter *iter;
370 struct stat st;
371
372 if (!lc)
373 return -EINVAL;
374
aee31ddc 375
10ee5932 376 iter = &lc->iter;
0bf03740 377 DBG(ITER, ul_debugobj(iter, "initialize"));
10ee5932
KZ
378
379 /* always zeroize
380 */
381 memset(iter, 0, sizeof(*iter));
382 iter->ncur = -1;
383 iter->flags = flags;
384 iter->default_check = 1;
385
386 if (!lc->extra_check) {
387 /*
388 * Check for /dev/loop/<N> subdirectory
389 */
82b4082e 390 if (!(lc->flags & LOOPDEV_FL_DEVSUBDIR) &&
10ee5932
KZ
391 stat(_PATH_DEV_LOOP, &st) == 0 && S_ISDIR(st.st_mode))
392 lc->flags |= LOOPDEV_FL_DEVSUBDIR;
393
394 lc->extra_check = 1;
395 }
396 return 0;
397}
398
399/*
400 * @lc: context
401 *
402 * Returns: <0 on error, 0 on success
403 */
404int loopcxt_deinit_iterator(struct loopdev_cxt *lc)
405{
7552258a 406 struct loopdev_iter *iter;
10ee5932
KZ
407
408 if (!lc)
409 return -EINVAL;
410
411 iter = &lc->iter;
0bf03740 412 DBG(ITER, ul_debugobj(iter, "de-initialize"));
10ee5932
KZ
413
414 free(iter->minors);
415 if (iter->proc)
416 fclose(iter->proc);
e4062c72
KZ
417 if (iter->sysblock)
418 closedir(iter->sysblock);
9a94b634
KZ
419
420 memset(iter, 0, sizeof(*iter));
10ee5932
KZ
421 return 0;
422}
423
424/*
425 * Same as loopcxt_set_device, but also checks if the device is
11026083 426 * associated with any file.
10ee5932
KZ
427 *
428 * Returns: <0 on error, 0 on success, 1 device does not match with
429 * LOOPITER_FL_{USED,FREE} flags.
430 */
431static int loopiter_set_device(struct loopdev_cxt *lc, const char *device)
432{
433 int rc = loopcxt_set_device(lc, device);
434 int used;
435
436 if (rc)
437 return rc;
438
439 if (!(lc->iter.flags & LOOPITER_FL_USED) &&
440 !(lc->iter.flags & LOOPITER_FL_FREE))
441 return 0; /* caller does not care about device status */
442
443 used = loopcxt_get_offset(lc, NULL) == 0;
444
445 if ((lc->iter.flags & LOOPITER_FL_USED) && used)
446 return 0;
447
448 if ((lc->iter.flags & LOOPITER_FL_FREE) && !used)
449 return 0;
450
0bf03740
KZ
451 DBG(ITER, ul_debugobj(&lc->iter, "failed to use %s device", lc->device));
452
defa0710 453 ignore_result( loopcxt_set_device(lc, NULL) );
10ee5932
KZ
454 return 1;
455}
456
457static int cmpnum(const void *p1, const void *p2)
458{
0145c00a
KZ
459 return (((* (const int *) p1) > (* (const int *) p2)) -
460 ((* (const int *) p1) < (* (const int *) p2)));
10ee5932
KZ
461}
462
463/*
464 * The classic scandir() is more expensive and less portable.
465 * We needn't full loop device names -- loop numbers (loop<N>)
466 * are enough.
467 */
468static int loop_scandir(const char *dirname, int **ary, int hasprefix)
469{
470 DIR *dir;
471 struct dirent *d;
472 unsigned int n, count = 0, arylen = 0;
473
474 if (!dirname || !ary)
475 return 0;
0bf03740
KZ
476
477 DBG(ITER, ul_debug("scan dir: %s", dirname));
478
10ee5932
KZ
479 dir = opendir(dirname);
480 if (!dir)
481 return 0;
10ee5932
KZ
482 free(*ary);
483 *ary = NULL;
484
485 while((d = readdir(dir))) {
486#ifdef _DIRENT_HAVE_D_TYPE
487 if (d->d_type != DT_BLK && d->d_type != DT_UNKNOWN &&
488 d->d_type != DT_LNK)
489 continue;
490#endif
491 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
492 continue;
493
494 if (hasprefix) {
495 /* /dev/loop<N> */
496 if (sscanf(d->d_name, "loop%u", &n) != 1)
497 continue;
498 } else {
499 /* /dev/loop/<N> */
500 char *end = NULL;
501
f0fe8ab5 502 errno = 0;
10ee5932
KZ
503 n = strtol(d->d_name, &end, 10);
504 if (d->d_name == end || (end && *end) || errno)
505 continue;
506 }
507 if (n < LOOPDEV_DEFAULT_NNODES)
508 continue; /* ignore loop<0..7> */
509
510 if (count + 1 > arylen) {
511 int *tmp;
512
513 arylen += 1;
514
64d6d400 515 tmp = reallocarray(*ary, arylen, sizeof(int));
10ee5932
KZ
516 if (!tmp) {
517 free(*ary);
34f6177a 518 *ary = NULL;
2e566efd 519 closedir(dir);
10ee5932
KZ
520 return -1;
521 }
522 *ary = tmp;
523 }
fc8b1f36
KZ
524 if (*ary)
525 (*ary)[count++] = n;
10ee5932 526 }
fc8b1f36 527 if (count && *ary)
10ee5932
KZ
528 qsort(*ary, count, sizeof(int), cmpnum);
529
530 closedir(dir);
531 return count;
532}
533
e4062c72
KZ
534/*
535 * Set the next *used* loop device according to /proc/partitions.
536 *
537 * Loop devices smaller than 512 bytes are invisible for this function.
538 */
539static int loopcxt_next_from_proc(struct loopdev_cxt *lc)
540{
541 struct loopdev_iter *iter = &lc->iter;
542 char buf[BUFSIZ];
543
0bf03740 544 DBG(ITER, ul_debugobj(iter, "scan /proc/partitions"));
e4062c72
KZ
545
546 if (!iter->proc)
b1fa3e22 547 iter->proc = fopen(_PATH_PROC_PARTITIONS, "r" UL_CLOEXECSTR);
e4062c72
KZ
548 if (!iter->proc)
549 return 1;
550
551 while (fgets(buf, sizeof(buf), iter->proc)) {
552 unsigned int m;
657d9adb 553 char name[128 + 1];
e4062c72
KZ
554
555
556 if (sscanf(buf, " %u %*s %*s %128[^\n ]",
557 &m, name) != 2 || m != LOOPDEV_MAJOR)
558 continue;
559
0bf03740 560 DBG(ITER, ul_debugobj(iter, "checking %s", name));
e4062c72
KZ
561
562 if (loopiter_set_device(lc, name) == 0)
563 return 0;
564 }
565
566 return 1;
567}
568
569/*
570 * Set the next *used* loop device according to
571 * /sys/block/loopN/loop/backing_file (kernel >= 2.6.37 is required).
572 *
573 * This is preferred method.
574 */
575static int loopcxt_next_from_sysfs(struct loopdev_cxt *lc)
576{
577 struct loopdev_iter *iter = &lc->iter;
578 struct dirent *d;
579 int fd;
580
0bf03740 581 DBG(ITER, ul_debugobj(iter, "scanning /sys/block"));
e4062c72
KZ
582
583 if (!iter->sysblock)
584 iter->sysblock = opendir(_PATH_SYS_BLOCK);
585
586 if (!iter->sysblock)
587 return 1;
588
589 fd = dirfd(iter->sysblock);
590
591 while ((d = readdir(iter->sysblock))) {
acecab61 592 char name[NAME_MAX + 18 + 1];
e4062c72
KZ
593 struct stat st;
594
0bf03740 595 DBG(ITER, ul_debugobj(iter, "check %s", d->d_name));
e4062c72
KZ
596
597 if (strcmp(d->d_name, ".") == 0
598 || strcmp(d->d_name, "..") == 0
599 || strncmp(d->d_name, "loop", 4) != 0)
600 continue;
601
602 snprintf(name, sizeof(name), "%s/loop/backing_file", d->d_name);
2208b3cc 603 if (fstatat(fd, name, &st, 0) != 0)
e4062c72
KZ
604 continue;
605
606 if (loopiter_set_device(lc, d->d_name) == 0)
607 return 0;
608 }
609
610 return 1;
611}
612
10ee5932
KZ
613/*
614 * @lc: context, has to initialized by loopcxt_init_iterator()
615 *
af5efcd8 616 * Returns: 0 on success, < 0 on error, 1 at the end of scanning. The details
10ee5932
KZ
617 * about the current loop device are available by
618 * loopcxt_get_{fd,backing_file,device,offset, ...} functions.
619 */
620int loopcxt_next(struct loopdev_cxt *lc)
621{
622 struct loopdev_iter *iter;
623
624 if (!lc)
625 return -EINVAL;
aee31ddc 626
aee31ddc 627
10ee5932
KZ
628 iter = &lc->iter;
629 if (iter->done)
630 return 1;
631
0bf03740
KZ
632 DBG(ITER, ul_debugobj(iter, "next"));
633
10ee5932
KZ
634 /* A) Look for used loop devices in /proc/partitions ("losetup -a" only)
635 */
636 if (iter->flags & LOOPITER_FL_USED) {
e4062c72
KZ
637 int rc;
638
639 if (loopcxt_sysfs_available(lc))
640 rc = loopcxt_next_from_sysfs(lc);
641 else
642 rc = loopcxt_next_from_proc(lc);
643 if (rc == 0)
644 return 0;
10ee5932
KZ
645 goto done;
646 }
647
648 /* B) Classic way, try first eight loop devices (default number
649 * of loop devices). This is enough for 99% of all cases.
650 */
651 if (iter->default_check) {
0bf03740 652 DBG(ITER, ul_debugobj(iter, "next: default check"));
10ee5932
KZ
653 for (++iter->ncur; iter->ncur < LOOPDEV_DEFAULT_NNODES;
654 iter->ncur++) {
655 char name[16];
656 snprintf(name, sizeof(name), "loop%d", iter->ncur);
657
658 if (loopiter_set_device(lc, name) == 0)
659 return 0;
660 }
661 iter->default_check = 0;
662 }
663
664 /* C) the worst possibility, scan whole /dev or /dev/loop/<N>
665 */
666 if (!iter->minors) {
0bf03740 667 DBG(ITER, ul_debugobj(iter, "next: scanning /dev"));
10ee5932
KZ
668 iter->nminors = (lc->flags & LOOPDEV_FL_DEVSUBDIR) ?
669 loop_scandir(_PATH_DEV_LOOP, &iter->minors, 0) :
670 loop_scandir(_PATH_DEV, &iter->minors, 1);
671 iter->ncur = -1;
672 }
673 for (++iter->ncur; iter->ncur < iter->nminors; iter->ncur++) {
674 char name[16];
675 snprintf(name, sizeof(name), "loop%d", iter->minors[iter->ncur]);
676
677 if (loopiter_set_device(lc, name) == 0)
678 return 0;
679 }
680done:
681 loopcxt_deinit_iterator(lc);
682 return 1;
683}
684
685/*
686 * @device: path to device
687 */
688int is_loopdev(const char *device)
689{
690 struct stat st;
fbc2fe82
KZ
691 int rc = 0;
692
693 if (!device || stat(device, &st) != 0 || !S_ISBLK(st.st_mode))
694 rc = 0;
695 else if (major(st.st_rdev) == LOOPDEV_MAJOR)
696 rc = 1;
d4423cce 697 else if (sysfs_devno_is_wholedisk(st.st_rdev)) {
fbc2fe82
KZ
698 /* It's possible that kernel creates a device with a different
699 * major number ... check by /sys it's really loop device.
700 */
701 char name[PATH_MAX], *cn, *p = NULL;
702
703 snprintf(name, sizeof(name), _PATH_SYS_DEVBLOCK "/%d:%d",
704 major(st.st_rdev), minor(st.st_rdev));
705 cn = canonicalize_path(name);
706 if (cn)
707 p = stripoff_last_component(cn);
708 rc = p && startswith(p, "loop");
709 free(cn);
710 }
10ee5932 711
fbc2fe82
KZ
712 if (rc == 0)
713 errno = ENODEV;
714 return rc;
10ee5932
KZ
715}
716
717/*
718 * @lc: context
719 *
720 * Returns result from LOOP_GET_STAT64 ioctl or NULL on error.
721 */
722struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc)
723{
724 int fd;
725
85794fb0
KZ
726 if (!lc || lc->info_failed) {
727 errno = EINVAL;
10ee5932 728 return NULL;
85794fb0
KZ
729 }
730 errno = 0;
10ee5932 731 if (lc->has_info)
d5fd456c 732 return &lc->config.info;
10ee5932
KZ
733
734 fd = loopcxt_get_fd(lc);
735 if (fd < 0)
736 return NULL;
737
d5fd456c 738 if (ioctl(fd, LOOP_GET_STATUS64, &lc->config.info) == 0) {
10ee5932 739 lc->has_info = 1;
6c224de1 740 lc->info_failed = 0;
0bf03740 741 DBG(CXT, ul_debugobj(lc, "reading loop_info64 OK"));
d5fd456c 742 return &lc->config.info;
10ee5932
KZ
743 }
744
85794fb0 745 lc->info_failed = 1;
0bf03740 746 DBG(CXT, ul_debugobj(lc, "reading loop_info64 FAILED"));
85794fb0 747
10ee5932
KZ
748 return NULL;
749}
750
751/*
752 * @lc: context
753 *
311e33af 754 * Returns (allocated) string with path to the file associated
10ee5932
KZ
755 * with the current loop device.
756 */
757char *loopcxt_get_backing_file(struct loopdev_cxt *lc)
758{
7604f85f 759 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
10ee5932
KZ
760 char *res = NULL;
761
762 if (sysfs)
fd7f0718 763 /*
11026083 764 * This is always preferred, the loop_info64
fd7f0718
KZ
765 * has too small buffer for the filename.
766 */
7604f85f 767 ul_path_read_string(sysfs, &res, "loop/backing_file");
10ee5932
KZ
768
769 if (!res && loopcxt_ioctl_enabled(lc)) {
770 struct loop_info64 *lo = loopcxt_get_info(lc);
771
772 if (lo) {
773 lo->lo_file_name[LO_NAME_SIZE - 2] = '*';
774 lo->lo_file_name[LO_NAME_SIZE - 1] = '\0';
775 res = strdup((char *) lo->lo_file_name);
776 }
777 }
aee31ddc 778
0bf03740 779 DBG(CXT, ul_debugobj(lc, "get_backing_file [%s]", res));
10ee5932
KZ
780 return res;
781}
782
db8f7815
KZ
783/*
784 * @lc: context
785 *
786 * Returns (allocated) string with loop reference. The same as backing file by
787 * default.
788 */
789char *loopcxt_get_refname(struct loopdev_cxt *lc)
790{
791 char *res = NULL;
792 struct loop_info64 *lo = loopcxt_get_info(lc);
793
794 if (lo) {
795 lo->lo_file_name[LO_NAME_SIZE - 1] = '\0';
796 res = strdup((char *) lo->lo_file_name);
797 }
798
799 DBG(CXT, ul_debugobj(lc, "get_refname [%s]", res));
800 return res;
801}
802
10ee5932
KZ
803/*
804 * @lc: context
805 * @offset: returns offset number for the given device
806 *
807 * Returns: <0 on error, 0 on success
808 */
809int loopcxt_get_offset(struct loopdev_cxt *lc, uint64_t *offset)
810{
7604f85f 811 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
10ee5932
KZ
812 int rc = -EINVAL;
813
814 if (sysfs)
fb4b6b11
JK
815 if (ul_path_read_u64(sysfs, offset, "loop/offset") == 0)
816 rc = 0;
10ee5932
KZ
817
818 if (rc && loopcxt_ioctl_enabled(lc)) {
819 struct loop_info64 *lo = loopcxt_get_info(lc);
820 if (lo) {
821 if (offset)
822 *offset = lo->lo_offset;
6c224de1 823 rc = 0;
85794fb0
KZ
824 } else
825 rc = -errno;
10ee5932
KZ
826 }
827
0bf03740 828 DBG(CXT, ul_debugobj(lc, "get_offset [rc=%d]", rc));
10ee5932
KZ
829 return rc;
830}
831
a1a41597
SB
832/*
833 * @lc: context
834 * @blocksize: returns logical blocksize for the given device
835 *
836 * Returns: <0 on error, 0 on success
837 */
838int loopcxt_get_blocksize(struct loopdev_cxt *lc, uint64_t *blocksize)
839{
7604f85f 840 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
a1a41597
SB
841 int rc = -EINVAL;
842
843 if (sysfs)
fb4b6b11
JK
844 if (ul_path_read_u64(sysfs, blocksize, "queue/logical_block_size") == 0)
845 rc = 0;
a1a41597
SB
846
847 /* Fallback based on BLKSSZGET ioctl */
848 if (rc) {
849 int fd = loopcxt_get_fd(lc);
850 int sz = 0;
851
852 if (fd < 0)
853 return -EINVAL;
854 rc = blkdev_get_sector_size(fd, &sz);
855 if (rc)
856 return rc;
857
858 *blocksize = sz;
859 }
860
861 DBG(CXT, ul_debugobj(lc, "get_blocksize [rc=%d]", rc));
862 return rc;
863}
864
10ee5932
KZ
865/*
866 * @lc: context
867 * @sizelimit: returns size limit for the given device
868 *
869 * Returns: <0 on error, 0 on success
870 */
871int loopcxt_get_sizelimit(struct loopdev_cxt *lc, uint64_t *size)
872{
7604f85f 873 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
10ee5932
KZ
874 int rc = -EINVAL;
875
876 if (sysfs)
fb4b6b11
JK
877 if (ul_path_read_u64(sysfs, size, "loop/sizelimit") == 0)
878 rc = 0;
10ee5932
KZ
879
880 if (rc && loopcxt_ioctl_enabled(lc)) {
881 struct loop_info64 *lo = loopcxt_get_info(lc);
882 if (lo) {
883 if (size)
884 *size = lo->lo_sizelimit;
6c224de1 885 rc = 0;
85794fb0
KZ
886 } else
887 rc = -errno;
10ee5932
KZ
888 }
889
0bf03740 890 DBG(CXT, ul_debugobj(lc, "get_sizelimit [rc=%d]", rc));
6c224de1
KZ
891 return rc;
892}
893
894/*
895 * @lc: context
a6ca0456 896 * @type: returns encryption type
6c224de1
KZ
897 *
898 * Cryptoloop is DEPRECATED!
899 *
900 * Returns: <0 on error, 0 on success
901 */
902int loopcxt_get_encrypt_type(struct loopdev_cxt *lc, uint32_t *type)
903{
904 struct loop_info64 *lo = loopcxt_get_info(lc);
85794fb0 905 int rc;
6c224de1 906
85794fb0 907 /* not provided by sysfs */
6c224de1
KZ
908 if (lo) {
909 if (type)
910 *type = lo->lo_encrypt_type;
911 rc = 0;
85794fb0
KZ
912 } else
913 rc = -errno;
914
0bf03740 915 DBG(CXT, ul_debugobj(lc, "get_encrypt_type [rc=%d]", rc));
6c224de1
KZ
916 return rc;
917}
918
919/*
920 * @lc: context
6c224de1
KZ
921 *
922 * Cryptoloop is DEPRECATED!
923 *
924 * Returns: <0 on error, 0 on success
925 */
926const char *loopcxt_get_crypt_name(struct loopdev_cxt *lc)
927{
928 struct loop_info64 *lo = loopcxt_get_info(lc);
929
930 if (lo)
931 return (char *) lo->lo_crypt_name;
932
0bf03740 933 DBG(CXT, ul_debugobj(lc, "get_crypt_name failed"));
6c224de1
KZ
934 return NULL;
935}
936
937/*
938 * @lc: context
939 * @devno: returns backing file devno
940 *
941 * Returns: <0 on error, 0 on success
942 */
943int loopcxt_get_backing_devno(struct loopdev_cxt *lc, dev_t *devno)
944{
945 struct loop_info64 *lo = loopcxt_get_info(lc);
85794fb0 946 int rc;
6c224de1
KZ
947
948 if (lo) {
949 if (devno)
950 *devno = lo->lo_device;
951 rc = 0;
85794fb0
KZ
952 } else
953 rc = -errno;
954
0bf03740 955 DBG(CXT, ul_debugobj(lc, "get_backing_devno [rc=%d]", rc));
6c224de1
KZ
956 return rc;
957}
958
959/*
960 * @lc: context
961 * @ino: returns backing file inode
962 *
963 * Returns: <0 on error, 0 on success
964 */
965int loopcxt_get_backing_inode(struct loopdev_cxt *lc, ino_t *ino)
966{
967 struct loop_info64 *lo = loopcxt_get_info(lc);
85794fb0 968 int rc;
6c224de1
KZ
969
970 if (lo) {
971 if (ino)
972 *ino = lo->lo_inode;
973 rc = 0;
85794fb0
KZ
974 } else
975 rc = -errno;
976
0bf03740 977 DBG(CXT, ul_debugobj(lc, "get_backing_inode [rc=%d]", rc));
10ee5932
KZ
978 return rc;
979}
980
59d749c3
KZ
981/*
982 * Check if the kernel supports partitioned loop devices.
983 *
984 * Notes:
985 * - kernels < 3.2 support partitioned loop devices and PT scanning
9e930041 986 * only if max_part= module parameter is non-zero
59d749c3
KZ
987 *
988 * - kernels >= 3.2 always support partitioned loop devices
989 *
990 * - kernels >= 3.2 always support BLKPG_{ADD,DEL}_PARTITION ioctls
991 *
992 * - kernels >= 3.2 enable PT scanner only if max_part= is non-zero or if the
993 * LO_FLAGS_PARTSCAN flag is set for the device. The PT scanner is disabled
994 * by default.
995 *
996 * See kernel commit e03c8dd14915fabc101aa495828d58598dc5af98.
997 */
998int loopmod_supports_partscan(void)
999{
1000 int rc, ret = 0;
1001 FILE *f;
1002
1003 if (get_linux_version() >= KERNEL_VERSION(3,2,0))
1004 return 1;
1005
b1fa3e22 1006 f = fopen("/sys/module/loop/parameters/max_part", "r" UL_CLOEXECSTR);
59d749c3
KZ
1007 if (!f)
1008 return 0;
1009 rc = fscanf(f, "%d", &ret);
1010 fclose(f);
8b04761d 1011 return rc == 1 ? ret : 0;
59d749c3
KZ
1012}
1013
10ee5932
KZ
1014/*
1015 * @lc: context
1016 *
59d749c3 1017 * Returns: 1 if the partscan flags is set *or* (for old kernels) partitions
9e930041 1018 * scanning is enabled for all loop devices.
59d749c3
KZ
1019 */
1020int loopcxt_is_partscan(struct loopdev_cxt *lc)
1021{
7604f85f 1022 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
59d749c3
KZ
1023
1024 if (sysfs) {
1025 /* kernel >= 3.2 */
1026 int fl;
7604f85f 1027 if (ul_path_read_s32(sysfs, &fl, "loop/partscan") == 0)
59d749c3
KZ
1028 return fl;
1029 }
1030
1031 /* old kernels (including kernels without loopN/loop/<flags> directory */
1032 return loopmod_supports_partscan();
1033}
1034
1035/*
1036 * @lc: context
1037 *
1038 * Returns: 1 if the autoclear flags is set.
10ee5932
KZ
1039 */
1040int loopcxt_is_autoclear(struct loopdev_cxt *lc)
1041{
7604f85f 1042 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
10ee5932
KZ
1043
1044 if (sysfs) {
1045 int fl;
7604f85f 1046 if (ul_path_read_s32(sysfs, &fl, "loop/autoclear") == 0)
10ee5932
KZ
1047 return fl;
1048 }
1049
1050 if (loopcxt_ioctl_enabled(lc)) {
1051 struct loop_info64 *lo = loopcxt_get_info(lc);
1052 if (lo)
1053 return lo->lo_flags & LO_FLAGS_AUTOCLEAR;
1054 }
1055 return 0;
1056}
1057
fd7f0718
KZ
1058/*
1059 * @lc: context
1060 *
59d749c3 1061 * Returns: 1 if the readonly flags is set.
fd7f0718
KZ
1062 */
1063int loopcxt_is_readonly(struct loopdev_cxt *lc)
1064{
7604f85f 1065 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
fd7f0718
KZ
1066
1067 if (sysfs) {
1068 int fl;
7604f85f 1069 if (ul_path_read_s32(sysfs, &fl, "ro") == 0)
fd7f0718
KZ
1070 return fl;
1071 }
1072
1073 if (loopcxt_ioctl_enabled(lc)) {
1074 struct loop_info64 *lo = loopcxt_get_info(lc);
1075 if (lo)
1076 return lo->lo_flags & LO_FLAGS_READ_ONLY;
1077 }
1078 return 0;
1079}
1080
faeef4d2
ML
1081/*
1082 * @lc: context
1083 *
1084 * Returns: 1 if the dio flags is set.
1085 */
1086int loopcxt_is_dio(struct loopdev_cxt *lc)
1087{
7604f85f 1088 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
faeef4d2
ML
1089
1090 if (sysfs) {
1091 int fl;
7604f85f 1092 if (ul_path_read_s32(sysfs, &fl, "loop/dio") == 0)
faeef4d2
ML
1093 return fl;
1094 }
1095 if (loopcxt_ioctl_enabled(lc)) {
1096 struct loop_info64 *lo = loopcxt_get_info(lc);
1097 if (lo)
1098 return lo->lo_flags & LO_FLAGS_DIRECT_IO;
1099 }
1100 return 0;
1101}
1102
6c224de1
KZ
1103/*
1104 * @lc: context
1105 * @st: backing file stat or NULL
1106 * @backing_file: filename
c444a71b
KZ
1107 * @offset: offset (use LOOPDEV_FL_OFFSET if specified)
1108 * @sizelimit: size limit (use LOOPDEV_FL_SIZELIMIT if specified)
1109 * @flags: LOOPDEV_FL_{OFFSET,SIZELIMIT}
6c224de1
KZ
1110 *
1111 * Returns 1 if the current @lc loopdev is associated with the given backing
1112 * file. Note that the preferred way is to use devno and inode number rather
1113 * than filename. The @backing_file filename is poor solution usable in case
1114 * that you don't have rights to call stat().
1115 *
74a4705a
SB
1116 * LOOPDEV_FL_SIZELIMIT requires LOOPDEV_FL_OFFSET being set as well.
1117 *
6c224de1
KZ
1118 * Don't forget that old kernels provide very restricted (in size) backing
1119 * filename by LOOP_GET_STAT64 ioctl only.
1120 */
1121int loopcxt_is_used(struct loopdev_cxt *lc,
1122 struct stat *st,
1123 const char *backing_file,
1124 uint64_t offset,
74a4705a 1125 uint64_t sizelimit,
6c224de1
KZ
1126 int flags)
1127{
3011b381
KZ
1128 ino_t ino = 0;
1129 dev_t dev = 0;
6c224de1
KZ
1130
1131 if (!lc)
1132 return 0;
1133
0bf03740 1134 DBG(CXT, ul_debugobj(lc, "checking %s vs. %s",
6c224de1
KZ
1135 loopcxt_get_device(lc),
1136 backing_file));
1137
1138 if (st && loopcxt_get_backing_inode(lc, &ino) == 0 &&
1139 loopcxt_get_backing_devno(lc, &dev) == 0) {
1140
1141 if (ino == st->st_ino && dev == st->st_dev)
1142 goto found;
1143
1144 /* don't use filename if we have devno and inode */
1145 return 0;
1146 }
1147
1148 /* poor man's solution */
1149 if (backing_file) {
1150 char *name = loopcxt_get_backing_file(lc);
1151 int rc = name && strcmp(name, backing_file) == 0;
1152
1153 free(name);
1154 if (rc)
1155 goto found;
1156 }
1157
1158 return 0;
1159found:
1160 if (flags & LOOPDEV_FL_OFFSET) {
3011b381 1161 uint64_t off = 0;
6c224de1 1162
74a4705a
SB
1163 int rc = loopcxt_get_offset(lc, &off) == 0 && off == offset;
1164
1165 if (rc && flags & LOOPDEV_FL_SIZELIMIT) {
3011b381 1166 uint64_t sz = 0;
74a4705a
SB
1167
1168 return loopcxt_get_sizelimit(lc, &sz) == 0 && sz == sizelimit;
042f62df
RP
1169 }
1170 return rc;
6c224de1
KZ
1171 }
1172 return 1;
1173}
1174
fd7f0718
KZ
1175/*
1176 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1177 */
10ee5932
KZ
1178int loopcxt_set_offset(struct loopdev_cxt *lc, uint64_t offset)
1179{
1180 if (!lc)
1181 return -EINVAL;
d5fd456c 1182 lc->config.info.lo_offset = offset;
aee31ddc 1183
0bf03740 1184 DBG(CXT, ul_debugobj(lc, "set offset=%jd", offset));
10ee5932
KZ
1185 return 0;
1186}
1187
fd7f0718
KZ
1188/*
1189 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1190 */
10ee5932
KZ
1191int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit)
1192{
1193 if (!lc)
1194 return -EINVAL;
d5fd456c 1195 lc->config.info.lo_sizelimit = sizelimit;
aee31ddc 1196
0bf03740 1197 DBG(CXT, ul_debugobj(lc, "set sizelimit=%jd", sizelimit));
10ee5932
KZ
1198 return 0;
1199}
1200
75d239ff
KZ
1201/*
1202 * The blocksize will be used by loopcxt_set_device(). For already exiting
1203 * devices use loopcxt_ioctl_blocksize().
1204 *
1205 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1206 */
1207int loopcxt_set_blocksize(struct loopdev_cxt *lc, uint64_t blocksize)
1208{
1209 if (!lc)
1210 return -EINVAL;
1211 lc->blocksize = blocksize;
1212
1213 DBG(CXT, ul_debugobj(lc, "set blocksize=%jd", blocksize));
1214 return 0;
1215}
1216
10ee5932
KZ
1217/*
1218 * @lc: context
1219 * @flags: kernel LO_FLAGS_{READ_ONLY,USE_AOPS,AUTOCLEAR} flags
1220 *
fd7f0718
KZ
1221 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1222 *
10ee5932
KZ
1223 * Returns: 0 on success, <0 on error.
1224 */
1225int loopcxt_set_flags(struct loopdev_cxt *lc, uint32_t flags)
1226{
1227 if (!lc)
1228 return -EINVAL;
d5fd456c 1229 lc->config.info.lo_flags = flags;
aee31ddc 1230
0bf03740 1231 DBG(CXT, ul_debugobj(lc, "set flags=%u", (unsigned) flags));
10ee5932
KZ
1232 return 0;
1233}
1234
db8f7815
KZ
1235/*
1236 * @lc: context
1237 * @refname: reference name (used to overwrite lo_file_name where is backing
1238 * file by default)
1239 *
1240 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1241 *
1242 * Returns: 0 on success, <0 on error.
1243 */
1244int loopcxt_set_refname(struct loopdev_cxt *lc, const char *refname)
1245{
1246 if (!lc)
1247 return -EINVAL;
1248
1249 memset(lc->config.info.lo_file_name, 0, sizeof(lc->config.info.lo_file_name));
1250 if (refname)
1251 xstrncpy((char *)lc->config.info.lo_file_name, refname, LO_NAME_SIZE);
1252
1253 DBG(CXT, ul_debugobj(lc, "set refname=%s", (char *)lc->config.info.lo_file_name));
1254 return 0;
1255}
1256
10ee5932
KZ
1257/*
1258 * @lc: context
1259 * @filename: backing file path (the path will be canonicalized)
1260 *
fd7f0718
KZ
1261 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1262 *
10ee5932
KZ
1263 * Returns: 0 on success, <0 on error.
1264 */
1265int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename)
1266{
1267 if (!lc)
1268 return -EINVAL;
1269
1270 lc->filename = canonicalize_path(filename);
1271 if (!lc->filename)
1272 return -errno;
1273
db8f7815
KZ
1274 if (!lc->config.info.lo_file_name[0])
1275 loopcxt_set_refname(lc, lc->filename);
10ee5932 1276
db8f7815 1277 DBG(CXT, ul_debugobj(lc, "set backing file=%s", lc->filename));
10ee5932
KZ
1278 return 0;
1279}
1280
293714c0
JM
1281/*
1282 * In kernels prior to v3.9, if the offset or sizelimit options
1283 * are used, the block device's size won't be synced automatically.
1284 * blockdev --getsize64 and filesystems will use the backing
1285 * file size until the block device has been re-opened or the
1286 * LOOP_SET_CAPACITY ioctl is called to sync the sizes.
1287 *
1288 * Since mount -oloop uses the LO_FLAGS_AUTOCLEAR option and passes
1289 * the open file descriptor to the mount system call, we need to use
1290 * the ioctl. Calling losetup directly doesn't have this problem since
1291 * it closes the device when it exits and whatever consumes the device
1292 * next will re-open it, causing the resync.
1293 */
1294static int loopcxt_check_size(struct loopdev_cxt *lc, int file_fd)
1295{
1296 uint64_t size, expected_size;
1297 int dev_fd;
1298 struct stat st;
1299
d5fd456c 1300 if (!lc->config.info.lo_offset && !lc->config.info.lo_sizelimit)
293714c0
JM
1301 return 0;
1302
01307ecf 1303 if (fstat(file_fd, &st)) {
0bf03740 1304 DBG(CXT, ul_debugobj(lc, "failed to fstat backing file"));
293714c0 1305 return -errno;
01307ecf 1306 }
e3b6cb87
KZ
1307 if (S_ISBLK(st.st_mode)) {
1308 if (blkdev_get_size(file_fd,
01307ecf 1309 (unsigned long long *) &expected_size)) {
0bf03740 1310 DBG(CXT, ul_debugobj(lc, "failed to determine device size"));
e3b6cb87 1311 return -errno;
01307ecf 1312 }
e3b6cb87
KZ
1313 } else
1314 expected_size = st.st_size;
1315
d5fd456c 1316 if (expected_size == 0 || expected_size <= lc->config.info.lo_offset) {
0bf03740 1317 DBG(CXT, ul_debugobj(lc, "failed to determine expected size"));
e3b6cb87
KZ
1318 return 0; /* ignore this error */
1319 }
293714c0 1320
d5fd456c
SK
1321 if (lc->config.info.lo_offset > 0)
1322 expected_size -= lc->config.info.lo_offset;
293714c0 1323
d5fd456c
SK
1324 if (lc->config.info.lo_sizelimit > 0 && lc->config.info.lo_sizelimit < expected_size)
1325 expected_size = lc->config.info.lo_sizelimit;
293714c0
JM
1326
1327 dev_fd = loopcxt_get_fd(lc);
01307ecf 1328 if (dev_fd < 0) {
0bf03740 1329 DBG(CXT, ul_debugobj(lc, "failed to get loop FD"));
293714c0 1330 return -errno;
01307ecf 1331 }
293714c0 1332
01307ecf 1333 if (blkdev_get_size(dev_fd, (unsigned long long *) &size)) {
0bf03740 1334 DBG(CXT, ul_debugobj(lc, "failed to determine loopdev size"));
293714c0 1335 return -errno;
01307ecf 1336 }
293714c0 1337
a7d5202b
KZ
1338 /* It's block device, so, align to 512-byte sectors */
1339 if (expected_size % 512) {
0bf03740 1340 DBG(CXT, ul_debugobj(lc, "expected size misaligned to 512-byte sectors"));
a7d5202b
KZ
1341 expected_size = (expected_size >> 9) << 9;
1342 }
1343
293714c0 1344 if (expected_size != size) {
0bf03740 1345 DBG(CXT, ul_debugobj(lc, "warning: loopdev and expected "
9e930041 1346 "size mismatch (%ju/%ju)",
e3b6cb87
KZ
1347 size, expected_size));
1348
9fcc8936 1349 if (loopcxt_ioctl_capacity(lc)) {
293714c0
JM
1350 /* ioctl not available */
1351 if (errno == ENOTTY || errno == EINVAL)
1352 errno = ERANGE;
1353 return -errno;
1354 }
1355
1356 if (blkdev_get_size(dev_fd, (unsigned long long *) &size))
1357 return -errno;
1358
01307ecf
KZ
1359 if (expected_size != size) {
1360 errno = ERANGE;
0bf03740 1361 DBG(CXT, ul_debugobj(lc, "failed to set loopdev size, "
01307ecf
KZ
1362 "size: %ju, expected: %ju",
1363 size, expected_size));
1364 return -errno;
1365 }
293714c0
JM
1366 }
1367
1368 return 0;
1369}
1370
9d5424c2 1371
10ee5932 1372/*
bfd4e1f7 1373 * @lc: context
10ee5932
KZ
1374 *
1375 * Associate the current device (see loopcxt_{set,get}_device()) with
1376 * a file (see loopcxt_set_backing_file()).
1377 *
fd7f0718
KZ
1378 * The device is initialized read-write by default. If you want read-only
1379 * device then set LO_FLAGS_READ_ONLY by loopcxt_set_flags(). The LOOPDEV_FL_*
1380 * flags are ignored and modified according to LO_FLAGS_*.
1381 *
1382 * If the device is already open by loopcxt_get_fd() then this setup device
1383 * function will re-open the device to fix read/write mode.
1384 *
1385 * The device is also initialized read-only if the backing file is not
1386 * possible to open read-write (e.g. read-only FS).
10ee5932
KZ
1387 *
1388 * Returns: <0 on error, 0 on success.
1389 */
1390int loopcxt_setup_device(struct loopdev_cxt *lc)
1391{
ced1142d
KZ
1392 int file_fd, dev_fd;
1393 mode_t flags = O_CLOEXEC, mode = O_RDWR;
1328e0f7 1394 int rc = -1, cnt = 0;
2cde9865 1395 int errsv = 0;
d5fd456c 1396 int fallback = 0;
10ee5932
KZ
1397
1398 if (!lc || !*lc->device || !lc->filename)
1399 return -EINVAL;
1400
0bf03740 1401 DBG(SETUP, ul_debugobj(lc, "device setup requested"));
aee31ddc 1402
10ee5932
KZ
1403 /*
1404 * Open backing file and device
1405 */
d5fd456c 1406 if (lc->config.info.lo_flags & LO_FLAGS_READ_ONLY)
fd7f0718 1407 mode = O_RDONLY;
10ee5932 1408
d53346ed
AXH
1409 if (lc->config.info.lo_flags & LO_FLAGS_DIRECT_IO)
1410 flags |= O_DIRECT;
1411
1412 if ((file_fd = open(lc->filename, mode | flags)) < 0) {
10ee5932 1413 if (mode != O_RDONLY && (errno == EROFS || errno == EACCES))
d53346ed 1414 file_fd = open(lc->filename, (mode = O_RDONLY) | flags);
10ee5932 1415
aee31ddc 1416 if (file_fd < 0) {
0bf03740 1417 DBG(SETUP, ul_debugobj(lc, "open backing file failed: %m"));
10ee5932 1418 return -errno;
aee31ddc 1419 }
10ee5932 1420 }
0bf03740 1421 DBG(SETUP, ul_debugobj(lc, "backing file open: OK"));
10ee5932 1422
ced1142d 1423 if (mode == O_RDONLY)
d5fd456c 1424 lc->config.info.lo_flags |= LO_FLAGS_READ_ONLY; /* kernel loopdev mode */
ced1142d 1425 else
d5fd456c 1426 lc->config.info.lo_flags &= ~LO_FLAGS_READ_ONLY;
10ee5932 1427
663bf040
KZ
1428 do {
1429 errno = 0;
ced1142d
KZ
1430
1431 /* For the ioctls, it's enough to use O_RDONLY, but udevd
1432 * monitor devices by inotify, and udevd needs IN_CLOSE_WRITE
1433 * event to trigger probing of the new device.
1434 *
1435 * The mode used for the device does not have to match the mode
1436 * used for the backing file.
1437 */
1438 dev_fd = __loopcxt_get_fd(lc, O_RDWR);
663bf040
KZ
1439 if (dev_fd >= 0 || lc->control_ok == 0)
1440 break;
1441 if (errno != EACCES && errno != ENOENT)
1442 break;
1443 /* We have permissions to open /dev/loop-control, but open
1444 * /dev/loopN failed with EACCES, it's probably because udevd
1445 * does not applied chown yet. Let's wait a moment. */
1446 xusleep(25000);
1447 } while (cnt++ < 16);
1448
10ee5932
KZ
1449 if (dev_fd < 0) {
1450 rc = -errno;
1451 goto err;
1452 }
1453
0bf03740 1454 DBG(SETUP, ul_debugobj(lc, "device open: OK"));
d356c5d2 1455
a61955ba
KZ
1456 /*
1457 * Atomic way to configure all by one ioctl call
1458 * -- since Linux v5.8-rc1, commit 3448914e8cc550ba792d4ccc74471d1ca4293aae
1459 */
d5fd456c 1460 lc->config.fd = file_fd;
854abba0
HE
1461 if (lc->blocksize > 0)
1462 lc->config.block_size = lc->blocksize;
9d5424c2
KZ
1463
1464 rc = repeat_on_eagain( ioctl(dev_fd, LOOP_CONFIGURE, &lc->config) );
1465 if (rc != 0) {
2cde9865 1466 errsv = errno;
f6385a6a 1467 if (errno != EINVAL && errno != ENOTTY && errno != ENOSYS) {
d5fd456c
SK
1468 DBG(SETUP, ul_debugobj(lc, "LOOP_CONFIGURE failed: %m"));
1469 goto err;
1470 }
1471 fallback = 1;
a61955ba 1472 } else {
d5fd456c 1473 DBG(SETUP, ul_debugobj(lc, "LOOP_CONFIGURE: OK"));
75d239ff
KZ
1474 }
1475
a61955ba
KZ
1476 /*
1477 * Old deprecated way; first assign backing file FD and then in the
1478 * second step set loop device properties.
1479 */
d5fd456c 1480 if (fallback) {
d5fd456c
SK
1481 if (ioctl(dev_fd, LOOP_SET_FD, file_fd) < 0) {
1482 rc = -errno;
1483 errsv = errno;
1484 DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD failed: %m"));
1485 goto err;
1486 }
d356c5d2 1487
d5fd456c
SK
1488 DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD: OK"));
1489
1490 if (lc->blocksize > 0
1491 && (rc = loopcxt_ioctl_blocksize(lc, lc->blocksize)) < 0) {
1492 errsv = -rc;
1493 goto err;
1494 }
1495
1328e0f7
KZ
1496 if ((rc = loopcxt_ioctl_status(lc)) < 0) {
1497 errsv = -rc;
d5fd456c
SK
1498 goto err;
1499 }
d5fd456c 1500 }
d356c5d2 1501
293714c0
JM
1502 if ((rc = loopcxt_check_size(lc, file_fd)))
1503 goto err;
1504
1505 close(file_fd);
293714c0 1506
d5fd456c 1507 memset(&lc->config, 0, sizeof(lc->config));
10ee5932 1508 lc->has_info = 0;
6c224de1 1509 lc->info_failed = 0;
10ee5932 1510
0bf03740 1511 DBG(SETUP, ul_debugobj(lc, "success [rc=0]"));
10ee5932
KZ
1512 return 0;
1513err:
1514 if (file_fd >= 0)
1515 close(file_fd);
f7e21185 1516 if (dev_fd >= 0 && rc != -EBUSY)
10ee5932 1517 ioctl(dev_fd, LOOP_CLR_FD, 0);
2cde9865
KZ
1518 if (errsv)
1519 errno = errsv;
10ee5932 1520
0bf03740 1521 DBG(SETUP, ul_debugobj(lc, "failed [rc=%d]", rc));
10ee5932
KZ
1522 return rc;
1523}
1524
9d5424c2 1525
bfd4e1f7
SB
1526/*
1527 * @lc: context
1528 *
1529 * Update status of the current device (see loopcxt_{set,get}_device()).
1530 *
1531 * Note that once initialized, kernel accepts only selected changes:
1532 * LO_FLAGS_AUTOCLEAR and LO_FLAGS_PARTSCAN
1533 * For more see linux/drivers/block/loop.c:loop_set_status()
1534 *
1535 * Returns: <0 on error, 0 on success.
1536 */
9fcc8936 1537int loopcxt_ioctl_status(struct loopdev_cxt *lc)
bfd4e1f7 1538{
9d5424c2 1539 int dev_fd, rc;
bfd4e1f7
SB
1540
1541 errno = 0;
1542 dev_fd = loopcxt_get_fd(lc);
1543
9d5424c2
KZ
1544 if (dev_fd < 0)
1545 return -errno;
bfd4e1f7 1546
9d5424c2 1547 DBG(SETUP, ul_debugobj(lc, "calling LOOP_SET_STATUS64"));
0ae7bb11 1548
9d5424c2
KZ
1549 rc = repeat_on_eagain( ioctl(dev_fd, LOOP_SET_STATUS64, &lc->config.info) );
1550 if (rc != 0) {
bfd4e1f7
SB
1551 DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64 failed: %m"));
1552 return rc;
1553 }
1554
1555 DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64: OK"));
1556 return 0;
1557}
1558
9fcc8936 1559int loopcxt_ioctl_capacity(struct loopdev_cxt *lc)
293714c0 1560{
9d5424c2 1561 int rc, fd = loopcxt_get_fd(lc);
293714c0
JM
1562
1563 if (fd < 0)
1564 return -EINVAL;
1565
9d5424c2
KZ
1566 DBG(SETUP, ul_debugobj(lc, "calling LOOP_SET_CAPACITY"));
1567
293714c0 1568 /* Kernels prior to v2.6.30 don't support this ioctl */
9d5424c2
KZ
1569 rc = repeat_on_eagain( ioctl(fd, LOOP_SET_CAPACITY, 0) );
1570 if (rc != 0) {
0bf03740 1571 DBG(CXT, ul_debugobj(lc, "LOOP_SET_CAPACITY failed: %m"));
293714c0
JM
1572 return rc;
1573 }
1574
0bf03740 1575 DBG(CXT, ul_debugobj(lc, "capacity set"));
293714c0
JM
1576 return 0;
1577}
1578
9fcc8936 1579int loopcxt_ioctl_dio(struct loopdev_cxt *lc, unsigned long use_dio)
64c3bb3c 1580{
9d5424c2 1581 int rc, fd = loopcxt_get_fd(lc);
64c3bb3c
ML
1582
1583 if (fd < 0)
1584 return -EINVAL;
1585
9d5424c2
KZ
1586 DBG(SETUP, ul_debugobj(lc, "calling LOOP_SET_DIRECT_IO"));
1587
64c3bb3c 1588 /* Kernels prior to v4.4 don't support this ioctl */
9d5424c2
KZ
1589 rc = repeat_on_eagain( ioctl(fd, LOOP_SET_DIRECT_IO, use_dio) );
1590 if (rc != 0) {
64c3bb3c
ML
1591 DBG(CXT, ul_debugobj(lc, "LOOP_SET_DIRECT_IO failed: %m"));
1592 return rc;
1593 }
1594
1595 DBG(CXT, ul_debugobj(lc, "direct io set"));
1596 return 0;
1597}
1598
c4e60bc0
KZ
1599/*
1600 * Kernel uses "unsigned long" as ioctl arg, but we use u64 for all sizes to
1601 * keep loopdev internal API simple.
1602 */
9fcc8936 1603int loopcxt_ioctl_blocksize(struct loopdev_cxt *lc, uint64_t blocksize)
a1a41597 1604{
9d5424c2 1605 int rc, fd = loopcxt_get_fd(lc);
a1a41597
SB
1606
1607 if (fd < 0)
1608 return -EINVAL;
1609
9d5424c2
KZ
1610 DBG(SETUP, ul_debugobj(lc, "calling LOOP_SET_BLOCK_SIZE"));
1611
1612 rc = repeat_on_eagain(
1613 ioctl(fd, LOOP_SET_BLOCK_SIZE, (unsigned long) blocksize) );
1614 if (rc != 0) {
1615 DBG(CXT, ul_debugobj(lc, "LOOP_SET_BLOCK_SIZE failed: %m"));
1616 return rc;
1617 }
a1a41597
SB
1618
1619 DBG(CXT, ul_debugobj(lc, "logical block size set"));
1620 return 0;
1621}
1622
10ee5932
KZ
1623int loopcxt_delete_device(struct loopdev_cxt *lc)
1624{
9d5424c2 1625 int rc, fd = loopcxt_get_fd(lc);
10ee5932
KZ
1626
1627 if (fd < 0)
1628 return -EINVAL;
1629
9d5424c2
KZ
1630 DBG(SETUP, ul_debugobj(lc, "calling LOOP_SET_CLR_FD"));
1631
1632 rc = repeat_on_eagain( ioctl(fd, LOOP_CLR_FD, 0) );
1633 if (rc != 0) {
0bf03740 1634 DBG(CXT, ul_debugobj(lc, "LOOP_CLR_FD failed: %m"));
9d5424c2 1635 return rc;
aee31ddc
KZ
1636 }
1637
0bf03740 1638 DBG(CXT, ul_debugobj(lc, "device removed"));
10ee5932
KZ
1639 return 0;
1640}
1641
3cb2413b
KZ
1642int loopcxt_add_device(struct loopdev_cxt *lc)
1643{
1644 int rc = -EINVAL;
1645 int ctl, nr = -1;
1646 const char *p, *dev = loopcxt_get_device(lc);
1647
1648 if (!dev)
1649 goto done;
1650
1651 if (!(lc->flags & LOOPDEV_FL_CONTROL)) {
1652 rc = -ENOSYS;
1653 goto done;
1654 }
1655
1656 p = strrchr(dev, '/');
1657 if (!p || (sscanf(p, "/loop%d", &nr) != 1 && sscanf(p, "/%d", &nr) != 1)
1658 || nr < 0)
1659 goto done;
1660
1661 ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC);
1662 if (ctl >= 0) {
0bf03740 1663 DBG(CXT, ul_debugobj(lc, "add_device %d", nr));
3cb2413b
KZ
1664 rc = ioctl(ctl, LOOP_CTL_ADD, nr);
1665 close(ctl);
1666 }
663bf040 1667 lc->control_ok = rc >= 0 ? 1 : 0;
3cb2413b 1668done:
0bf03740 1669 DBG(CXT, ul_debugobj(lc, "add_device done [rc=%d]", rc));
3cb2413b
KZ
1670 return rc;
1671}
1672
59d749c3
KZ
1673/*
1674 * Note that LOOP_CTL_GET_FREE ioctl is supported since kernel 3.1. In older
1675 * kernels we have to check all loop devices to found unused one.
1676 *
1677 * See kernel commit 770fe30a46a12b6fb6b63fbe1737654d28e8484.
3c540264
TW
1678 *
1679 * Returns: 0 = success, < 0 error
59d749c3 1680 */
10ee5932
KZ
1681int loopcxt_find_unused(struct loopdev_cxt *lc)
1682{
0b14bf7a 1683 int rc = -1;
10ee5932 1684
0bf03740 1685 DBG(CXT, ul_debugobj(lc, "find_unused requested"));
aee31ddc 1686
0b14bf7a 1687 if (lc->flags & LOOPDEV_FL_CONTROL) {
9a94b634
KZ
1688 int ctl;
1689
1690 DBG(CXT, ul_debugobj(lc, "using loop-control"));
10ee5932 1691
9a94b634 1692 ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC);
0b14bf7a
KZ
1693 if (ctl >= 0)
1694 rc = ioctl(ctl, LOOP_CTL_GET_FREE);
3c540264
TW
1695 else
1696 rc = -errno;
0b14bf7a
KZ
1697 if (rc >= 0) {
1698 char name[16];
1699 snprintf(name, sizeof(name), "loop%d", rc);
1700
1701 rc = loopiter_set_device(lc, name);
1702 }
663bf040 1703 lc->control_ok = ctl >= 0 && rc == 0 ? 1 : 0;
0b14bf7a
KZ
1704 if (ctl >= 0)
1705 close(ctl);
0bf03740 1706 DBG(CXT, ul_debugobj(lc, "find_unused by loop-control [rc=%d]", rc));
0b14bf7a
KZ
1707 }
1708
1709 if (rc < 0) {
9a94b634 1710 DBG(CXT, ul_debugobj(lc, "using loop scan"));
0b14bf7a
KZ
1711 rc = loopcxt_init_iterator(lc, LOOPITER_FL_FREE);
1712 if (rc)
1713 return rc;
10ee5932 1714
0b14bf7a
KZ
1715 rc = loopcxt_next(lc);
1716 loopcxt_deinit_iterator(lc);
0bf03740 1717 DBG(CXT, ul_debugobj(lc, "find_unused by scan [rc=%d]", rc));
3c540264
TW
1718 if (rc)
1719 return -ENOENT;
0b14bf7a 1720 }
10ee5932
KZ
1721 return rc;
1722}
1723
1724
1725
1726/*
1727 * Return: TRUE/FALSE
1728 */
1729int loopdev_is_autoclear(const char *device)
1730{
1731 struct loopdev_cxt lc;
1732 int rc;
1733
1734 if (!device)
1735 return 0;
1736
defa0710
KZ
1737 rc = loopcxt_init(&lc, 0);
1738 if (!rc)
1739 rc = loopcxt_set_device(&lc, device);
1740 if (!rc)
1741 rc = loopcxt_is_autoclear(&lc);
10ee5932 1742
defa0710 1743 loopcxt_deinit(&lc);
10ee5932
KZ
1744 return rc;
1745}
1746
1747char *loopdev_get_backing_file(const char *device)
1748{
1749 struct loopdev_cxt lc;
defa0710 1750 char *res = NULL;
10ee5932
KZ
1751
1752 if (!device)
1753 return NULL;
defa0710
KZ
1754 if (loopcxt_init(&lc, 0))
1755 return NULL;
1756 if (loopcxt_set_device(&lc, device) == 0)
1757 res = loopcxt_get_backing_file(&lc);
10ee5932 1758
10ee5932 1759 loopcxt_deinit(&lc);
10ee5932
KZ
1760 return res;
1761}
1762
af5efcd8
TW
1763/*
1764 * Returns: TRUE/FALSE
1765 */
14bb8e3c
KZ
1766int loopdev_has_backing_file(const char *device)
1767{
1768 char *tmp = loopdev_get_backing_file(device);
1769
1770 if (tmp) {
1771 free(tmp);
1772 return 1;
1773 }
1774 return 0;
1775}
1776
10ee5932
KZ
1777/*
1778 * Returns: TRUE/FALSE
1779 */
1780int loopdev_is_used(const char *device, const char *filename,
74a4705a 1781 uint64_t offset, uint64_t sizelimit, int flags)
10ee5932
KZ
1782{
1783 struct loopdev_cxt lc;
6c224de1 1784 struct stat st;
10ee5932
KZ
1785 int rc = 0;
1786
8b470b20 1787 if (!device || !filename)
10ee5932
KZ
1788 return 0;
1789
defa0710
KZ
1790 rc = loopcxt_init(&lc, 0);
1791 if (!rc)
1792 rc = loopcxt_set_device(&lc, device);
1793 if (rc)
1794 return rc;
10ee5932 1795
6c224de1 1796 rc = !stat(filename, &st);
74a4705a 1797 rc = loopcxt_is_used(&lc, rc ? &st : NULL, filename, offset, sizelimit, flags);
10ee5932 1798
10ee5932 1799 loopcxt_deinit(&lc);
10ee5932
KZ
1800 return rc;
1801}
1802
af5efcd8
TW
1803/*
1804 * Returns: 0 = success, < 0 error
1805 */
10ee5932
KZ
1806int loopdev_delete(const char *device)
1807{
1808 struct loopdev_cxt lc;
1809 int rc;
1810
8b470b20
KZ
1811 if (!device)
1812 return -EINVAL;
1813
defa0710
KZ
1814 rc = loopcxt_init(&lc, 0);
1815 if (!rc)
1816 rc = loopcxt_set_device(&lc, device);
10ee5932
KZ
1817 if (!rc)
1818 rc = loopcxt_delete_device(&lc);
1819 loopcxt_deinit(&lc);
1820 return rc;
1821}
1822
1823/*
1824 * Returns: 0 = success, < 0 error, 1 not found
1825 */
1826int loopcxt_find_by_backing_file(struct loopdev_cxt *lc, const char *filename,
74a4705a 1827 uint64_t offset, uint64_t sizelimit, int flags)
10ee5932 1828{
6c224de1
KZ
1829 int rc, hasst;
1830 struct stat st;
10ee5932
KZ
1831
1832 if (!filename)
1833 return -EINVAL;
1834
6c224de1
KZ
1835 hasst = !stat(filename, &st);
1836
10ee5932
KZ
1837 rc = loopcxt_init_iterator(lc, LOOPITER_FL_USED);
1838 if (rc)
1839 return rc;
1840
6c224de1 1841 while ((rc = loopcxt_next(lc)) == 0) {
10ee5932 1842
6c224de1 1843 if (loopcxt_is_used(lc, hasst ? &st : NULL,
74a4705a 1844 filename, offset, sizelimit, flags))
6c224de1 1845 break;
10ee5932
KZ
1846 }
1847
1848 loopcxt_deinit_iterator(lc);
1849 return rc;
1850}
1851
211e1d46 1852/*
dff7e160 1853 * Returns: 0 = not found, < 0 error, 1 found, 2 found full size and offset match
211e1d46 1854 */
c444a71b 1855int loopcxt_find_overlap(struct loopdev_cxt *lc, const char *filename,
211e1d46
SB
1856 uint64_t offset, uint64_t sizelimit)
1857{
1858 int rc, hasst;
1859 struct stat st;
1860
1861 if (!filename)
1862 return -EINVAL;
1863
9a94b634 1864 DBG(CXT, ul_debugobj(lc, "find_overlap requested"));
211e1d46
SB
1865 hasst = !stat(filename, &st);
1866
1867 rc = loopcxt_init_iterator(lc, LOOPITER_FL_USED);
1868 if (rc)
1869 return rc;
1870
1871 while ((rc = loopcxt_next(lc)) == 0) {
1872 uint64_t lc_sizelimit, lc_offset;
1873
1874 rc = loopcxt_is_used(lc, hasst ? &st : NULL,
1875 filename, offset, sizelimit, 0);
562990b5
JK
1876 /*
1877 * Either the loopdev is unused or we've got an error which can
1878 * happen when we are racing with device autoclear. Just ignore
1879 * this loopdev...
1880 */
1881 if (rc <= 0)
1882 continue;
c444a71b 1883
211e1d46
SB
1884 DBG(CXT, ul_debugobj(lc, "found %s backed by %s",
1885 loopcxt_get_device(lc), filename));
c444a71b 1886
211e1d46
SB
1887 rc = loopcxt_get_offset(lc, &lc_offset);
1888 if (rc) {
1889 DBG(CXT, ul_debugobj(lc, "failed to get offset for device %s",
1890 loopcxt_get_device(lc)));
562990b5 1891 continue;
211e1d46
SB
1892 }
1893 rc = loopcxt_get_sizelimit(lc, &lc_sizelimit);
1894 if (rc) {
1895 DBG(CXT, ul_debugobj(lc, "failed to get sizelimit for device %s",
1896 loopcxt_get_device(lc)));
562990b5 1897 continue;
211e1d46
SB
1898 }
1899
dff7e160
KZ
1900 /* full match */
1901 if (lc_sizelimit == sizelimit && lc_offset == offset) {
1902 DBG(CXT, ul_debugobj(lc, "overlapping loop device %s (full match)",
1903 loopcxt_get_device(lc)));
1904 rc = 2;
1905 goto found;
1906 }
1907
1908 /* overlap */
211e1d46
SB
1909 if (lc_sizelimit != 0 && offset >= lc_offset + lc_sizelimit)
1910 continue;
1911 if (sizelimit != 0 && offset + sizelimit <= lc_offset)
1912 continue;
dff7e160 1913
211e1d46
SB
1914 DBG(CXT, ul_debugobj(lc, "overlapping loop device %s",
1915 loopcxt_get_device(lc)));
dff7e160
KZ
1916 rc = 1;
1917 goto found;
211e1d46 1918 }
dff7e160
KZ
1919
1920 if (rc == 1)
1921 rc = 0; /* not found */
1922found:
211e1d46 1923 loopcxt_deinit_iterator(lc);
9a94b634 1924 DBG(CXT, ul_debugobj(lc, "find_overlap done [rc=%d]", rc));
211e1d46
SB
1925 return rc;
1926}
1927
10ee5932
KZ
1928/*
1929 * Returns allocated string with device name
1930 */
74a4705a 1931char *loopdev_find_by_backing_file(const char *filename, uint64_t offset, uint64_t sizelimit, int flags)
10ee5932
KZ
1932{
1933 struct loopdev_cxt lc;
1934 char *res = NULL;
1935
1936 if (!filename)
1937 return NULL;
1938
defa0710
KZ
1939 if (loopcxt_init(&lc, 0))
1940 return NULL;
74a4705a 1941 if (loopcxt_find_by_backing_file(&lc, filename, offset, sizelimit, flags) == 0)
10ee5932
KZ
1942 res = loopcxt_strdup_device(&lc);
1943 loopcxt_deinit(&lc);
1944
1945 return res;
1946}
1947
d5688130
KZ
1948/*
1949 * Returns number of loop devices associated with @file, if only one loop
11026083 1950 * device is associated with the given @filename and @loopdev is not NULL then
d5688130
KZ
1951 * @loopdev returns name of the device.
1952 */
1953int loopdev_count_by_backing_file(const char *filename, char **loopdev)
1954{
1955 struct loopdev_cxt lc;
defa0710 1956 int count = 0, rc;
d5688130
KZ
1957
1958 if (!filename)
1959 return -1;
1960
defa0710
KZ
1961 rc = loopcxt_init(&lc, 0);
1962 if (rc)
1963 return rc;
d5688130
KZ
1964 if (loopcxt_init_iterator(&lc, LOOPITER_FL_USED))
1965 return -1;
1966
1967 while(loopcxt_next(&lc) == 0) {
1968 char *backing = loopcxt_get_backing_file(&lc);
1969
ad296391 1970 if (!backing || strcmp(backing, filename) != 0) {
d5688130
KZ
1971 free(backing);
1972 continue;
1973 }
1974
1975 free(backing);
1976 if (loopdev && count == 0)
1977 *loopdev = loopcxt_strdup_device(&lc);
1978 count++;
1979 }
1980
1981 loopcxt_deinit(&lc);
1982
1983 if (loopdev && count > 1) {
1984 free(*loopdev);
1985 *loopdev = NULL;
1986 }
1987 return count;
1988}
1989
d4423cce
KZ
1990#ifdef TEST_PROGRAM_LOOPDEV
1991int main(int argc, char *argv[])
1992{
1993 if (argc < 2)
1994 goto usage;
1995
1996 if (strcmp(argv[1], "--is-loopdev") == 0 && argc == 3)
1997 printf("%s: %s\n", argv[2], is_loopdev(argv[2]) ? "OK" : "FAIL");
1998 else
1999 goto usage;
2000
2001 return EXIT_SUCCESS;
2002usage:
2003 fprintf(stderr, "usage: %1$s --is-loopdev <dev>\n",
2004 program_invocation_short_name);
2005 return EXIT_FAILURE;
2006}
2007#endif
2008