};
/**
+ * Different FID Format
+ * http://arch.lustre.org/index.php?title=Interoperability_fids_zfs#NEW.0
+ *
+ * FID:
+ * File IDentifier generated by client from range allocated by the seq service.
+ * First 0x400 sequences [2^33, 2^33 + 0x400] are reserved for system use. Note
+ * that on ldiskfs MDTs that IGIF FIDs can use inode numbers starting at 12,
+ * but this is in the IGIF SEQ rangeand does not conflict with assigned FIDs.
+ *
+ * IGIF:
+ * Inode and Generation In FID, a surrogate FID used to globally identify an
+ * existing object on OLD formatted MDT file system. This would only be used on
+ * MDT0 in a DNE filesystem, because there are not expected to be any OLD
+ * formatted DNE filesystems. Belongs to a sequence in [12, 2^32 - 1] range,
+ * where sequence number is inode number, and inode generation is used as OID.
+ * NOTE: This assumes no more than 2^32-1 inodes exist in the MDT filesystem,
+ * which is the maximum possible for an ldiskfs backend. NOTE: This assumes
+ * that the reserved ext3/ext4/ldiskfs inode numbers [0-11] are never visible
+ * to clients, which has always been true.
+ *
+ * IDIF:
+ * Object ID in FID, a surrogate FID used to globally identify an existing
+ * object on OLD formatted OST file system. Belongs to a sequence in
+ * [2^32, 2^33 - 1]. Sequence number is calculated as:
+ * 1 << 32 | (ost_index << 16) | ((objid >> 32) & 0xffff)
+ * that is, SEQ consists of 16-bit OST index, and higher 16 bits of object ID.
+ * The generation of unique SEQ values per OST allows the IDIF FIDs to be
+ * identified in the FLD correctly. The OID field is calculated as:
+ * objid & 0xffffffff
+ * that is, it consists of lower 32 bits of object ID. NOTE This assumes that
+ * no more than 2^48-1 objects have ever been created on an OST, and that no
+ * more than 65535 OSTs are in use. Both are very reasonable assumptions (can
+ * uniquely map all objects on an OST that created 1M objects per second for 9
+ * years, or combinations thereof).
+ *
+ * OST_MDT0:
+ * Surrogate FID used to identify an existing object on OLD formatted OST
+ * filesystem. Belongs to the reserved sequence 0, and is used internally prior
+ * to the introduction of FID-on-OST, at which point IDIF will be used to
+ * identify objects as residing on a specific OST.
+ *
+ * LLOG:
+ * For Lustre Log objects the object sequence 1 is used. This is compatible with
+ * both OLD and NEW.1 namespaces, as this SEQ number is in the ext3/ldiskfs
+ * reserved inode range and does not conflict with IGIF sequence numbers.
+ *
+ * ECHO:
+ * For testing OST IO performance the object sequence 2 is used. This is
+ * compatible with both OLD and NEW.1 namespaces, as this SEQ number is in the
+ * ext3/ldiskfs reserved inode range and does not conflict with IGIF sequence
+ * numbers.
+ *
+ * OST_MDT1 .. OST_MAX:
+ * For testing with multiple MDTs the object sequence 3 through 9 is used,
+ * allowing direct mapping of MDTs 1 through 7 respectively, for a total of 8
+ * MDTs including OST_MDT0. This matches the legacy CMD project "group"
+ * mappings. However, this SEQ range is only for testing prior to any production
+ * DNE release, as the objects in this range conflict across all OSTs, as the
+ * OST index is not part of the FID.
+ *
+ *
+ * For compatibility with existing OLD OST network protocol structures, the FID
+ * must map onto the o_id and o_gr in a manner that ensures existing objects are
+ * identified consistently for IO, as well as onto the lock namespace to ensure
+ * both IDIFs map onto the same objects for IO as well as resources in the DLM.
+ *
+ * DLM OLD OBIF/IDIF:
+ * resource[] = {o_id, o_seq, 0, 0}; // o_seq == 0 for production releases
+ *
+ * DLM NEW.1 FID (this is the same for both the MDT and OST):
+ * resource[] = {SEQ, OID, VER, HASH};
+ *
+ * Note that for mapping IDIF values to DLM resource names the o_id may be
+ * larger than the 2^33 reserved sequence numbers for IDIF, so it is possible
+ * for the o_id numbers to overlap FID SEQ numbers in the resource. However, in
+ * all production releases the OLD o_seq field is always zero, and all valid FID
+ * OID values are non-zero, so the lock resources will not collide.
+ *
+ * For objects within the IDIF range, group extraction (non-CMD) will be:
+ * o_id = (fid->f_seq & 0x7fff) << 16 | fid->f_oid;
+ * o_seq = 0; // formerly group number
+ */
+
+/**
* Note that reserved SEQ numbers below 12 will conflict with ldiskfs
* inodes in the IGIF namespace, so these reserved SEQ numbers can be
* used for other purposes and not risk collisions with existing inodes.
- *
- * Different FID Format
- * http://arch.lustre.org/index.php?title=Interoperability_fids_zfs#NEW.0
*/
enum fid_seq {
FID_SEQ_OST_MDT0 = 0,
oi->oi.oi_seq = fid_seq(fid);
}
+/**
+ * Unpack an OST object id/seq (group) into a FID. This is needed for
+ * converting all obdo, lmm, lsm, etc. 64-bit id/seq pairs into proper
+ * FIDs. Note that if an id/seq is already in FID/IDIF format it will
+ * be passed through unchanged. Only legacy OST objects in "group 0"
+ * will be mapped into the IDIF namespace so that they can fit into the
+ * struct lu_fid fields without loss.
+ */
+static inline int ostid_to_fid(struct lu_fid *fid, const struct ost_id *ostid,
+ __u32 ost_idx)
+{
+ __u64 seq = ostid_seq(ostid);
+
+ if (ost_idx > 0xffff) {
+ CERROR("bad ost_idx, "DOSTID" ost_idx:%u\n", POSTID(ostid),
+ ost_idx);
+ return -EBADF;
+ }
+
+ if (fid_seq_is_mdt0(seq)) {
+ __u64 oid = ostid_id(ostid);
+
+ /* This is a "legacy" (old 1.x/2.early) OST object in "group 0"
+ * that we map into the IDIF namespace. It allows up to 2^48
+ * objects per OST, as this is the object namespace that has
+ * been in production for years. This can handle create rates
+ * of 1M objects/s/OST for 9 years, or combinations thereof.
+ */
+ if (oid >= IDIF_MAX_OID) {
+ CERROR("bad MDT0 id(1), "DOSTID" ost_idx:%u\n",
+ POSTID(ostid), ost_idx);
+ return -EBADF;
+ }
+ fid->f_seq = fid_idif_seq(oid, ost_idx);
+ /* truncate to 32 bits by assignment */
+ fid->f_oid = oid;
+ /* in theory, not currently used */
+ fid->f_ver = oid >> 48;
+ } else if (!fid_seq_is_default(seq)) {
+ /* This is either an IDIF object, which identifies objects
+ * across all OSTs, or a regular FID. The IDIF namespace
+ * maps legacy OST objects into the FID namespace. In both
+ * cases, we just pass the FID through, no conversion needed.
+ */
+ if (ostid->oi_fid.f_ver) {
+ CERROR("bad MDT0 id(2), "DOSTID" ost_idx:%u\n",
+ POSTID(ostid), ost_idx);
+ return -EBADF;
+ }
+ *fid = ostid->oi_fid;
+ }
+
+ return 0;
+}
#endif
#define VERBOSE_DEFAULT (VERBOSE_COUNT | VERBOSE_SIZE | \
VERBOSE_OFFSET | VERBOSE_POOL | \
VERBOSE_OBJID | VERBOSE_GENERATION | \
- VERBOSE_LAYOUT | VERBOSE_HASH_TYPE)
+ VERBOSE_LAYOUT | VERBOSE_HASH_TYPE | \
+ VERBOSE_COMP_COUNT | VERBOSE_COMP_FLAGS | \
+ VERBOSE_COMP_START | VERBOSE_COMP_END | \
+ VERBOSE_COMP_ID)
struct find_param {
unsigned int fp_max_depth;
/* these need to be signed values */
int fp_size_sign:2,
fp_stripe_size_sign:2,
- fp_stripe_count_sign:2;
+ fp_stripe_count_sign:2,
+ fp_comp_start_sign:2,
+ fp_comp_end_sign:2,
+ fp_comp_count_sign:2;
unsigned long long fp_size;
unsigned long long fp_size_units;
- unsigned long fp_zero_end:1,
+ unsigned long long fp_zero_end:1,
fp_recursive:1,
fp_exclude_pattern:1,
fp_exclude_type:1,
fp_check_layout:1,
fp_exclude_layout:1,
fp_get_default_lmv:1, /* Get default LMV */
- fp_migrate:1;
+ fp_migrate:1,
+ fp_check_comp_count:1,
+ fp_exclude_comp_count:1,
+ fp_check_comp_flags:1,
+ fp_exclude_comp_flags:1,
+ fp_check_comp_start:1,
+ fp_exclude_comp_start:1,
+ fp_check_comp_end:1,
+ fp_exclude_comp_end:1,
+ fp_check_comp_id:1,
+ fp_exclude_comp_id:1;
int fp_verbose;
int fp_quiet;
unsigned long long fp_stripe_count;
__u32 fp_layout;
+ __u32 fp_comp_count;
+ __u32 fp_comp_flags;
+ __u32 fp_comp_id;
+ unsigned long long fp_comp_start;
+ unsigned long long fp_comp_start_units;
+ unsigned long long fp_comp_end;
+ unsigned long long fp_comp_end_units;
+
/* In-process parameters. */
unsigned long fp_got_uuids:1,
fp_obds_printed:1;
}
}
-/**
- * Unpack an OST object id/seq (group) into a FID. This is needed for
- * converting all obdo, lmm, lsm, etc. 64-bit id/seq pairs into proper
- * FIDs. Note that if an id/seq is already in FID/IDIF format it will
- * be passed through unchanged. Only legacy OST objects in "group 0"
- * will be mapped into the IDIF namespace so that they can fit into the
- * struct lu_fid fields without loss. For reference see:
- * http://arch.lustre.org/index.php?title=Interoperability_fids_zfs
- */
-static inline int ostid_to_fid(struct lu_fid *fid, const struct ost_id *ostid,
- u32 ost_idx)
-{
- u64 seq = ostid_seq(ostid);
-
- if (ost_idx > 0xffff) {
- CERROR("bad ost_idx, "DOSTID" ost_idx:%u\n", POSTID(ostid),
- ost_idx);
- return -EBADF;
- }
-
- if (fid_seq_is_mdt0(seq)) {
- u64 oid = ostid_id(ostid);
-
- /* This is a "legacy" (old 1.x/2.early) OST object in "group 0"
- * that we map into the IDIF namespace. It allows up to 2^48
- * objects per OST, as this is the object namespace that has
- * been in production for years. This can handle create rates
- * of 1M objects/s/OST for 9 years, or combinations thereof.
- */
- if (oid >= IDIF_MAX_OID) {
- CERROR("bad MDT0 id(1), "DOSTID" ost_idx:%u\n",
- POSTID(ostid), ost_idx);
- return -EBADF;
- }
- fid->f_seq = fid_idif_seq(oid, ost_idx);
- /* truncate to 32 bits by assignment */
- fid->f_oid = oid;
- /* in theory, not currently used */
- fid->f_ver = oid >> 48;
- } else if (likely(!fid_seq_is_default(seq))) {
- /* This is either an IDIF object, which identifies objects
- * across all OSTs, or a regular FID. The IDIF namespace
- * maps legacy OST objects into the FID namespace. In both
- * cases, we just pass the FID through, no conversion needed.
- */
- if (ostid->oi_fid.f_ver) {
- CERROR("bad MDT0 id(2), "DOSTID" ost_idx:%u\n",
- POSTID(ostid), ost_idx);
- return -EBADF;
- }
- *fid = ostid->oi_fid;
- }
-
- return 0;
-}
-
static inline void ost_fid_from_resid(struct lu_fid *fid,
const struct ldlm_res_id *name,
int ost_idx)
" [--stripe-index|-i <start_ost_idx>]\n" \
" [--stripe-size|-S <stripe_size>]\n" \
" [--pool|-p <pool_name>]\n" \
- " [--ost|-o <ost_indices>]\n"
+ " [--ost|-o <ost_indices>]\n" \
+ " [--component-end|-E <comp_end>]\n"
#define SSM_HELP_COMMON \
"\tstripe_size: Number of bytes on each OST (0 filesystem default)\n" \
"\t -o <ost_1>,<ost_i>-<ost_j>,<ost_n>\n" \
"\t Or:\n" \
"\t -o <ost_1> -o <ost_i>-<ost_j> -o <ost_n>\n" \
- "\t If --pool is set with --ost, then the OSTs\n" \
- "\t must be the members of the pool."
+ "\t If --pool is set with --ost, then the OSTs\n" \
+ "\t must be the members of the pool." \
+ "\tcomp_end: Extent end of the component\n" \
+ "\t Can be specified with k, m or g (in KB, MB and GB\n" \
+ "\t respectively, -1 for EOF), it must be aligned with\n"\
+ "\t the stripe_size\n"
#define SETSTRIPE_USAGE \
SSM_CMD_COMMON("setstripe") \
" <directory|filename>\n" \
- SSM_HELP_COMMON
+ SSM_HELP_COMMON \
#define MIGRATE_USAGE \
SSM_CMD_COMMON("migrate ") \
{"setstripe", lfs_setstripe, 0,
"Create a new file with a specific striping pattern or\n"
"set the default striping pattern on an existing directory or\n"
- "delete the default striping pattern from an existing directory\n"
- "usage: setstripe -d <directory> (to delete default striping)\n"\
+ "delete the default striping pattern from an existing directory or\n"
+ "add layout component(s) to an existing composite file or\n"
+ "delete specified component(s) from an existing composite file\n\n"
+ "To delete default striping from an existing directory:\n"
+ "usage: setstripe -d <directory>\n"
+ " or\n"
+ "To delete component(s) from an existing composite file:\n"
+ "usage: setstripe --component-del [--component-id|-I <comp_id>]\n"
+ " [--component-flags|-F <comp_flags>]\n"
+ " <filename>\n"
+ "\tcomp_id: Unique component ID\n"
+ "\tcomp_flags: 'init' indicating all instantiated components\n"
+ "\t-I and -F can't be specified at the same time\n"
+ " or\n"
+ "To add component(s) to an existing composite file:\n"
+ SSM_CMD_COMMON("setstripe --component-add")
" or\n"
+ "To create a file with specified striping/composite layout:\n"
SETSTRIPE_USAGE},
{"getstripe", lfs_getstripe, 0,
"To list the striping info for a given file or files in a\n"
" [--pool|-p] [--stripe-size|-S] [--directory|-d]\n"
" [--mdt|-m] [--recursive|-r] [--raw|-R]\n"
" [--layout|-L] [--fid|-F] [--generation|-g]\n"
+ " [--component-id|-I [comp_id]]\n"
+ " [--component-flags [comp_flags]]\n"
+ " [--component-count [comp_count]]\n"
+ " [--component-start [comp_start]]\n"
+ " [--component-end|-E [comp_end]]\n"
" <directory|filename> ..."},
{"setdirstripe", lfs_setdirstripe, 0,
"To create a striped directory on a specified MDT. This can only\n"
" [[!] --gid|-g|--group|-G <gid>|<gname>]\n"
" [[!] --uid|-u|--user|-U <uid>|<uname>] [[!] --pool <pool>]\n"
" [[!] --layout|-L released,raid0]\n"
+ " [[!] --component-count [+-]<comp_cnt>]\n"
+ " [[!] --component-start [+-]N[kMGTPE]]\n"
+ " [[!] --component-end|-E [+-]N[kMGTPE]]\n"
+ " [[!] --component-flags <comp_flags>]\n"
"\t !: used before an option indicates 'NOT' requested attribute\n"
"\t -: used before a value indicates 'AT MOST' requested value\n"
"\t +: used before a value indicates 'AT LEAST' requested value\n"},
return 0;
}
+static int lfs_component_set(char *fname, int comp_id, __u32 flags)
+{
+ return -ENOTSUP;
+}
+
+static int lfs_component_del(char *fname, __u32 comp_id, __u32 flags)
+{
+ int rc = 0;
+
+ if (flags != 0 && comp_id != 0)
+ return -EINVAL;
+
+ /* LCME_FL_INIT is the only supported flag in PFL */
+ if (flags != 0) {
+ if (flags & ~LCME_KNOWN_FLAGS) {
+ fprintf(stderr, "Invalid component flags %#x\n", flags);
+ return -EINVAL;
+ }
+ comp_id = LCME_ID_NONE | flags;
+ } else if (comp_id > LCME_ID_MAX) {
+ fprintf(stderr, "Invalid component id %u\n", comp_id);
+ return -EINVAL;
+ }
+
+ rc = llapi_layout_file_comp_del(fname, comp_id);
+ if (rc)
+ fprintf(stderr, "Delete component %#x from %s failed. %s\n",
+ comp_id, fname, strerror(errno));
+ return rc;
+}
+
+static int lfs_component_add(char *fname, struct llapi_layout *layout)
+{
+ int rc;
+
+ if (layout == NULL)
+ return -EINVAL;
+
+ rc = llapi_layout_file_comp_add(fname, layout);
+ if (rc)
+ fprintf(stderr, "Add layout component(s) to %s failed. %s\n",
+ fname, strerror(errno));
+ return rc;
+}
+
+static int lfs_component_create(char *fname, int open_flags, mode_t open_mode,
+ struct llapi_layout *layout)
+{
+ struct stat st;
+ int fd;
+
+ if (layout == NULL)
+ return -EINVAL;
+
+ fd = lstat(fname, &st);
+ if (fd == 0 && S_ISDIR(st.st_mode)) {
+ open_flags = O_DIRECTORY | O_RDONLY;
+ fd = llapi_layout_file_open(fname, open_flags, open_mode,
+ layout);
+ } else {
+ fd = llapi_layout_file_create(fname, open_flags, open_mode,
+ layout);
+ }
+
+ if (fd < 0)
+ fprintf(stderr, "%s %s failed. %s\n",
+ S_ISDIR(st.st_mode) ?
+ "Set default composite layout to " :
+ "Create composite file",
+ fname, strerror(errno));
+ return fd;
+}
+
static int lfs_migrate(char *name, __u64 migration_flags,
- struct llapi_stripe_param *param)
+ struct llapi_stripe_param *param,
+ struct llapi_layout *layout)
{
int fd = -1;
int fdv = -1;
int rc;
struct lov_user_md *lum = NULL;
int lum_size;
- int buf_size;
+ int buf_size = 1024 * 1024 * 4;
bool have_lease_rdlck = false;
struct stat st;
struct stat stv;
* (eg: no stripe)
* in case of a real error, a later call will fail with better
* error management */
- if (rc < 0)
- buf_size = 1024 * 1024;
- else
- buf_size = lum->lmm_stripe_size;
+ if (rc == 0) {
+ if ((lum->lmm_magic == LOV_USER_MAGIC_V1 ||
+ lum->lmm_magic == LOV_USER_MAGIC_V3) &&
+ lum->lmm_stripe_size != 0)
+ buf_size = lum->lmm_stripe_size;
+ }
/* open file, direct io */
/* even if the file is only read, WR mode is nedeed to allow
}
do {
+ int open_flags = O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW;
+ mode_t open_mode = S_IRUSR | S_IWUSR;
+
random_value = random();
rc = snprintf(volatile_file, sizeof(volatile_file),
"%s/%s:%.4X:%.4X", parent, LUSTRE_VOLATILE_HDR,
}
/* create, open a volatile file, use caching (ie no directio) */
- fdv = llapi_file_open_param(volatile_file,
- O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW,
- S_IRUSR | S_IWUSR, param);
+ if (param != NULL)
+ fdv = llapi_file_open_param(volatile_file, open_flags,
+ open_mode, param);
+ else if (layout != NULL)
+ fdv = lfs_component_create(volatile_file, open_flags,
+ open_mode, layout);
+ else
+ fdv = -EINVAL;
} while (fdv == -EEXIST);
if (fdv < 0) {
return rc < 0 ? rc : nr;
}
+static int verify_pool_name(char *prog_name, char *pool_name)
+{
+ char *ptr;
+ int rc;
+
+ if (pool_name == NULL)
+ return 0;
+
+ ptr = strchr(pool_name, '.');
+ if (ptr == NULL) {
+ ptr = pool_name;
+ } else {
+ if (ptr == pool_name) {
+ fprintf(stderr, "error: %s: fsname is empty "
+ "in pool name '%s'\n",
+ prog_name, pool_name);
+ return -EINVAL;
+ }
+ ++ptr;
+ }
+
+ rc = lustre_is_poolname_valid(ptr, 1, LOV_MAXPOOLNAME);
+ if (rc == -1) {
+ fprintf(stderr, "error: %s: poolname '%s' is empty\n",
+ prog_name, pool_name);
+ return -EINVAL;
+ } else if (rc == -2) {
+ fprintf(stderr, "error: %s: pool name '%s' is too long "
+ "(max is %d characters)\n",
+ prog_name, pool_name, LOV_MAXPOOLNAME);
+ return -EINVAL;
+ } else if (rc > 0) {
+ fprintf(stderr, "error: %s: char '%c' not allowed in "
+ "pool name '%s'\n",
+ prog_name, rc, pool_name);
+ return -EINVAL;
+ }
+ return rc;
+}
+
+struct lfs_setstripe_args {
+ __u64 lsa_comp_end;
+ unsigned long long lsa_stripe_size;
+ int lsa_stripe_count;
+ int lsa_stripe_off;
+ __u32 lsa_comp_flags;
+ int lsa_nr_osts;
+ __u32 *lsa_osts;
+ char *lsa_pool_name;
+};
+
+static inline void setstripe_args_init(struct lfs_setstripe_args *lsa)
+{
+ memset(lsa, 0, sizeof(*lsa));
+ lsa->lsa_stripe_off = -1;
+}
+
+static inline bool setstripe_args_specified(struct lfs_setstripe_args *lsa)
+{
+ return (lsa->lsa_stripe_size != 0 || lsa->lsa_stripe_count != 0 ||
+ lsa->lsa_stripe_off != -1 || lsa->lsa_pool_name != NULL ||
+ lsa->lsa_comp_end != 0);
+}
+
+static int comp_args_to_layout(struct llapi_layout **composite,
+ struct lfs_setstripe_args *lsa)
+{
+ struct llapi_layout *layout = *composite;
+ uint64_t prev_end = 0;
+ int i = 0, rc;
+
+ if (layout == NULL) {
+ layout = llapi_layout_alloc();
+ if (layout == NULL) {
+ fprintf(stderr, "Alloc llapi_layout failed. %s\n",
+ strerror(errno));
+ return -ENOMEM;
+ }
+ *composite = layout;
+ } else {
+ uint64_t start;
+
+ /* Get current component extent, current component
+ * must be the tail component. */
+ rc = llapi_layout_comp_extent_get(layout, &start, &prev_end);
+ if (rc) {
+ fprintf(stderr, "Get comp extent failed. %s\n",
+ strerror(errno));
+ return rc;
+ }
+
+ rc = llapi_layout_comp_add(layout);
+ if (rc) {
+ fprintf(stderr, "Add component failed. %s\n",
+ strerror(errno));
+ return rc;
+ }
+ }
+
+ rc = llapi_layout_comp_extent_set(layout, prev_end, lsa->lsa_comp_end);
+ if (rc) {
+ fprintf(stderr, "Set extent [%lu, %llu) failed. %s\n",
+ prev_end, lsa->lsa_comp_end, strerror(errno));
+ return rc;
+ }
+
+ if (lsa->lsa_stripe_size != 0) {
+ rc = llapi_layout_stripe_size_set(layout,
+ lsa->lsa_stripe_size);
+ if (rc) {
+ fprintf(stderr, "Set stripe size %llu failed. %s\n",
+ lsa->lsa_stripe_size, strerror(errno));
+ return rc;
+ }
+ }
+
+ if (lsa->lsa_stripe_count != 0) {
+ rc = llapi_layout_stripe_count_set(layout,
+ lsa->lsa_stripe_count == -1 ?
+ LLAPI_LAYOUT_WIDE :
+ lsa->lsa_stripe_count);
+ if (rc) {
+ fprintf(stderr, "Set stripe count %d failed. %s\n",
+ lsa->lsa_stripe_count, strerror(errno));
+ return rc;
+ }
+ }
+
+ if (lsa->lsa_pool_name != NULL) {
+ rc = llapi_layout_pool_name_set(layout, lsa->lsa_pool_name);
+ if (rc) {
+ fprintf(stderr, "Set pool name: %s failed. %s\n",
+ lsa->lsa_pool_name, strerror(errno));
+ return rc;
+ }
+ }
+
+ if (lsa->lsa_nr_osts > 0) {
+ if (lsa->lsa_stripe_count > 0 &&
+ lsa->lsa_nr_osts != lsa->lsa_stripe_count) {
+ fprintf(stderr, "stripe_count(%d) != nr_osts(%d)\n",
+ lsa->lsa_stripe_count, lsa->lsa_nr_osts);
+ return -EINVAL;
+ }
+ for (i = 0; i < lsa->lsa_nr_osts; i++) {
+ rc = llapi_layout_ost_index_set(layout, i,
+ lsa->lsa_osts[i]);
+ if (rc)
+ break;
+ }
+ } else if (lsa->lsa_stripe_off != -1) {
+ rc = llapi_layout_ost_index_set(layout, 0, lsa->lsa_stripe_off);
+ }
+ if (rc) {
+ fprintf(stderr, "Set ost index %d failed. %s\n",
+ i, strerror(errno));
+ return rc;
+ }
+
+ return 0;
+}
+
+/* In 'lfs setstripe --component-add' mode, we need to fetch the extent
+ * end of the last component in the existing file, and adjust the
+ * first extent start of the components to be added accordingly. */
+static int adjust_first_extent(char *fname, struct llapi_layout *layout)
+{
+ struct llapi_layout *head;
+ uint64_t start, end, stripe_size, prev_end = 0;
+ int rc;
+
+ if (layout == NULL)
+ return -EINVAL;
+
+ head = llapi_layout_get_by_path(fname, 0);
+ if (head == NULL) {
+ fprintf(stderr, "Read layout from %s failed. %s\n",
+ fname, strerror(errno));
+ return -EINVAL;
+ }
+
+ /* Current component of 'head' should be tail of component list. */
+ rc = llapi_layout_comp_extent_get(head, &start, &prev_end);
+ if (rc) {
+ fprintf(stderr, "Get prev extent failed. %s\n",
+ strerror(errno));
+ llapi_layout_free(head);
+ return rc;
+ }
+
+ llapi_layout_free(head);
+
+ /* Make sure we use the first component of the layout to be added. */
+ rc = llapi_layout_comp_move(layout, LLAPI_LAYOUT_COMP_POS_FIRST);
+ if (rc < 0) {
+ fprintf(stderr, "Move component cursor failed. %s\n",
+ strerror(errno));
+ return rc;
+ }
+
+ rc = llapi_layout_comp_extent_get(layout, &start, &end);
+ if (rc) {
+ fprintf(stderr, "Get extent failed. %s\n", strerror(errno));
+ return rc;
+ }
+
+ if (start > prev_end || end <= prev_end) {
+ fprintf(stderr, "First extent to be set [%lu, %lu) isn't "
+ "adjacent with the existing file extent end: %lu\n",
+ start, end, prev_end);
+ return -EINVAL;
+ }
+
+ rc = llapi_layout_stripe_size_get(layout, &stripe_size);
+ if (rc) {
+ fprintf(stderr, "Get stripe size failed. %s\n",
+ strerror(errno));
+ return rc;
+ }
+
+ if (stripe_size != LLAPI_LAYOUT_DEFAULT &&
+ (prev_end & (stripe_size - 1))) {
+ fprintf(stderr, "Stripe size %lu not aligned with %lu\n",
+ stripe_size, prev_end);
+ return -EINVAL;
+ }
+
+ rc = llapi_layout_comp_extent_set(layout, prev_end, end);
+ if (rc) {
+ fprintf(stderr, "Set component extent [%lu, %lu) failed. %s\n",
+ prev_end, end, strerror(errno));
+ return rc;
+ }
+
+ return 0;
+}
+
+static int comp_name2flags(__u32 *flags, char *name)
+{
+ char *ptr;
+
+ if (name == NULL)
+ return -EINVAL;
+
+ *flags = 0;
+ for (ptr = name; ; ptr = NULL) {
+ char *flg = strtok(ptr, ",");
+ if (flg == NULL)
+ break;
+ if (strcmp(flg, "init") == 0)
+ *flags |= LCME_FL_INIT;
+ else
+ return -EINVAL;
+ }
+ return (*flags == 0) ? -EINVAL : 0;
+}
+
+enum {
+ LFS_POOL_OPT = 3,
+ LFS_COMP_COUNT_OPT,
+ LFS_COMP_START_OPT,
+ LFS_COMP_FLAGS_OPT,
+ LFS_COMP_DEL_OPT,
+ LFS_COMP_SET_OPT,
+ LFS_COMP_ADD_OPT
+};
+
/* functions */
static int lfs_setstripe(int argc, char **argv)
{
+ struct lfs_setstripe_args lsa;
struct llapi_stripe_param *param = NULL;
struct find_param migrate_mdt_param = {
.fp_max_depth = -1,
char *fname;
int result;
int result2 = 0;
- unsigned long long st_size;
- int st_offset, st_count;
char *end;
int c;
int delete = 0;
- char *stripe_size_arg = NULL;
- char *stripe_off_arg = NULL;
- char *stripe_count_arg = NULL;
- char *pool_name_arg = NULL;
char *mdt_idx_arg = NULL;
unsigned long long size_units = 1;
bool migrate_mode = false;
bool migration_block = false;
__u64 migration_flags = 0;
__u32 osts[LOV_MAX_STRIPE_COUNT] = { 0 };
- int nr_osts = 0;
+ int comp_del = 0, comp_set = 0;
+ int comp_add = 0;
+ __u32 comp_id = 0;
+ struct llapi_layout *layout = NULL;
struct option long_opts[] = {
/* --block is only valid in migrate mode */
{"block", no_argument, 0, 'b'},
+ {"component-add", no_argument, 0, LFS_COMP_ADD_OPT},
+ {"component-del", no_argument, 0, LFS_COMP_DEL_OPT},
+ {"component-flags", required_argument, 0, LFS_COMP_FLAGS_OPT},
+ {"component-set", no_argument, 0, LFS_COMP_SET_OPT},
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0)
/* This formerly implied "stripe-count", but was explicitly
* made "stripe-count" for consistency with other options,
{"stripe-count", required_argument, 0, 'c'},
{"stripe_count", required_argument, 0, 'c'},
{"delete", no_argument, 0, 'd'},
+ {"component-end", required_argument, 0, 'E'},
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0)
/* This formerly implied "stripe-index", but was explicitly
* made "stripe-index" for consistency with other options,
#endif
{"stripe-index", required_argument, 0, 'i'},
{"stripe_index", required_argument, 0, 'i'},
+ {"component-id", required_argument, 0, 'I'},
{"mdt", required_argument, 0, 'm'},
{"mdt-index", required_argument, 0, 'm'},
{"mdt_index", required_argument, 0, 'm'},
{0, 0, 0, 0}
};
- st_size = 0;
- st_offset = -1;
- st_count = 0;
+ setstripe_args_init(&lsa);
if (strcmp(argv[0], "migrate") == 0)
migrate_mode = true;
- while ((c = getopt_long(argc, argv, "bc:di:m:no:p:s:S:v",
+ while ((c = getopt_long(argc, argv, "bc:dE:i:I:m:no:p:s:S:v",
long_opts, NULL)) >= 0) {
switch (c) {
case 0:
/* Long options. */
break;
+ case LFS_COMP_ADD_OPT:
+ comp_add = 1;
+ break;
+ case LFS_COMP_DEL_OPT:
+ comp_del = 1;
+ break;
+ case LFS_COMP_FLAGS_OPT:
+ result = comp_name2flags(&lsa.lsa_comp_flags, optarg);
+ if (result != 0) {
+ fprintf(stderr, "error: %s: bad comp flags "
+ "'%s'\n", argv[0], optarg);
+ goto error;
+ }
+ break;
+ case LFS_COMP_SET_OPT:
+ comp_set = 1;
+ break;
case 'b':
if (!migrate_mode) {
fprintf(stderr, "--block is valid only for"
" migrate mode\n");
- return CMD_HELP;
+ goto error;
}
migration_block = true;
break;
fprintf(stderr, "warning: '--count' deprecated"
", use '--stripe-count' instead\n");
#endif
- stripe_count_arg = optarg;
+ lsa.lsa_stripe_count = strtoul(optarg, &end, 0);
+ if (*end != '\0') {
+ fprintf(stderr, "error: %s: bad stripe count "
+ "'%s'\n", argv[0], optarg);
+ goto error;
+ }
break;
case 'd':
/* delete the default striping pattern */
delete = 1;
break;
- case 'o':
- nr_osts = parse_targets(osts,
- sizeof(osts) / sizeof(__u32),
- nr_osts, optarg);
- if (nr_osts < 0) {
- fprintf(stderr,
- "error: %s: bad OST indices '%s'\n",
- argv[0], optarg);
- return CMD_HELP;
+ case 'E':
+ if (lsa.lsa_comp_end != 0) {
+ result = comp_args_to_layout(&layout, &lsa);
+ if (result)
+ goto error;
+
+ setstripe_args_init(&lsa);
}
- if (st_offset == -1) /* first in the command line */
- st_offset = osts[0];
+ if (!strncmp(optarg, "-1", strlen("-1")) ||
+ !strncmp(optarg, "EOF", strlen("EOF")) ||
+ !strncmp(optarg, "eof", strlen("eof"))) {
+ lsa.lsa_comp_end = LUSTRE_EOF;
+ } else {
+ result = llapi_parse_size(optarg,
+ &lsa.lsa_comp_end,
+ &size_units, 0);
+ if (result) {
+ fprintf(stderr, "error: %s: "
+ "bad component end '%s'\n",
+ argv[0], optarg);
+ goto error;
+ }
+ }
break;
case 'i':
-#if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 6, 53, 0)
if (strcmp(argv[optind - 1], "--index") == 0)
fprintf(stderr, "warning: '--index' deprecated"
", use '--stripe-index' instead\n");
-#endif
- stripe_off_arg = optarg;
+ lsa.lsa_stripe_off = strtol(optarg, &end, 0);
+ if (*end != '\0') {
+ fprintf(stderr, "error: %s: bad stripe offset "
+ "'%s'\n", argv[0], optarg);
+ goto error;
+ }
+ break;
+ case 'I':
+ comp_id = strtoul(optarg, &end, 0);
+ if (*end != '\0' || comp_id == 0) {
+ fprintf(stderr, "error: %s: bad comp ID "
+ "'%s'\n", argv[0], optarg);
+ goto error;
+ }
break;
case 'm':
if (!migrate_mode) {
fprintf(stderr, "--mdt-index is valid only for"
" migrate mode\n");
- return CMD_HELP;
+ goto error;
}
mdt_idx_arg = optarg;
break;
if (!migrate_mode) {
fprintf(stderr, "--non-block is valid only for"
" migrate mode\n");
- return CMD_HELP;
+ goto error;
}
migration_flags |= MIGRATION_NONBLOCK;
break;
+ case 'o':
+ lsa.lsa_nr_osts = parse_targets(osts,
+ sizeof(osts) / sizeof(__u32),
+ lsa.lsa_nr_osts, optarg);
+ if (lsa.lsa_nr_osts < 0) {
+ fprintf(stderr,
+ "error: %s: bad OST indices '%s'\n",
+ argv[0], optarg);
+ goto error;
+ }
+
+ lsa.lsa_osts = osts;
+ if (lsa.lsa_stripe_off == -1)
+ lsa.lsa_stripe_off = osts[0];
+ break;
+ case 'p':
+ result = verify_pool_name(argv[0], optarg);
+ if (result)
+ goto error;
+ lsa.lsa_pool_name = optarg;
+ break;
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0)
case 's':
#if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 6, 53, 0)
#endif
#endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0) */
case 'S':
- stripe_size_arg = optarg;
- break;
- case 'p':
- pool_name_arg = optarg;
+ result = llapi_parse_size(optarg, &lsa.lsa_stripe_size,
+ &size_units, 0);
+ if (result) {
+ fprintf(stderr, "error: %s: bad stripe size "
+ "'%s'\n", argv[0], optarg);
+ goto error;
+ }
break;
case 'v':
if (!migrate_mode) {
fprintf(stderr, "--verbose is valid only for"
" migrate mode\n");
- return CMD_HELP;
+ goto error;
}
migrate_mdt_param.fp_verbose = VERBOSE_DETAIL;
break;
default:
- return CMD_HELP;
+ goto error;
}
}
fname = argv[optind];
- if (delete &&
- (stripe_size_arg != NULL || stripe_off_arg != NULL ||
- stripe_count_arg != NULL || pool_name_arg != NULL)) {
- fprintf(stderr, "error: %s: cannot specify -d with "
- "-s, -c, -o, or -p options\n",
- argv[0]);
- return CMD_HELP;
+ if (lsa.lsa_comp_end != 0) {
+ result = comp_args_to_layout(&layout, &lsa);
+ if (result)
+ goto error;
}
if (optind == argc) {
fprintf(stderr, "error: %s: missing filename|dirname\n",
argv[0]);
- return CMD_HELP;
+ goto error;
}
- if (mdt_idx_arg != NULL && optind > 3) {
- fprintf(stderr, "error: %s: cannot specify -m with other "
- "options\n", argv[0]);
- return CMD_HELP;
+ /* Only LCME_FL_INIT flags is used in PFL, and it shouldn't be
+ * altered by user space tool, so we don't need to support the
+ * --component-set for this moment. */
+ if (comp_set != 0) {
+ fprintf(stderr, "error: %s: --component-set isn't supported.\n",
+ argv[0]);
+ goto error;
}
- if ((migration_flags & MIGRATION_NONBLOCK) && migration_block) {
- fprintf(stderr,
- "error: %s: cannot specify --non-block and --block\n",
+ if ((delete + comp_set + comp_del + comp_add) > 1) {
+ fprintf(stderr, "error: %s: can't specify --component-set, "
+ "--component-del, --component-add or -d together\n",
argv[0]);
- return CMD_HELP;
+ goto error;
}
- if (pool_name_arg != NULL) {
- char *ptr;
- int rc;
+ if (delete && (setstripe_args_specified(&lsa) || comp_id != 0 ||
+ lsa.lsa_comp_flags != 0 || layout != NULL)) {
+ fprintf(stderr, "error: %s: can't specify -d with "
+ "-s, -c, -o, -p, -I, -F or -E options\n",
+ argv[0]);
+ goto error;
+ }
- ptr = strchr(pool_name_arg, '.');
- if (ptr == NULL) {
- ptr = pool_name_arg;
- } else {
- if ((ptr - pool_name_arg) == 0) {
- fprintf(stderr, "error: %s: fsname is empty "
- "in pool name '%s'\n",
- argv[0], pool_name_arg);
- return CMD_HELP;
- }
+ if ((comp_set || comp_del) &&
+ (setstripe_args_specified(&lsa) || layout != NULL)) {
+ fprintf(stderr, "error: %s: can't specify --component-del or "
+ "--component-set with -s, -c, -o, -p or -E options.\n",
+ argv[0]);
+ goto error;
+ }
- ++ptr;
- }
+ if (comp_del && comp_id != 0 && lsa.lsa_comp_flags != 0) {
+ fprintf(stderr, "error: %s: can't specify both -I and -F for "
+ "--component-del option.\n", argv[0]);
+ goto error;
+ }
- rc = lustre_is_poolname_valid(ptr, 1, LOV_MAXPOOLNAME);
- if (rc == -1) {
- fprintf(stderr, "error: %s: poolname '%s' is "
- "empty\n",
- argv[0], pool_name_arg);
- return CMD_HELP;
- } else if (rc == -2) {
- fprintf(stderr, "error: %s: pool name '%s' is too long "
- "(max is %d characters)\n",
- argv[0], pool_name_arg, LOV_MAXPOOLNAME);
- return CMD_HELP;
- } else if (rc > 0) {
- fprintf(stderr, "error: %s: char '%c' not allowed in "
- "pool name '%s'\n",
- argv[0], rc, pool_name_arg);
- return CMD_HELP;
+ if (comp_add) {
+ if (layout == NULL) {
+ fprintf(stderr, "error: %s: -E option must be present"
+ "in --component-add mode.\n", argv[0]);
+ goto error;
}
+ result = adjust_first_extent(fname, layout);
+ if (result != 0)
+ goto error;
}
- /* get the stripe size */
- if (stripe_size_arg != NULL) {
- result = llapi_parse_size(stripe_size_arg, &st_size,
- &size_units, 0);
- if (result) {
- fprintf(stderr, "error: %s: bad stripe size '%s'\n",
- argv[0], stripe_size_arg);
- return CMD_HELP;
- }
+ if (mdt_idx_arg != NULL && optind > 3) {
+ fprintf(stderr, "error: %s: cannot specify -m with other "
+ "options\n", argv[0]);
+ goto error;
+ }
+
+ if ((migration_flags & MIGRATION_NONBLOCK) && migration_block) {
+ fprintf(stderr,
+ "error: %s: cannot specify --non-block and --block\n",
+ argv[0]);
+ goto error;
+ }
+
+ /* support --component-id option for migrate later. */
+ if (migrate_mode && comp_id != 0) {
+ fprintf(stderr, "error: %s: -I isn't supported yet.\n",
+ argv[0]);
+ goto error;
}
- /* get the stripe offset */
- if (stripe_off_arg != NULL) {
- st_offset = strtol(stripe_off_arg, &end, 0);
- if (*end != '\0') {
- fprintf(stderr, "error: %s: bad stripe offset '%s'\n",
- argv[0], stripe_off_arg);
- return CMD_HELP;
- }
- }
- /* get the stripe count */
- if (stripe_count_arg != NULL) {
- st_count = strtoul(stripe_count_arg, &end, 0);
- if (*end != '\0') {
- fprintf(stderr, "error: %s: bad stripe count '%s'\n",
- argv[0], stripe_count_arg);
- return CMD_HELP;
- }
- }
if (mdt_idx_arg != NULL) {
/* initialize migrate mdt parameters */
if (*end != '\0') {
fprintf(stderr, "error: %s: bad MDT index '%s'\n",
argv[0], mdt_idx_arg);
- return CMD_HELP;
+ goto error;
}
migrate_mdt_param.fp_migrate = 1;
- } else {
+ } else if (layout == NULL) {
/* initialize stripe parameters */
- param = calloc(1, offsetof(typeof(*param), lsp_osts[nr_osts]));
+ param = calloc(1, offsetof(typeof(*param),
+ lsp_osts[lsa.lsa_nr_osts]));
if (param == NULL) {
- fprintf(stderr, "error: %s: run out of memory\n",
- argv[0]);
- return CMD_HELP;
+ fprintf(stderr, "error: %s: %s\n", argv[0],
+ strerror(ENOMEM));
+ goto error;
}
- param->lsp_stripe_size = st_size;
- param->lsp_stripe_offset = st_offset;
- param->lsp_stripe_count = st_count;
+ param->lsp_stripe_size = lsa.lsa_stripe_size;
+ param->lsp_stripe_offset = lsa.lsa_stripe_off;
+ param->lsp_stripe_count = lsa.lsa_stripe_count;
param->lsp_stripe_pattern = 0;
- param->lsp_pool = pool_name_arg;
+ param->lsp_pool = lsa.lsa_pool_name;
param->lsp_is_specific = false;
- if (nr_osts > 0) {
- if (st_count > 0 && nr_osts != st_count) {
+ if (lsa.lsa_nr_osts > 0) {
+ if (lsa.lsa_stripe_count > 0 &&
+ lsa.lsa_nr_osts != lsa.lsa_stripe_count) {
fprintf(stderr, "error: %s: stripe count '%d' "
"doesn't match the number of OSTs: %d\n"
- , argv[0], st_count, nr_osts);
+ , argv[0], lsa.lsa_stripe_count,
+ lsa.lsa_nr_osts);
free(param);
- return CMD_HELP;
+ goto error;
}
param->lsp_is_specific = true;
- param->lsp_stripe_count = nr_osts;
- memcpy(param->lsp_osts, osts, sizeof(*osts) * nr_osts);
+ param->lsp_stripe_count = lsa.lsa_nr_osts;
+ memcpy(param->lsp_osts, osts,
+ sizeof(*osts) * lsa.lsa_nr_osts);
}
}
for (fname = argv[optind]; fname != NULL; fname = argv[++optind]) {
- if (!migrate_mode) {
+ char *op;
+ if (mdt_idx_arg != NULL) {
+ result = llapi_migrate_mdt(fname, &migrate_mdt_param);
+ op = "migrate mdt objects of";
+ } else if (migrate_mode) {
+ result = lfs_migrate(fname, migration_flags, param,
+ layout);
+ op = "migrate ost objects of";
+ } else if (comp_set != 0) {
+ result = lfs_component_set(fname, comp_id,
+ lsa.lsa_comp_flags);
+ op = "modify component flags of";
+ } else if (comp_del != 0) {
+ result = lfs_component_del(fname, comp_id,
+ lsa.lsa_comp_flags);
+ op = "delete component of";
+ } else if (comp_add != 0) {
+ result = lfs_component_add(fname, layout);
+ op = "add component to";
+ } else if (layout != NULL) {
+ result = lfs_component_create(fname, O_CREAT | O_WRONLY,
+ 0644, layout);
+ if (result >= 0) {
+ close(result);
+ result = 0;
+ }
+ op = "create composite";
+ } else {
result = llapi_file_open_param(fname,
O_CREAT | O_WRONLY,
0644, param);
close(result);
result = 0;
}
- } else if (mdt_idx_arg != NULL) {
- result = llapi_migrate_mdt(fname, &migrate_mdt_param);
- } else {
- result = lfs_migrate(fname, migration_flags, param);
+ op = "create striped";
}
if (result) {
/* Save the first error encountered. */
if (result2 == 0)
result2 = result;
fprintf(stderr, "error: %s: %s file '%s' failed: %s\n",
- argv[0], migrate_mode ? "migrate" : "create",
- fname,
- pool_name_arg != NULL && result == EINVAL ?
+ argv[0], op, fname,
+ lsa.lsa_pool_name != NULL && result == EINVAL ?
"OST not in pool?" : strerror(errno));
continue;
}
}
free(param);
+ llapi_layout_free(layout);
return result2;
+error:
+ llapi_layout_free(layout);
+ return CMD_HELP;
}
static int lfs_poollist(int argc, char **argv)
return 0;
}
-#define FIND_POOL_OPT 3
static int lfs_find(int argc, char **argv)
{
int c, rc;
.fp_quiet = 1,
};
struct option long_opts[] = {
- {"atime", required_argument, 0, 'A'},
- {"stripe-count", required_argument, 0, 'c'},
- {"stripe_count", required_argument, 0, 'c'},
- {"ctime", required_argument, 0, 'C'},
- {"maxdepth", required_argument, 0, 'D'},
- {"gid", required_argument, 0, 'g'},
- {"group", required_argument, 0, 'G'},
- {"stripe-index", required_argument, 0, 'i'},
- {"stripe_index", required_argument, 0, 'i'},
+ {"atime", required_argument, 0, 'A'},
+ {"component-count", required_argument, 0, LFS_COMP_COUNT_OPT},
+ {"component-flags", required_argument, 0, LFS_COMP_FLAGS_OPT},
+ {"component-start", required_argument, 0, LFS_COMP_START_OPT},
+ {"stripe-count", required_argument, 0, 'c'},
+ {"stripe_count", required_argument, 0, 'c'},
+ {"ctime", required_argument, 0, 'C'},
+ {"maxdepth", required_argument, 0, 'D'},
+ {"component-end", required_argument, 0, 'E'},
+ {"gid", required_argument, 0, 'g'},
+ {"group", required_argument, 0, 'G'},
+ {"stripe-index", required_argument, 0, 'i'},
+ {"stripe_index", required_argument, 0, 'i'},
+ /*{"component-id", required_argument, 0, 'I'},*/
{"layout", required_argument, 0, 'L'},
{"mdt", required_argument, 0, 'm'},
{"mdt-index", required_argument, 0, 'm'},
{"obd", required_argument, 0, 'O'},
{"ost", required_argument, 0, 'O'},
/* no short option for pool, p/P already used */
- {"pool", required_argument, 0, FIND_POOL_OPT},
+ {"pool", required_argument, 0, LFS_POOL_OPT},
{"print0", no_argument, 0, 'p'},
{"print", no_argument, 0, 'P'},
{"size", required_argument, 0, 's'},
/* when getopt_long_only() hits '!' it returns 1, puts "!" in optarg */
while ((c = getopt_long_only(argc, argv,
- "-A:c:C:D:g:G:i:L:m:M:n:O:Ppqrs:S:t:u:U:v",
- long_opts, NULL)) >= 0) {
+ "-A:c:C:D:E:g:G:i:L:m:M:n:O:Ppqrs:S:t:u:U:v",
+ long_opts, NULL)) >= 0) {
xtime = NULL;
xsign = NULL;
if (neg_opt)
if (rc)
*xsign = rc;
break;
+ case LFS_COMP_COUNT_OPT:
+ if (optarg[0] == '+') {
+ param.fp_comp_count_sign = -1;
+ optarg++;
+ } else if (optarg[0] == '-') {
+ param.fp_comp_count_sign = 1;
+ optarg++;
+ }
+
+ param.fp_comp_count = strtoul(optarg, &endptr, 0);
+ if (*endptr != '\0') {
+ fprintf(stderr, "error: bad component count "
+ "'%s'\n", optarg);
+ goto err;
+ }
+ param.fp_check_comp_count = 1;
+ param.fp_exclude_comp_count = !!neg_opt;
+ break;
+ case LFS_COMP_FLAGS_OPT:
+ rc = comp_name2flags(¶m.fp_comp_flags, optarg);
+ if (rc) {
+ fprintf(stderr, "error: bad component flags "
+ "'%s'\n", optarg);
+ goto err;
+ }
+ param.fp_check_comp_flags = 1;
+ param.fp_exclude_comp_flags = !!neg_opt;
+ break;
+ case LFS_COMP_START_OPT:
+ if (optarg[0] == '+') {
+ param.fp_comp_start_sign = -1;
+ optarg++;
+ } else if (optarg[0] == '-') {
+ param.fp_comp_start_sign = 1;
+ optarg++;
+ }
+
+ rc = llapi_parse_size(optarg, ¶m.fp_comp_start,
+ ¶m.fp_comp_start_units, 0);
+ if (rc) {
+ fprintf(stderr, "error: bad component start "
+ "'%s'\n", optarg);
+ goto err;
+ }
+ param.fp_check_comp_start = 1;
+ param.fp_exclude_comp_start = !!neg_opt;
+ break;
case 'c':
if (optarg[0] == '+') {
param.fp_stripe_count_sign = -1;
case 'D':
param.fp_max_depth = strtol(optarg, 0, 0);
break;
+ case 'E':
+ if (optarg[0] == '+') {
+ param.fp_comp_end_sign = -1;
+ optarg++;
+ } else if (optarg[0] == '-') {
+ param.fp_comp_end_sign = 1;
+ optarg++;
+ }
+
+ rc = llapi_parse_size(optarg, ¶m.fp_comp_end,
+ ¶m.fp_comp_end_units, 0);
+ if (rc) {
+ fprintf(stderr, "error: bad component end "
+ "'%s'\n", optarg);
+ goto err;
+ }
+ param.fp_check_comp_end = 1;
+ param.fp_exclude_comp_end = !!neg_opt;
+ break;
case 'g':
case 'G':
rc = name2id(¶m.fp_gid, optarg, GROUP);
param.fp_exclude_uid = !!neg_opt;
param.fp_check_uid = 1;
break;
- case FIND_POOL_OPT:
+ case LFS_POOL_OPT:
if (strlen(optarg) > LOV_MAXPOOLNAME) {
fprintf(stderr,
"Pool name %s is too long"
struct find_param *param)
{
struct option long_opts[] = {
+ {"component-count", no_argument, 0, LFS_COMP_COUNT_OPT},
+ {"component-flags", required_argument, 0, LFS_COMP_FLAGS_OPT},
+ {"component-start", required_argument, 0, LFS_COMP_START_OPT},
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0)
/* This formerly implied "stripe-count", but was explicitly
* made "stripe-count" for consistency with other options,
{"stripe_count", no_argument, 0, 'c'},
{"directory", no_argument, 0, 'd'},
{"default", no_argument, 0, 'D'},
+ {"component-end", required_argument, 0, 'E'},
{"fid", no_argument, 0, 'F'},
{"generation", no_argument, 0, 'g'},
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 59, 0)
#endif
{"stripe-index", no_argument, 0, 'i'},
{"stripe_index", no_argument, 0, 'i'},
+ {"component-id", required_argument, 0, 'I'},
{"layout", no_argument, 0, 'L'},
{"mdt", no_argument, 0, 'm'},
{"mdt-index", no_argument, 0, 'm'},
{0, 0, 0, 0}
};
int c, rc;
+ char *end, *tmp;
- while ((c = getopt_long(argc, argv, "cdDFghiLmMoO:pqrRsSv",
+ while ((c = getopt_long(argc, argv, "cdDE:FghiI:LmMoO:pqrRsSv",
long_opts, NULL)) != -1) {
switch (c) {
case 'O':
case 'q':
param->fp_quiet++;
break;
+ case LFS_COMP_COUNT_OPT:
+ param->fp_verbose |= VERBOSE_COMP_COUNT;
+ param->fp_max_depth = 0;
+ break;
+ case LFS_COMP_FLAGS_OPT:
+ if (optarg != NULL) {
+ rc = comp_name2flags(¶m->fp_comp_flags,
+ optarg);
+ if (rc != 0) {
+ param->fp_verbose |=
+ VERBOSE_COMP_FLAGS;
+ param->fp_max_depth = 0;
+ optind--;
+ } else {
+ param->fp_check_comp_flags = 1;
+ }
+ } else {
+ param->fp_verbose |= VERBOSE_COMP_FLAGS;
+ param->fp_max_depth = 0;
+ }
+ break;
+ case LFS_COMP_START_OPT:
+ if (optarg != NULL) {
+ tmp = optarg;
+ if (tmp[0] == '+') {
+ param->fp_comp_start_sign = 1;
+ tmp++;
+ } else if (tmp[0] == '-') {
+ param->fp_comp_start_sign = -1;
+ tmp++;
+ }
+ rc = llapi_parse_size(tmp,
+ ¶m->fp_comp_start,
+ ¶m->fp_comp_start_units, 0);
+ if (rc != 0) {
+ param->fp_verbose |= VERBOSE_COMP_START;
+ param->fp_max_depth = 0;
+ optind--;
+ } else {
+ param->fp_check_comp_start = 1;
+ }
+ } else {
+ param->fp_verbose |= VERBOSE_COMP_START;
+ param->fp_max_depth = 0;
+ }
+ break;
case 'd':
param->fp_max_depth = 0;
break;
case 'D':
param->fp_get_default_lmv = 1;
break;
+ case 'E':
+ if (optarg != NULL) {
+ tmp = optarg;
+ if (tmp[0] == '+') {
+ param->fp_comp_end_sign = 1;
+ tmp++;
+ } else if (tmp[0] == '-') {
+ param->fp_comp_end_sign = -1;
+ tmp++;
+ }
+ rc = llapi_parse_size(tmp,
+ ¶m->fp_comp_end,
+ ¶m->fp_comp_end_units, 0);
+ if (rc != 0) {
+ param->fp_verbose |= VERBOSE_COMP_END;
+ param->fp_max_depth = 0;
+ optind--;
+ } else {
+ param->fp_check_comp_end = 1;
+ }
+ } else {
+ param->fp_verbose |= VERBOSE_COMP_END;
+ param->fp_max_depth = 0;
+ }
+ break;
case 'F':
if (!(param->fp_verbose & VERBOSE_DETAIL)) {
param->fp_verbose |= VERBOSE_DFID;
param->fp_max_depth = 0;
}
break;
+ case 'I':
+ if (optarg != NULL) {
+ param->fp_comp_id = strtoul(optarg, &end, 0);
+ if (*end != '\0') {
+ param->fp_verbose |= VERBOSE_COMP_ID;
+ param->fp_max_depth = 0;
+ optind--;
+ } else {
+ param->fp_check_comp_id = 1;
+ }
+ } else {
+ param->fp_max_depth = 0;
+ param->fp_verbose |= VERBOSE_COMP_ID;
+ }
+ break;
case 'p':
if (!(param->fp_verbose & VERBOSE_DETAIL)) {
param->fp_verbose |= VERBOSE_POOL;
if (param->fp_recursive)
param->fp_max_depth = -1;
+ else if (param->fp_verbose & VERBOSE_DETAIL)
+ param->fp_max_depth = 1;
if (!param->fp_verbose)
param->fp_verbose = VERBOSE_DEFAULT;
return 0;
}
+enum lov_dump_flags {
+ LDF_IS_DIR = 0x0001,
+ LDF_IS_RAW = 0x0002,
+ LDF_INDENT = 0x0004,
+};
+
static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
struct lov_user_ost_data_v1 *objects,
- int is_dir, int verbose, int depth,
- int raw, char *pool_name)
+ int verbose, int depth, char *pool_name,
+ enum lov_dump_flags flags)
{
+ bool is_dir = flags & LDF_IS_DIR;
+ bool is_raw = flags & LDF_IS_RAW;
+ bool indent = flags & LDF_INDENT;
char *prefix = is_dir ? "" : "lmm_";
char *separator = "";
+ char *space = indent ? " " : "";
int rc;
if (is_dir && lmm_oi_seq(&lum->lmm_oi) == FID_SEQ_LOV_DEFAULT) {
lmm_oi_set_seq(&lum->lmm_oi, 0);
- if (verbose & VERBOSE_DETAIL)
- llapi_printf(LLAPI_MSG_NORMAL, "(Default) ");
+ if (!indent && (verbose & VERBOSE_DETAIL))
+ llapi_printf(LLAPI_MSG_NORMAL, "%s(Default) ", space);
}
- if (depth && path && ((verbose != VERBOSE_OBJID) || !is_dir))
+ if (!indent && depth && path && ((verbose != VERBOSE_OBJID) || !is_dir))
llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
if ((verbose & VERBOSE_DETAIL) && !is_dir) {
- llapi_printf(LLAPI_MSG_NORMAL, "lmm_magic: 0x%08X\n",
- lum->lmm_magic);
- llapi_printf(LLAPI_MSG_NORMAL, "lmm_seq: %#jx\n",
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%smagic: 0x%08X\n",
+ space, prefix, lum->lmm_magic);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%sseq: %#jx\n",
+ space, prefix,
(uintmax_t)lmm_oi_seq(&lum->lmm_oi));
- llapi_printf(LLAPI_MSG_NORMAL, "lmm_object_id: %#jx\n",
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%sobject_id: %#jx\n",
+ space, prefix,
(uintmax_t)lmm_oi_id(&lum->lmm_oi));
}
if ((verbose & (VERBOSE_DETAIL | VERBOSE_DFID)) && !is_dir) {
if (verbose & ~VERBOSE_DFID)
- llapi_printf(LLAPI_MSG_NORMAL, "lmm_fid: ");
+ llapi_printf(LLAPI_MSG_NORMAL, "%slmm_fid: ",
+ space);
/* This needs a bit of hand-holding since old 1.x lmm_oi
* have { oi.oi_id = mds_inum, oi.oi_seq = 0 } and 2.x lmm_oi
* have { oi.oi_id = mds_oid, oi.oi_seq = mds_seq } instead of
if (verbose & VERBOSE_COUNT) {
if (verbose & ~VERBOSE_COUNT)
- llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_count: ",
- prefix);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%sstripe_count: ",
+ space, prefix);
if (is_dir) {
- if (!raw && lum->lmm_stripe_count == 0) {
+ if (!is_raw && lum->lmm_stripe_count == 0) {
unsigned int scount;
rc = sattr_cache_get_defaults(NULL, path,
&scount, NULL,
if (verbose & VERBOSE_SIZE) {
llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_SIZE)
- llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_size: ",
- prefix);
- if (is_dir && !raw && lum->lmm_stripe_size == 0) {
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%sstripe_size: ",
+ space, prefix);
+ if (is_dir && !is_raw && lum->lmm_stripe_size == 0) {
unsigned int ssize;
rc = sattr_cache_get_defaults(NULL, path, NULL, &ssize,
NULL);
if ((verbose & VERBOSE_LAYOUT) && !is_dir) {
llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_LAYOUT)
- llapi_printf(LLAPI_MSG_NORMAL, "%spattern: ",
- prefix);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%spattern: ",
+ space, prefix);
llapi_printf(LLAPI_MSG_NORMAL, "%.x", lum->lmm_pattern);
separator = "\n";
}
if ((verbose & VERBOSE_GENERATION) && !is_dir) {
llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_GENERATION)
- llapi_printf(LLAPI_MSG_NORMAL, "%slayout_gen: ",
- prefix);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%slayout_gen: ",
+ space, prefix);
llapi_printf(LLAPI_MSG_NORMAL, "%u",
(int)lum->lmm_layout_gen);
separator = "\n";
if (verbose & VERBOSE_OFFSET) {
llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_OFFSET)
- llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_offset: ",
- prefix);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%sstripe_offset: ",
+ space, prefix);
if (is_dir)
llapi_printf(LLAPI_MSG_NORMAL, "%d",
lum->lmm_stripe_offset ==
separator = is_dir ? " " : "\n";
}
- if ((verbose & VERBOSE_POOL) && (pool_name != NULL)) {
+ if ((verbose & VERBOSE_POOL) && pool_name && (pool_name[0] != '\0')) {
llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_POOL)
- llapi_printf(LLAPI_MSG_NORMAL, "%spool: ",
- prefix);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%spool: ",
+ space, prefix);
llapi_printf(LLAPI_MSG_NORMAL, "%s", pool_name);
+ separator = is_dir ? " " : "\n";
}
- if (!is_dir || (is_dir && (verbose != VERBOSE_OBJID)))
+ if (strlen(separator) != 0)
llapi_printf(LLAPI_MSG_NORMAL, "\n");
}
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 depth, int header, int raw)
+ struct lov_user_ost_data_v1 *objects,
+ char *path, int obdindex, int depth,
+ int header, enum lov_dump_flags flags)
{
- int i, obdstripe = (obdindex != OBD_NOT_FOUND) ? 0 : 1;
+ bool is_dir = flags & LDF_IS_DIR;
+ bool indent = flags & LDF_INDENT;
+ int i, obdstripe = (obdindex != OBD_NOT_FOUND) ? 0 : 1;
- if (!obdstripe) {
- for (i = 0; !is_dir && i < lum->lmm_stripe_count; i++) {
- if (obdindex == objects[i].l_ost_idx) {
- obdstripe = 1;
- break;
- }
- }
- }
+ if (!obdstripe) {
+ for (i = 0; !is_dir && i < lum->lmm_stripe_count; i++) {
+ if (obdindex == objects[i].l_ost_idx) {
+ obdstripe = 1;
+ break;
+ }
+ }
+ }
- if (obdstripe == 1)
- lov_dump_user_lmm_header(lum, path, objects, is_dir, header,
- depth, raw, pool_name);
+ if (obdstripe == 0)
+ return;
- if (!is_dir && (header & VERBOSE_OBJID) &&
+ lov_dump_user_lmm_header(lum, path, objects, header, depth, pool_name,
+ flags);
+
+ if (!is_dir && (header & VERBOSE_OBJID) &&
!(lum->lmm_pattern & LOV_PATTERN_F_RELEASED)) {
- if (obdstripe == 1)
- llapi_printf(LLAPI_MSG_NORMAL,
- "\tobdidx\t\t objid\t\t objid\t\t group\n");
-
- for (i = 0; i < lum->lmm_stripe_count; i++) {
- int idx = objects[i].l_ost_idx;
- long long oid = ostid_id(&objects[i].l_ost_oi);
- long long gr = ostid_seq(&objects[i].l_ost_oi);
- if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx)) {
+ char *space = " - ";
+
+ if (indent)
+ llapi_printf(LLAPI_MSG_NORMAL,
+ "%6slmm_objects:\n", " ");
+ else
+ llapi_printf(LLAPI_MSG_NORMAL,
+ "\tobdidx\t\t objid\t\t objid\t\t group\n");
+
+ for (i = 0; i < lum->lmm_stripe_count; i++) {
+ int idx = objects[i].l_ost_idx;
+ long long oid = ostid_id(&objects[i].l_ost_oi);
+ long long gr = ostid_seq(&objects[i].l_ost_oi);
+
+ if (obdindex != OBD_NOT_FOUND && obdindex != idx)
+ continue;
+
+ if (indent) {
+ struct lu_fid fid = { 0 };
+
+ ostid_to_fid(&fid, &objects[i].l_ost_oi, idx);
+ llapi_printf(LLAPI_MSG_NORMAL,
+ "%s%d: { l_ost_idx: %d, l_fid: "DFID" }\n",
+ space, i, idx, PFID(&fid));
+ } else {
char fmt[48];
sprintf(fmt, "%s%s%s\n",
"\t%6u\t%14llu\t%#13llx\t",
oid, gr,
obdindex == idx ? " *" : "");
}
-
- }
- llapi_printf(LLAPI_MSG_NORMAL, "\n");
- }
+ }
+ llapi_printf(LLAPI_MSG_NORMAL, "\n");
+ }
}
void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name,
llapi_printf(LLAPI_MSG_NORMAL, "\n");
}
-void llapi_lov_dump_user_lmm(struct find_param *param, char *path, int is_dir)
+static void lov_dump_comp_v1_header(struct find_param *param, char *path,
+ enum lov_dump_flags flags)
+{
+ struct lov_comp_md_v1 *comp_v1 = (void *)¶m->fp_lmd->lmd_lmm;
+ int depth = param->fp_max_depth;
+ int verbose = param->fp_verbose;
+
+ if (depth && path && ((verbose != VERBOSE_OBJID) ||
+ !(flags & LDF_IS_DIR)))
+ llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
+
+ if (verbose & VERBOSE_DETAIL) {
+ llapi_printf(LLAPI_MSG_NORMAL, "composite_header:\n");
+ llapi_printf(LLAPI_MSG_NORMAL, "%2slcm_magic: 0x%08X\n",
+ " ", comp_v1->lcm_magic);
+ llapi_printf(LLAPI_MSG_NORMAL, "%2slcm_size: %u\n",
+ " ", comp_v1->lcm_size);
+ llapi_printf(LLAPI_MSG_NORMAL, "%2slcm_flags: %u\n",
+ " ", comp_v1->lcm_flags);
+ }
+
+ if (verbose & VERBOSE_GENERATION) {
+ if (verbose & ~VERBOSE_GENERATION)
+ llapi_printf(LLAPI_MSG_NORMAL, "%2slcm_layout_gen: ",
+ " ");
+ llapi_printf(LLAPI_MSG_NORMAL, "%u\n", comp_v1->lcm_layout_gen);
+ }
+
+ if (verbose & VERBOSE_COMP_COUNT) {
+ if (verbose & ~VERBOSE_COMP_COUNT)
+ llapi_printf(LLAPI_MSG_NORMAL, "%2slcm_entry_count: ",
+ " ");
+ llapi_printf(LLAPI_MSG_NORMAL, "%u\n",
+ comp_v1->lcm_entry_count);
+ }
+
+ if (verbose & VERBOSE_DETAIL)
+ llapi_printf(LLAPI_MSG_NORMAL, "components:\n");
+}
+
+static void lov_dump_comp_v1_entry(struct find_param *param,
+ enum lov_dump_flags flags, int index)
+{
+ struct lov_comp_md_v1 *comp_v1 = (void *)¶m->fp_lmd->lmd_lmm;
+ struct lov_comp_md_entry_v1 *entry;
+ char *separator = "";
+ int verbose = param->fp_verbose;
+
+ entry = &comp_v1->lcm_entries[index];
+
+ if (verbose & VERBOSE_COMP_ID) {
+ if (verbose & VERBOSE_DETAIL)
+ llapi_printf(LLAPI_MSG_NORMAL,
+ "%slcme_id: ", " - ");
+ else if (verbose & ~VERBOSE_COMP_ID)
+ llapi_printf(LLAPI_MSG_NORMAL,
+ "%4slcme_id: ", " ");
+ if (!(flags & LDF_IS_DIR))
+ llapi_printf(LLAPI_MSG_NORMAL, "%u", entry->lcme_id);
+ else
+ llapi_printf(LLAPI_MSG_NORMAL, "N/A");
+ separator = "\n";
+ }
+
+ if (verbose & VERBOSE_COMP_FLAGS) {
+ llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
+ if (verbose & ~VERBOSE_COMP_FLAGS)
+ llapi_printf(LLAPI_MSG_NORMAL,
+ "%4slcme_flags: ", " ");
+ llapi_printf(LLAPI_MSG_NORMAL, "%#x", entry->lcme_flags);
+ separator = "\n";
+ }
+
+ if (verbose & VERBOSE_COMP_START) {
+ llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
+ if (verbose & ~VERBOSE_COMP_START)
+ llapi_printf(LLAPI_MSG_NORMAL,
+ "%4slcme_extent.e_start: ", " ");
+ llapi_printf(LLAPI_MSG_NORMAL, "%llu",
+ entry->lcme_extent.e_start);
+ separator = "\n";
+ }
+
+ if (verbose & VERBOSE_COMP_END) {
+ llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
+ if (verbose & ~VERBOSE_COMP_END)
+ llapi_printf(LLAPI_MSG_NORMAL,
+ "%4slcme_extent.e_end: ", " ");
+ if (entry->lcme_extent.e_end == LUSTRE_EOF)
+ llapi_printf(LLAPI_MSG_NORMAL, "%s", "EOF");
+ else
+ llapi_printf(LLAPI_MSG_NORMAL, "%llu",
+ entry->lcme_extent.e_end);
+ separator = "\n";
+ }
+
+ if (verbose & VERBOSE_DETAIL) {
+ llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
+ llapi_printf(LLAPI_MSG_NORMAL, "%4slcme_offset: %u\n",
+ " ", entry->lcme_offset);
+ llapi_printf(LLAPI_MSG_NORMAL, "%4slcme_size: %u\n",
+ " ", entry->lcme_size);
+ llapi_printf(LLAPI_MSG_NORMAL, "%4ssub_layout:\n", " ");
+ } else {
+ llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
+ }
+}
+
+/* Check if the value matches 1 of the given criteria (e.g. --atime +/-N).
+ * @mds indicates if this is MDS timestamps and there are attributes on OSTs.
+ *
+ * The result is -1 if it does not match, 0 if not yet clear, 1 if matches.
+ * The table below gives the answers for the specified parameters (value and
+ * sign), 1st column is the answer for the MDS value, the 2nd is for the OST:
+ * --------------------------------------
+ * 1 | file > limit; sign > 0 | -1 / -1 |
+ * 2 | file = limit; sign > 0 | -1 / -1 |
+ * 3 | file < limit; sign > 0 | ? / 1 |
+ * 4 | file > limit; sign = 0 | -1 / -1 |
+ * 5 | file = limit; sign = 0 | ? / 1 | <- (see the Note below)
+ * 6 | file < limit; sign = 0 | ? / -1 |
+ * 7 | file > limit; sign < 0 | 1 / 1 |
+ * 8 | file = limit; sign < 0 | ? / -1 |
+ * 9 | file < limit; sign < 0 | ? / -1 |
+ * --------------------------------------
+ * Note: 5th actually means that the value is within the interval
+ * (limit - margin, limit]. */
+static int find_value_cmp(unsigned long long file, unsigned long long limit,
+ int sign, int negopt, unsigned long long margin,
+ int mds)
+{
+ int ret = -1;
+
+ if (sign > 0) {
+ /* Drop the fraction of margin (of days). */
+ if (file + margin <= limit)
+ ret = mds ? 0 : 1;
+ } else if (sign == 0) {
+ if (file <= limit && file + margin > limit)
+ ret = mds ? 0 : 1;
+ else if (file + margin <= limit)
+ ret = mds ? 0 : -1;
+ } else if (sign < 0) {
+ if (file > limit)
+ ret = 1;
+ else if (mds)
+ ret = 0;
+ }
+
+ return negopt ? ~ret + 1 : ret;
+}
+
+static inline struct lov_user_md *
+lov_comp_entry(struct lov_comp_md_v1 *comp_v1, int ent_idx)
+{
+ return (struct lov_user_md *)((char *)comp_v1 +
+ comp_v1->lcm_entries[ent_idx].lcme_offset);
+}
+
+static inline struct lov_user_ost_data_v1 *
+lov_v1v3_objects(struct lov_user_md *v1)
+{
+ if (v1->lmm_magic == LOV_USER_MAGIC_V3)
+ return ((struct lov_user_md_v3 *)v1)->lmm_objects;
+ else
+ return v1->lmm_objects;
+}
+
+static inline void
+lov_v1v3_pool_name(struct lov_user_md *v1, char *pool_name)
+{
+ if (v1->lmm_magic == LOV_USER_MAGIC_V3)
+ strlcpy(pool_name, ((struct lov_user_md_v3 *)v1)->lmm_pool_name,
+ LOV_MAXPOOLNAME);
+ else
+ pool_name[0] = '\0';
+}
+
+/**
+ * An example of "getstripe -v" for a two components PFL file:
+ *
+ * composite_header:
+ * lcm_magic: 0x0BD60BD0
+ * lcm_size: 264
+ * lcm_flags: 0
+ * lcm_layout_gen: 2
+ * lcm_entry_count: 2
+ * components:
+ * - lcme_id: 1
+ * lcme_flags: 0x10
+ * lcme_extent.e_start: 0
+ * lcme_extent.e_end: 1048576
+ * lcme_offset: 128
+ * lcme_size: 56
+ * sub_layout:
+ * lmm_magic: 0x0BD10BD0
+ * lmm_seq: 0x200000401
+ * lmm_object_id: 0x1
+ * lmm_fid: [0x200000401:0x1:0x0]
+ * lmm_stripe_count: 1
+ * lmm_stripe_size: 1048576
+ * lmm_pattern: 1
+ * lmm_layout_gen: 0
+ * lmm_stripe_offset: 0
+ * lmm_objects:
+ * - 0: { l_ost_idx: 0, l_fid: [0x100000000:0x2:0x0] }
+ *
+ * - lcme_id: 2
+ * lcme_flags: 0x10
+ * lcme_extent.e_start: 1048576
+ * lcme_extent.e_end: EOF
+ * lcme_offset: 184
+ * lcme_size: 80
+ * sub_layout:
+ * lmm_magic: 0x0BD10BD0
+ * lmm_seq: 0x200000401
+ * lmm_object_id: 0x1
+ * lmm_fid: [0x200000401:0x1:0x0]
+ * lmm_stripe_count: 2
+ * lmm_stripe_size: 1048576
+ * lmm_pattern: 1
+ * lmm_layout_gen: 0
+ * lmm_stripe_offset: 1
+ * lmm_objects:
+ * - 0: { l_ost_idx: 1, l_fid: [0x100010000:0x2:0x0] }
+ * - 1: { l_ost_idx: 0, l_fid: [0x100000000:0x3:0x0] }
+ */
+static void lov_dump_comp_v1(struct find_param *param, char *path,
+ enum lov_dump_flags flags)
+{
+ struct lov_comp_md_entry_v1 *entry;
+ struct lov_user_ost_data_v1 *objects;
+ struct lov_comp_md_v1 *comp_v1 = (void *)¶m->fp_lmd->lmd_lmm;
+ struct lov_user_md_v1 *v1;
+ char pool_name[LOV_MAXPOOLNAME + 1];
+ int obdindex = param->fp_obd_index;
+ int i, j, match, obdstripe = 0;
+
+ if (obdindex != OBD_NOT_FOUND) {
+ for (i = 0; !(flags & LDF_IS_DIR) &&
+ i < comp_v1->lcm_entry_count; i++) {
+ if (!(comp_v1->lcm_entries[i].lcme_flags &
+ LCME_FL_INIT))
+ continue;
+
+ v1 = lov_comp_entry(comp_v1, i);
+ objects = lov_v1v3_objects(v1);
+
+ for (j = 0; j < v1->lmm_stripe_count; j++) {
+ if (obdindex == objects[j].l_ost_idx) {
+ obdstripe = 1;
+ break;
+ }
+ }
+ }
+ } else {
+ obdstripe = 1;
+ }
+
+ if (obdstripe == 0)
+ return;
+
+ lov_dump_comp_v1_header(param, path, flags);
+
+ flags |= LDF_INDENT;
+
+ for (i = 0; i < comp_v1->lcm_entry_count; i++) {
+ entry = &comp_v1->lcm_entries[i];
+
+ if (param->fp_check_comp_flags &&
+ !(param->fp_comp_flags & entry->lcme_flags))
+ continue;
+
+ if (param->fp_check_comp_id &&
+ param->fp_comp_id != entry->lcme_id)
+ continue;
+
+ if (param->fp_check_comp_start) {
+ match = find_value_cmp(entry->lcme_extent.e_start,
+ param->fp_comp_start,
+ param->fp_comp_start_sign,
+ 0,
+ param->fp_comp_start_units, 0);
+ if (match == -1)
+ continue;
+ }
+
+ if (param->fp_check_comp_end) {
+ unsigned long long margin;
+
+ margin = entry->lcme_extent.e_end == LUSTRE_EOF ?
+ 0 : param->fp_comp_end_units;
+
+ match = find_value_cmp(entry->lcme_extent.e_end,
+ param->fp_comp_end,
+ param->fp_comp_end_sign,
+ 0, margin, 0);
+ if (match == -1)
+ continue;
+ }
+
+ lov_dump_comp_v1_entry(param, flags, i);
+
+ v1 = lov_comp_entry(comp_v1, i);
+ objects = lov_v1v3_objects(v1);
+ lov_v1v3_pool_name(v1, pool_name);
+
+ lov_dump_user_lmm_v1v3(v1, pool_name, objects, path, obdindex,
+ param->fp_max_depth, param->fp_verbose,
+ flags);
+ }
+}
+
+static void llapi_lov_dump_user_lmm(struct find_param *param, char *path,
+ enum lov_dump_flags flags)
{
__u32 magic;
else
magic = *(__u32 *)¶m->fp_lmd->lmd_lmm; /* lum->lmm_magic */
+ if (param->fp_raw)
+ flags |= LDF_IS_RAW;
+
switch (magic) {
- case LOV_USER_MAGIC_V1:
+ case LOV_USER_MAGIC_V1:
lov_dump_user_lmm_v1v3(¶m->fp_lmd->lmd_lmm, NULL,
param->fp_lmd->lmd_lmm.lmm_objects,
- path, is_dir,
- param->fp_obd_index, param->fp_max_depth,
- param->fp_verbose, param->fp_raw);
- break;
- case LOV_USER_MAGIC_V3: {
- char pool_name[LOV_MAXPOOLNAME + 1];
- struct lov_user_ost_data_v1 *objects;
+ path, param->fp_obd_index,
+ param->fp_max_depth, param->fp_verbose,
+ flags);
+ break;
+ case LOV_USER_MAGIC_V3: {
+ char pool_name[LOV_MAXPOOLNAME + 1];
+ struct lov_user_ost_data_v1 *objects;
struct lov_user_md_v3 *lmmv3 = (void *)¶m->fp_lmd->lmd_lmm;
strlcpy(pool_name, lmmv3->lmm_pool_name, sizeof(pool_name));
objects = lmmv3->lmm_objects;
- lov_dump_user_lmm_v1v3(¶m->fp_lmd->lmd_lmm,
- pool_name[0] == '\0' ? NULL : pool_name,
- objects, path, is_dir,
- param->fp_obd_index, param->fp_max_depth,
- param->fp_verbose, param->fp_raw);
- break;
+ lov_dump_user_lmm_v1v3(¶m->fp_lmd->lmd_lmm, pool_name,
+ objects, path, param->fp_obd_index,
+ param->fp_max_depth, param->fp_verbose,
+ flags);
+ break;
}
case LMV_MAGIC_V1:
case LMV_USER_MAGIC: {
lum = (struct lmv_user_md *)param->fp_lmv_md;
strlcpy(pool_name, lum->lum_pool_name, sizeof(pool_name));
- lmv_dump_user_lmm(lum,
- pool_name[0] == '\0' ? NULL : pool_name,
- path, param->fp_obd_index,
+ lmv_dump_user_lmm(lum, pool_name, path, param->fp_obd_index,
param->fp_max_depth, param->fp_verbose);
break;
}
+ case LOV_USER_MAGIC_COMP_V1:
+ lov_dump_comp_v1(param, path, flags);
+ break;
default:
llapi_printf(LLAPI_MSG_NORMAL, "unknown lmm_magic: %#x "
"(expecting one of %#x %#x %#x %#x)\n",
return rc;
}
-/* Check if the value matches 1 of the given criteria (e.g. --atime +/-N).
- * @mds indicates if this is MDS timestamps and there are attributes on OSTs.
- *
- * The result is -1 if it does not match, 0 if not yet clear, 1 if matches.
- * The table below gives the answers for the specified parameters (value and
- * sign), 1st column is the answer for the MDS value, the 2nd is for the OST:
- * --------------------------------------
- * 1 | file > limit; sign > 0 | -1 / -1 |
- * 2 | file = limit; sign > 0 | -1 / -1 |
- * 3 | file < limit; sign > 0 | ? / 1 |
- * 4 | file > limit; sign = 0 | -1 / -1 |
- * 5 | file = limit; sign = 0 | ? / 1 | <- (see the Note below)
- * 6 | file < limit; sign = 0 | ? / -1 |
- * 7 | file > limit; sign < 0 | 1 / 1 |
- * 8 | file = limit; sign < 0 | ? / -1 |
- * 9 | file < limit; sign < 0 | ? / -1 |
- * --------------------------------------
- * Note: 5th actually means that the value is within the interval
- * (limit - margin, limit]. */
-static int find_value_cmp(unsigned long long file, unsigned long long limit,
- int sign, int negopt, unsigned long long margin,
- int mds)
-{
- int ret = -1;
-
- if (sign > 0) {
- /* Drop the fraction of margin (of days). */
- if (file + margin <= limit)
- ret = mds ? 0 : 1;
- } else if (sign == 0) {
- if (file <= limit && file + margin > limit)
- ret = mds ? 0 : 1;
- else if (file + margin <= limit)
- ret = mds ? 0 : -1;
- } else if (sign < 0) {
- if (file > limit)
- ret = 1;
- else if (mds)
- ret = 0;
- }
-
- return negopt ? ~ret + 1 : ret;
-}
-
/* Check if the file time matches all the given criteria (e.g. --atime +/-N).
* Return -1 or 1 if file timestamp does not or does match the given criteria
* correspondingly. Return 0 if the MDS time is being checked and there are
*/
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;
- struct lov_user_ost_data_v1 *lmm_objects;
- int i, j;
+ int i, j, k, count = 1;
if (param->fp_obd_uuid && param->fp_obd_index == OBD_NOT_FOUND)
return 0;
/* Only those files should be accepted, which have a
* stripe on the specified OST. */
- if (!param->fp_lmd->lmd_lmm.lmm_stripe_count)
- 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;
+ }
- if (param->fp_lmd->lmd_lmm.lmm_magic ==
- LOV_USER_MAGIC_V3) {
- struct lov_user_md_v3 *lmmv3 = (void *)¶m->fp_lmd->lmd_lmm;
+ for (i = 0; i < count; i++) {
+ if (comp_v1)
+ v1 = lov_comp_entry(comp_v1, i);
- lmm_objects = lmmv3->lmm_objects;
- } else if (param->fp_lmd->lmd_lmm.lmm_magic == LOV_USER_MAGIC_V1) {
- lmm_objects = param->fp_lmd->lmd_lmm.lmm_objects;
- } else {
- llapi_err_noerrno(LLAPI_MSG_ERROR, "%s:Unknown magic: 0x%08X\n",
- __func__, param->fp_lmd->lmd_lmm.lmm_magic);
- return -EINVAL;
- }
+ objects = lov_v1v3_objects(v1);
- for (i = 0; i < param->fp_lmd->lmd_lmm.lmm_stripe_count; i++) {
- for (j = 0; j < param->fp_num_obds; j++) {
- if (param->fp_obd_indexes[j] ==
- lmm_objects[i].l_ost_idx) {
- if (param->fp_exclude_obd)
- return 0;
- return 1;
+ for (j = 0; j < v1->lmm_stripe_count; j++) {
+ for (k = 0; k < param->fp_num_obds; k++) {
+ if (param->fp_obd_indexes[k] ==
+ objects[j].l_ost_idx)
+ return !param->fp_exclude_obd;
}
}
}
- if (param->fp_exclude_obd)
- return 1;
-
- return 0;
+ return param->fp_exclude_obd;
}
static int check_mdt_match(struct find_param *param)
return ret;
}
+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;
+ int ret, i, count = 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)
+ 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 */
+ if (ret != -1)
+ break;
+ }
+
+ return ret;
+}
+
+static __u32 find_get_stripe_count(struct find_param *param)
+{
+ struct lov_comp_md_v1 *comp_v1 = NULL;
+ struct lov_user_md_v1 *v1 = ¶m->fp_lmd->lmd_lmm;
+ int i, count = 1;
+ __u32 stripe_count = 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)
+ v1 = lov_comp_entry(comp_v1, i);
+ stripe_count += v1->lmm_stripe_count;
+ }
+
+ return stripe_count;
+}
+
+#define LOV_PATTERN_INVALID 0xFFFFFFFF
+
+static int find_check_layout(struct find_param *param)
+{
+ struct lov_comp_md_v1 *comp_v1 = NULL;
+ struct lov_user_md_v1 *v1 = ¶m->fp_lmd->lmd_lmm;
+ int i, count = 1;
+ bool found = false, valid = false;
+
+ 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)
+ v1 = lov_comp_entry(comp_v1, i);
+
+ if (v1->lmm_pattern == LOV_PATTERN_INVALID)
+ continue;
+
+ valid = true;
+ if (v1->lmm_pattern & param->fp_layout) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!valid)
+ return -1;
+
+ if ((found && !param->fp_exclude_layout) ||
+ (!found && param->fp_exclude_layout))
+ return 1;
+
+ return -1;
+}
+
+static int find_check_pool(struct find_param *param)
+{
+ struct lov_comp_md_v1 *comp_v1 = NULL;
+ struct lov_user_md_v1 *v1 = ¶m->fp_lmd->lmd_lmm;
+ struct lov_user_md_v3 *v3 = (void *)v1;
+ int i, count = 1;
+ bool found = false;
+
+ if (v1->lmm_magic == LOV_USER_MAGIC_COMP_V1) {
+ comp_v1 = (struct lov_comp_md_v1 *)v1;
+ count = comp_v1->lcm_entry_count;
+ /* empty requested pool is taken as no pool search */
+ if (count == 0 && param->fp_poolname[0] == '\0')
+ found = true;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (comp_v1 != NULL)
+ v1 = lov_comp_entry(comp_v1, i);
+
+ if (((v1->lmm_magic == LOV_USER_MAGIC_V1) &&
+ (param->fp_poolname[0] == '\0')) ||
+ ((v1->lmm_magic == LOV_USER_MAGIC_V3) &&
+ (strncmp(v3->lmm_pool_name,
+ param->fp_poolname, LOV_MAXPOOLNAME) == 0)) ||
+ ((v1->lmm_magic == LOV_USER_MAGIC_V3) &&
+ (strcmp(param->fp_poolname, "*") == 0))) {
+ found = true;
+ break;
+ }
+ }
+
+ if ((found && !param->fp_exclude_pool) ||
+ (!found && param->fp_exclude_pool))
+ return 1;
+
+ return -1;
+}
+
+static int find_check_comp_options(struct find_param *param)
+{
+ struct lov_comp_md_v1 *comp_v1;
+ struct lov_user_md_v1 *v1 = ¶m->fp_lmd->lmd_lmm;
+ struct lov_comp_md_entry_v1 *entry;
+ int i, ret;
+
+ if (v1->lmm_magic != LOV_USER_MAGIC_COMP_V1) {
+ if ((param->fp_check_comp_count &&
+ !param->fp_exclude_comp_count) ||
+ (param->fp_check_comp_flags &&
+ !param->fp_exclude_comp_flags) ||
+ (param->fp_check_comp_start &&
+ !param->fp_exclude_comp_start) ||
+ (param->fp_check_comp_end &&
+ !param->fp_exclude_comp_end))
+ return -1;
+ else
+ return 1;
+ }
+
+ comp_v1 = (struct lov_comp_md_v1 *)v1;
+
+ if (param->fp_check_comp_count) {
+ ret = find_value_cmp(comp_v1->lcm_entry_count,
+ param->fp_comp_count,
+ param->fp_comp_count_sign,
+ param->fp_exclude_comp_count, 1, 0);
+ if (ret == -1)
+ return ret;
+ }
+
+ if (comp_v1->lcm_entry_count == 0) {
+ if ((param->fp_check_comp_flags &&
+ !param->fp_exclude_comp_flags) ||
+ (param->fp_check_comp_start &&
+ !param->fp_exclude_comp_start) ||
+ (param->fp_check_comp_end &&
+ !param->fp_exclude_comp_end))
+ return -1;
+ }
+
+ if (param->fp_check_comp_flags) {
+ for (i = 0; i < comp_v1->lcm_entry_count; i++) {
+ entry = &comp_v1->lcm_entries[i];
+
+ if (((entry->lcme_flags & param->fp_comp_flags) &&
+ param->fp_exclude_comp_flags) ||
+ (!(entry->lcme_flags & param->fp_comp_flags) &&
+ !param->fp_exclude_comp_flags))
+ ret = -1;
+ else
+ ret = 1;
+ /* If any flags matches */
+ if (ret != -1)
+ break;
+ }
+ if (ret == -1)
+ return ret;
+ }
+
+ if (param->fp_check_comp_start) {
+ for (i = 0; i < comp_v1->lcm_entry_count; i++) {
+ entry = &comp_v1->lcm_entries[i];
+
+ ret = find_value_cmp(entry->lcme_extent.e_start,
+ param->fp_comp_start,
+ param->fp_comp_start_sign,
+ param->fp_exclude_comp_start,
+ param->fp_comp_start_units, 0);
+ /* If any extent start matches */
+ if (ret != -1)
+ break;
+ }
+ if (ret == -1)
+ return ret;
+ }
+
+ if (param->fp_check_comp_end) {
+ for (i = 0; i < comp_v1->lcm_entry_count; i++) {
+ unsigned long long margin;
+ entry = &comp_v1->lcm_entries[i];
+
+ margin = entry->lcme_extent.e_end == LUSTRE_EOF ?
+ 0 : param->fp_comp_end_units;
+
+ ret = find_value_cmp(entry->lcme_extent.e_end,
+ param->fp_comp_end,
+ param->fp_comp_end_sign,
+ param->fp_exclude_comp_end, margin,
+ 0);
+ /* If any extent end matches */
+ if (ret != -1)
+ break;
+ }
+ if (ret == -1)
+ return ret;
+ }
+
+ return 1;
+}
+
+static bool find_check_lmm_info(struct find_param *param)
+{
+ return param->fp_check_pool || param->fp_check_stripe_count ||
+ 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;
+}
+
static int cb_find_init(char *path, DIR *parent, DIR **dirp,
void *data, struct dirent64 *de)
{
- struct find_param *param = (struct find_param *)data;
+ struct find_param *param = (struct find_param *)data;
DIR *dir = dirp == NULL ? NULL : *dirp;
- int decision = 1; /* 1 is accepted; -1 is rejected. */
+ int decision = 1; /* 1 is accepted; -1 is rejected. */
lstat_t *st = ¶m->fp_lmd->lmd_st;
- int lustre_fs = 1;
- int checked_type = 0;
- int ret = 0;
+ int lustre_fs = 1;
+ int checked_type = 0;
+ int ret = 0;
+ __u32 stripe_count = 0;
if (parent == NULL && dir == NULL)
return -EINVAL;
- param->fp_lmd->lmd_lmm.lmm_stripe_count = 0;
-
/* If a regular expression is presented, make the initial decision */
if (param->fp_pattern != NULL) {
char *fname = strrchr(path, '/');
if (param->fp_obd_uuid || param->fp_mdt_uuid ||
param->fp_check_uid || param->fp_check_gid ||
param->fp_atime || param->fp_mtime || param->fp_ctime ||
- param->fp_check_pool || param->fp_check_size ||
- param->fp_check_stripe_count || param->fp_check_stripe_size ||
- param->fp_check_layout)
+ param->fp_check_size || find_check_lmm_info(param))
decision = 0;
if (param->fp_type != 0 && checked_type == 0)
ret = get_lmd_info(path, parent, dir, param->fp_lmd,
param->fp_lum_size);
if (ret == 0 && param->fp_lmd->lmd_lmm.lmm_magic == 0 &&
- (param->fp_check_pool || param->fp_check_stripe_count ||
- param->fp_check_stripe_size || param->fp_check_layout)) {
+ find_check_lmm_info(param)) {
struct lov_user_md *lmm = ¶m->fp_lmd->lmd_lmm;
/* We need to "fake" the "use the default" values
goto decided;
return ret;
+ } else {
+ stripe_count = find_get_stripe_count(param);
}
}
}
if (param->fp_check_stripe_size) {
- decision = find_value_cmp(
- param->fp_lmd->lmd_lmm.lmm_stripe_size,
- param->fp_stripe_size,
- param->fp_stripe_size_sign,
- param->fp_exclude_stripe_size,
- param->fp_stripe_size_units, 0);
+ decision = find_check_stripe_size(param);
if (decision == -1)
goto decided;
}
if (param->fp_check_stripe_count) {
- decision = find_value_cmp(
- param->fp_lmd->lmd_lmm.lmm_stripe_count,
- param->fp_stripe_count,
- param->fp_stripe_count_sign,
- param->fp_exclude_stripe_count, 1, 0);
+ decision = find_value_cmp(stripe_count, param->fp_stripe_count,
+ param->fp_stripe_count_sign,
+ param->fp_exclude_stripe_count, 1, 0);
if (decision == -1)
goto decided;
- }
+ }
if (param->fp_check_layout) {
- __u32 found;
-
- found = (param->fp_lmd->lmd_lmm.lmm_pattern & param->fp_layout);
- if ((param->fp_lmd->lmd_lmm.lmm_pattern == 0xFFFFFFFF) ||
- (found && param->fp_exclude_layout) ||
- (!found && !param->fp_exclude_layout)) {
- decision = -1;
+ decision = find_check_layout(param);
+ if (decision == -1)
goto decided;
- }
}
/* If an OBD UUID is specified but none matches, skip this file. */
}
if (param->fp_check_pool) {
- struct lov_user_md_v3 *lmmv3 = (void *)¶m->fp_lmd->lmd_lmm;
+ decision = find_check_pool(param);
+ if (decision == -1)
+ goto decided;
+ }
- /* empty requested pool is taken as no pool search => V1 */
- if (((param->fp_lmd->lmd_lmm.lmm_magic == LOV_USER_MAGIC_V1) &&
- (param->fp_poolname[0] == '\0')) ||
- ((param->fp_lmd->lmd_lmm.lmm_magic == LOV_USER_MAGIC_V3) &&
- (strncmp(lmmv3->lmm_pool_name,
- param->fp_poolname, LOV_MAXPOOLNAME) == 0)) ||
- ((param->fp_lmd->lmd_lmm.lmm_magic == LOV_USER_MAGIC_V3) &&
- (strcmp(param->fp_poolname, "*") == 0))) {
- if (param->fp_exclude_pool)
- goto decided;
- } else {
- if (!param->fp_exclude_pool)
- goto decided;
- }
+ if (param->fp_check_comp_count || param->fp_check_comp_flags ||
+ param->fp_check_comp_start || param->fp_check_comp_end) {
+ decision = find_check_comp_options(param);
+ if (decision == -1)
+ goto decided;
}
/* Check the time on mds. */
if (param->fp_atime || param->fp_mtime || param->fp_ctime) {
int for_mds;
- for_mds = lustre_fs ? (S_ISREG(st->st_mode) &&
- param->fp_lmd->lmd_lmm.lmm_stripe_count)
- : 0;
+ 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;
The regular stat is almost of the same speed as some new
'glimpse-size-ioctl'. */
- if (param->fp_check_size && S_ISREG(st->st_mode) &&
- param->fp_lmd->lmd_lmm.lmm_stripe_count)
- decision = 0;
+ if (param->fp_check_size && S_ISREG(st->st_mode) && stripe_count)
+ decision = 0;
if (param->fp_check_size && S_ISDIR(st->st_mode))
decision = 0;
dump:
if (!(param->fp_verbose & VERBOSE_MDTINDEX))
- llapi_lov_dump_user_lmm(param, path, d ? 1 : 0);
+ llapi_lov_dump_user_lmm(param, path, d ? LDF_IS_DIR : 0);
out:
/* Do not get down anymore? */