#include <sys/time.h>
#include <sys/types.h>
#include <sys/xattr.h>
+#include <sys/sysmacros.h>
#include <time.h>
#include <fnmatch.h>
#include <libgen.h> /* for dirname() */
#endif
#include <poll.h>
#include <time.h>
+#include <inttypes.h>
#include <libcfs/util/ioctl.h>
#include <libcfs/util/param.h>
char *mdt_hash_name[] = { "none",
LMV_HASH_NAME_ALL_CHARS,
- LMV_HASH_NAME_FNV_1A_64 };
+ LMV_HASH_NAME_FNV_1A_64,
+};
+
+struct lustre_foreign_type lu_foreign_types[] = {
+ {.lft_type = LU_FOREIGN_TYPE_NONE, .lft_name = "none"},
+ {.lft_type = LU_FOREIGN_TYPE_DAOS, .lft_name = "daos"},
+ /* must be the last element */
+ {.lft_type = LU_FOREIGN_TYPE_UNKNOWN, .lft_name = NULL}
+ /* array max dimension must be <= UINT32_MAX */
+};
void llapi_msg_set_level(int level)
{
int llapi_stripe_limit_check(unsigned long long stripe_size, int stripe_offset,
int stripe_count, int stripe_pattern)
{
- int page_size, rc;
+ static int page_size;
+ int rc = 0;
- /* 64 KB is the largest common page size I'm aware of (on ia64), but
- * check the local page size just in case. */
- page_size = LOV_MIN_STRIPE_SIZE;
- if (getpagesize() > page_size) {
- page_size = getpagesize();
- llapi_err_noerrno(LLAPI_MSG_WARN,
- "warning: your page size (%u) is "
- "larger than expected (%u)", page_size,
- LOV_MIN_STRIPE_SIZE);
+ if (page_size == 0) {
+ /* 64 KB is the largest common page size (on ia64/PPC/ARM),
+ * but check the local page size just in case. The page_size
+ * will not change for the lifetime of this process at least.
+ */
+ page_size = LOV_MIN_STRIPE_SIZE;
+ if (getpagesize() > page_size) {
+ page_size = getpagesize();
+ llapi_err_noerrno(LLAPI_MSG_WARN,
+ "warning: page size (%u) larger than expected (%u)",
+ page_size, LOV_MIN_STRIPE_SIZE);
+ }
}
if (!llapi_stripe_size_is_aligned(stripe_size)) {
rc = -EINVAL;
llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe_size %llu, "
"must be an even multiple of %d bytes",
- stripe_size, page_size);
- return rc;
+ (unsigned long long)stripe_size, page_size);
+ goto out;
}
if (!llapi_stripe_index_is_valid(stripe_offset)) {
rc = -EINVAL;
llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe offset %d",
stripe_offset);
- return rc;
+ goto out;
}
if (!llapi_stripe_count_is_valid(stripe_count)) {
rc = -EINVAL;
llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe count %d",
stripe_count);
- return rc;
+ goto out;
}
if (llapi_stripe_size_is_too_big(stripe_size)) {
rc = -EINVAL;
llapi_error(LLAPI_MSG_ERROR, rc,
- "warning: stripe size 4G or larger "
- "is not currently supported and would wrap");
- return rc;
+ "error: stripe size '%llu' over 4GB limit",
+ (unsigned long long)stripe_size);
+ goto out;
}
- return 0;
+
+out:
+ errno = -rc;
+ return rc;
}
int llapi_dir_stripe_limit_check(int stripe_offset, int stripe_count,
return get_param_lmv(path, "uuid", buf, bufsize);
}
-/*
- * if pool is NULL, search tgtname in target_obd
- * if pool is not NULL:
- * if pool not found returns errno < 0
- * if tgtname is NULL, returns 1 if pool is not empty and 0 if pool empty
- * if tgtname is not NULL, returns 1 if OST is in pool and 0 if not
- */
-int llapi_search_tgt(char *fsname, char *poolname, char *tgtname, bool is_mdt)
-{
- char buffer[PATH_MAX];
- size_t len = 0;
- glob_t param;
- FILE *fd;
- int rc;
-
- /* You need one or the other */
- if (poolname == NULL && fsname == NULL)
- return -EINVAL;
-
- if (tgtname != NULL)
- len = strlen(tgtname);
-
- if (poolname == NULL && len == 0)
- return -EINVAL;
-
- /* Search by poolname and fsname if is not NULL */
- if (poolname != NULL) {
- rc = poolpath(¶m, fsname, NULL);
- if (rc == 0) {
- snprintf(buffer, sizeof(buffer), "%s/%s",
- param.gl_pathv[0], poolname);
- }
- } else if (fsname != NULL) {
- rc = get_lustre_param_path(is_mdt ? "lmv" : "lov", fsname,
- FILTER_BY_FS_NAME,
- "target_obd", ¶m);
- if (rc == 0) {
- strncpy(buffer, param.gl_pathv[0],
- sizeof(buffer));
- }
- } else {
- return -EINVAL;
- }
- cfs_free_param_data(¶m);
- if (rc)
- return rc;
-
- fd = fopen(buffer, "r");
- if (fd == NULL)
- return -errno;
-
- while (fgets(buffer, sizeof(buffer), fd) != NULL) {
- if (poolname == NULL) {
- char *ptr;
- /* Search for an tgtname in the list of targets
- * Line format is IDX: fsname-OST/MDTxxxx_UUID STATUS */
- ptr = strchr(buffer, ' ');
- if ((ptr != NULL) &&
- (strncmp(ptr + 1, tgtname, len) == 0)) {
- fclose(fd);
- return 1;
- }
- } else {
- /* Search for an tgtname in a pool,
- * (or an existing non-empty pool if no tgtname) */
- if ((tgtname == NULL) ||
- (strncmp(buffer, tgtname, len) == 0)) {
- fclose(fd);
- return 1;
- }
- }
- }
- fclose(fd);
- return 0;
-}
-
-int llapi_search_ost(char *fsname, char *poolname, char *ostname)
-{
- return llapi_search_tgt(fsname, poolname, ostname, false);
-}
-
/**
* Open a Lustre file.
*
/* sanity check of target list */
if (param->lsp_is_specific) {
- char ostname[MAX_OBD_NAME + 1];
+ char ostname[MAX_OBD_NAME + 64];
bool found = false;
int i;
stripe_pattern, NULL);
}
+int llapi_file_create_foreign(const char *name, mode_t mode, __u32 type,
+ __u32 flags, char *foreign_lov)
+{
+ size_t len;
+ struct lov_foreign_md *lfm;
+ int fd, rc;
+
+ if (foreign_lov == NULL) {
+ rc = -EINVAL;
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "foreign LOV EA content must be provided");
+ goto out_err;
+ }
+
+ len = strlen(foreign_lov);
+ if (len > XATTR_SIZE_MAX - offsetof(struct lov_foreign_md, lfm_value) ||
+ len <= 0) {
+ rc = -EINVAL;
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "foreign LOV EA size %zu (must be 0 < len < %zu)",
+ len, XATTR_SIZE_MAX -
+ offsetof(struct lov_foreign_md, lfm_value));
+ goto out_err;
+ }
+
+ lfm = malloc(len + offsetof(struct lov_foreign_md, lfm_value));
+ if (lfm == NULL) {
+ rc = -ENOMEM;
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "failed to allocate lov_foreign_md");
+ goto out_err;
+ }
+
+ fd = open(name, O_WRONLY|O_CREAT|O_LOV_DELAY_CREATE, mode);
+ if (fd == -1) {
+ fd = -errno;
+ llapi_error(LLAPI_MSG_ERROR, fd, "open '%s' failed", name);
+ goto out_free;
+ }
+
+ lfm->lfm_magic = LOV_USER_MAGIC_FOREIGN;
+ lfm->lfm_length = len;
+ lfm->lfm_type = type;
+ lfm->lfm_flags = flags;
+ memcpy(lfm->lfm_value, foreign_lov, len);
+
+ if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, lfm) != 0) {
+ char *errmsg = "stripe already set";
+
+ rc = -errno;
+ if (errno == ENOTTY)
+ errmsg = "not on a Lustre filesystem";
+ else if (errno == EEXIST || errno == EALREADY)
+ errmsg = "stripe already set";
+ else
+ errmsg = strerror(errno);
+
+ llapi_err_noerrno(LLAPI_MSG_ERROR,
+ "setstripe error for '%s': %s", name, errmsg);
+
+ close(fd);
+ fd = rc;
+ }
+
+out_free:
+ free(lfm);
+
+ return fd;
+
+out_err:
+ errno = -rc;
+ return rc;
+}
+
int llapi_file_create(const char *name, unsigned long long stripe_size,
int stripe_offset, int stripe_count, int stripe_pattern)
{
/* sanity check of target list */
if (param->lsp_is_specific) {
- char mdtname[MAX_OBD_NAME + 1];
+ char mdtname[MAX_OBD_NAME + 64];
bool found = false;
int i;
return rc;
}
+/**
+ * Create a foreign directory.
+ *
+ * \param name the name of the directory to be created
+ * \param mode permission of the file if it is created, see mode in open(2)
+ * \param type foreign type to be set in LMV EA
+ * \param flags foreign flags to be set in LMV EA
+ * \param value foreign pattern to be set in LMV EA
+ *
+ * \retval 0 on success
+ * \retval negative errno on failure
+ */
+int llapi_dir_create_foreign(const char *name, mode_t mode, __u32 type,
+ __u32 flags, const char *value)
+{
+ struct lmv_foreign_md *lfm = NULL;
+ size_t lfm_size, len;
+ struct obd_ioctl_data data = { 0 };
+ char rawbuf[8192];
+ char *buf = rawbuf;
+ char *dirpath = NULL;
+ char *namepath = NULL;
+ char *dir;
+ char *filename;
+ int fd, rc;
+
+ len = strlen(value);
+ if (len > XATTR_SIZE_MAX - offsetof(struct lmv_foreign_md, lfm_value) ||
+ len <= 0) {
+ rc = -EINVAL;
+ llapi_error(LLAPI_MSG_ERROR, rc, "invalid LOV EA length %zu "
+ "(must be 0 < len < %zu)\n", len,
+ XATTR_SIZE_MAX -
+ offsetof(struct lmv_foreign_md, lfm_value));
+ return rc;
+ }
+ lfm_size = len + offsetof(struct lmv_foreign_md, lfm_value);
+ lfm = calloc(1, lfm_size);
+ if (lfm == NULL)
+ return -ENOMEM;
+
+ dirpath = strdup(name);
+ if (!dirpath) {
+ free(lfm);
+ return -ENOMEM;
+ }
+
+ namepath = strdup(name);
+ if (!namepath) {
+ free(dirpath);
+ free(lfm);
+ return -ENOMEM;
+ }
+
+ lfm->lfm_magic = LMV_MAGIC_FOREIGN;
+ lfm->lfm_length = len;
+ lfm->lfm_type = type;
+ lfm->lfm_flags = flags;
+ memcpy(lfm->lfm_value, value, len);
+
+ filename = basename(namepath);
+ dir = dirname(dirpath);
+
+ data.ioc_inlbuf1 = (char *)filename;
+ data.ioc_inllen1 = strlen(filename) + 1;
+ data.ioc_inlbuf2 = (char *)lfm;
+ data.ioc_inllen2 = lfm_size;
+ data.ioc_type = mode;
+ rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf));
+ if (rc) {
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "error: LL_IOC_LMV_SETSTRIPE pack failed '%s'.",
+ name);
+ goto out;
+ }
+
+ fd = open(dir, O_DIRECTORY | O_RDONLY);
+ if (fd < 0) {
+ rc = -errno;
+ llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'", name);
+ goto out;
+ }
+
+ if (ioctl(fd, LL_IOC_LMV_SETSTRIPE, buf)) {
+ char *errmsg = "stripe already set";
+
+ rc = -errno;
+ if (errno != EEXIST && errno != EALREADY)
+ errmsg = strerror(errno);
+
+ llapi_err_noerrno(LLAPI_MSG_ERROR,
+ "dirstripe error on '%s': %s", name, errmsg);
+ }
+ close(fd);
+out:
+ free(namepath);
+ free(dirpath);
+ free(lfm);
+ return rc;
+}
int llapi_dir_create_pool(const char *name, int mode, int stripe_offset,
int stripe_count, int stripe_pattern,
FILE *fp;
int idx = 0, len = 0, mntlen, fd;
int rc = -ENODEV;
+ int fsnamelen, mountlen;
/* get the mount point */
fp = setmntent(PROC_MOUNTS, "r");
ptr_end++;
/* Check the fsname for a match, if given */
+ mountlen = ptr_end - ptr;
if (!(want & WANT_FSNAME) && fsname != NULL &&
- (strlen(fsname) > 0) &&
- (strncmp(ptr, fsname, ptr_end - ptr) != 0))
- continue;
+ (fsnamelen = strlen(fsname)) > 0 &&
+ (fsnamelen != mountlen ||
+ (strncmp(ptr, fsname, mountlen) != 0)))
+ continue;
/* If the path isn't set return the first one we find */
if (path == NULL || strlen(path) == 0) {
- strncpy(mntdir, mnt.mnt_dir, strlen(mnt.mnt_dir));
- mntdir[strlen(mnt.mnt_dir)] = '\0';
+ strncpy(mntdir, mnt.mnt_dir, sizeof(mntdir) - 1);
+ mntdir[sizeof(mntdir) - 1] = '\0';
if ((want & WANT_FSNAME) && fsname != NULL) {
- strncpy(fsname, ptr, ptr_end - ptr);
- fsname[ptr_end - ptr] = '\0';
+ strncpy(fsname, ptr, mountlen);
+ fsname[mountlen] = '\0';
}
rc = 0;
break;
/* Otherwise find the longest matching path */
} else if ((strlen(path) >= mntlen) && (mntlen >= len) &&
(strncmp(mnt.mnt_dir, path, mntlen) == 0)) {
- strncpy(mntdir, mnt.mnt_dir, strlen(mnt.mnt_dir));
- mntdir[strlen(mnt.mnt_dir)] = '\0';
+ strncpy(mntdir, mnt.mnt_dir, sizeof(mntdir) - 1);
+ mntdir[sizeof(mntdir) - 1] = '\0';
len = mntlen;
if ((want & WANT_FSNAME) && fsname != NULL) {
- strncpy(fsname, ptr, ptr_end - ptr);
- fsname[ptr_end - ptr] = '\0';
+ strncpy(fsname, ptr, mountlen);
+ fsname[mountlen] = '\0';
}
rc = 0;
}
/* Found it */
if (rc == 0) {
if ((want & WANT_PATH) && path != NULL) {
- strncpy(path, mntdir, strlen(mntdir));
+ strncpy(path, mntdir, PATH_MAX);
path[strlen(mntdir)] = '\0';
}
if (want & WANT_FD) {
int llapi_search_rootpath(char *pathname, const char *fsname)
{
+ /* pathname can be used as an argument by get_root_path(),
+ * clear it for safety */
+ pathname[0] = 0;
return get_root_path(WANT_PATH, (char *)fsname, NULL, pathname, -1);
}
int llapi_get_poollist(const char *name, char **poollist, int list_size,
char *buffer, int buffer_size)
{
- char rname[PATH_MAX];
glob_t pathname;
char *fsname;
- char *ptr;
- DIR *dir;
+ char *ptr;
+ DIR *dir;
struct dirent *pool;
- int rc = 0;
- unsigned int nb_entries = 0;
- unsigned int used = 0;
- unsigned int i;
+ int rc = 0;
+ unsigned int nb_entries = 0;
+ unsigned int used = 0;
+ unsigned int i;
/* initialize output array */
- for (i = 0; i < list_size; i++)
- poollist[i] = NULL;
-
- /* is name a pathname ? */
- ptr = strchr(name, '/');
- if (ptr != NULL) {
- /* only absolute pathname is supported */
- if (*name != '/')
- return -EINVAL;
+ for (i = 0; i < list_size; i++)
+ poollist[i] = NULL;
- if (!realpath(name, rname)) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc, "invalid path '%s'",
- name);
- return rc;
- }
+ /* is name a pathname ? */
+ ptr = strchr(name, '/');
+ if (ptr != NULL) {
+ char fsname_buf[MAXNAMLEN];
+
+ /* We will need fsname for printing later */
+ rc = llapi_getname(name, fsname_buf, sizeof(fsname_buf));
+ if (rc)
+ return rc;
+
+ ptr = strrchr(fsname_buf, '-');
+ if (ptr)
+ *ptr = '\0';
- fsname = strdup(rname);
+ fsname = strdup(fsname_buf);
if (!fsname)
return -ENOMEM;
-
- rc = poolpath(&pathname, NULL, rname);
} else {
/* name is FSNAME */
fsname = strdup(name);
if (!fsname)
return -ENOMEM;
- rc = poolpath(&pathname, fsname, NULL);
}
+
+ rc = poolpath(&pathname, fsname, NULL);
if (rc != 0) {
llapi_error(LLAPI_MSG_ERROR, rc,
"Lustre filesystem '%s' not found", name);
#define OBD_NOT_FOUND (-1)
+static void find_param_fini(struct find_param *param)
+{
+ if (param->fp_migrate)
+ return;
+
+ if (param->fp_obd_indexes) {
+ free(param->fp_obd_indexes);
+ param->fp_obd_indexes = NULL;
+ }
+
+ if (param->fp_lmd) {
+ free(param->fp_lmd);
+ param->fp_lmd = NULL;
+ }
+
+ if (param->fp_lmv_md) {
+ free(param->fp_lmv_md);
+ param->fp_lmv_md = NULL;
+ }
+}
+
static int common_param_init(struct find_param *param, char *path)
{
int lum_size = get_mds_md_size(path);
lum_size = PATH_MAX + 1;
param->fp_lum_size = lum_size;
- param->fp_lmd = calloc(1, sizeof(lstat_t) + lum_size);
+ param->fp_lmd = calloc(1, offsetof(typeof(*param->fp_lmd), lmd_lmm) +
+ lum_size);
if (param->fp_lmd == NULL) {
llapi_error(LLAPI_MSG_ERROR, -ENOMEM,
- "error: allocation of %zu bytes for ioctl",
+ "error: allocate %zu bytes for layout failed",
sizeof(lstat_t) + param->fp_lum_size);
return -ENOMEM;
}
"error: allocation of %d bytes for ioctl",
lmv_user_md_size(param->fp_lmv_stripe_count,
LMV_USER_MAGIC_SPECIFIC));
+ find_param_fini(param);
return -ENOMEM;
}
return 0;
}
-static void find_param_fini(struct find_param *param)
-{
- if (param->fp_migrate)
- return;
-
- if (param->fp_obd_indexes)
- free(param->fp_obd_indexes);
-
- if (param->fp_lmd)
- free(param->fp_lmd);
-
- if (param->fp_lmv_md)
- free(param->fp_lmv_md);
-}
-
static int cb_common_fini(char *path, DIR *parent, DIR **dirp, void *data,
struct dirent64 *de)
{
int stripe_count;
int lmv_size;
- stripe_count = (__u32)param->fp_lmv_md->lum_stripe_count;
+ /* if foreign LMV case, fake stripes number */
+ if (param->fp_lmv_md->lum_magic == LMV_MAGIC_FOREIGN) {
+ struct lmv_foreign_md *lfm;
+
+ lfm = (struct lmv_foreign_md *)param->fp_lmv_md;
+ if (lfm->lfm_length < XATTR_SIZE_MAX -
+ offsetof(typeof(*lfm), lfm_value)) {
+ uint32_t size = lfm->lfm_length +
+ offsetof(typeof(*lfm), lfm_value);
+
+ stripe_count = lmv_foreign_to_md_stripes(size);
+ } else {
+ llapi_error(LLAPI_MSG_ERROR, -EINVAL,
+ "error: invalid %d foreign size "
+ "returned from ioctl",
+ lfm->lfm_length);
+ return -EINVAL;
+ }
+ } else {
+ stripe_count = param->fp_lmv_md->lum_stripe_count;
+ }
if (stripe_count <= param->fp_lmv_stripe_count)
return ret;
return ret;
}
-int get_lmd_info_fd(char *path, int parent_fd, int dir_fd,
+static void convert_lmd_statx(struct lov_user_mds_data *lmd_v2, lstat_t *st,
+ bool strict)
+{
+ memset(&lmd_v2->lmd_stx, 0, sizeof(lmd_v2->lmd_stx));
+ lmd_v2->lmd_stx.stx_blksize = st->st_blksize;
+ lmd_v2->lmd_stx.stx_nlink = st->st_nlink;
+ lmd_v2->lmd_stx.stx_uid = st->st_uid;
+ lmd_v2->lmd_stx.stx_gid = st->st_gid;
+ lmd_v2->lmd_stx.stx_mode = st->st_mode;
+ lmd_v2->lmd_stx.stx_ino = st->st_ino;
+ lmd_v2->lmd_stx.stx_size = st->st_size;
+ lmd_v2->lmd_stx.stx_blocks = st->st_blocks;
+ lmd_v2->lmd_stx.stx_atime.tv_sec = st->st_atime;
+ lmd_v2->lmd_stx.stx_ctime.tv_sec = st->st_ctime;
+ lmd_v2->lmd_stx.stx_mtime.tv_sec = st->st_mtime;
+ lmd_v2->lmd_stx.stx_rdev_major = major(st->st_rdev);
+ lmd_v2->lmd_stx.stx_rdev_minor = minor(st->st_rdev);
+ lmd_v2->lmd_stx.stx_dev_major = major(st->st_dev);
+ lmd_v2->lmd_stx.stx_dev_minor = minor(st->st_dev);
+ lmd_v2->lmd_stx.stx_mask |= STATX_BASIC_STATS;
+
+ lmd_v2->lmd_flags = 0;
+ if (strict) {
+ lmd_v2->lmd_flags |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
+ } else {
+ lmd_v2->lmd_stx.stx_mask &= ~(STATX_SIZE | STATX_BLOCKS);
+ if (lmd_v2->lmd_stx.stx_size)
+ lmd_v2->lmd_flags |= OBD_MD_FLLAZYSIZE;
+ if (lmd_v2->lmd_stx.stx_blocks)
+ lmd_v2->lmd_flags |= OBD_MD_FLLAZYBLOCKS;
+ }
+ lmd_v2->lmd_flags |= OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME |
+ OBD_MD_FLBLKSZ | OBD_MD_FLMODE | OBD_MD_FLTYPE |
+ OBD_MD_FLUID | OBD_MD_FLGID | OBD_MD_FLNLINK |
+ OBD_MD_FLRDEV;
+
+}
+
+static int convert_lmdbuf_v1v2(void *lmdbuf, int lmdlen)
+{
+ struct lov_user_mds_data_v1 *lmd_v1 = lmdbuf;
+ struct lov_user_mds_data *lmd_v2 = lmdbuf;
+ lstat_t st;
+ int size;
+
+ size = lov_comp_md_size((struct lov_comp_md_v1 *)&lmd_v1->lmd_lmm);
+ if (size < 0)
+ return size;
+
+ if (lmdlen < sizeof(lmd_v1->lmd_st) + size)
+ return -EOVERFLOW;
+
+ st = lmd_v1->lmd_st;
+ memmove(&lmd_v2->lmd_lmm, &lmd_v1->lmd_lmm,
+ lmdlen - (&lmd_v2->lmd_lmm - &lmd_v1->lmd_lmm));
+ convert_lmd_statx(lmd_v2, &st, false);
+ lmd_v2->lmd_lmmsize = 0;
+ lmd_v2->lmd_padding = 0;
+
+ return 0;
+}
+
+int get_lmd_info_fd(const char *path, int parent_fd, int dir_fd,
void *lmdbuf, int lmdlen, enum get_lmd_info_type type)
{
struct lov_user_mds_data *lmd = lmdbuf;
- lstat_t *st = &lmd->lmd_st;
+ static bool use_old_ioctl;
+ unsigned long cmd;
int ret = 0;
if (parent_fd < 0 && dir_fd < 0)
* and returns struct lov_user_mds_data, while
* LL_IOC_LOV_GETSTRIPE returns only struct lov_user_md.
*/
- ret = ioctl(dir_fd, type == GET_LMD_INFO ? LL_IOC_MDC_GETINFO :
- LL_IOC_LOV_GETSTRIPE,
- lmdbuf);
+ if (type == GET_LMD_INFO)
+ cmd = use_old_ioctl ? LL_IOC_MDC_GETINFO_OLD :
+ LL_IOC_MDC_GETINFO;
+ else
+ cmd = LL_IOC_LOV_GETSTRIPE;
+
+retry_getinfo:
+ ret = ioctl(dir_fd, cmd, lmdbuf);
+ if (ret < 0 && errno == ENOTTY && cmd == LL_IOC_MDC_GETINFO) {
+ cmd = LL_IOC_MDC_GETINFO_OLD;
+ use_old_ioctl = true;
+ goto retry_getinfo;
+ }
+
+ if (cmd == LL_IOC_MDC_GETINFO_OLD && !ret)
+ ret = convert_lmdbuf_v1v2(lmdbuf, lmdlen);
} else if (parent_fd >= 0) {
- char *fname = strrchr(path, '/');
+ const char *fname = strrchr(path, '/');
/* IOC_MDC_GETFILEINFO takes as input the filename (relative to
* the parent directory) and returns struct lov_user_mds_data,
errno = -ret;
else if (ret >= lmdlen || ret++ == 0)
errno = EINVAL;
- else
- ret = ioctl(parent_fd, type == GET_LMD_INFO ?
- IOC_MDC_GETFILEINFO :
- IOC_MDC_GETFILESTRIPE, lmdbuf);
+ else {
+ if (type == GET_LMD_INFO)
+ cmd = use_old_ioctl ? IOC_MDC_GETFILEINFO_OLD :
+ IOC_MDC_GETFILEINFO;
+ else
+ cmd = IOC_MDC_GETFILESTRIPE;
+
+retry_getfileinfo:
+ ret = ioctl(parent_fd, cmd, lmdbuf);
+ if (ret < 0 && errno == ENOTTY &&
+ cmd == IOC_MDC_GETFILEINFO) {
+ cmd = IOC_MDC_GETFILEINFO_OLD;
+ use_old_ioctl = true;
+ goto retry_getfileinfo;
+ }
+
+ if (cmd == IOC_MDC_GETFILEINFO_OLD && !ret)
+ ret = convert_lmdbuf_v1v2(lmdbuf, lmdlen);
+ }
}
if (ret && type == GET_LMD_INFO) {
if (errno == ENOTTY) {
+ lstat_t st;
+
/* ioctl is not supported, it is not a lustre fs.
* Do the regular lstat(2) instead.
*/
- ret = lstat_f(path, st);
+ ret = lstat_f(path, &st);
if (ret) {
ret = -errno;
llapi_error(LLAPI_MSG_ERROR, ret,
"error: %s: lstat failed for %s",
__func__, path);
}
+
+ convert_lmd_statx(lmd, &st, true);
+ /* It may be wrong to set use_old_ioctl with true as
+ * the file is not a lustre fs. So reset it with false
+ * directly here.
+ */
+ use_old_ioctl = false;
} else if (errno == ENOENT) {
ret = -errno;
llapi_error(LLAPI_MSG_WARN, ret,
strcat(path, dent->d_name);
if (dent->d_type == DT_UNKNOWN) {
- lstat_t *st = ¶m->fp_lmd->lmd_st;
+ lstatx_t *stx = ¶m->fp_lmd->lmd_stx;
rc = get_lmd_info(path, d, NULL, param->fp_lmd,
param->fp_lum_size, GET_LMD_INFO);
if (rc == 0)
- dent->d_type = IFTODT(st->st_mode);
+ dent->d_type = IFTODT(stx->stx_mode);
else if (ret == 0)
ret = rc;
static char *layout2name(__u32 layout_pattern)
{
- if (layout_pattern == LOV_PATTERN_MDT)
+ if (layout_pattern & LOV_PATTERN_F_RELEASED)
+ return "released";
+ else if (layout_pattern == LOV_PATTERN_MDT)
return "mdt";
else if (layout_pattern == LOV_PATTERN_RAID0)
return "raid0";
- else if (layout_pattern == (LOV_PATTERN_RAID0 | LOV_PATTERN_F_RELEASED))
- return "released";
+ else if (layout_pattern ==
+ (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING))
+ return "raid0,overstriped";
else
return "unknown";
}
LDF_INDENT = 0x0004,
LDF_SKIP_OBJS = 0x0008,
LDF_YAML = 0x0010,
+ LDF_EXTENSION = 0x0020,
};
static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
bool indent = flags & LDF_INDENT;
bool yaml = flags & LDF_YAML;
bool skip_objs = flags & LDF_SKIP_OBJS;
+ bool extension = flags & LDF_EXTENSION;
char *prefix = is_dir ? "" : "lmm_";
char *separator = "";
char *space = indent ? " " : "";
ver = (__u32)(lmm_oi_id(&lum->lmm_oi) >> 32);
if (yaml)
llapi_printf(LLAPI_MSG_NORMAL, DFID_NOBRACE"\n",
- seq, oid, ver);
+ (unsigned long long)seq, oid, ver);
else
llapi_printf(LLAPI_MSG_NORMAL, DFID"\n",
- seq, oid, ver);
+ (unsigned long long)seq, oid, ver);
}
if (verbose & VERBOSE_STRIPE_COUNT) {
" stripe count.");
} else {
llapi_printf(LLAPI_MSG_NORMAL, "%d",
- lum->lmm_stripe_count ==
- (typeof(lum->lmm_stripe_count))(-1)
- ? -1 : lum->lmm_stripe_count);
+ extension ? 0 :
+ (__s16)lum->lmm_stripe_count);
}
} else {
llapi_printf(LLAPI_MSG_NORMAL, "%hd",
+ extension ? 0 :
(__s16)lum->lmm_stripe_count);
}
if (!yaml && is_dir)
separator = "\n";
}
- if (verbose & VERBOSE_STRIPE_SIZE) {
+ if (((verbose & VERBOSE_STRIPE_SIZE) && !extension) ||
+ ((verbose & VERBOSE_EXT_SIZE) && extension)) {
llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
- if (verbose & ~VERBOSE_STRIPE_SIZE)
+ if (verbose & ~VERBOSE_EXT_SIZE && extension)
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%sextension_size: ",
+ space, prefix);
+ if (verbose & ~VERBOSE_STRIPE_SIZE && !extension)
llapi_printf(LLAPI_MSG_NORMAL, "%s%sstripe_size: ",
space, prefix);
if (is_dir && !is_raw && lum->lmm_stripe_size == 0) {
"Cannot determine default"
" stripe size.");
} else {
- llapi_printf(LLAPI_MSG_NORMAL, "%u",
- lum->lmm_stripe_size);
+ /* Extension size is in KiB */
+ llapi_printf(LLAPI_MSG_NORMAL, "%llu",
+ extension ?
+ (unsigned long long)(lum->lmm_stripe_size * SEL_UNIT_SIZE) :
+ (unsigned long long)lum->lmm_stripe_size);
}
if (!yaml && is_dir)
separator = " ";
else
llapi_printf(LLAPI_MSG_NORMAL, "%#x", type);
+ if (flags & LMV_HASH_FLAG_SPACE)
+ llapi_printf(LLAPI_MSG_NORMAL, ",space");
if (flags & LMV_HASH_FLAG_MIGRATION)
llapi_printf(LLAPI_MSG_NORMAL, ",migrating");
- if (flags & LMV_HASH_FLAG_DEAD)
- llapi_printf(LLAPI_MSG_NORMAL, ",dead");
if (flags & LMV_HASH_FLAG_BAD_TYPE)
llapi_printf(LLAPI_MSG_NORMAL, ",bad_type");
if (flags & LMV_HASH_FLAG_LOST_LMV)
"%4slcme_timestamp: ", " ");
if (yaml) {
llapi_printf(LLAPI_MSG_NORMAL, "%llu",
- entry->lcme_timestamp);
+ (unsigned long long)entry->lcme_timestamp);
} else {
time_t stamp = entry->lcme_timestamp;
char *date_str = asctime(localtime(&stamp));
llapi_printf(LLAPI_MSG_NORMAL,
"%4slcme_extent.e_start: ", " ");
llapi_printf(LLAPI_MSG_NORMAL, "%llu",
- entry->lcme_extent.e_start);
+ (unsigned long long)entry->lcme_extent.e_start);
separator = "\n";
}
llapi_printf(LLAPI_MSG_NORMAL, "%s", "EOF");
else
llapi_printf(LLAPI_MSG_NORMAL, "%llu",
- entry->lcme_extent.e_end);
+ (unsigned long long)entry->lcme_extent.e_end);
separator = "\n";
}
struct lov_user_md_v1 *v1;
char pool_name[LOV_MAXPOOLNAME + 1];
int obdindex = param->fp_obd_index;
- int i, j, match;
+ int i, j, match, ext;
bool obdstripe = false;
__u16 mirror_index = 0;
__u16 mirror_id = 0;
*/
if (entry->lcme_flags & LCME_FL_INIT)
continue;
- else
- break;
+
+ if (param->fp_verbose & VERBOSE_EXT_SIZE) {
+ if (entry->lcme_flags & LCME_FL_EXTENSION)
+ /* moved back below */
+ i++;
+ else
+ continue;
+ }
+ break;
}
if (entry->lcme_flags & LCME_FL_INIT) {
objects = lov_v1v3_objects(v1);
lov_v1v3_pool_name(v1, pool_name);
+ ext = entry->lcme_flags & LCME_FL_EXTENSION ? LDF_EXTENSION : 0;
lov_dump_user_lmm_v1v3(v1, pool_name, objects, path, obdindex,
param->fp_max_depth, param->fp_verbose,
- flags);
+ flags | ext);
}
if (print_last_init_comp(param)) {
/**
objects = lov_v1v3_objects(v1);
lov_v1v3_pool_name(v1, pool_name);
+ entry = &comp_v1->lcm_entries[i];
+ ext = entry->lcme_flags & LCME_FL_EXTENSION ? LDF_EXTENSION : 0;
lov_dump_user_lmm_v1v3(v1, pool_name, objects, path, obdindex,
param->fp_max_depth, param->fp_verbose,
- flags);
+ flags | ext);
}
}
int lum_size = lov_user_md_size(is_dir ? 0 : lum->lmm_stripe_count,
lum->lmm_magic);
- new = malloc(sizeof(lstat_t) + lum_off + lum_size);
+ new = malloc(offsetof(typeof(*new), lmd_lmm) + lum_off + lum_size);
if (new == NULL) {
llapi_printf(LLAPI_MSG_NORMAL, "out of memory\n");
return new;
}
- memcpy(new, orig, sizeof(lstat_t));
+ memcpy(new, orig, sizeof(new->lmd_stx) + sizeof(new->lmd_flags)
+ + sizeof(new->lmd_lmmsize));
comp_v1 = (struct lov_comp_md_v1 *)&new->lmd_lmm;
comp_v1->lcm_magic = lum->lmm_magic;
}
}
+static uint32_t check_foreign_type(uint32_t foreign_type)
+{
+ uint32_t i;
+
+ for (i = 0; i < LU_FOREIGN_TYPE_UNKNOWN; i++) {
+ if (lu_foreign_types[i].lft_name == NULL)
+ break;
+ if (foreign_type == lu_foreign_types[i].lft_type)
+ return i;
+ }
+
+ return LU_FOREIGN_TYPE_UNKNOWN;
+}
+
+static void lov_dump_foreign_lmm(struct find_param *param, char *path,
+ enum lov_dump_flags flags)
+{
+ struct lov_foreign_md *lfm = (void *)¶m->fp_lmd->lmd_lmm;
+ bool yaml = flags & LDF_YAML;
+
+ if (!yaml && param->fp_depth && path)
+ llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
+
+ if (param->fp_verbose & VERBOSE_DETAIL) {
+ uint32_t type = check_foreign_type(lfm->lfm_type);
+
+ llapi_printf(LLAPI_MSG_NORMAL, "lfm_magic: 0x%08X\n",
+ lfm->lfm_magic);
+ llapi_printf(LLAPI_MSG_NORMAL, "lfm_length: %u\n",
+ lfm->lfm_length);
+ llapi_printf(LLAPI_MSG_NORMAL, "lfm_type: 0x%08X",
+ lfm->lfm_type);
+ if (type < LU_FOREIGN_TYPE_UNKNOWN)
+ llapi_printf(LLAPI_MSG_NORMAL, " (%s)\n",
+ lu_foreign_types[type].lft_name);
+ else
+ llapi_printf(LLAPI_MSG_NORMAL, " (unknown)\n");
+
+ llapi_printf(LLAPI_MSG_NORMAL, "lfm_flags: 0x%08X\n",
+ lfm->lfm_flags);
+ }
+ llapi_printf(LLAPI_MSG_NORMAL, "lfm_value: '%.*s'\n",
+ lfm->lfm_length, lfm->lfm_value);
+ llapi_printf(LLAPI_MSG_NORMAL, "\n");
+}
+
+static void lmv_dump_foreign_lmm(struct find_param *param, char *path,
+ enum lov_dump_flags flags)
+{
+ struct lmv_foreign_md *lfm = (struct lmv_foreign_md *)param->fp_lmv_md;
+ bool yaml = flags & LDF_YAML;
+
+ if (!yaml && param->fp_depth && path)
+ llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
+
+ if (param->fp_verbose & VERBOSE_DETAIL) {
+ uint32_t type = check_foreign_type(lfm->lfm_type);
+
+ llapi_printf(LLAPI_MSG_NORMAL, "lfm_magic: 0x%08X\n",
+ lfm->lfm_magic);
+ llapi_printf(LLAPI_MSG_NORMAL, "lfm_length: %u\n",
+ lfm->lfm_length);
+ llapi_printf(LLAPI_MSG_NORMAL, "lfm_type: 0x%08X",
+ lfm->lfm_type);
+ if (type < LU_FOREIGN_TYPE_UNKNOWN)
+ llapi_printf(LLAPI_MSG_NORMAL, " (%s)\n",
+ lu_foreign_types[type].lft_name);
+ else
+ llapi_printf(LLAPI_MSG_NORMAL, " (unknown)\n");
+
+ llapi_printf(LLAPI_MSG_NORMAL, "lfm_flags: 0x%08X\n",
+ lfm->lfm_flags);
+ }
+ llapi_printf(LLAPI_MSG_NORMAL, "lfm_value: '%.*s'\n",
+ lfm->lfm_length, lfm->lfm_value);
+ llapi_printf(LLAPI_MSG_NORMAL, "\n");
+}
+
static void llapi_lov_dump_user_lmm(struct find_param *param, char *path,
enum lov_dump_flags flags)
{
case LOV_USER_MAGIC_SPECIFIC:
lov_dump_plain_user_lmm(param, path, flags);
break;
+ case LOV_USER_MAGIC_FOREIGN:
+ lov_dump_foreign_lmm(param, path, flags);
+ break;
case LMV_MAGIC_V1:
case LMV_USER_MAGIC: {
char pool_name[LOV_MAXPOOLNAME + 1];
case LOV_USER_MAGIC_COMP_V1:
lov_dump_comp_v1(param, path, flags);
break;
+ case LMV_MAGIC_FOREIGN:
+ lmv_dump_foreign_lmm(param, path, flags);
+ break;
default:
llapi_printf(LLAPI_MSG_NORMAL, "unknown lmm_magic: %#x "
"(expecting one of %#x %#x %#x %#x)\n",
fd = open(dname, O_RDONLY | O_NONBLOCK);
if (fd == -1) {
rc = -errno;
- free(dname);
- return rc;
+ goto out_free;
}
strcpy((char *)lum, fname);
if (close(fd) == -1 && rc == 0)
rc = -errno;
+out_free:
free(dname);
return rc;
}
*
* If 0 is returned, we need to do another RPC to the OSTs to obtain the
* updated timestamps. */
-static int find_time_check(lstat_t *st, struct find_param *param, int mds)
+static int find_time_check(lstatx_t *stx, struct find_param *param, int mds)
{
int rc = 1;
int rc2;
/* Check if file is accepted. */
if (param->fp_atime) {
- rc2 = find_value_cmp(st->st_atime, param->fp_atime,
+ rc2 = find_value_cmp(stx->stx_atime.tv_sec, param->fp_atime,
param->fp_asign, param->fp_exclude_atime,
param->fp_time_margin, mds);
if (rc2 < 0)
}
if (param->fp_mtime) {
- rc2 = find_value_cmp(st->st_mtime, param->fp_mtime,
+ rc2 = find_value_cmp(stx->stx_mtime.tv_sec, param->fp_mtime,
param->fp_msign, param->fp_exclude_mtime,
param->fp_time_margin, mds);
if (rc2 < 0)
}
if (param->fp_ctime) {
- rc2 = find_value_cmp(st->st_ctime, param->fp_ctime,
+ rc2 = find_value_cmp(stx->stx_ctime.tv_sec, param->fp_ctime,
param->fp_csign, param->fp_exclude_ctime,
param->fp_time_margin, mds);
if (rc2 < 0)
struct lov_user_ost_data_v1 *objects;
struct lov_comp_md_v1 *comp_v1 = NULL;
struct lov_user_md_v1 *v1 = ¶m->fp_lmd->lmd_lmm;
- lstat_t *st = ¶m->fp_lmd->lmd_st;
+ lstatx_t *stx = ¶m->fp_lmd->lmd_stx;
int i, j, k, count = 1;
if (param->fp_obd_uuid && param->fp_obd_index == OBD_NOT_FOUND)
return 0;
- if (!S_ISREG(st->st_mode))
+ if (!S_ISREG(stx->stx_mode))
return 0;
+ /* exclude foreign */
+ if (v1->lmm_magic == LOV_USER_MAGIC_FOREIGN)
+ return param->fp_exclude_obd;
+
/* Only those files should be accepted, which have a
* stripe on the specified OST. */
if (v1->lmm_magic == LOV_USER_MAGIC_COMP_V1) {
{
struct lov_comp_md_v1 *comp_v1 = NULL;
struct lov_user_md_v1 *v1 = ¶m->fp_lmd->lmd_lmm;
+ __u32 stripe_size = 0;
int ret, i, count = 1;
+ if (v1->lmm_magic == LOV_USER_MAGIC_FOREIGN)
+ return param->fp_exclude_stripe_size ? 1 : -1;
+
+ ret = param->fp_exclude_stripe_size ? 1 : -1;
if (v1->lmm_magic == LOV_USER_MAGIC_COMP_V1) {
comp_v1 = (struct lov_comp_md_v1 *)v1;
count = comp_v1->lcm_entry_count;
- ret = param->fp_exclude_stripe_size ? 1 : -1;
}
for (i = 0; i < count; i++) {
- if (comp_v1)
+ struct lov_comp_md_entry_v1 *ent;
+
+ if (comp_v1) {
v1 = lov_comp_entry(comp_v1, i);
- ret = find_value_cmp(v1->lmm_stripe_size, param->fp_stripe_size,
- param->fp_stripe_size_sign,
- param->fp_exclude_stripe_size,
- param->fp_stripe_size_units, 0);
- /* If any stripe_size matches */
+ ent = &comp_v1->lcm_entries[i];
+ if (ent->lcme_flags & LCME_FL_EXTENSION)
+ continue;
+ if (!(ent->lcme_flags & LCME_FL_INIT))
+ continue;
+ }
+ stripe_size = v1->lmm_stripe_size;
+ }
+
+ ret = find_value_cmp(stripe_size, param->fp_stripe_size,
+ param->fp_stripe_size_sign,
+ param->fp_exclude_stripe_size,
+ param->fp_stripe_size_units, 0);
+
+ return ret;
+}
+
+static int find_check_ext_size(struct find_param *param)
+{
+ struct lov_comp_md_v1 *comp_v1;
+ struct lov_user_md_v1 *v1;
+ int ret, i;
+
+ ret = param->fp_exclude_ext_size ? 1 : -1;
+ comp_v1 = (struct lov_comp_md_v1 *)¶m->fp_lmd->lmd_lmm;
+ if (comp_v1->lcm_magic != LOV_USER_MAGIC_COMP_V1)
+ return ret;
+
+ for (i = 0; i < comp_v1->lcm_entry_count; i++) {
+ struct lov_comp_md_entry_v1 *ent;
+
+ v1 = lov_comp_entry(comp_v1, i);
+
+ ent = &comp_v1->lcm_entries[i];
+ if (!(ent->lcme_flags & LCME_FL_EXTENSION))
+ continue;
+
+ ret = find_value_cmp(v1->lmm_stripe_size, param->fp_ext_size,
+ param->fp_ext_size_sign,
+ param->fp_exclude_ext_size,
+ param->fp_ext_size_units, 0);
+ /* If any ext_size matches */
if (ret != -1)
break;
}
int i, count = 1;
__u32 stripe_count = 0;
+ if (v1->lmm_magic == LOV_USER_MAGIC_FOREIGN)
+ return 0;
+
if (v1->lmm_magic == LOV_USER_MAGIC_COMP_V1) {
comp_v1 = (struct lov_comp_md_v1 *)v1;
count = comp_v1->lcm_entry_count;
}
for (i = 0; i < count; i++) {
- if (comp_v1)
+ if (comp_v1) {
+ struct lov_comp_md_entry_v1 *ent;
+
v1 = lov_comp_entry(comp_v1, i);
- stripe_count += v1->lmm_stripe_count;
+
+ ent = &comp_v1->lcm_entries[i];
+ if (!(ent->lcme_flags & LCME_FL_INIT))
+ continue;
+
+ if (ent->lcme_flags & LCME_FL_EXTENSION)
+ continue;
+ }
+ stripe_count = v1->lmm_stripe_count;
}
return stripe_count;
if (comp_v1)
v1 = lov_comp_entry(comp_v1, i);
+ /* foreign file have a special magic but no pattern field */
+ if (v1->lmm_magic == LOV_USER_MAGIC_FOREIGN)
+ continue;
+
if (v1->lmm_pattern == LOV_PATTERN_INVALID)
continue;
return -1;
}
+/* if no type specified, check/exclude all foreign
+ * if type specified, check all foreign&type and exclude !foreign + foreign&type
+ */
+static int find_check_foreign(struct find_param *param)
+{
+ if (S_ISREG(param->fp_lmd->lmd_stx.stx_mode)) {
+ struct lov_foreign_md *lfm;
+
+ lfm = (void *)¶m->fp_lmd->lmd_lmm;
+ if (lfm->lfm_magic != LOV_USER_MAGIC_FOREIGN) {
+ if (param->fp_foreign_type == LU_FOREIGN_TYPE_UNKNOWN)
+ return param->fp_exclude_foreign ? 1 : -1;
+ return -1;
+ } else {
+ if (param->fp_foreign_type == LU_FOREIGN_TYPE_UNKNOWN ||
+ lfm->lfm_type == param->fp_foreign_type)
+ return param->fp_exclude_foreign ? -1 : 1;
+ return param->fp_exclude_foreign ? 1 : -1;
+ }
+ }
+
+ if (S_ISDIR(param->fp_lmd->lmd_stx.stx_mode)) {
+ struct lmv_foreign_md *lfm;
+
+ lfm = (void *)param->fp_lmv_md;
+ if (lfm->lfm_magic != LMV_MAGIC_FOREIGN) {
+ if (param->fp_foreign_type == LU_FOREIGN_TYPE_UNKNOWN)
+ return param->fp_exclude_foreign ? 1 : -1;
+ return -1;
+ } else {
+ if (param->fp_foreign_type == LU_FOREIGN_TYPE_UNKNOWN ||
+ lfm->lfm_type == param->fp_foreign_type)
+ return param->fp_exclude_foreign ? -1 : 1;
+ return param->fp_exclude_foreign ? 1 : -1;
+ }
+ }
+ return -1;
+}
+
static int find_check_pool(struct find_param *param)
{
struct lov_comp_md_v1 *comp_v1 = NULL;
if (comp_v1 != NULL)
v1 = lov_comp_entry(comp_v1, i);
+ if (v1->lmm_magic == LOV_USER_MAGIC_FOREIGN)
+ continue;
+
if (((v1->lmm_magic == LOV_USER_MAGIC_V1) &&
(param->fp_poolname[0] == '\0')) ||
((v1->lmm_magic == LOV_USER_MAGIC_V3) &&
static int find_check_comp_options(struct find_param *param)
{
- lstat_t *st = ¶m->fp_lmd->lmd_st;
+ lstatx_t *stx = ¶m->fp_lmd->lmd_stx;
struct lov_comp_md_v1 *comp_v1, *forged_v1 = NULL;
struct lov_user_md_v1 *v1 = ¶m->fp_lmd->lmd_lmm;
struct lov_comp_md_entry_v1 *entry;
int i, ret = 0;
+ if (v1->lmm_magic == LOV_USER_MAGIC_FOREIGN)
+ return -1;
+
if (v1->lmm_magic == LOV_USER_MAGIC_COMP_V1) {
comp_v1 = (struct lov_comp_md_v1 *)v1;
} else {
comp_v1 = forged_v1;
comp_v1->lcm_entry_count = 1;
entry = &comp_v1->lcm_entries[0];
- entry->lcme_flags = S_ISDIR(st->st_mode) ? 0 : LCME_FL_INIT;
+ entry->lcme_flags = S_ISDIR(stx->stx_mode) ? 0 : LCME_FL_INIT;
entry->lcme_extent.e_start = 0;
entry->lcme_extent.e_end = LUSTRE_EOF;
}
break;
}
out:
- if (forged_v1 != NULL)
+ if (forged_v1)
free(forged_v1);
return ret;
}
param->fp_check_stripe_size || param->fp_check_layout ||
param->fp_check_comp_count || param->fp_check_comp_end ||
param->fp_check_comp_start || param->fp_check_comp_flags ||
- param->fp_check_mirror_count ||
- param->fp_check_mirror_state ||
+ param->fp_check_mirror_count || param->fp_check_foreign ||
+ param->fp_check_mirror_state || param->fp_check_ext_size ||
param->fp_check_projid;
}
struct find_param *param = (struct find_param *)data;
DIR *dir = dirp == NULL ? NULL : *dirp;
int decision = 1; /* 1 is accepted; -1 is rejected. */
- lstat_t *st = ¶m->fp_lmd->lmd_st;
+ lstatx_t *stx = ¶m->fp_lmd->lmd_stx;
int lustre_fs = 1;
int checked_type = 0;
int ret = 0;
__u32 stripe_count = 0;
+ __u64 flags;
int fd = -2;
if (parent == NULL && dir == NULL)
decision = 0;
if (decision == 0) {
- if (param->fp_check_mdt_count || param->fp_check_hash_type) {
+ if (dir && (param->fp_check_mdt_count ||
+ param->fp_check_hash_type || param->fp_check_foreign)) {
param->fp_get_lmv = 1;
ret = cb_get_dirstripe(path, dir, param);
- if (ret != 0)
+ if (ret != 0) {
+ /* XXX this works to decide for foreign
+ * criterion only
+ */
+ if (errno == ENODATA &&
+ param->fp_check_foreign) {
+ if (param->fp_exclude_foreign)
+ goto foreign;
+ goto decided;
+ }
return ret;
+ }
}
param->fp_lmd->lmd_lmm.lmm_magic = 0;
if (dir != NULL) {
ret = llapi_file_fget_mdtidx(dirfd(dir),
¶m->fp_file_mdt_index);
- } else if (S_ISREG(st->st_mode)) {
+ } else if (S_ISREG(stx->stx_mode)) {
/* FIXME: we could get the MDT index from the
* file's FID in lmd->lmd_lmm.lmm_oi without
* opening the file, once we are sure that
}
if (param->fp_type && !checked_type) {
- if ((st->st_mode & S_IFMT) == param->fp_type) {
+ if ((stx->stx_mode & S_IFMT) == param->fp_type) {
if (param->fp_exclude_type)
goto decided;
} else {
/* Prepare odb. */
if (param->fp_obd_uuid || param->fp_mdt_uuid) {
if (lustre_fs && param->fp_got_uuids &&
- param->fp_dev != st->st_dev) {
+ param->fp_dev != makedev(stx->stx_dev_major,
+ stx->stx_dev_minor)) {
/* A lustre/lustre mount point is crossed. */
param->fp_got_uuids = 0;
param->fp_obds_printed = 0;
if (ret)
goto out;
- param->fp_dev = st->st_dev;
+ param->fp_dev = makedev(stx->stx_dev_major,
+ stx->stx_dev_minor);
} else if (!lustre_fs && param->fp_got_uuids) {
/* A lustre/non-lustre mount point is crossed. */
param->fp_got_uuids = 0;
}
}
+ if (param->fp_check_foreign) {
+ decision = find_check_foreign(param);
+ if (decision == -1)
+ goto decided;
+ }
+
if (param->fp_check_stripe_size) {
decision = find_check_stripe_size(param);
if (decision == -1)
goto decided;
}
+ if (param->fp_check_ext_size) {
+ decision = find_check_ext_size(param);
+ if (decision == -1)
+ goto decided;
+ }
+
if (param->fp_check_stripe_count) {
decision = find_value_cmp(stripe_count, param->fp_stripe_count,
param->fp_stripe_count_sign,
}
if (param->fp_check_mdt_count) {
+ if (param->fp_lmv_md->lum_magic == LMV_MAGIC_FOREIGN) {
+ decision = -1;
+ goto decided;
+ }
+
decision = find_value_cmp(
param->fp_lmv_md->lum_stripe_count,
param->fp_mdt_count,
if (param->fp_check_hash_type) {
__u32 found;
+ if (param->fp_lmv_md->lum_magic == LMV_MAGIC_FOREIGN) {
+ decision = -1;
+ goto decided;
+ }
+
found = param->fp_lmv_md->lum_hash_type & param->fp_hash_type;
if ((found && param->fp_exclude_hash_type) ||
(!found && !param->fp_exclude_hash_type)) {
obd_matches:
if (param->fp_check_uid) {
- if (st->st_uid == param->fp_uid) {
+ if (stx->stx_uid == param->fp_uid) {
if (param->fp_exclude_uid)
goto decided;
} else {
}
if (param->fp_check_gid) {
- if (st->st_gid == param->fp_gid) {
+ if (stx->stx_gid == param->fp_gid) {
if (param->fp_exclude_gid)
goto decided;
} else {
int for_mds;
for_mds = lustre_fs ?
- (S_ISREG(st->st_mode) && stripe_count) : 0;
- decision = find_time_check(st, param, for_mds);
- if (decision == -1)
- goto decided;
- }
+ (S_ISREG(stx->stx_mode) && stripe_count) : 0;
+ decision = find_time_check(stx, param, for_mds);
+ if (decision == -1)
+ goto decided;
+ }
- /* If file still fits the request, ask ost for updated info.
- The regular stat is almost of the same speed as some new
- 'glimpse-size-ioctl'. */
+ flags = param->fp_lmd->lmd_flags;
+ if (param->fp_check_size &&
+ ((S_ISREG(stx->stx_mode) && stripe_count) ||
+ S_ISDIR(stx->stx_mode)) &&
+ !(flags & OBD_MD_FLSIZE ||
+ (param->fp_lazy && flags & OBD_MD_FLLAZYSIZE)))
+ decision = 0;
- if ((param->fp_check_size || param->fp_check_blocks) &&
- ((S_ISREG(st->st_mode) && stripe_count) || S_ISDIR(st->st_mode)))
+ if (param->fp_check_blocks &&
+ ((S_ISREG(stx->stx_mode) && stripe_count) ||
+ S_ISDIR(stx->stx_mode)) &&
+ !(flags & OBD_MD_FLBLOCKS ||
+ (param->fp_lazy && flags & OBD_MD_FLLAZYBLOCKS)))
decision = 0;
+ /* If file still fits the request, ask ost for updated info.
+ * The regular stat is almost of the same speed as some new
+ * 'glimpse-size-ioctl'.
+ */
if (!decision) {
+ lstat_t st;
+
/* For regular files with the stripe the decision may have not
* been taken yet if *time or size is to be checked. */
if (param->fp_obd_index != OBD_NOT_FOUND)
print_failed_tgt(param, path, LL_STATFS_LMV);
if (dir != NULL)
- ret = fstat_f(dirfd(dir), st);
+ ret = fstat_f(dirfd(dir), &st);
else if (de != NULL)
- ret = fstatat_f(dirfd(parent), de->d_name, st,
+ ret = fstatat_f(dirfd(parent), de->d_name, &st,
AT_SYMLINK_NOFOLLOW);
else
- ret = lstat_f(path, st);
-
- if (ret) {
- if (errno == ENOENT) {
- llapi_error(LLAPI_MSG_ERROR, -ENOENT,
- "warning: %s: %s does not exist",
- __func__, path);
- goto decided;
- } else {
+ ret = lstat_f(path, &st);
+
+ if (ret) {
+ if (errno == ENOENT) {
+ llapi_error(LLAPI_MSG_ERROR, -ENOENT,
+ "warning: %s: %s does not exist",
+ __func__, path);
+ goto decided;
+ } else {
ret = -errno;
llapi_error(LLAPI_MSG_ERROR, ret,
- "%s: IOC_LOV_GETINFO on %s failed",
+ "%s: stat on %s failed",
__func__, path);
goto out;
}
}
+ convert_lmd_statx(param->fp_lmd, &st, true);
/* Check the time on osc. */
- decision = find_time_check(st, param, 0);
+ decision = find_time_check(stx, param, 0);
if (decision == -1)
goto decided;
}
if (param->fp_check_size) {
- decision = find_value_cmp(st->st_size, param->fp_size,
+ decision = find_value_cmp(stx->stx_size, param->fp_size,
param->fp_size_sign,
param->fp_exclude_size,
param->fp_size_units, 0);
}
if (param->fp_check_blocks) { /* convert st_blocks to bytes */
- decision = find_value_cmp(st->st_blocks * 512, param->fp_blocks,
+ decision = find_value_cmp(stx->stx_blocks * 512,
+ param->fp_blocks,
param->fp_blocks_sign,
param->fp_exclude_blocks,
param->fp_blocks_units, 0);
goto decided;
}
+foreign:
llapi_printf(LLAPI_MSG_NORMAL, "%s", path);
if (param->fp_zero_end)
llapi_printf(LLAPI_MSG_NORMAL, "%c", '\0');
/* Is this a lustre fs? */
int llapi_is_lustre_mnttype(const char *type)
{
- return (strcmp(type, "lustre") == 0 || strcmp(type,"lustre_lite") == 0);
+ return strcmp(type, "lustre") == 0 || strcmp(type, "lustre_tgt") == 0;
}
/* Is this a lustre client fs? */
int flags)
{
char mntdir[PATH_MAX];
- char path[PATH_MAX];
+ char path[PATH_MAX + 64];
int rc;
rc = llapi_search_mounts(lustre_dir, 0, mntdir, NULL);