X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Fliblustreapi.c;h=754536f1178dbaacacbf7fccfb7f0aa26f1f8bd9;hp=59d02deb01396cbcc20761623c7616878acde2d1;hb=c1d0a355a6a64ec97c9f56c38ba036e5e50cd8c4;hpb=4eddf36ac3607c66c172668b30eb5dcf921e3de4 diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 59d02de..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() */ @@ -1261,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"); @@ -1294,18 +1296,20 @@ 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, 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; @@ -1316,8 +1320,8 @@ int get_root_path(int want, char *fsname, int *outfd, char *path, int index) 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; } @@ -1450,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); } @@ -1794,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; } @@ -1906,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) @@ -1923,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, @@ -1947,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, @@ -2046,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; @@ -3001,8 +3109,6 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name, 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_BAD_TYPE) @@ -3601,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; @@ -3878,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) @@ -3894,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) @@ -3907,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) @@ -3932,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 */ @@ -4173,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; @@ -4189,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; @@ -4251,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; @@ -4269,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; } @@ -4397,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) @@ -4486,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 @@ -4520,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 { @@ -4532,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; @@ -4546,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; @@ -4648,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 { @@ -4658,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 { @@ -4713,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) @@ -4737,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); @@ -4775,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); @@ -5082,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; @@ -5339,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? */