#include <lustre/lustreapi.h>
#include "lustreapi_internal.h"
+#define OPEN_BY_FID_PATH dot_lustre_name"/fid"
+
/****** HSM Copytool API ********/
#define CT_PRIV_MAGIC 0xC0BE2001
struct hsm_copytool_private {
int magic;
char *mnt;
int mnt_fd;
+ int open_by_fid_fd;
lustre_kernelcomm kuc;
__u32 archives;
};
__s32 data_fd;
const struct hsm_copytool_private *ct_priv;
struct hsm_copy copy;
+ struct stat stat;
};
#include <libcfs/libcfs.h>
if (ct == NULL)
return -ENOMEM;
- ct->mnt_fd = open(mnt, O_DIRECTORY | O_RDONLY | O_NONBLOCK);
- if (ct->mnt_fd < 0) {
- rc = -errno;
- goto out_err;
- }
+ ct->magic = CT_PRIV_MAGIC;
+ ct->mnt_fd = -1;
+ ct->open_by_fid_fd = -1;
+ ct->kuc.lk_rfd = LK_NOFD;
+ ct->kuc.lk_wfd = LK_NOFD;
ct->mnt = strdup(mnt);
if (ct->mnt == NULL) {
goto out_err;
}
- ct->magic = CT_PRIV_MAGIC;
+ ct->mnt_fd = open(ct->mnt, O_RDONLY);
+ if (ct->mnt_fd < 0) {
+ rc = -errno;
+ goto out_err;
+ }
+
+ ct->open_by_fid_fd = openat(ct->mnt_fd, OPEN_BY_FID_PATH, O_RDONLY);
+ if (ct->open_by_fid_fd < 0) {
+ rc = -errno;
+ goto out_err;
+ }
/* no archives specified means "match all". */
ct->archives = 0;
out_err:
if (!(ct->mnt_fd < 0))
close(ct->mnt_fd);
+
+ if (!(ct->open_by_fid_fd < 0))
+ close(ct->open_by_fid_fd);
+
if (ct->mnt != NULL)
free(ct->mnt);
+
free(ct);
+
return rc;
}
/* Shut down the kernelcomms */
libcfs_ukuc_stop(&ct->kuc);
+ close(ct->open_by_fid_fd);
close(ct->mnt_fd);
free(ct->mnt);
free(ct);
return rc;
}
+static int ct_open_by_fid(const struct hsm_copytool_private *ct,
+ const struct lu_fid *fid, int open_flags)
+{
+ char fid_name[FID_NOBRACE_LEN + 1];
+
+ snprintf(fid_name, sizeof(fid_name), DFID_NOBRACE, PFID(fid));
+
+ return openat(ct->open_by_fid_fd, fid_name, open_flags);
+}
+
+static int ct_stat_by_fid(const struct hsm_copytool_private *ct,
+ const struct lu_fid *fid,
+ struct stat *buf)
+{
+ char fid_name[FID_NOBRACE_LEN + 1];
+
+ snprintf(fid_name, sizeof(fid_name), DFID_NOBRACE, PFID(fid));
+
+ return fstatat(ct->open_by_fid_fd, fid_name, buf, 0);
+}
+
/** Create the destination volatile file for a restore operation.
*
* \param hcp Private copyaction handle.
* \return 0 on success.
*/
static int create_restore_volatile(struct hsm_copyaction_private *hcp,
- int mdt_index, int flags)
+ int mdt_index, int open_flags)
{
int rc;
int fd;
if (rc < 0) {
/* fid_parent() failed, try to keep on going */
llapi_error(LLAPI_MSG_ERROR, rc,
- "cannot get parent path to restore "DFID
+ "cannot get parent path to restore "DFID" "
"using '%s'", PFID(&hai->hai_fid), mnt);
snprintf(parent, sizeof(parent), "%s", mnt);
}
- fd = llapi_create_volatile_idx(parent, mdt_index, flags);
+ fd = llapi_create_volatile_idx(parent, mdt_index, open_flags);
if (fd < 0)
return fd;
+ rc = fchown(fd, hcp->stat.st_uid, hcp->stat.st_gid);
+ if (rc < 0)
+ goto err_cleanup;
+
rc = llapi_fd2fid(fd, &hai->hai_dfid);
if (rc < 0)
goto err_cleanup;
goto ok_out;
if (hai->hai_action == HSMA_RESTORE) {
+ rc = ct_stat_by_fid(hcp->ct_priv, &hai->hai_fid, &hcp->stat);
+ if (rc < 0)
+ goto err_out;
+
rc = create_restore_volatile(hcp, restore_mdt_index,
restore_open_flags);
if (rc < 0)
* \return 0 on success.
*/
int llapi_hsm_action_end(struct hsm_copyaction_private **phcp,
- const struct hsm_extent *he, int flags, int errval)
+ const struct hsm_extent *he, int hp_flags, int errval)
{
struct hsm_copyaction_private *hcp;
struct hsm_action_item *hai;
hai = &hcp->copy.hc_hai;
+ if (hai->hai_action == HSMA_RESTORE && errval == 0) {
+ struct timeval tv[2];
+
+ /* Set {a,m}time of volatile file to that of original. */
+ tv[0].tv_sec = hcp->stat.st_atime;
+ tv[0].tv_usec = 0;
+ tv[1].tv_sec = hcp->stat.st_mtime;
+ tv[1].tv_usec = 0;
+ if (futimes(hcp->data_fd, tv) < 0) {
+ errval = -errno;
+ goto end;
+ }
+
+ rc = fsync(hcp->data_fd);
+ if (rc < 0) {
+ errval = -errno;
+ goto end;
+ }
+ }
+
+end:
/* In some cases, like restore, 2 FIDs are used.
* Set the right FID to use here. */
if (hai->hai_action == HSMA_ARCHIVE || hai->hai_action == HSMA_RESTORE)
/* Fill the last missing data that will be needed by
* kernel to send a hsm_progress. */
- hcp->copy.hc_flags = flags;
+ hcp->copy.hc_flags = hp_flags;
hcp->copy.hc_errval = abs(errval);
hcp->copy.hc_hai.hai_extent = *he;
if (hcp->magic != CP_PRIV_MAGIC)
return -EINVAL;
- if (hai->hai_action != HSMA_RESTORE)
+ if (hai->hai_action == HSMA_ARCHIVE)
+ return ct_open_by_fid(hcp->ct_priv, &hai->hai_dfid,
+ O_RDONLY | O_NOATIME | O_NOFOLLOW | O_NONBLOCK);
+ else if (hai->hai_action == HSMA_RESTORE)
+ return dup(hcp->data_fd);
+ else
return -EINVAL;
-
- return dup(hcp->data_fd);
}
/**