X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Fliblustreapi.c;h=754536f1178dbaacacbf7fccfb7f0aa26f1f8bd9;hp=d21f8dafb5d62665c76e06e34d6e780b5812d5a6;hb=c1d0a355a6a64ec97c9f56c38ba036e5e50cd8c4;hpb=fdad38781cccb05c4cf3f1458c2d2d7c8b2b5bec diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index d21f8da..754536f 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include /* for dirname() */ @@ -69,6 +70,7 @@ #endif #include #include +#include #include #include @@ -84,7 +86,8 @@ const char *liblustreapi_cmd; 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"}, @@ -384,45 +387,52 @@ int llapi_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len) 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, @@ -530,87 +540,6 @@ int llapi_get_agent_uuid(char *path, char *buf, size_t bufsize) 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. * @@ -680,7 +609,7 @@ int llapi_file_open_param(const char *name, int flags, mode_t mode, /* 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; @@ -814,32 +743,35 @@ int llapi_file_create_foreign(const char *name, mode_t mode, __u32 type, int fd, rc; if (foreign_lov == NULL) { - llapi_error(LLAPI_MSG_ERROR, -EINVAL, + rc = -EINVAL; + llapi_error(LLAPI_MSG_ERROR, rc, "foreign LOV EA content must be provided"); - return -EINVAL; + goto out_err; } len = strlen(foreign_lov); if (len > XATTR_SIZE_MAX - offsetof(struct lov_foreign_md, lfm_value) || len <= 0) { - llapi_error(LLAPI_MSG_ERROR, -EINVAL, + 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)); - return -EINVAL; + goto out_err; } lfm = malloc(len + offsetof(struct lov_foreign_md, lfm_value)); if (lfm == NULL) { - llapi_error(LLAPI_MSG_ERROR, -ENOMEM, + rc = -ENOMEM; + llapi_error(LLAPI_MSG_ERROR, rc, "failed to allocate lov_foreign_md"); - return -ENOMEM; + goto out_err; } fd = open(name, O_WRONLY|O_CREAT|O_LOV_DELAY_CREATE, mode); if (fd == -1) { - perror("open()"); - rc = -errno; + fd = -errno; + llapi_error(LLAPI_MSG_ERROR, fd, "open '%s' failed", name); goto out_free; } @@ -851,21 +783,18 @@ int llapi_file_create_foreign(const char *name, mode_t mode, __u32 type, if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, lfm) != 0) { char *errmsg = "stripe already set"; - char fsname[MAX_OBD_NAME + 1] = { 0 }; rc = -errno; - if (errno != EEXIST && errno != EALREADY) + 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); - /* Make sure we are on a Lustre file system */ - if (rc == -ENOTTY && llapi_search_fsname(name, fsname)) - llapi_error(LLAPI_MSG_ERROR, rc, - "'%s' is not on a Lustre filesystem", - name); - close(fd); fd = rc; } @@ -874,6 +803,10 @@ out_free: free(lfm); return fd; + +out_err: + errno = -rc; + return rc; } int llapi_file_create(const char *name, unsigned long long stripe_size, @@ -961,7 +894,7 @@ static int verify_dir_param(const char *name, /* 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; @@ -1219,7 +1152,7 @@ int llapi_dir_create_foreign(const char *name, mode_t mode, __u32 type, lfm->lfm_length = len; lfm->lfm_type = type; lfm->lfm_flags = flags; - strncpy(lfm->lfm_value, value, len); + memcpy(lfm->lfm_value, value, len); filename = basename(namepath); dir = dirname(dirpath); @@ -1329,6 +1262,7 @@ int get_root_path(int want, char *fsname, int *outfd, char *path, int index) FILE *fp; int idx = 0, len = 0, mntlen, fd; int rc = -ENODEV; + int fsnamelen, mountlen; /* get the mount point */ fp = setmntent(PROC_MOUNTS, "r"); @@ -1362,30 +1296,32 @@ int get_root_path(int want, char *fsname, int *outfd, char *path, int index) 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; } @@ -1395,7 +1331,7 @@ int get_root_path(int want, char *fsname, int *outfd, char *path, int index) /* 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) { @@ -1518,6 +1454,9 @@ int llapi_search_fsname(const char *pathname, char *fsname) 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); } @@ -1651,47 +1590,45 @@ int llapi_get_poolmembers(const char *poolname, char **members, 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); @@ -1864,10 +1801,11 @@ static int common_param_init(struct find_param *param, char *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; } @@ -1976,11 +1914,74 @@ again: 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) @@ -1993,11 +1994,24 @@ int get_lmd_info_fd(char *path, int parent_fd, int dir_fd, * 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, @@ -2017,24 +2031,48 @@ int get_lmd_info_fd(char *path, int parent_fd, int dir_fd, 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, @@ -2116,12 +2154,12 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent, 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; @@ -2683,12 +2721,15 @@ int sattr_cache_get_defaults(const char *const fsname, 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"; } @@ -2699,6 +2740,7 @@ enum lov_dump_flags { 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, @@ -2712,6 +2754,7 @@ 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 ? " " : ""; @@ -2769,10 +2812,10 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, 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) { @@ -2795,12 +2838,12 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, " 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) @@ -2809,9 +2852,13 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, 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) { @@ -2825,8 +2872,11 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, "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 = " "; @@ -3061,8 +3111,6 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name, 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) @@ -3244,7 +3292,7 @@ static void lov_dump_comp_v1_entry(struct find_param *param, "%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)); @@ -3262,7 +3310,7 @@ static void lov_dump_comp_v1_entry(struct find_param *param, 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"; } @@ -3275,7 +3323,7 @@ static void lov_dump_comp_v1_entry(struct find_param *param, 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"; } @@ -3463,7 +3511,7 @@ static void lov_dump_comp_v1(struct find_param *param, char *path, 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; @@ -3560,8 +3608,15 @@ static void lov_dump_comp_v1(struct find_param *param, char *path, */ 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) { @@ -3591,9 +3646,10 @@ static void lov_dump_comp_v1(struct find_param *param, char *path, 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)) { /** @@ -3612,9 +3668,11 @@ static void lov_dump_comp_v1(struct find_param *param, char *path, 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); } } @@ -3649,13 +3707,14 @@ struct lov_user_mds_data *lov_forge_comp_v1(struct lov_user_mds_data *orig, 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; @@ -3926,14 +3985,14 @@ int llapi_file_lookup(int dirfd, const char *name) * * 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) @@ -3942,7 +4001,7 @@ static int find_time_check(lstat_t *st, struct find_param *param, int mds) } 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) @@ -3955,7 +4014,7 @@ static int find_time_check(lstat_t *st, struct find_param *param, int mds) } 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) @@ -3980,13 +4039,13 @@ static int check_obd_match(struct find_param *param) 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 */ @@ -4073,26 +4132,66 @@ static int find_check_stripe_size(struct find_param *param) { 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; } @@ -4116,9 +4215,19 @@ static __u32 find_get_stripe_count(struct find_param *param) } 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; @@ -4171,7 +4280,7 @@ static int find_check_layout(struct find_param *param) */ static int find_check_foreign(struct find_param *param) { - if (S_ISREG(param->fp_lmd->lmd_st.st_mode)) { + if (S_ISREG(param->fp_lmd->lmd_stx.stx_mode)) { struct lov_foreign_md *lfm; lfm = (void *)¶m->fp_lmd->lmd_lmm; @@ -4187,7 +4296,7 @@ static int find_check_foreign(struct find_param *param) } } - if (S_ISDIR(param->fp_lmd->lmd_st.st_mode)) { + if (S_ISDIR(param->fp_lmd->lmd_stx.stx_mode)) { struct lmv_foreign_md *lfm; lfm = (void *)param->fp_lmv_md; @@ -4249,7 +4358,7 @@ static int find_check_pool(struct find_param *param) 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; @@ -4267,7 +4376,7 @@ static int find_check_comp_options(struct find_param *param) 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; } @@ -4367,7 +4476,7 @@ static bool find_check_lmm_info(struct find_param *param) 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_foreign || - param->fp_check_mirror_state || + param->fp_check_mirror_state || param->fp_check_ext_size || param->fp_check_projid; } @@ -4395,11 +4504,12 @@ static int cb_find_init(char *path, DIR *parent, DIR **dirp, 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) @@ -4484,7 +4594,7 @@ static int cb_find_init(char *path, DIR *parent, DIR **dirp, 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 @@ -4518,7 +4628,7 @@ static int cb_find_init(char *path, DIR *parent, DIR **dirp, } 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 { @@ -4530,7 +4640,8 @@ static int cb_find_init(char *path, DIR *parent, DIR **dirp, /* 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; @@ -4544,7 +4655,8 @@ static int cb_find_init(char *path, DIR *parent, DIR **dirp, 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; @@ -4565,6 +4677,12 @@ static int cb_find_init(char *path, DIR *parent, DIR **dirp, 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, @@ -4640,7 +4758,7 @@ static int cb_find_init(char *path, DIR *parent, DIR **dirp, 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 { @@ -4650,7 +4768,7 @@ obd_matches: } 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 { @@ -4705,21 +4823,34 @@ obd_matches: 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) @@ -4729,36 +4860,37 @@ obd_matches: 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); @@ -4767,7 +4899,8 @@ obd_matches: } 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); @@ -5074,7 +5207,7 @@ static int cb_getstripe(char *path, DIR *parent, DIR **dirp, void *data, lum->lum_magic = LMV_USER_MAGIC; lum->lum_stripe_count = 0; - lum->lum_stripe_offset = -1; + lum->lum_stripe_offset = LMV_OFFSET_DEFAULT; goto dump; } else if (param->fp_get_lmv) { struct lmv_user_md *lum = param->fp_lmv_md; @@ -5331,7 +5464,7 @@ int llapi_target_check(int type_num, char **obd_type, char *dir) /* 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? */ @@ -5949,7 +6082,7 @@ int llapi_open_by_fid(const char *lustre_dir, const struct lu_fid *fid, 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);