return REPAIR_DONE;
}
+/* Make sure the reopened file is on the same fs as the monitor. */
+static bool
+is_same_fs(
+ int mnt_fd,
+ void *data)
+{
+ struct xfs_health_file_on_monitored_fs hms = {
+ .fd = mnt_fd,
+ };
+ FILE *mon_fp = data;
+ int ret;
+
+ ret = ioctl(fileno(mon_fp), XFS_IOC_HEALTH_FD_ON_MONITORED_FS, &hms);
+ return ret == 0;
+}
+
/* Repair a metadata corruption. */
int
repair_metadata(
int repair_fd;
int ret;
- ret = weakhandle_reopen(ctx->wh, &repair_fd);
+ ret = weakhandle_reopen(ctx->wh, &repair_fd, is_same_fs, ctx->mon_fp);
if (ret) {
fprintf(stderr, "%s: %s: %s\n", ctx->mntpoint,
_("cannot open filesystem to repair"),
weakhandle_reopen_from(
struct weakhandle *wh,
const char *path,
- int *fd)
+ int *fd,
+ weakhandle_fd_t is_acceptable,
+ void *data)
{
void *hanp;
size_t hlen;
goto out_handle;
}
+ if (is_acceptable && !is_acceptable(mnt_fd, data)) {
+ errno = ESTALE;
+ goto out_handle;
+ }
+
free_handle(hanp, hlen);
*fd = mnt_fd;
return 0;
int
weakhandle_reopen(
struct weakhandle *wh,
- int *fd)
+ int *fd,
+ weakhandle_fd_t is_acceptable,
+ void *data)
{
const size_t smbuf_size =
libfrog_statmount_sizeof(PATH_MAX);
int ret;
/* First try reopening using the original mountpoint */
- ret = weakhandle_reopen_from(wh, wh->mntpoint, fd);
+ ret = weakhandle_reopen_from(wh, wh->mntpoint, fd, is_acceptable, data);
if (!ret)
return 0;
STATMOUNT_MNT_POINT, smbuf, smbuf_size);
if (ret || !(smbuf->mask & STATMOUNT_MNT_POINT))
goto fallback;
- ret = weakhandle_reopen_from(wh, smbuf->str + smbuf->mnt_point, fd);
+ ret = weakhandle_reopen_from(wh, smbuf->str + smbuf->mnt_point, fd,
+ is_acceptable, data);
if (!ret)
return 0;
if (strcmp(mnt->mnt_fsname, wh->fsname))
continue;
- ret = weakhandle_reopen_from(wh, mnt->mnt_dir, fd);
+ ret = weakhandle_reopen_from(wh, mnt->mnt_dir, fd,
+ is_acceptable, data);
if (!ret)
break;
}
fakehandle.ha_fid.fid_ino = ino;
fakehandle.ha_fid.fid_gen = gen;
- ret = weakhandle_reopen(wh, &mnt_fd);
+ ret = weakhandle_reopen(wh, &mnt_fd, NULL, NULL);
if (ret)
return ret;
/* weakhandle.c */
int weakhandle_alloc(int fd, const char *mountpoint, uint64_t mnt_id,
const char *fsname, struct weakhandle **whp);
-int weakhandle_reopen(struct weakhandle *wh, int *fd);
+typedef bool (*weakhandle_fd_t)(int mnt_fd, void *data);
+int weakhandle_reopen(struct weakhandle *wh, int *fd,
+ weakhandle_fd_t is_acceptable, void *data);
void weakhandle_free(struct weakhandle **whp);
int weakhandle_getpath_for(struct weakhandle *wh, uint64_t ino, uint32_t gen,
char *path, size_t pathlen);