From 742ca2d5686cb55a7dd939f04d4514677baae793 Mon Sep 17 00:00:00 2001 From: nathan Date: Fri, 22 Aug 2008 17:41:15 +0000 Subject: [PATCH] b=15899 i=nathan i=adilger add OST pools --- lustre/utils/liblustreapi.c | 559 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 445 insertions(+), 114 deletions(-) diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 015c422..f16a740 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -58,7 +58,9 @@ #include #include #include +#include #include +#include #ifdef HAVE_ASM_TYPES_H #include #endif @@ -217,27 +219,11 @@ int parse_size(char *optarg, unsigned long long *size, return 0; } -int llapi_file_open(const char *name, int flags, int mode, - unsigned long stripe_size, int stripe_offset, - int stripe_count, int stripe_pattern) +int llapi_stripe_limit_check(unsigned long stripe_size, int stripe_offset, + int stripe_count, int stripe_pattern) { - struct lov_user_md lum = { 0 }; - int fd, rc = 0; - int isdir = 0; int page_size; - fd = open(name, flags | O_LOV_DELAY_CREATE, mode); - if (fd < 0 && errno == EISDIR) { - fd = open(name, O_DIRECTORY | O_RDONLY); - isdir++; - } - - if (fd < 0) { - rc = -errno; - llapi_err(LLAPI_MSG_ERROR, "unable to open '%s'", name); - return rc; - } - /* 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; @@ -249,29 +235,53 @@ int llapi_file_open(const char *name, int flags, int mode, LOV_MIN_STRIPE_SIZE); } if (stripe_size < 0 || (stripe_size & (LOV_MIN_STRIPE_SIZE - 1))) { - errno = rc = -EINVAL; llapi_err(LLAPI_MSG_ERROR, "error: bad stripe_size %lu, " "must be an even multiple of %d bytes", stripe_size, page_size); - goto out; + return -EINVAL; } if (stripe_offset < -1 || stripe_offset > MAX_OBD_DEVICES) { - errno = rc = -EINVAL; llapi_err(LLAPI_MSG_ERROR, "error: bad stripe offset %d", stripe_offset); - goto out; + return -EINVAL; } if (stripe_count < -1 || stripe_count > LOV_MAX_STRIPE_COUNT) { - errno = rc = -EINVAL; llapi_err(LLAPI_MSG_ERROR, "error: bad stripe count %d", stripe_count); - goto out; + return -EINVAL; } if (stripe_count > 0 && (__u64)stripe_size * stripe_count > 0xffffffff){ - errno = rc = -EINVAL; llapi_err(LLAPI_MSG_ERROR, "error: stripe_size %lu * " "stripe_count %u exceeds 4GB", stripe_size, stripe_count); + return -EINVAL; + } + return 0; +} + +int llapi_file_open(const char *name, int flags, int mode, + unsigned long stripe_size, int stripe_offset, + int stripe_count, int stripe_pattern) +{ + struct lov_user_md lum = { 0 }; + int fd, rc = 0; + int isdir = 0; + + fd = open(name, flags | O_LOV_DELAY_CREATE, mode); + if (fd < 0 && errno == EISDIR) { + fd = open(name, O_DIRECTORY | O_RDONLY); + isdir++; + } + + if (fd < 0) { + rc = -errno; + llapi_err(LLAPI_MSG_ERROR, "unable to open '%s'", name); + return rc; + } + + if ((rc = llapi_stripe_limit_check(stripe_size, stripe_offset, + stripe_count, stripe_pattern)) != 0) { + errno = rc; goto out; } @@ -301,6 +311,74 @@ out: return fd; } +static int poolpath(char *fsname, char *pathname, char *pool_pathname); + +int llapi_file_open_pool(const char *name, int flags, int mode, + unsigned long stripe_size, int stripe_offset, + int stripe_count, int stripe_pattern, char *pool_name) +{ + struct lov_user_md_v3 lum = { 0 }; + int fd, rc = 0; + int isdir = 0; + char fsname[MAX_OBD_NAME + 1], *ptr; + + fd = open(name, flags | O_LOV_DELAY_CREATE, mode); + if (fd < 0 && errno == EISDIR) { + fd = open(name, O_DIRECTORY | O_RDONLY); + isdir++; + } + + if (fd < 0) { + rc = -errno; + llapi_err(LLAPI_MSG_ERROR, "unable to open '%s'", name); + return rc; + } + + if ((rc = llapi_stripe_limit_check(stripe_size, stripe_offset, + stripe_count, stripe_pattern)) != 0) { + errno = rc; + goto out; + } + + /* in case user give the full pool name ., skip + * the fsname */ + ptr = strchr(pool_name, '.'); + if (ptr != NULL) { + strncpy(fsname, pool_name, ptr - pool_name); + fsname[ptr - pool_name] = '\0'; + /* if fsname matches a fs skip it + * if not keep the poolname as is */ + if (poolpath(fsname, NULL, NULL) == 0) + pool_name = ptr + 1; + } + + /* Initialize IOCTL striping pattern structure */ + lum.lmm_magic = LOV_USER_MAGIC_V3; + lum.lmm_pattern = stripe_pattern; + lum.lmm_stripe_size = stripe_size; + lum.lmm_stripe_count = stripe_count; + lum.lmm_stripe_offset = stripe_offset; + strncpy(lum.lmm_pool_name, pool_name, MAXPOOLNAME); + + if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, &lum)) { + char *errmsg = "stripe already set"; + rc = -errno; + if (errno != EEXIST && errno != EALREADY) + errmsg = strerror(errno); + + llapi_err_noerrno(LLAPI_MSG_ERROR, + "error on ioctl "LPX64" for '%s' (%d): %s", + (__u64)LL_IOC_LOV_SETSTRIPE, name, fd, errmsg); + } +out: + if (rc) { + close(fd); + fd = rc; + } + + return fd; +} + int llapi_file_create(const char *name, unsigned long stripe_size, int stripe_offset, int stripe_count, int stripe_pattern) { @@ -315,6 +393,202 @@ int llapi_file_create(const char *name, unsigned long stripe_size, return 0; } +int llapi_file_create_pool(const char *name, unsigned long stripe_size, + int stripe_offset, int stripe_count, + int stripe_pattern, char *pool_name) +{ + int fd; + + fd = llapi_file_open_pool(name, O_CREAT | O_WRONLY, 0644, stripe_size, + stripe_offset, stripe_count, stripe_pattern, + pool_name); + if (fd < 0) + return fd; + + close(fd); + return 0; +} + + +static int print_pool_members(char *fs, char *pool_dir, char *pool_file) +{ + char path[MAXPATHLEN + 1]; + char buf[1024]; + FILE *fd; + + llapi_printf(LLAPI_MSG_NORMAL, "Pool: %s.%s\n", fs, pool_file); + sprintf(path, "%s/%s", pool_dir, pool_file); + if ((fd = fopen(path, "r")) == NULL) { + llapi_err(LLAPI_MSG_ERROR, "Cannot open %s\n", path); + return -EINVAL; + } + while (fgets(buf, sizeof(buf), fd) != NULL) + llapi_printf(LLAPI_MSG_NORMAL, buf); + + fclose(fd); + return 0; +} + +/* + * search lustre fsname from pathname + * + */ +static int search_fsname(char *pathname, char *fsname) +{ + char *ptr; + FILE *fp; + struct mntent *mnt = NULL; + + /* get the mount point */ + fp = setmntent(MOUNTED, "r"); + if (fp == NULL) { + llapi_err(LLAPI_MSG_ERROR, + "setmntent(%s) failed: %s:", MOUNTED, + strerror (errno)); + return -EIO; + } + mnt = getmntent(fp); + while ((feof(fp) == 0) && ferror(fp) == 0) { + if (llapi_is_lustre_mnt(mnt)) { + /* search by pathname */ + if (strncmp(mnt->mnt_dir, pathname, + strlen(mnt->mnt_dir)) == 0) { + ptr = strchr(mnt->mnt_fsname, '/'); + if (ptr == NULL) + return -EINVAL; + ptr++; + strcpy(fsname, ptr); + return 0; + } + } + mnt = getmntent(fp); + } + endmntent(fp); + return -ENOENT; + +} + +/* + * find the pool directory path under /proc + * (can be also used to test if a fsname is known) + */ +static int poolpath(char *fsname, char *pathname, char *pool_pathname) +{ + int rc = 0; + glob_t glob_info; + char pattern[MAXPATHLEN + 1]; + char buffer[MAXPATHLEN]; + + if (fsname == NULL) { + rc = search_fsname(pathname, buffer); + if (rc != 0) + return rc; + fsname = buffer; + strcpy(pathname, fsname); + } + + snprintf(pattern, MAXPATHLEN, + "/proc/fs/lustre/lov/%s-*/pools", + fsname); + rc = glob(pattern, GLOB_BRACE, NULL, &glob_info); + if (rc) + return -ENOENT; + + if (glob_info.gl_pathc == 0) { + globfree(&glob_info); + return -ENOENT; + } + + /* in fsname test mode, pool_pathname is NULL */ + if (pool_pathname != NULL) + strcpy(pool_pathname, glob_info.gl_pathv[0]); + + return 0; +} + +int llapi_poollist(char *name) +{ + char *poolname; + char *fsname; + char rname[MAXPATHLEN + 1], pathname[MAXPATHLEN + 1]; + char *ptr; + int rc = 0; + + /* is name a pathname ? */ + ptr = strchr(name, '/'); + if (ptr != NULL) { + /* only absolute pathname is supported */ + if (*name != '/') + return -EINVAL; + if (!realpath(name, rname)) { + rc = -errno; + llapi_err(LLAPI_MSG_ERROR, + "llapi_poollist: invalid path '%s'", + name); + return rc; + } + + rc = poolpath(NULL, rname, pathname); + if (rc != 0) { + errno = -rc; + llapi_err(LLAPI_MSG_ERROR, + "llapi_poollist: '%s' is not" + " a Lustre filesystem", + name); + return rc; + } + fsname = rname; + poolname = NULL; + } else { + /* name is FSNAME[.POOLNAME] */ + fsname = name; + poolname = strchr(name, '.'); + if (poolname != NULL) { + *poolname = '\0'; + poolname++; + } + rc = poolpath(fsname, NULL, pathname); + if (rc != 0) { + errno = -rc; + llapi_err(LLAPI_MSG_ERROR, + "llapi_poollist: Lustre filesystem '%s'" + " not found", name); + return rc; + } + } + if (rc != 0) { + errno = -rc; + llapi_err(LLAPI_MSG_ERROR, + "llapi_poollist: Lustre filesystem '%s' not found", + name); + return rc; + } + + if (poolname != NULL) { + rc = print_pool_members(fsname, pathname, poolname); + poolname--; + *poolname = '.'; + } else { + DIR *dir; + struct dirent *pool; + + llapi_printf(LLAPI_MSG_NORMAL, "Pools from %s:\n", fsname); + if ((dir = opendir(pathname)) == NULL) { + return -EINVAL; + } + while ((pool = readdir(dir)) != NULL) { + if (!((pool->d_name[0] == '.') && + (pool->d_name[1] == '\0')) && + !((pool->d_name[0] == '.') && + (pool->d_name[1] == '.') && + (pool->d_name[2] == '\0'))) + llapi_printf(LLAPI_MSG_NORMAL, " %s.%s\n", fsname, pool->d_name); + } + closedir(dir); + } + return rc; +} + typedef int (semantic_func_t)(char *path, DIR *parent, DIR *d, void *data, struct dirent64 *de); @@ -323,7 +597,7 @@ typedef int (semantic_func_t)(char *path, DIR *parent, DIR *d, static int common_param_init(struct find_param *param) { - param->lumlen = lov_mds_md_size(MAX_LOV_UUID_COUNT); + param->lumlen = lov_mds_md_size(MAX_LOV_UUID_COUNT, LOV_MAGIC_V3); if ((param->lmd = malloc(sizeof(lstat_t) + param->lumlen)) == NULL) { llapi_err(LLAPI_MSG_ERROR, "error: allocation of %d bytes for ioctl", @@ -346,7 +620,7 @@ static void find_param_fini(struct find_param *param) free(param->lmd); } -int llapi_file_get_lov_fuuid(int fd, struct obd_uuid *lov_name) +int llapi_file_fget_lov_uuid(int fd, struct obd_uuid *lov_name) { int rc = ioctl(fd, OBD_IOC_GETNAME, lov_name); if (rc) { @@ -363,11 +637,11 @@ int llapi_file_get_lov_uuid(const char *path, struct obd_uuid *lov_uuid) fd = open(path, O_RDONLY); if (fd < 0) { rc = errno; - llapi_err(LLAPI_MSG_ERROR, "error opening %s\n", path); + llapi_err(LLAPI_MSG_ERROR, "error opening %s", path); return rc; } - rc = llapi_file_get_lov_fuuid(fd, lov_uuid); + rc = llapi_file_fget_lov_uuid(fd, lov_uuid); close(fd); @@ -388,7 +662,7 @@ int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count) int rc = 0, index = 0; /* Get the lov name */ - rc = llapi_file_get_lov_fuuid(fd, &lov_name); + rc = llapi_file_fget_lov_uuid(fd, &lov_name); if (rc) return rc; @@ -430,7 +704,7 @@ static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param) int rc = 0, index; /* Get the lov name */ - rc = llapi_file_get_lov_fuuid(dirfd(dir), &lov_uuid); + rc = llapi_file_fget_lov_uuid(dirfd(dir), &lov_uuid); if (rc) { if (errno != ENOTTY) { rc = errno; @@ -547,80 +821,9 @@ retry_get_uuids: return 0; } -void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *path, int is_dir, - int obdindex, int quiet, int header, int body) -{ - int i, obdstripe = 0; - - if (obdindex != OBD_NOT_FOUND) { - for (i = 0; !is_dir && i < lum->lmm_stripe_count; i++) { - if (obdindex == lum->lmm_objects[i].l_ost_idx) { - llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path); - obdstripe = 1; - break; - } - } - } else if (!quiet) { - llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path); - obdstripe = 1; - } - - /* if it's a directory */ - if (is_dir) { - if (obdstripe == 1) { - if (lum->lmm_object_gr == LOV_OBJECT_GROUP_DEFAULT) { - llapi_printf(LLAPI_MSG_NORMAL, "(Default) "); - lum->lmm_object_gr = LOV_OBJECT_GROUP_CLEAR; - } - llapi_printf(LLAPI_MSG_NORMAL, - "stripe_count: %d stripe_size: %u " - "stripe_offset: %d\n", - lum->lmm_stripe_count == (__u16)-1 ? -1 : - lum->lmm_stripe_count, - lum->lmm_stripe_size, - lum->lmm_stripe_offset == (__u16)-1 ? -1 : - lum->lmm_stripe_offset); - } - return; - } - - if (header && (obdstripe == 1)) { - llapi_printf(LLAPI_MSG_NORMAL, "lmm_magic: 0x%08X\n", - lum->lmm_magic); - llapi_printf(LLAPI_MSG_NORMAL, "lmm_object_gr: "LPX64"\n", - lum->lmm_object_gr); - llapi_printf(LLAPI_MSG_NORMAL, "lmm_object_id: "LPX64"\n", - lum->lmm_object_id); - llapi_printf(LLAPI_MSG_NORMAL, "lmm_stripe_count: %u\n", - (int)lum->lmm_stripe_count); - llapi_printf(LLAPI_MSG_NORMAL, "lmm_stripe_size: %u\n", - lum->lmm_stripe_size); - llapi_printf(LLAPI_MSG_NORMAL, "lmm_stripe_pattern: %x\n", - lum->lmm_pattern); - } - - if (body) { - if ((!quiet) && (obdstripe == 1)) - llapi_printf(LLAPI_MSG_NORMAL, - "\tobdidx\t\t objid\t\tobjid\t\t group\n"); - - for (i = 0; i < lum->lmm_stripe_count; i++) { - int idx = lum->lmm_objects[i].l_ost_idx; - long long oid = lum->lmm_objects[i].l_object_id; - long long gr = lum->lmm_objects[i].l_object_gr; - if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx)) - llapi_printf(LLAPI_MSG_NORMAL, - "\t%6u\t%14llu\t%#13llx\t%14llu%s\n", - idx, oid, oid, gr, - obdindex == idx ? " *" : ""); - } - llapi_printf(LLAPI_MSG_NORMAL, "\n"); - } -} - -void lov_dump_user_lmm_join(struct lov_user_md_v1 *lum, char *path, - int is_dir, int obdindex, int quiet, - int header, int body) +static void lov_dump_user_lmm_join(struct lov_user_md_v1 *lum, char *path, + int is_dir, int obdindex, int quiet, + int header, int body) { struct lov_user_md_join *lumj = (struct lov_user_md_join *)lum; int i, obdstripe = 0; @@ -688,15 +891,97 @@ void lov_dump_user_lmm_join(struct lov_user_md_v1 *lum, char *path, } } +static void lov_dump_user_lmm_v1v3(struct lov_user_md *lum, char *pool_name, + struct lov_user_ost_data_v1 *objects, + char *path, + int is_dir, int obdindex, int quiet, + int header, int body) +{ + int i, obdstripe = 0; + + if (obdindex != OBD_NOT_FOUND) { + for (i = 0; !is_dir && i < lum->lmm_stripe_count; i++) { + if (obdindex == objects[i].l_ost_idx) { + llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path); + obdstripe = 1; + break; + } + } + } else if (!quiet) { + llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path); + obdstripe = 1; + } + + /* if it's a directory */ + if (is_dir) { + if (obdstripe == 1) { + if (lum->lmm_object_gr == LOV_OBJECT_GROUP_DEFAULT) { + llapi_printf(LLAPI_MSG_NORMAL, "(Default) "); + lum->lmm_object_gr = LOV_OBJECT_GROUP_CLEAR; + } + llapi_printf(LLAPI_MSG_NORMAL, + "stripe_count: %d stripe_size: %u " + "stripe_offset: %d%s%s\n", + lum->lmm_stripe_count == (__u16)-1 ? -1 : + lum->lmm_stripe_count, + lum->lmm_stripe_size, + lum->lmm_stripe_offset == (__u16)-1 ? -1 : + lum->lmm_stripe_offset, + pool_name != NULL ? " pool: " : "", + pool_name != NULL ? pool_name : ""); + } + return; + } + + if (header && (obdstripe == 1)) { + llapi_printf(LLAPI_MSG_NORMAL, + "lmm_magic: 0x%08X\n", lum->lmm_magic); + llapi_printf(LLAPI_MSG_NORMAL, + "lmm_object_gr: "LPX64"\n", lum->lmm_object_gr); + llapi_printf(LLAPI_MSG_NORMAL, + "lmm_object_id: "LPX64"\n", lum->lmm_object_id); + llapi_printf(LLAPI_MSG_NORMAL, + "lmm_stripe_count: %u\n", (int)lum->lmm_stripe_count); + llapi_printf(LLAPI_MSG_NORMAL, + "lmm_stripe_size: %u\n", lum->lmm_stripe_size); + llapi_printf(LLAPI_MSG_NORMAL, + "lmm_stripe_pattern: %x\n", lum->lmm_pattern); + if (pool_name != NULL) + llapi_printf(LLAPI_MSG_NORMAL, + "lmm_pool_name: %s\n", pool_name); + } + + if (body) { + if ((!quiet) && (obdstripe == 1)) + llapi_printf(LLAPI_MSG_NORMAL, + "\tobdidx\t\t objid\t\tobjid\t\t group\n"); + + for (i = 0; i < lum->lmm_stripe_count; i++) { + int idx = objects[i].l_ost_idx; + long long oid = objects[i].l_object_id; + long long gr = objects[i].l_object_gr; + if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx)) + llapi_printf(LLAPI_MSG_NORMAL, + "\t%6u\t%14llu\t%#13llx\t%14llu%s\n", + idx, oid, oid, gr, + obdindex == idx ? " *" : ""); + } + llapi_printf(LLAPI_MSG_NORMAL, "\n"); + } +} + + void llapi_lov_dump_user_lmm(struct find_param *param, char *path, int is_dir) { switch(*(__u32 *)¶m->lmd->lmd_lmm) { /* lum->lmm_magic */ case LOV_USER_MAGIC_V1: - lov_dump_user_lmm_v1(¶m->lmd->lmd_lmm, path, is_dir, - param->obdindex, param->quiet, - param->verbose, - (param->verbose || !param->obduuid)); + lov_dump_user_lmm_v1v3(¶m->lmd->lmd_lmm, NULL, + param->lmd->lmd_lmm.lmm_objects, + path, is_dir, + param->obdindex, param->quiet, + param->verbose, + (param->verbose || !param->obduuid)); break; case LOV_USER_MAGIC_JOIN: lov_dump_user_lmm_join(¶m->lmd->lmd_lmm, path, is_dir, @@ -704,10 +989,28 @@ void llapi_lov_dump_user_lmm(struct find_param *param, param->verbose, (param->verbose || !param->obduuid)); break; + case LOV_USER_MAGIC_V3: { + char pool_name[MAXPOOLNAME + 1]; + struct lov_user_ost_data_v1 *objects; + + strncpy(pool_name, + ((struct lov_user_md_v3 *)(¶m->lmd->lmd_lmm))->lmm_pool_name, + MAXPOOLNAME); + pool_name[MAXPOOLNAME] = '\0'; + objects = ((struct lov_user_md_v3 *)(¶m->lmd->lmd_lmm))->lmm_objects; + lov_dump_user_lmm_v1v3(¶m->lmd->lmd_lmm, pool_name, + objects, path, is_dir, + param->obdindex, param->quiet, + param->verbose, + (param->verbose || !param->obduuid)); + break; + } default: - llapi_printf(LLAPI_MSG_NORMAL, - "unknown lmm_magic: %#x (expecting %#x)\n", - *(__u32 *)¶m->lmd->lmd_lmm, LOV_USER_MAGIC_V1); + llapi_printf(LLAPI_MSG_NORMAL, "unknown lmm_magic: %#x " + "(expecting one of %#x %#x %#x)\n", + *(__u32 *)¶m->lmd->lmd_lmm, + LOV_USER_MAGIC_V1, LOV_USER_MAGIC_JOIN, + LOV_USER_MAGIC_V3); return; } } @@ -792,7 +1095,8 @@ int llapi_mds_getfileinfo(char *path, DIR *parent, fname = (fname == NULL ? path : fname + 1); /* retrieve needed file info */ - strncpy((char *)lmd, fname, lov_mds_md_size(MAX_LOV_UUID_COUNT)); + strncpy((char *)lmd, fname, lov_mds_md_size(MAX_LOV_UUID_COUNT, + LOV_MAGIC)); ret = ioctl(dirfd(parent), IOC_MDC_GETFILEINFO, (void *)lmd); if (ret) { @@ -1134,6 +1438,23 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, } } + if (param->check_pool) { + /* empty requested pool is taken as no pool search => V1 */ + if (((param->lmd->lmd_lmm.lmm_magic == LOV_USER_MAGIC_V1) && + (param->poolname[0] == '\0')) || + ((param->lmd->lmd_lmm.lmm_magic == LOV_USER_MAGIC_V3) && + (strncmp(((struct lov_user_md_v3 *)(&(param->lmd->lmd_lmm)))->lmm_pool_name, + param->poolname, MAXPOOLNAME) == 0)) || + ((param->lmd->lmd_lmm.lmm_magic == LOV_USER_MAGIC_V3) && + (strcmp(param->poolname, "*") == 0))) { + if (param->exclude_pool) + goto decided; + } else { + if (!param->exclude_pool) + goto decided; + } + } + /* Check the time on mds. */ if (!decision) { int for_mds; @@ -1194,11 +1515,21 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, goto decided; } else { int i, j; + struct lov_user_ost_data_v1 *lmm_objects; + + if (param->lmd->lmd_lmm.lmm_magic == + LOV_USER_MAGIC_V3) { + lmm_objects = + ((struct lov_user_md_v3 *)(&(param->lmd->lmd_lmm)))->lmm_objects; + } else { + lmm_objects = param->lmd->lmd_lmm.lmm_objects; + } + for (i = 0; i < param->lmd->lmd_lmm.lmm_stripe_count; i++) { for (j = 0; j < param->num_obds; j++) { if (param->obdindexes[j] == - param->lmd->lmd_lmm.lmm_objects[i].l_ost_idx) + lmm_objects[i].l_ost_idx) goto obd_matches; } } -- 1.8.3.1