mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-12-09 00:00:17 +03:00
xclose()
Add a helper to check for close errrors - especially bad file descriptors, that can be a fun source of heisenbugs. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
7b35cb1e4a
commit
e99da4dddb
@ -48,7 +48,7 @@ static void propagate_recurse(int dirfd)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
propagate_recurse(fd);
|
propagate_recurse(fd);
|
||||||
close(fd);
|
xclose(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errno)
|
if (errno)
|
||||||
@ -80,7 +80,7 @@ static void do_setattr(char *path, struct bch_opt_strs opts)
|
|||||||
die("error opening %s: %m", path);
|
die("error opening %s: %m", path);
|
||||||
|
|
||||||
propagate_recurse(dirfd);
|
propagate_recurse(dirfd);
|
||||||
close(dirfd);
|
xclose(dirfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setattr_usage(void)
|
static void setattr_usage(void)
|
||||||
|
|||||||
@ -167,7 +167,7 @@ static int cmd_data_scrub(int argc, char *argv[])
|
|||||||
|
|
||||||
if (dev->progress_fd >= 0 &&
|
if (dev->progress_fd >= 0 &&
|
||||||
read(dev->progress_fd, &e, sizeof(e)) != sizeof(e)) {
|
read(dev->progress_fd, &e, sizeof(e)) != sizeof(e)) {
|
||||||
close(dev->progress_fd);
|
xclose(dev->progress_fd);
|
||||||
dev->progress_fd = -1;
|
dev->progress_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ static int cmd_data_scrub(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dev->progress_fd >= 0 && e.ret) {
|
if (dev->progress_fd >= 0 && e.ret) {
|
||||||
close(dev->progress_fd);
|
xclose(dev->progress_fd);
|
||||||
dev->progress_fd = -1;
|
dev->progress_fd = -1;
|
||||||
dev->ret = e.ret;
|
dev->ret = e.ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -172,7 +172,7 @@ int cmd_dump(int argc, char *argv[])
|
|||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
dump_one_device(c, ca, fd, entire_journal);
|
dump_one_device(c, ca, fd, entire_journal);
|
||||||
close(fd);
|
xclose(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
up_read(&c->state_lock);
|
up_read(&c->state_lock);
|
||||||
|
|||||||
@ -116,10 +116,6 @@ static void build_fs(struct bch_fs *c, const char *src_path)
|
|||||||
{
|
{
|
||||||
struct copy_fs_state s = {};
|
struct copy_fs_state s = {};
|
||||||
int src_fd = xopen(src_path, O_RDONLY|O_NOATIME);
|
int src_fd = xopen(src_path, O_RDONLY|O_NOATIME);
|
||||||
struct stat stat = xfstat(src_fd);
|
|
||||||
|
|
||||||
if (!S_ISDIR(stat.st_mode))
|
|
||||||
die("%s is not a directory", src_path);
|
|
||||||
|
|
||||||
copy_fs(c, src_fd, src_path, &s, 0);
|
copy_fs(c, src_fd, src_path, &s, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,7 +86,8 @@ static int splice_fd_to_stdinout(int fd)
|
|||||||
stdin_closed = true;
|
stdin_closed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return close(fd);
|
xclose(fd);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fsck_online(const char *dev_path, const char *opt_str)
|
static int fsck_online(const char *dev_path, const char *opt_str)
|
||||||
|
|||||||
@ -147,7 +147,7 @@ static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
|
|||||||
range_add(&extents, e.fe_physical, e.fe_length);
|
range_add(&extents, e.fe_physical, e.fe_length);
|
||||||
}
|
}
|
||||||
fiemap_iter_exit(&iter);
|
fiemap_iter_exit(&iter);
|
||||||
close(fd);
|
xclose(fd);
|
||||||
|
|
||||||
ranges_sort_merge(&extents);
|
ranges_sort_merge(&extents);
|
||||||
return extents;
|
return extents;
|
||||||
@ -425,7 +425,7 @@ int cmd_migrate_superblock(int argc, char *argv[])
|
|||||||
xpwrite(fd, zeroes, BCH_SB_SECTOR << 9, 0, "zeroing start of disk");
|
xpwrite(fd, zeroes, BCH_SB_SECTOR << 9, 0, "zeroing start of disk");
|
||||||
|
|
||||||
bch2_super_write(fd, sb);
|
bch2_super_write(fd, sb);
|
||||||
close(fd);
|
xclose(fd);
|
||||||
|
|
||||||
/* mark new superblocks */
|
/* mark new superblocks */
|
||||||
|
|
||||||
|
|||||||
@ -329,7 +329,7 @@ struct bch_sb *bch2_format(struct bch_opt_strs fs_opt_strs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bch2_super_write(i->bdev->bd_fd, sb.sb);
|
bch2_super_write(i->bdev->bd_fd, sb.sb);
|
||||||
close(i->bdev->bd_fd);
|
xclose(i->bdev->bd_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.sb;
|
return sb.sb;
|
||||||
@ -402,8 +402,8 @@ int bcachectl_open(void)
|
|||||||
|
|
||||||
void bcache_fs_close(struct bchfs_handle fs)
|
void bcache_fs_close(struct bchfs_handle fs)
|
||||||
{
|
{
|
||||||
close(fs.ioctl_fd);
|
xclose(fs.ioctl_fd);
|
||||||
close(fs.sysfs_fd);
|
xclose(fs.sysfs_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bcache_fs_open_by_uuid(const char *uuid_str, struct bchfs_handle *fs)
|
static int bcache_fs_open_by_uuid(const char *uuid_str, struct bchfs_handle *fs)
|
||||||
@ -460,7 +460,7 @@ int bcache_fs_open_fallible(const char *path, struct bchfs_handle *fs)
|
|||||||
char buf[1024], *uuid_str;
|
char buf[1024], *uuid_str;
|
||||||
|
|
||||||
struct stat stat = xstat(path);
|
struct stat stat = xstat(path);
|
||||||
close(path_fd);
|
xclose(path_fd);
|
||||||
|
|
||||||
if (S_ISBLK(stat.st_mode)) {
|
if (S_ISBLK(stat.st_mode)) {
|
||||||
char *sysfs = mprintf("/sys/dev/block/%u:%u/bcachefs",
|
char *sysfs = mprintf("/sys/dev/block/%u:%u/bcachefs",
|
||||||
@ -607,7 +607,7 @@ int bchu_data(struct bchfs_handle fs, struct bch_ioctl_data cmd)
|
|||||||
}
|
}
|
||||||
printf("\nDone\n");
|
printf("\nDone\n");
|
||||||
|
|
||||||
close(progress_fd);
|
xclose(progress_fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,7 +830,7 @@ void bch2_opts_usage(unsigned opt_types)
|
|||||||
|
|
||||||
dev_names bchu_fs_get_devices(struct bchfs_handle fs)
|
dev_names bchu_fs_get_devices(struct bchfs_handle fs)
|
||||||
{
|
{
|
||||||
DIR *dir = fdopendir(fs.sysfs_fd);
|
DIR *dir = fdopendir(dup(fs.sysfs_fd));
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
dev_names devs;
|
dev_names devs;
|
||||||
|
|
||||||
|
|||||||
@ -160,7 +160,7 @@ static void write_data(struct bch_fs *c,
|
|||||||
op.nr_replicas = 1;
|
op.nr_replicas = 1;
|
||||||
op.subvol = 1;
|
op.subvol = 1;
|
||||||
op.pos = SPOS(dst_inode->bi_inum, dst_offset >> 9, U32_MAX);
|
op.pos = SPOS(dst_inode->bi_inum, dst_offset >> 9, U32_MAX);
|
||||||
op.flags |= BCH_WRITE_sync;
|
op.flags |= BCH_WRITE_sync|BCH_WRITE_only_specified_devs;
|
||||||
|
|
||||||
int ret = bch2_disk_reservation_get(c, &op.res, len >> 9,
|
int ret = bch2_disk_reservation_get(c, &op.res, len >> 9,
|
||||||
c->opts.data_replicas, 0);
|
c->opts.data_replicas, 0);
|
||||||
@ -345,7 +345,7 @@ static void copy_dir(struct copy_fs_state *s,
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (fchdir(src_fd))
|
if (fchdir(src_fd))
|
||||||
die("chdir error: %m");
|
die("fchdir error: %m");
|
||||||
|
|
||||||
struct stat stat =
|
struct stat stat =
|
||||||
xfstatat(src_fd, d->d_name, AT_SYMLINK_NOFOLLOW);
|
xfstatat(src_fd, d->d_name, AT_SYMLINK_NOFOLLOW);
|
||||||
@ -387,7 +387,7 @@ static void copy_dir(struct copy_fs_state *s,
|
|||||||
case DT_DIR:
|
case DT_DIR:
|
||||||
fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
|
fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
|
||||||
copy_dir(s, c, &inode, fd, child_path, reserve_start);
|
copy_dir(s, c, &inode, fd, child_path, reserve_start);
|
||||||
close(fd);
|
xclose(fd);
|
||||||
break;
|
break;
|
||||||
case DT_REG:
|
case DT_REG:
|
||||||
inode.bi_size = stat.st_size;
|
inode.bi_size = stat.st_size;
|
||||||
@ -395,7 +395,7 @@ static void copy_dir(struct copy_fs_state *s,
|
|||||||
fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
|
fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
|
||||||
copy_file(c, &inode, fd, stat.st_size,
|
copy_file(c, &inode, fd, stat.st_size,
|
||||||
child_path, s, reserve_start);
|
child_path, s, reserve_start);
|
||||||
close(fd);
|
xclose(fd);
|
||||||
break;
|
break;
|
||||||
case DT_LNK:
|
case DT_LNK:
|
||||||
inode.bi_size = stat.st_size;
|
inode.bi_size = stat.st_size;
|
||||||
@ -420,7 +420,6 @@ next:
|
|||||||
}
|
}
|
||||||
|
|
||||||
darray_exit(&dirents);
|
darray_exit(&dirents);
|
||||||
closedir(dir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reserve_old_fs_space(struct bch_fs *c,
|
static void reserve_old_fs_space(struct bch_fs *c,
|
||||||
@ -454,7 +453,11 @@ static void reserve_old_fs_space(struct bch_fs *c,
|
|||||||
void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
|
void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
|
||||||
struct copy_fs_state *s, u64 reserve_start)
|
struct copy_fs_state *s, u64 reserve_start)
|
||||||
{
|
{
|
||||||
syncfs(src_fd);
|
if (!S_ISDIR(xfstat(src_fd).st_mode))
|
||||||
|
die("%s is not a directory", src_path);
|
||||||
|
|
||||||
|
if (s->type == BCH_MIGRATE_migrate)
|
||||||
|
syncfs(src_fd);
|
||||||
|
|
||||||
struct bch_inode_unpacked root_inode;
|
struct bch_inode_unpacked root_inode;
|
||||||
int ret = bch2_inode_find_by_inum(c, (subvol_inum) { 1, BCACHEFS_ROOT_INO },
|
int ret = bch2_inode_find_by_inum(c, (subvol_inum) { 1, BCACHEFS_ROOT_INO },
|
||||||
@ -463,23 +466,20 @@ void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
|
|||||||
die("error looking up root directory: %s", bch2_err_str(ret));
|
die("error looking up root directory: %s", bch2_err_str(ret));
|
||||||
|
|
||||||
if (fchdir(src_fd))
|
if (fchdir(src_fd))
|
||||||
die("chdir error: %m");
|
die("fchdir error: %m");
|
||||||
|
|
||||||
struct stat stat = xfstat(src_fd);
|
struct stat stat = xfstat(src_fd);
|
||||||
copy_times(c, &root_inode, &stat);
|
copy_times(c, &root_inode, &stat);
|
||||||
copy_xattrs(c, &root_inode, ".");
|
copy_xattrs(c, &root_inode, ".");
|
||||||
|
|
||||||
|
|
||||||
/* now, copy: */
|
/* now, copy: */
|
||||||
copy_dir(s, c, &root_inode, src_fd, src_path, reserve_start);
|
copy_dir(s, c, &root_inode, src_fd, src_path, reserve_start);
|
||||||
|
|
||||||
if (BCH_MIGRATE_migrate == s->type)
|
if (s->type == BCH_MIGRATE_migrate)
|
||||||
reserve_old_fs_space(c, &root_inode, &s->extents, reserve_start);
|
reserve_old_fs_space(c, &root_inode, &s->extents, reserve_start);
|
||||||
|
|
||||||
update_inode(c, &root_inode);
|
update_inode(c, &root_inode);
|
||||||
|
|
||||||
if (BCH_MIGRATE_migrate == s->type)
|
darray_exit(&s->extents);
|
||||||
darray_exit(&s->extents);
|
|
||||||
|
|
||||||
genradix_free(&s->hardlinks);
|
genradix_free(&s->hardlinks);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,5 +50,5 @@ struct copy_fs_state {
|
|||||||
* initialized (`hardlinks` is initialized with zeroes).
|
* initialized (`hardlinks` is initialized with zeroes).
|
||||||
*/
|
*/
|
||||||
void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
|
void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
|
||||||
struct copy_fs_state *s, u64);
|
struct copy_fs_state *s, u64);
|
||||||
#endif /* _LIBBCACHE_H */
|
#endif /* _LIBBCACHE_H */
|
||||||
|
|||||||
@ -107,7 +107,7 @@ void write_file_str(int dirfd, const char *path, const char *str)
|
|||||||
wrote = write(fd, str, len);
|
wrote = write(fd, str, len);
|
||||||
if (wrote != len)
|
if (wrote != len)
|
||||||
die("read error: %m");
|
die("read error: %m");
|
||||||
close(fd);
|
xclose(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *read_file_str(int dirfd, const char *path)
|
char *read_file_str(int dirfd, const char *path)
|
||||||
@ -129,7 +129,7 @@ char *read_file_str(int dirfd, const char *path)
|
|||||||
buf = NULL;
|
buf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
xclose(fd);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,6 +82,12 @@ static inline void *xrealloc(void *p, size_t size)
|
|||||||
_ret; \
|
_ret; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define xclose(_fd) \
|
||||||
|
do { \
|
||||||
|
if (close(_fd)) \
|
||||||
|
die("error closing fd: %m at %s:%u", __FILE__, __LINE__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
void write_file_str(int, const char *, const char *);
|
void write_file_str(int, const char *, const char *);
|
||||||
char *read_file_str(int, const char *);
|
char *read_file_str(int, const char *);
|
||||||
u64 read_file_u64(int, const char *);
|
u64 read_file_u64(int, const char *);
|
||||||
|
|||||||
@ -356,8 +356,8 @@ static void aio_cleanup(void)
|
|||||||
|
|
||||||
put_task_struct(p);
|
put_task_struct(p);
|
||||||
|
|
||||||
close(fds[0]);
|
xclose(fds[0]);
|
||||||
close(fds[1]);
|
xclose(fds[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aio_op(struct bio *bio, struct iovec *iov, unsigned i, int opcode)
|
static void aio_op(struct bio *bio, struct iovec *iov, unsigned i, int opcode)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user