}
if (need_attr & LIPE_OBJECT_ATTR_LINKEA) {
- rc = fgetxattr(fd, XATTR_NAME_LINK, attrs->loa_leh_buf,
- sizeof(attrs->loa_leh_buf));
+ char buf[XATTR_SIZE_MAX];
+
+ rc = fgetxattr(fd, XATTR_NAME_LINK, buf, sizeof(buf));
if (rc >= 0)
- rc = lipe_object_attrs_set_links(attrs, attrs->loa_leh_buf, rc);
+ rc = lipe_object_attrs_set_links(attrs, buf, rc);
}
if (need_attr & LIPE_OBJECT_ATTR_HSMEA) {
goto out;
}
- resync = lamigo_striping_is_in_sync((void *)attrs->loa_lum, fast_pools,
+ resync = lamigo_striping_is_in_sync(attrs->loa_lum, fast_pools,
slow_pools, &mo);
if (resync == AMIGO_RESYNC_NONE) {
lamigo_hist_add(&attrs->loa_fid, resync);
/* skip snapshot inodes */
continue;
}
-
+
if (!LINUX_S_ISDIR(inode->i_mode) &&
(inode->i_flags & EXT2_NODUMP_FL)) {
/* skip files which are not to be backuped */
LDEBUG("failed to apply policy on inode [%d]\n", ino);
rc = 0;
}
+
+ if (object->u.lo_ldiskfs.lol_xattr_handle != NULL)
+ ext2fs_xattrs_close(&object->u.lo_ldiskfs.lol_xattr_handle);
+
+ object->u.lo_ldiskfs.lol_xattr_handle = NULL;
}
return rc;
struct lipe_instance *instance = info->ti_instance;
const char *dev = instance->li_device;
struct scan_result *result = &info->ti_result;
- struct lipe_object object;
+ struct lipe_object object = {
+ .lo_backfs_ops = &ldiskfs_operations,
+ .lo_backfs_type = instance->li_detected_fstype,
+ };
ext2_filsys fs;
ext2_inode_scan scan;
struct ext2_inode_large *inode;
goto out;
}
- object.lo_backfs_ops = &ldiskfs_operations;
- object.lo_backfs_type = instance->li_detected_fstype;
-
gettimeofday(&result->sr_time_start, NULL);
sysattrs.lps_sys_time = result->sr_time_start.tv_sec * 1000 +
result->sr_time_start.tv_usec / 1000;
goto out_free_attrs;
}
- object.u.lo_ldiskfs.lol_fs = fs;
-
rc = ext2fs_read_inode_bitmap(fs);
if (rc) {
LERROR("failed to ext2fs_read_inode_bitmap on [%s]: %s\n", dev,
goto out_close;
}
-
inode_size = EXT2_INODE_SIZE(fs->super);
if (inode_size < sizeof(*inode))
inode_size = sizeof(*inode);
goto out_scan;
}
+ object.u.lo_ldiskfs.lol_fs = fs;
object.u.lo_ldiskfs.lol_inode = inode;
while (1) {
LASSERT(lipe_list_empty(&attrs->loa_xattrs));
}
-void lipe_object_attrs_reset(struct lipe_object_attrs *attrs)
-{
- struct lov_user_md *lum = attrs->loa_lum;
- int lum_size = attrs->loa_lum_size;
-
- lipe_object_attrs_links_fini(attrs);
- lipe_object_attrs_paths_fini(attrs);
- lipe_object_attrs_xattrs_fini(attrs);
- memset(lum, 0, lum_size);
- memset(attrs, 0, sizeof(*attrs));
- attrs->loa_lum = lum;
- attrs->loa_lum_size = lum_size;
- LIPE_INIT_LIST_HEAD(&attrs->loa_links);
- LIPE_INIT_LIST_HEAD(&attrs->loa_paths);
- LIPE_INIT_LIST_HEAD(&attrs->loa_xattrs);
-}
-
int lipe_object_attrs_init(struct lipe_object_attrs *attrs)
{
memset(attrs, 0, sizeof(*attrs));
- attrs->loa_lum_size = lov_user_md_size(LOV_MAX_STRIPE_COUNT,
- LOV_USER_MAGIC_V3);
- LIPE_ALLOC(attrs->loa_lum, attrs->loa_lum_size);
- if (attrs->loa_lum == NULL)
- return -ENOMEM;
-
LIPE_INIT_LIST_HEAD(&attrs->loa_links);
LIPE_INIT_LIST_HEAD(&attrs->loa_paths);
LIPE_INIT_LIST_HEAD(&attrs->loa_xattrs);
lipe_object_attrs_links_fini(attrs);
lipe_object_attrs_paths_fini(attrs);
lipe_object_attrs_xattrs_fini(attrs);
- LIPE_FREE(attrs->loa_lum, attrs->loa_lum_size);
+ free(attrs->loa_lum);
+ free(attrs->loa_lmv);
+}
+
+void lipe_object_attrs_reset(struct lipe_object_attrs *attrs)
+{
+ lipe_object_attrs_fini(attrs);
+ lipe_object_attrs_init(attrs);
}
int lipe_object_attrs_add_link(struct lipe_object_attrs *attrs,
const struct lu_fid *parent_fid,
- const char *name)
+ const char *name, int namelen)
{
struct lipe_link_entry *lle = NULL;
int rc;
+ if (namelen <= 0)
+ return -EOVERFLOW; /* ? */
+
LIPE_ALLOC_PTR(lle);
if (lle == NULL) {
rc = -ENOMEM;
lle->lle_parent_fid = *parent_fid;
- lle->lle_name = strdup(name);
+ lle->lle_name = strndup(name, namelen);
if (lle->lle_name == NULL) {
rc = -ENOMEM;
goto out;
for (i = 0; i < reccount; i++) {
unsigned int reclen = (lee->lee_reclen[0] << 8) | lee->lee_reclen[1];
struct lu_fid parent_fid;
+ int namelen;
pos += reclen;
if (pos > len) {
fid_be_to_cpu(&parent_fid, (const struct lu_fid *)&lee->lee_parent_fid);
- LDEBUG(" %d: parent_fid "DFID", name '%s'\n",
- i, PFID(&parent_fid), lee->lee_name);
+ namelen = reclen - offsetof(struct link_ea_entry, lee_name[0]);
+
+ LDEBUG(" %d: parent_fid "DFID", name '%.*s'\n",
+ i, PFID(&parent_fid), namelen, lee->lee_name);
- rc = lipe_object_attrs_add_link(attrs, &parent_fid, lee->lee_name);
+ rc = lipe_object_attrs_add_link(attrs, &parent_fid, lee->lee_name, namelen);
if (rc < 0)
return rc;
struct lu_fid loa_fid;
char loa_fid_str[FID_NOBRACE_LEN + 1];
__u64 loa_attr_bits;
- /* Buffer for struct link_ea_header */
- char loa_leh_buf[MAX_LINKEA_SIZE];
- /* Buffer for lmv */
- char loa_lmv_buf[XATTR_SIZE_MAX];
- struct lov_user_md *loa_lum;
- int loa_lum_size;
+ void *loa_lmv;
+ size_t loa_lmv_size;
+ void *loa_lum;
+ size_t loa_lum_size;
struct hsm_user_state loa_hsm_state;
enum lustre_dom_status loa_dom_status;
struct lustre_som_attrs loa_som;
void lipe_object_attrs_reset(struct lipe_object_attrs *attrs);
int lipe_object_attrs_add_link(struct lipe_object_attrs *attrs,
const struct lu_fid *parent_fid,
- const char *name);
+ const char *name, int namelen);
int lipe_object_attrs_set_links(struct lipe_object_attrs *attrs,
const void *link_xattr,
size_t link_xattr_size);
static int zfs_get_xattr(struct lipe_object *lobject,
struct lipe_object_attrs *attrs,
- const char *xattr_name, uchar_t *value, uint_t cnt)
+ const char *xattr_name, void *value, size_t value_size)
{
int rc;
- rc = lipe_object_attrs_add_xattr(attrs, xattr_name, (const char *)value,
- cnt);
+ rc = lipe_object_attrs_add_xattr(attrs, xattr_name, value, value_size);
if (rc) {
OBJ_ERROR(lobject, "failed to add xattr [%s]\n", xattr_name);
return rc;
}
if (strcmp(xattr_name, XATTR_NAME_LMA) == 0) {
- struct lustre_mdt_attrs *lma;
+ struct lustre_mdt_attrs *lma = value;
- lma = (struct lustre_mdt_attrs *)value;
fid_le_to_cpu(&attrs->loa_fid, &lma->lma_self_fid);
snprintf(attrs->loa_fid_str,
sizeof(attrs->loa_fid_str), DFID_NOBRACE,
struct filter_fid *ff = &attrs->loa_filter_fid;
struct lu_fid pfid;
- memcpy(ff, value, cnt);
+ memcpy(ff, value, value_size);
fid_le_to_cpu(&pfid, &ff->ff_parent);
ff->ff_parent = pfid;
attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_FILTER_FID;
- attrs->loa_filter_fid_size = cnt;
+ attrs->loa_filter_fid_size = value_size;
} else if (strcmp(xattr_name, XATTR_NAME_LINK) == 0) {
- memcpy(attrs->loa_leh_buf, value, cnt);
-
- rc = lipe_object_attrs_set_links(attrs, value, cnt);
+ rc = lipe_object_attrs_set_links(attrs, value, value_size);
if (rc) {
OBJ_ERROR(lobject, "failed to decode linkea\n");
return rc;
}
} else if (strcmp(xattr_name, XATTR_NAME_LMV) == 0) {
- if (cnt > sizeof(attrs->loa_lmv_buf)) {
- OBJ_ERROR(lobject, "invalid lmv ea\n");
- return -EINVAL;
- }
- memcpy(attrs->loa_lmv_buf, value, cnt);
+ rc = xmemdup(&attrs->loa_lmv, &attrs->loa_lmv_size, value, value_size);
+ if (rc < 0)
+ return rc;
} else if (strcmp(xattr_name, XATTR_NAME_HSM) == 0) {
+ struct hsm_attrs *hsm = value;
struct hsm_user_state *hus = &attrs->loa_hsm_state;
- struct hsm_attrs *hsm;
- hsm = (struct hsm_attrs *)value;
rc = lipe_hsm2user(hsm, hus);
if (rc) {
OBJ_ERROR(lobject,
}
attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_HSMEA;
} else if (strcmp(xattr_name, XATTR_NAME_LOV) == 0) {
- rc = decode_lum((struct lov_user_md *)value, cnt);
+ rc = decode_lum(value, value_size);
if (rc) {
OBJ_ERROR(lobject, "failed to decode LOV EA, rc = %d\n",
rc);
return rc;
}
- memcpy(attrs->loa_lum, value, cnt);
+
+ rc = xmemdup(&attrs->loa_lum, &attrs->loa_lum_size, value, value_size);
+ if (rc < 0)
+ return rc;
+
attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LOVEA;
} else if (strcmp(xattr_name, XATTR_NAME_SOM) == 0) {
- if (cnt != sizeof(attrs->loa_som)) {
+ if (value_size != sizeof(attrs->loa_som)) {
OBJ_ERROR(lobject,
"unexpected size of LSoM xattr, expected [%u] got [%u]\n",
- sizeof(attrs->loa_som), cnt);
+ sizeof(attrs->loa_som), value_size);
}
- lipe_som_swab((struct lustre_som_attrs *)value);
- memcpy(&attrs->loa_som, value, cnt);
+
+ lipe_som_swab(value);
+ attrs->loa_som = *(struct lustre_som_attrs *)value;
}
return 0;
}
*
* Author: Li Xi <lixi@ddn.com>
*/
+#include <assert.h>
#include <errno.h>
#include <fnmatch.h>
+#include <malloc.h>
+#include <string.h>
#include <lustre/lustreapi.h>
#include <linux/lustre/lustre_ostid.h>
#include "lustre_ea.h"
#include "debug.h"
+int xmemdup(void **pdst, size_t *pdst_size, const void *src, size_t src_size)
+{
+ void *dst;
+
+ assert(*pdst == NULL);
+ assert(*pdst_size == 0);
+
+ dst = malloc(src_size);
+ if (dst == NULL && src_size != 0)
+ return -ENOMEM;
+
+ memcpy(dst, src, src_size);
+
+ *pdst = dst;
+ *pdst_size = src_size;
+
+ return 0;
+}
+
/* Copied from Lustre/utils/liblustreapi.c */
static inline struct lov_user_md *
lov_comp_entry(struct lov_comp_md_v1 *comp_v1, int ent_idx)
*/
#ifndef _LIPE_LUSTRE_EA_H_
#define _LIPE_LUSTRE_EA_H_
-
+#include <stddef.h>
#include <linux/lustre/lustre_ostid.h>
#include "general_policy.h"
#include "lipe_object_attrs.h"
+int xmemdup(void **pdst, size_t *pdst_size, const void *src, size_t src_size);
int match_lum_ost(struct lov_user_md *lum, int64_t ost_index);
int regular_expression_match_lum_pool(struct lov_user_md *lum, regex_t *reg);
int shell_pattern_match_lum_pool(struct lov_user_md *lum, char *pattern);
#include "debug.h"
#include "policy.h"
-int get_link_ea_ldiskfs(struct lipe_object *object,
- struct lipe_object_attrs *attrs)
-{
- int size;
- int rc;
- ext2_filsys fs = object->u.lo_ldiskfs.lol_fs;
- ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino;
- struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode;
-
- rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode,
- EXT2_ATTR_INDEX_TRUSTED,
- XATTR_NAME_LINK + strlen("trusted."),
- attrs->loa_leh_buf, sizeof(attrs->loa_leh_buf),
- &size);
- if (rc) {
- LDEBUG("inode [%d] has no [%s] xattr, ignoring rc = %d\n",
- ino, XATTR_NAME_LINK, rc);
- return -ENODATA;
- }
-
- rc = lipe_object_attrs_set_links(attrs, attrs->loa_leh_buf, size);
- if (rc) {
- LERROR("failed to decode linkea for inode [%d]\n", ino);
- return rc;
- }
-
- attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LINKEA;
- return 0;
-}
+#define min(x, y) ({ \
+ typeof(x) _min1 = (x); \
+ typeof(y) _min2 = (y); \
+ (void) (&_min1 == &_min2); \
+ _min1 < _min2 ? _min1 : _min2; \
+})
/* Due to a bug in e2fsprogs-1.45.6.wc3, and potential ongoing changes in
* upstream releases, the definition of EXT2_ET_EA_NAME_NOT_FOUND may be
#define EXT2_ET_EA_NAME_NOT_FOUND_1456WC3 (2133571514L)
#define EXT2_ET_EA_NAME_NOT_FOUND_1462WC3 (2133571515L)
+static ext2_ino_t lo_ino(const struct lipe_object *lo)
+{
+ return lo->u.lo_ldiskfs.lol_ino;
+}
+
static bool xattr_name_not_found(long errcode)
{
- return errcode == EXT2_ET_EA_NAME_NOT_FOUND ||
+ return errcode == EXT2_ET_EA_KEY_NOT_FOUND ||
+ errcode == EXT2_ET_EA_NAME_NOT_FOUND ||
errcode == EXT2_ET_EA_NAME_NOT_FOUND_1445WC1 ||
errcode == EXT2_ET_EA_NAME_NOT_FOUND_1456WC1 ||
errcode == EXT2_ET_EA_NAME_NOT_FOUND_1456WC3 ||
errcode == EXT2_ET_EA_NAME_NOT_FOUND_1462WC3;
}
-int get_lmv_ea_ldiskfs(struct lipe_object *object,
- struct lipe_object_attrs *attrs)
+static int ldiskfs_xattr_get(struct lipe_object *lo,
+ const char *name,
+ void **value, size_t *value_size)
{
- int size;
- long rc;
- ext2_filsys fs = object->u.lo_ldiskfs.lol_fs;
- ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino;
- struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode;
-
- memset(attrs->loa_lmv_buf, 0, sizeof(attrs->loa_lmv_buf));
- rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode,
- EXT2_ATTR_INDEX_TRUSTED,
- XATTR_NAME_LMV + strlen("trusted."),
- attrs->loa_lmv_buf, sizeof(attrs->loa_lmv_buf),
- &size);
+ ext2_filsys fs = lo->u.lo_ldiskfs.lol_fs;
+ struct ext2_inode_large *inode = lo->u.lo_ldiskfs.lol_inode;
+ struct ext2_xattr_handle *handle = NULL;
+ errcode_t rc;
+
+ assert(*value == NULL);
+ assert(*value_size == 0);
+
+ if (lo->u.lo_ldiskfs.lol_xattr_handle == NULL) {
+ rc = ext2fs_xattrs_open(fs, lo_ino(lo), &handle);
+ if (rc != 0)
+ goto out;
+
+ rc = ext2fs_xattrs_read_inode(handle, inode);
+ if (rc != 0)
+ goto out;
+
+ lo->u.lo_ldiskfs.lol_xattr_handle = handle;
+ handle = NULL; /* lo owns it now. */
+ }
+
+ rc = ext2fs_xattr_get(lo->u.lo_ldiskfs.lol_xattr_handle, name, value, value_size);
+out:
if (xattr_name_not_found(rc)) {
- LDEBUG("inode [%d] has no [%s] xattr ignoring rc = %u\n",
- ino, XATTR_NAME_LMV, rc);
- return 1;
- } else if (rc) {
- LERROR("failed to get [%s] xattr for inode [%d], rc = %d\n",
- XATTR_NAME_LMV, ino, rc);
- return -ENODATA;
+ rc = -ENODATA;
+ } else if (rc != 0) {
+ /* EXT2_ET_EA_TOO_BIG, what else? */
+
+ LERROR("ino = %u: cannot get '%s' xattr: rc = %ld (%s)\n",
+ lo_ino(lo), name, rc, error_message(rc));
+ rc = -EINVAL;
}
- return 0;
+ if (handle != NULL)
+ ext2fs_xattrs_close(&handle);
+
+ return rc;
}
-int get_lma_ea_ldiskfs(struct lipe_object *object,
- struct lipe_object_attrs *attrs)
+static int get_link_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa)
{
- char buf[MAX_LINKEA_SIZE];
+ const char *name = XATTR_NAME_LINK;
+ void *value = NULL;
+ size_t value_size = 0;
+ int rc;
+
+ rc = ldiskfs_xattr_get(lo, name, &value, &value_size);
+ if (rc != 0) {
+ LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n",
+ lo_ino(lo), name, rc);
+ goto out;
+ }
+
+ rc = lipe_object_attrs_set_links(loa, value, value_size);
+ if (rc != 0) {
+ LDEBUG("ino = %u: cannot decode '%s' xattr, ignoring: rc = %d\n",
+ lo_ino(lo), name, rc);
+ goto out;
+ }
+
+ loa->loa_attr_bits |= LIPE_OBJECT_ATTR_LINKEA;
+out:
+ free(value);
+
+ return rc;
+}
+
+static int get_lmv_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa)
+{
+ const char *name = XATTR_NAME_LMV;
+ void *value = NULL;
+ size_t value_size = 0;
+ int rc;
+
+ rc = ldiskfs_xattr_get(lo, name, &value, &value_size);
+ if (rc != 0) {
+ LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n",
+ lo_ino(lo), name, rc);
+ goto out;
+ }
+
+ loa->loa_lmv = value;
+ loa->loa_lmv_size = value_size;
+ value = NULL;
+ value_size = 0;
+
+ /* There is no LIPE_OBJECT_ATTR_LMVEA. */
+out:
+ free(value);
+
+ return rc;
+}
+
+static int get_lma_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa)
+{
+ const char *name = XATTR_NAME_LMA;
struct lustre_mdt_attrs *lma;
- int size;
- int rc;
- ext2_filsys fs = object->u.lo_ldiskfs.lol_fs;
- ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino;
- struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode;
-
- rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode,
- EXT2_ATTR_INDEX_TRUSTED,
- XATTR_NAME_LMA + strlen("trusted."),
- buf, MAX_LINKEA_SIZE, &size);
- if (rc) {
- LDEBUG("inode [%d] has no [%s] xattr, ignoring rc = %d\n",
- ino, XATTR_NAME_LMA, rc);
- return -ENODATA;
+ void *value = NULL;
+ size_t value_size = 0;
+ int rc;
+
+ rc = ldiskfs_xattr_get(lo, name, &value, &value_size);
+ if (rc != 0) {
+ LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n",
+ lo_ino(lo), name, rc);
+ goto out;
}
- lma = (struct lustre_mdt_attrs *)buf;
- fid_le_to_cpu(&attrs->loa_fid, &lma->lma_self_fid);
- snprintf(attrs->loa_fid_str, sizeof(attrs->loa_fid_str), DFID_NOBRACE,
- PFID(&attrs->loa_fid));
- attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LMAEA;
- return 0;
+ /* FIXME Check value_size. */
+
+ lma = value;
+ fid_le_to_cpu(&loa->loa_fid, &lma->lma_self_fid);
+ snprintf(loa->loa_fid_str, sizeof(loa->loa_fid_str), DFID_NOBRACE,
+ PFID(&loa->loa_fid));
+
+ loa->loa_attr_bits |= LIPE_OBJECT_ATTR_LMAEA;
+out:
+ free(value);
+
+ return rc;
}
-int get_hsm_ea_ldiskfs(struct lipe_object *object,
- struct lipe_object_attrs *attrs)
+static int get_hsm_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa)
{
- char buf[MAX_LINKEA_SIZE];
- struct hsm_attrs *hsm;
- long rc;
- int size;
- struct hsm_user_state *hus = &attrs->loa_hsm_state;
- ext2_filsys fs = object->u.lo_ldiskfs.lol_fs;
- ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino;
- struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode;
-
- LASSERT(sizeof(*hsm) < MAX_LINKEA_SIZE);
-
- rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode,
- EXT2_ATTR_INDEX_TRUSTED,
- XATTR_NAME_HSM + strlen("trusted."),
- buf, MAX_LINKEA_SIZE, &size);
- if (xattr_name_not_found(rc)) {
- LDEBUGW(&attrs->loa_fid, "inode [%d] has no [%s] xattr\n",
- ino, XATTR_NAME_HSM);
- hus->hus_states = 0;
- hus->hus_archive_id = 0;
- } else if (rc) {
- LERROR("failed to get [%s] xattr for inode [%d], rc = %d\n",
- XATTR_NAME_HSM, ino, rc);
- return -ENODATA;
- } else {
- hsm = (struct hsm_attrs *)buf;
- rc = lipe_hsm2user(hsm, hus);
- if (rc) {
- LERROR("failed to extract [%s] xattr for inode [%d], rc = %d\n",
- XATTR_NAME_HSM, ino, rc);
- return rc;
- }
+ const char *name = XATTR_NAME_HSM;
+ void *value = NULL;
+ size_t value_size = 0;
+ int rc;
+ struct hsm_user_state *hus = &loa->loa_hsm_state;
+ struct hsm_attrs *hsm;
+
+ memset(hus, 0, sizeof(*hus));
+
+ rc = ldiskfs_xattr_get(lo, name, &value, &value_size);
+ if (rc != 0) {
+ LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n",
+ lo_ino(lo), name, rc);
+ goto out;
}
- attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_HSMEA;
- return 0;
+
+ if (value_size < sizeof(*hsm)) {
+ LERROR("ino = %u: xattr '%s': got size %zu, expected %zu\n",
+ lo_ino(lo), name, value_size, sizeof(*hsm));
+ rc = -ENODATA;
+ goto out;
+ }
+
+ hsm = value;
+ rc = lipe_hsm2user(hsm, hus);
+ if (rc != 0) {
+ LERROR("ino = %u: cannot parse '%s' xattr: rc = %d\n", lo_ino(lo), name, rc);
+ goto out;
+ }
+
+ loa->loa_attr_bits |= LIPE_OBJECT_ATTR_HSMEA;
+out:
+ free(value);
+
+ return rc;
}
-int get_fid_ea_ldiskfs(struct lipe_object *object,
- struct lipe_object_attrs *attrs)
+static int get_fid_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa)
{
- ext2_filsys fs = object->u.lo_ldiskfs.lol_fs;
- ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino;
- struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode;
- struct filter_fid *ff = &attrs->loa_filter_fid;
- struct lu_fid pfid;
- int size;
- int rc;
-
- rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode,
- EXT2_ATTR_INDEX_TRUSTED,
- XATTR_NAME_FID + strlen("trusted."),
- (char *)ff, sizeof(*ff), &size);
- if (rc) {
- LDEBUG("inode [%d] has no [%s] xattr, ignoring rc = %d\n",
- ino, XATTR_NAME_FID, rc);
- return -ENODATA;
+ const char *name = XATTR_NAME_FID;
+ void *value = NULL;
+ size_t value_size = 0;
+ int rc;
+ struct filter_fid *ff = &loa->loa_filter_fid;
+
+ rc = ldiskfs_xattr_get(lo, name, &value, &value_size);
+ if (rc != 0) {
+ LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n",
+ lo_ino(lo), name, rc);
+ goto out;
}
- fid_le_to_cpu(&pfid, &ff->ff_parent);
- ff->ff_parent = pfid;
- attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_FILTER_FID;
- attrs->loa_filter_fid_size = size;
- return 0;
+ if (value_size < sizeof(ff->ff_parent)) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ memset(ff, 0, sizeof(&ff));
+ memcpy(ff, value, min(sizeof(*ff), value_size));
+ fid_le_to_cpu(&ff->ff_parent, &ff->ff_parent);
+ /* ...? */
+
+ loa->loa_filter_fid_size = value_size;
+ loa->loa_attr_bits |= LIPE_OBJECT_ATTR_FILTER_FID;
+out:
+ free(value);
+
+ return rc;
}
-int get_lum_ea_ldiskfs(struct lipe_object *object,
- struct lipe_object_attrs *attrs)
+static int get_lum_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa)
{
- int rc;
- int size;
- struct lov_user_md *lov = attrs->loa_lum;
- ext2_filsys fs = object->u.lo_ldiskfs.lol_fs;
- ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino;
- struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode;
-
- rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode,
- EXT2_ATTR_INDEX_TRUSTED,
- XATTR_NAME_LOV + strlen("trusted."),
- (char *)lov, attrs->loa_lum_size, &size);
- if (rc) {
- LDEBUGW(&attrs->loa_fid, "inode [%d] has no [%s] xattr, rc = %d\n",
- ino, XATTR_NAME_LOV, rc);
- return -ENODATA;
+ const char *name = XATTR_NAME_LOV;
+ void *value = NULL;
+ size_t value_size = 0;
+ int rc;
+
+ rc = ldiskfs_xattr_get(lo, name, &value, &value_size);
+ if (rc != 0) {
+ LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n",
+ lo_ino(lo), name, rc);
+ goto out;
}
- rc = decode_lum(lov, size);
- if (rc) {
- LERROR("failed to decode lovea for inode [%d], rc = %d\n",
- ino, rc);
- return rc;
+ rc = decode_lum(value, value_size);
+ if (rc != 0) {
+ LERROR("ino = %u: cannot decode '%s' xattr: rc = %d\n",
+ lo_ino(lo), name, rc);
+ goto out;
}
- attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LOVEA;
- return 0;
+
+ loa->loa_lum = value;
+ loa->loa_lum_size = value_size;
+ value = NULL;
+ value_size = 0;
+
+ loa->loa_attr_bits |= LIPE_OBJECT_ATTR_LOVEA;
+out:
+ free(value);
+
+ return rc;
}
-/*
- * llapi_layout_get_by_xattr() and LSoM are both included in Lustre-2.12,
- * so no need to duplicate the macros.
- */
-int get_som_ea_ldiskfs(struct lipe_object *object,
- struct lipe_object_attrs *attrs)
+static int get_som_ea_ldiskfs(struct lipe_object *lo, struct lipe_object_attrs *loa)
{
- int rc;
- int size;
- struct lustre_som_attrs *som = &attrs->loa_som;
- ext2_filsys fs = object->u.lo_ldiskfs.lol_fs;
- ext2_ino_t ino = object->u.lo_ldiskfs.lol_ino;
- struct ext2_inode_large *inode = object->u.lo_ldiskfs.lol_inode;
-
- rc = ext2fs_attr_get(fs, (struct ext2_inode *)inode,
- EXT2_ATTR_INDEX_TRUSTED,
- XATTR_NAME_SOM + strlen("trusted."),
- (char *)som, sizeof(*som), &size);
- if (rc) {
- LDEBUGW(&attrs->loa_fid, "inode [%d] has no [%s] xattr, rc = %d\n",
- ino, XATTR_NAME_SOM, rc);
- return -ENODATA;
+ const char *name = XATTR_NAME_SOM;
+ void *value = NULL;
+ size_t value_size = 0;
+ int rc;
+ struct lustre_som_attrs *som = &loa->loa_som;
+
+ rc = ldiskfs_xattr_get(lo, name, &value, &value_size);
+ if (rc != 0) {
+ LDEBUG("ino = %u: no '%s' xattr, ignoring: rc = %d\n",
+ lo_ino(lo), name, rc);
+ goto out;
}
- if (size != sizeof(*som)) {
- LERROR("unexpected size of [%s] xattr for inode [%d], expected [%d], got [%d]\n",
- XATTR_NAME_SOM, ino, sizeof(*som), size);
- return -ENODATA;
+ if (value_size < sizeof(*som)) {
+ LERROR("ino = %u: xattr '%s': got size %zu, expected %zu\n",
+ lo_ino(lo), name, value_size, sizeof(*som));
+ rc = -ENODATA;
+ goto out;
}
+ *som = *(struct lustre_som_attrs *)value;
lipe_som_swab(som);
+ /* LIPE_OBJECT_ATTR_SOM is set in get_som_ea() according to flags. */
+out:
+ free(value);
+
return rc;
}
if (rc && rc != -ENOTSUP)
return false;
- lmm = (union lmv_mds_md *)attrs->loa_lmv_buf;
- if (lmm->lmv_magic == LMV_MAGIC_STRIPE)
- return true;
- return false;
+ lmm = attrs->loa_lmv;
+ assert(lmm != NULL);
+
+ return lmm->lmv_magic == LMV_MAGIC_STRIPE;
}
static int get_lma_ea(struct lipe_object *object,
ext2_filsys lol_fs;
ext2_ino_t lol_ino;
struct ext2_inode_large *lol_inode;
+ struct ext2_xattr_handle *lol_xattr_handle;
};
struct lipe_object_zfs {
int rc;
ssize_t size;
const char *path = object->u.lo_posix.lop_path;
+ char buf[XATTR_SIZE_MAX];
- size = lgetxattr(path, XATTR_NAME_LINK, attrs->loa_leh_buf,
- sizeof(attrs->loa_leh_buf));
+ size = lgetxattr(path, XATTR_NAME_LINK, buf, sizeof(buf));
if (size < 0) {
if (errno == ENOATTR)
LDEBUG("path [%s] has no [%s] xattr, ignoring\n",
return -errno;
}
- rc = lipe_object_attrs_set_links(attrs, attrs->loa_leh_buf, size);
+ rc = lipe_object_attrs_set_links(attrs, buf, size);
if (rc) {
LERROR("failed to decode linkea for path [%s]\n", path);
return -1;
static int get_lmv_ea_posix(struct lipe_object *object,
struct lipe_object_attrs *attrs)
{
- ssize_t rc;
- const char *path = object->u.lo_posix.lop_path;
-
- memset(attrs->loa_lmv_buf, 0, sizeof(attrs->loa_lmv_buf));
+ const char *path = object->u.lo_posix.lop_path;
+ char buf[XATTR_SIZE_MAX];
+ ssize_t rc;
- rc = lgetxattr(path, XATTR_NAME_LMV, attrs->loa_lmv_buf,
- sizeof(attrs->loa_lmv_buf));
+ rc = lgetxattr(path, XATTR_NAME_LMV, buf, sizeof(buf));
if (rc < 0) {
if (errno == ENOATTR) {
LDEBUG("path [%s] has no [%s] xattr, ignoring\n",
}
}
- return 0;
+ return xmemdup(&attrs->loa_lmv, &attrs->loa_lmv_size, buf, rc);
}
static int get_lma_ea_posix(struct lipe_object *object,
struct lipe_object_attrs *attrs)
{
- char buf[MAX_LINKEA_SIZE];
- struct lustre_mdt_attrs *lma;
- ssize_t size;
- const char *path = object->u.lo_posix.lop_path;
+ const char *path = object->u.lo_posix.lop_path;
+ struct lustre_mdt_attrs *lma;
+ char buf[XATTR_SIZE_MAX];
+ ssize_t size;
- size = lgetxattr(path, XATTR_NAME_LMA, buf,
- MAX_LINKEA_SIZE);
+ size = lgetxattr(path, XATTR_NAME_LMA, buf, sizeof(buf));
if (size < 0) {
if (errno == ENOATTR)
LDEBUG("path [%d] has no [%s] xattr, ignoring\n",
static int get_lum_ea_posix(struct lipe_object *object,
struct lipe_object_attrs *attrs)
{
- int rc;
- int size;
- struct lov_user_md *lov = attrs->loa_lum;
- const char *path = object->u.lo_posix.lop_path;
+ const char *path = object->u.lo_posix.lop_path;
+ char buf[XATTR_SIZE_MAX];
+ int size;
+ int rc;
- size = lgetxattr(path, XATTR_NAME_LOV,
- (char *)lov, attrs->loa_lum_size);
+ size = lgetxattr(path, XATTR_NAME_LOV, buf, sizeof(buf));
if (size < 0) {
if (errno == ENOATTR)
LDEBUG("path [%d] has no [%s] xattr, ignoring\n",
return -errno;
}
- rc = decode_lum(lov, size);
+ rc = decode_lum((struct lov_user_md_v1 *)buf, size);
if (rc) {
LERROR("failed to decode lovea for path [%s]\n", path);
return rc;
}
+
+ rc = xmemdup(&attrs->loa_lum, &attrs->loa_lum_size, buf, size);
+ if (rc < 0)
+ return rc;
+
attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LOVEA;
return 0;
}
}
run_test 23 "lipe_find -size and -blocks work"
+test_100() {
+ local file=$DIR/$tdir/$tfile
+ local facet=${LIPE_MDS_FACET:-$(lipe_get_random_mds)}
+ local index=$(($(facet_number $facet) - 1))
+ local link_count=200
+ local i
+
+ $LFS mkdir -i $index $DIR/$tdir || error "$LFS mkdir '$td' failed"
+ touch $file
+
+ for ((i = 1; i < link_count; i++)); do
+ ln $file $file.$i
+ done
+
+ lipe_find_expect_file $facet $file true
+ lipe_find_expect_file $facet $file true -name $tfile
+ lipe_find_expect_file $facet $file true -name $tfile.1
+}
+run_test 100 "lipe_find works with big link xattrs"
+
do_lipe_scan2_facet() {
local facet="$1"
local device="$(facet_device $facet)"