Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

btrfs-progs: remove loopback device resolution #940

Open
wants to merge 1 commit into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions common/open-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@
#include "common/open-utils.h"

/*
* Check if a file is used (directly or indirectly via a loop device) by a
* device in fs_devices
* Check if a file is used by a device in fs_devices
*/
static int blk_file_in_dev_list(struct btrfs_fs_devices* fs_devices,
const char* file)
Expand All @@ -46,7 +45,7 @@ static int blk_file_in_dev_list(struct btrfs_fs_devices* fs_devices,
struct btrfs_device *device;

list_for_each_entry(device, &fs_devices->devices, dev_list) {
if((ret = is_same_loop_file(device->name, file)))
if((ret = is_same_blk_file(device->name, file)))
return ret;
}

Expand Down Expand Up @@ -94,7 +93,7 @@ int check_mounted_where(int fd, const char *file, char *where, int size,
else if(!ret)
continue;

ret = is_same_loop_file(file, mnt->mnt_fsname);
ret = is_same_blk_file(file, mnt->mnt_fsname);
}

if(ret < 0)
Expand Down
127 changes: 1 addition & 126 deletions common/path-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,87 +107,11 @@ int path_exists(const char *path)
return 1;
}

/* checks if a device is a loop device */
static int is_loop_device(const char *device)
{
struct stat statbuf;

if(stat(device, &statbuf) < 0)
return -errno;

return (S_ISBLK(statbuf.st_mode) &&
MAJOR(statbuf.st_rdev) == LOOP_MAJOR);
}

/*
* Takes a loop device path (e.g. /dev/loop0) and returns
* the associated file (e.g. /images/my_btrfs.img) using
* loopdev API
*/
static int resolve_loop_device_with_loopdev(const char* loop_dev, char* loop_file)
{
int fd;
int ret;
struct loop_info64 lo64;

fd = open(loop_dev, O_RDONLY | O_NONBLOCK);
if (fd < 0)
return -errno;
ret = ioctl(fd, LOOP_GET_STATUS64, &lo64);
if (ret < 0) {
ret = -errno;
goto out;
}

memcpy(loop_file, lo64.lo_file_name, sizeof(lo64.lo_file_name));
loop_file[sizeof(lo64.lo_file_name)] = 0;

out:
close(fd);

return ret;
}

/*
* Takes a loop device path (e.g. /dev/loop0) and returns
* the associated file (e.g. /images/my_btrfs.img)
*/
static int resolve_loop_device(const char* loop_dev, char* loop_file,
int max_len)
{
int ret;
FILE *f;
char fmt[20];
char p[PATH_MAX];
char real_loop_dev[PATH_MAX];

if (!realpath(loop_dev, real_loop_dev))
return -errno;
snprintf(p, PATH_MAX, "/sys/block/%s/loop/backing_file", strrchr(real_loop_dev, '/'));
if (!(f = fopen(p, "r"))) {
if (errno == ENOENT)
/*
* It's possibly a partitioned loop device, which is
* resolvable with loopdev API.
*/
return resolve_loop_device_with_loopdev(loop_dev, loop_file);
return -errno;
}

snprintf(fmt, 20, "%%%i[^\n]", max_len - 1);
ret = fscanf(f, fmt, loop_file);
fclose(f);
if (ret == EOF)
return -errno;

return 0;
}

/*
* Checks whether a and b are identical or device
* files associated with the same block device
*/
static int is_same_blk_file(const char* a, const char* b)
int is_same_blk_file(const char* a, const char* b)
{
struct stat st_buf_a, st_buf_b;
char real_a[PATH_MAX];
Expand Down Expand Up @@ -224,55 +148,6 @@ static int is_same_blk_file(const char* a, const char* b)
return 0;
}

/*
* Checks if a and b are identical or device files associated with the same
* block device or if one file is a loop device that uses the other file.
*/
int is_same_loop_file(const char *a, const char *b)
{
char res_a[PATH_MAX];
char res_b[PATH_MAX];
const char* final_a = NULL;
const char* final_b = NULL;
int ret;

/* Resolve a if it is a loop device */
if ((ret = is_loop_device(a)) < 0) {
if (ret == -ENOENT)
return 0;
return ret;
} else if (ret) {
ret = resolve_loop_device(a, res_a, sizeof(res_a));
if (ret < 0) {
if (errno != EPERM)
return ret;
} else {
final_a = res_a;
}
} else {
final_a = a;
}

/* Resolve b if it is a loop device */
if ((ret = is_loop_device(b)) < 0) {
if (ret == -ENOENT)
return 0;
return ret;
} else if (ret) {
ret = resolve_loop_device(b, res_b, sizeof(res_b));
if (ret < 0) {
if (errno != EPERM)
return ret;
} else {
final_b = res_b;
}
} else {
final_b = b;
}

return is_same_blk_file(final_a, final_b);
}

/* Checks if a file exists and is a block or regular file*/
int path_is_reg_or_block_device(const char *filename)
{
Expand Down
2 changes: 1 addition & 1 deletion common/path-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ int path_is_a_mount_point(const char *file);
int path_exists(const char *file);
int path_is_reg_file(const char *path);
int path_is_dir(const char *path);
int is_same_loop_file(const char *a, const char *b);
int is_same_blk_file(const char* a, const char* b);
int path_is_reg_or_block_device(const char *filename);
int path_is_in_dir(const char *parent, const char *path);
char *path_basename(char *path);
Expand Down
Loading