From eb2f436c8635cd9106619d2b2238d86d29ced705 Mon Sep 17 00:00:00 2001 From: Qian Yingjin Date: Wed, 26 Apr 2023 05:18:18 -0400 Subject: [PATCH] EX-7395 pcc: use llapi_open_by_fid to check pinned files When check whether a file was pinned in PCC backend, it reported: "cannot read or parse pin xattr of file '/lustre/fsr/.lustre/fid/[0x780001b83:0x2138:0x0]'.: No such file or directory (2)" The failure reason is that open by FID is not configured for subdirectory mounts. In this patch, we use llapi_open_by_fid (which supports for subdirectory mount) to open the file to solve this error. Change-Id: If0120d745418836cfdf449a795b6f524c40f9c27 Signed-off-by: Qian Yingjin Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/50770 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger --- lustre/include/lustre/lustreapi.h | 2 + lustre/utils/liblustreapi_pcc.c | 165 ++++++++++++++++++++++++++++++++------ 2 files changed, 141 insertions(+), 26 deletions(-) diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 2e65763..96392c8 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -668,11 +668,13 @@ int llapi_pccdev_set(const char *mntpath, const char *cmd); int llapi_pccdev_get(const char *mntpath); int llapi_pcc_del(const char *mntpath, const char *pccpath, __u32 flags); int llapi_pcc_clear(const char *mntpath, __u32 flags); +int llapi_pcc_pin_fd(int fd, __u32 id); int llapi_pcc_pin_file(const char *path, __u32 id); int llapi_pcc_pin_fid(const char *lustre_dir, const struct lu_fid *fid, __u32 id); int llapi_pcc_unpin_file(const char *path, __u32 id); int llapi_pcc_backend_id_get(const char *path, enum lu_pcc_type type, __u32 *id); +bool llapi_pcc_is_pinned_fd(int fd, __u32 id); bool llapi_pcc_is_pinned_file(const char *path, __u32 id); bool llapi_pcc_is_pinned_fid(const char *lustre_dir, const struct lu_fid *fid, __u32 id); diff --git a/lustre/utils/liblustreapi_pcc.c b/lustre/utils/liblustreapi_pcc.c index 3e84fb7..c62f9d1 100644 --- a/lustre/utils/liblustreapi_pcc.c +++ b/lustre/utils/liblustreapi_pcc.c @@ -923,6 +923,37 @@ out: return obj; } +static struct json_object *read_pin_xattr_object_fd(int fd) +{ + int rc; + struct json_object *obj = NULL; + char buff[XATTR_SIZE_MAX]; + + rc = fgetxattr(fd, XATTR_LUSTRE_PIN, buff, sizeof(buff)); + if (rc < 0) + goto out; + buff[rc] = '\0'; + + obj = json_tokener_parse(buff); + if (obj == NULL) { + llapi_error(LLAPI_MSG_ERROR, -EINVAL, + "failed to parse pin xattr '%s'.", buff); + errno = -EINVAL; + goto out; + } + + rc = verify_pin_xattr_object(obj); + if (rc) { + llapi_error(LLAPI_MSG_ERROR, -rc, "invalid pin object."); + json_object_put(obj); + obj = NULL; + errno = -rc; + goto out; + } +out: + return obj; +} + int llapi_pcc_pin_file(const char *path, __u32 id) { int rc = 0, i; @@ -961,7 +992,8 @@ int llapi_pcc_pin_file(const char *path, __u32 id) add_entry: /* add a new entry */ node = json_object_new_object(); - json_object_object_add(node, PIN_JSON_HSM_STR, json_object_new_int64(id)); + json_object_object_add(node, PIN_JSON_HSM_STR, + json_object_new_int64(id)); json_object_array_add(obj, node); str = json_object_to_json_string_ext(obj, 0); @@ -973,6 +1005,56 @@ out: return rc; } +int llapi_pcc_pin_fd(int fd, __u32 id) +{ + int rc = 0, i; + struct json_object *obj = NULL, *node, *val; + const char *str = NULL; + bool found; + + obj = read_pin_xattr_object_fd(fd); + + if (obj == NULL && errno == ENODATA) { + obj = json_object_new_array(); + goto add_entry; + + } + if (obj == NULL) { + llapi_error(LLAPI_MSG_ERROR, errno, + "cannot read or parse pin xattr"); + rc = -errno; + goto out; + } + + /* Now we have an valid pin object, search for existing entry */ + for (i = 0; i < json_object_array_length(obj); i++) { + node = json_object_array_get_idx(obj, i); + found = json_object_object_get_ex(node, PIN_JSON_HSM_STR, &val); + if (found && json_object_get_int64(val) == id) + break; + } + /* found existing entry, do nothing and return success */ + if (i < json_object_array_length(obj)) { + rc = 0; + goto out; + } + +add_entry: + /* add a new entry */ + node = json_object_new_object(); + json_object_object_add(node, PIN_JSON_HSM_STR, + json_object_new_int64(id)); + json_object_array_add(obj, node); + str = json_object_to_json_string_ext(obj, 0); + + rc = fsetxattr(fd, XATTR_LUSTRE_PIN, str, strlen(str), 0); + if (rc < 0) + rc = -errno; +out: + json_object_put(obj); + return rc; +} + int llapi_pcc_unpin_file(const char *path, __u32 id) { int rc = 0, i; @@ -1021,23 +1103,6 @@ out: return rc; } -static int generate_fid_path(const char *lustre_dir, const struct lu_fid *fid, - char *path, int maxlen) -{ - int rc; - - rc = snprintf(path, maxlen, "%s/.lustre/fid/"DFID, lustre_dir, - PFID(fid)); - if (rc >= maxlen) - rc = -EOVERFLOW; - else if (rc > 0) - rc = 0; - else - rc = -errno; - - return rc; -} - /** * Pin a given file with lustre mount point and fid for a PCC backend. * @@ -1049,14 +1114,20 @@ static int generate_fid_path(const char *lustre_dir, const struct lu_fid *fid, int llapi_pcc_pin_fid(const char *lustre_dir, const struct lu_fid *fid, __u32 id) { + int fd; int rc; - char path[PATH_MAX]; - rc = generate_fid_path(lustre_dir, fid, path, PATH_MAX); - if (rc) + fd = llapi_open_by_fid(lustre_dir, fid, O_RDWR); + if (fd < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, + "llapi_open_by_fid for " DFID "failed", PFID(fid)); return rc; + } - return llapi_pcc_pin_file(path, id); + rc = llapi_pcc_pin_fd(fd, id); + close(fd); + return rc; } bool llapi_pcc_is_pinned_file(const char *path, __u32 id) @@ -1093,15 +1164,57 @@ bool llapi_pcc_is_pinned_file(const char *path, __u32 id) return false; } +bool llapi_pcc_is_pinned_fd(int fd, __u32 id) +{ + struct json_object *obj, *node, *val; + int i; + + obj = read_pin_xattr_object_fd(fd); + if (obj == NULL && errno == ENODATA) { + errno = 0; + return false; + } + + if (obj == NULL) { + llapi_error(LLAPI_MSG_ERROR, errno, + "cannot read or parse pin xattr for file"); + return false; + } + + /* Now we have an valid pin object, search for the entry */ + for (i = 0; i < json_object_array_length(obj); i++) { + bool found; + + node = json_object_array_get_idx(obj, i); + found = json_object_object_get_ex(node, PIN_JSON_HSM_STR, &val); + if (found && json_object_get_int64(val) == id) { + json_object_put(obj); + return true; + } + } + + json_object_put(obj); + errno = 0; + return false; +} + bool llapi_pcc_is_pinned_fid(const char *lustre_dir, const struct lu_fid *fid, __u32 id) { - char path[PATH_MAX]; + bool pinned; + int fd; int rc; - rc = generate_fid_path(lustre_dir, fid, path, PATH_MAX); - if (rc) + fd = llapi_open_by_fid(lustre_dir, fid, O_RDONLY); + if (fd < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, + "llapi_open_by_fid for " DFID "failed", PFID(fid)); return rc; + } + + pinned = llapi_pcc_is_pinned_fd(fd, id); + close(fd); - return llapi_pcc_is_pinned_file(path, id); + return pinned; } -- 1.8.3.1