Show only the file layout, which is one of:
.RS 1.2i
.TP
+.B bad
+Files that have an invalid layout and are inaccessible.
+.TP
+.B foreign
+Files that have a foreign (non-Lustre/free format) component.
+Such files may be inaccessible without external software integration.
+.TP
+.B hole
+Files that are missing a data object,
+possibly due to OST failure and layout reconstruction by LFSCK.
+.TP
+.B mdt
+Files that store the first data component on the MDT holding the inode.
+.TP
+.B overstriped
+Files have more than one stripe per OST for improved lock scalability.
+.TP
.B raid0
Traditional Lustre RAID-0 striping format.
.TP
.B released
HSM-archived files that are not resident in the filesystem.
-.TP
-.B mdt
-Files that have the first data component on an MDT.
.RE
.TP
.BR -m ", " --mdt ", " --mdt-index
allows the MDS to choose the starting index and it is strongly recommended, as
this allows space and load balancing to be done by the MDS as needed.
.TP
-
+.BR -L ", " --layout " \fILAYOUT_TYPE"
The type of layout for that component, which can be one of:
.RS
.B raid0\fR - stripe the file data across
llapi_layout_stripe_count_set.3 \
llapi_layout_stripe_size_get.3 \
llapi_layout_stripe_size_set.3 \
+ llapi_lov_pattern_string.3 \
+ llapi_lov_string_pattern.3 \
llapi_open_by_fid.3 \
llapi_open_by_fid_at.3 \
llapi_param_get_paths.3 \
--- /dev/null
+.TH LLAPI_LOV_STRING_PATTERN 3 2025-06-04 "Lustre User API" "Lustre Library Functions"
+.SH NAME
+llapi_lov_string_pattern \- convert pattern name string to LOV_PATTERN mask
+.SH SYNOPSIS
+.nf
+.B #include <lustre/lustreapi.h>
+.PP
+.BI "int llapi_lov_string_pattern(const char *" string ", enum lov_pattern *" pattern );
+.fi
+.SH DESCRIPTION
+.B llapi_lov_string_pattern()
+converts the comma-separated list of LOV pattern names in
+.I string
+to a mask of
+.B LOV_PATTERN_*
+flags returned in
+.IR pattern .
+.SH RETURN VALUES
+.BR llapi_lov_string_pattern( )
+returns 0 on success, or
+.B -EINVAL
+on failure (in which case, errno is set appropriately).
+.SH AVAILABILITY
+.BR llapi_lov_string_pattern ()
+is part of the
+.BR lustre (7)
+user application interface library since release 2.17.0
+.SH SEE ALSO
+.BR llapi_lov_pattern_string (3),
+.BR lustre (7),
+.BR lustreapi (7)
--- /dev/null
+.TH LLAPI_LOV_PATTERN_STRING 3 2025-06-04 "Lustre User API" "Lustre Library Functions"
+.SH NAME
+llapi_lov_pattern_string \- convert LOV_PATTERN mask to string
+.SH SYNOPSIS
+.nf
+.B #include <lustre/lustreapi.h>
+.PP
+.BI "int llapi_lov_pattern_string(enum lov_pattern " pattern ", char *" buf \
+ ", size_t " buflen ");"
+.fi
+.SH DESCRIPTION
+.B llapi_lov_pattern_string()
+converts the
+.I pattern
+mask to a comma-separated string of pattern names
+in the
+.I buf
+buffer, up to
+.I buflen
+bytes in length.
+.SH RETURN VALUES
+.B llapi_lov_pattern_string()
+returns a pointer to the
+.B buf
+string on success, or NULL on failure
+(currently only in case of buffer overflow).
+.SH AVAILABILITY
+.BR llapi_lov_pattern_string ()
+is part of the
+.BR lustre (7)
+user application interface library since release 2.17.0
+.SH SEE ALSO
+.BR llapi_lov_string_pattern (3),
+.BR lustre (7),
+.BR lustreapi (7)
unsigned long long lsp_stripe_size;
char *lsp_pool;
int lsp_stripe_offset;
- int lsp_stripe_pattern;
+ enum lov_pattern lsp_stripe_pattern;
/* Number of stripes. Size of lsp_osts[] if lsp_specific is true.*/
int lsp_stripe_count;
bool lsp_is_specific;
LLAPI_MIGRATION_VERBOSE = 0x0008,
};
-__u32 llapi_pattern_to_lov(uint64_t pattern);
+enum lov_pattern llapi_pattern_to_lov(uint64_t pattern);
int llapi_file_open_param(const char *name, int flags, mode_t mode,
const struct llapi_stripe_param *param);
int llapi_file_create_foreign(const char *name, mode_t mode, __u32 type,
__u32 flags, char *foreign_lov);
int llapi_file_create(const char *name, unsigned long long stripe_size,
- int stripe_offset, int stripe_count, int stripe_pattern);
+ int stripe_offset, int stripe_count,
+ enum lov_pattern stripe_pattern);
int llapi_file_open(const char *name, int flags, int mode,
unsigned long long stripe_size, int stripe_offset,
- int stripe_count, int stripe_pattern);
+ int stripe_count, enum lov_pattern stripe_pattern);
int llapi_file_create_pool(const char *name, unsigned long long stripe_size,
int stripe_offset, int stripe_count,
- int stripe_pattern, char *pool_name);
+ enum lov_pattern stripe_pattern, char *pool_name);
int llapi_file_open_pool(const char *name, int flags, int mode,
unsigned long long stripe_size, int stripe_offset,
- int stripe_count, int stripe_pattern, char *pool_name);
+ int stripe_count, enum lov_pattern stripe_pattern,
+ char *pool_name);
int llapi_poollist(const char *name);
int llapi_get_poolbuf(const char *name, char **buf,
char ***poolist, int *poolcount);
int llapi_dir_create_foreign(const char *name, mode_t mode, __u32 type,
__u32 flags, const char *value);
int llapi_dir_create_pool(const char *name, int flags, int stripe_offset,
- int stripe_count, int stripe_pattern,
+ int stripe_count, enum lov_pattern stripe_pattern,
const char *poolname);
int llapi_direntry_remove(char *dname);
int llapi_unlink_foreign(char *dname);
int llapi_hsm_action_get_fd(const struct hsm_copyaction_private *hcp);
int llapi_hsm_import(const char *dst, int archive, const struct stat *st,
unsigned long long stripe_size, int stripe_offset,
- int stripe_count, int stripe_pattern, char *pool_name,
- struct lu_fid *newfid);
+ int stripe_count, enum lov_pattern stripe_pattern,
+ char *pool_name, struct lu_fid *newfid);
/* HSM user interface */
struct hsm_user_request *llapi_hsm_user_request_alloc(int itemcount,
int llapi_layout_flags_get(struct llapi_layout *layout, uint32_t *flags);
const char *llapi_layout_flags_string(uint32_t flags);
__u16 llapi_layout_string_flags(char *string);
+char *llapi_lov_pattern_string(enum lov_pattern pattern, char *buf,
+ size_t buflen);
+int llapi_lov_string_pattern(const char *string, enum lov_pattern *pattern);
/**
* llapi_layout_mirror_count_get() - Get mirror count from the header of
#define lov_mds_md lov_mds_md_v1
struct lov_mds_md_v1 { /* LOV EA mds/wire data (little-endian) */
- __u32 lmm_magic; /* magic number = LOV_MAGIC_V1 */
- __u32 lmm_pattern; /* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */
- struct ost_id lmm_oi; /* LOV object ID */
- __u32 lmm_stripe_size; /* size of stripe in bytes */
- /* lmm_stripe_count used to be __u32 */
- __u16 lmm_stripe_count; /* num stripes in use for this object */
- __u16 lmm_layout_gen; /* layout generation number */
- struct lov_ost_data_v1 lmm_objects[]; /* per-stripe data */
+ __u32 lmm_magic; /* LOV_MAGIC_V1 */
+ enum lov_pattern lmm_pattern; /* LOV_PATTERN_RAID0, ... */
+ struct ost_id lmm_oi; /* LOV object ID */
+ __u32 lmm_stripe_size; /* size of stripe in bytes */
+ __u16 lmm_stripe_count; /* OST stripes in layout */
+ __u16 lmm_layout_gen; /* layout generation number */
+ struct lov_ost_data_v1 lmm_objects[]; /* per-stripe data */
};
#define MAX_MD_SIZE_OLD (sizeof(struct lov_mds_md) + \
#define XATTR_JOB_MAX_LEN 13
struct lov_mds_md_v3 { /* LOV EA mds/wire data (little-endian) */
- __u32 lmm_magic; /* magic number = LOV_MAGIC_V3 */
- __u32 lmm_pattern; /* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */
- struct ost_id lmm_oi; /* LOV object ID */
- __u32 lmm_stripe_size; /* size of stripe in bytes */
- /* lmm_stripe_count used to be __u32 */
- __u16 lmm_stripe_count; /* num stripes in use for this object */
- __u16 lmm_layout_gen; /* layout generation number */
- char lmm_pool_name[LOV_MAXPOOLNAME + 1]; /* must be 32bit aligned */
- struct lov_ost_data_v1 lmm_objects[]; /* per-stripe data */
+ __u32 lmm_magic; /* LOV_MAGIC_V3 */
+ enum lov_pattern lmm_pattern; /* LOV_PATTERN_RAID0, ... */
+ struct ost_id lmm_oi; /* LOV object ID */
+ __u32 lmm_stripe_size; /* size of stripe in bytes */
+ __u16 lmm_stripe_count; /* OST stripes in layout */
+ __u16 lmm_layout_gen; /* layout generation number */
+ char lmm_pool_name[LOV_MAXPOOLNAME + 1];
+ struct lov_ost_data_v1 lmm_objects[]; /* per-stripe data */
};
static inline __u32 lov_mds_md_size(__u16 stripes, __u32 lmm_magic)
__u32 ld_tgt_count; /* how many OBD's */
__u32 ld_active_tgt_count; /* how many active */
__s32 ld_default_stripe_count; /* how many objects are used */
- __u32 ld_pattern; /* default PATTERN_RAID0 */
+ enum lov_pattern ld_pattern; /* default LOV_PATTERN_RAID0 */
__u64 ld_default_stripe_size; /* in bytes */
__s64 ld_default_stripe_offset; /* starting OST index */
__u32 ld_padding_0; /* unused */
#define LMV_USER_MAGIC_V0 0x0CD20CD0 /* old default lmv magic*/
#define LMV_USER_MAGIC_SPECIFIC 0x0CD40CD0
-#define LOV_PATTERN_NONE 0x000
-#define LOV_PATTERN_RAID0 0x001
-#define LOV_PATTERN_RAID1 0x002
-#define LOV_PATTERN_MDT 0x100
-#define LOV_PATTERN_OVERSTRIPING 0x200
-#define LOV_PATTERN_FOREIGN 0x400
-#define LOV_PATTERN_COMPRESS 0x800
-
-/* combine exclusive patterns as a bad pattern */
-#define LOV_PATTERN_BAD (LOV_PATTERN_RAID1 | LOV_PATTERN_MDT | \
- LOV_PATTERN_FOREIGN)
-
-#define LOV_PATTERN_F_MASK 0xffff0000
-#define LOV_PATTERN_F_HOLE 0x40000000 /* there is hole in LOV EA */
-#define LOV_PATTERN_F_RELEASED 0x80000000 /* HSM released file */
-#define LOV_PATTERN_DEFAULT 0xffffffff
+enum lov_pattern {
+ LOV_PATTERN_NONE = 0x000,
+ LOV_PATTERN_RAID0 = 0x001,
+ LOV_PATTERN_RAID1 = 0x002,
+ LOV_PATTERN_MDT = 0x100,
+ LOV_PATTERN_OVERSTRIPING = 0x200,
+ LOV_PATTERN_FOREIGN = 0x400,
+ LOV_PATTERN_COMPRESS = 0x800,
+
+ /* combine exclusive patterns as a bad pattern */
+ LOV_PATTERN_BAD = (LOV_PATTERN_RAID1 | LOV_PATTERN_MDT |
+ LOV_PATTERN_FOREIGN),
+
+ LOV_PATTERN_F_MASK = 0xffff0000,
+ LOV_PATTERN_F_HOLE = 0x40000000, /* hole in LOV EA objects */
+ LOV_PATTERN_F_RELEASED = 0x80000000, /* HSM released file */
+ LOV_PATTERN_DEFAULT = 0xffffffff
+};
#define LOV_OFFSET_DEFAULT ((__u16)-1)
#define LMV_OFFSET_DEFAULT ((__u32)-1)
-static inline bool lov_pattern_supported(__u32 pattern)
+static inline bool lov_pattern_supported(enum lov_pattern pattern)
{
- __u32 pattern_base = pattern & ~LOV_PATTERN_F_RELEASED;
+ enum lov_pattern pattern_base = pattern & ~LOV_PATTERN_F_RELEASED;
return pattern_base == LOV_PATTERN_RAID0 ||
pattern_base == (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING) ||
* having many extra checks on lov_pattern_supported, we have this separate
* check for non-released, non-readonly, non-DOM components
*/
-static inline bool lov_pattern_supported_normal_comp(__u32 pattern)
+static inline bool lov_pattern_supported_normal_comp(enum lov_pattern pattern)
{
return pattern == LOV_PATTERN_RAID0 ||
pattern == (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING);
echo -n "Verifying released pattern: "
local PTRN=$($LFS getstripe -L $f)
echo $PTRN
- [[ $PTRN == released ]] || error "Is not released"
+ [[ $PTRN =~ released ]] || error "Is not released"
local fid=$(path2fid $f)
echo "Verifying new fid $fid in archive"
run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
test_229() { # LU-2482, LU-3448
- [ $PARALLEL == "yes" ] && skip "skip parallel run"
- [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
- [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
- skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
+ [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
+ (( $OSTCOUNT >= 2 )) || skip_env "needs >= 2 OSTs"
+ (( $MDS1_VERSION >= $(version_code 2.4.50.0-53-ga61ff5914b) )) ||
+ skip "need MDS >= 2.4.50.53 for HSM released file"
rm -f $DIR/$tfile
$LFS getstripe -v $DIR/$tfile
local pattern=$($LFS getstripe -L $DIR/$tfile)
- [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
+ [[ "$pattern" =~ "released" ]] || error "pattern error ($pattern)"
local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
error "getstripe"
- [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
+ (( $stripe_count == 2 )) || error "stripe count not 2 ($stripe_count)"
stat $DIR/$tfile || error "failed to stat released file"
chown $RUNAS_ID $DIR/$tfile ||
return 0;
}
-static int name2layout(__u32 *layout, char *name)
-{
- char *ptr, *layout_name;
-
- *layout = 0;
- for (ptr = name; ; ptr = NULL) {
- layout_name = strtok(ptr, ",");
- if (!layout_name)
- break;
- if (strcmp(layout_name, "released") == 0)
- *layout |= LOV_PATTERN_F_RELEASED;
- else if (strcmp(layout_name, "raid0") == 0)
- *layout |= LOV_PATTERN_RAID0;
- else if (strcmp(layout_name, "mdt") == 0)
- *layout |= LOV_PATTERN_MDT;
- else if (strcmp(layout_name, "overstriping") == 0)
- *layout |= LOV_PATTERN_OVERSTRIPING;
- else if (strcmp(layout_name, "foreign") == 0)
- *layout |= LOV_PATTERN_FOREIGN;
- else
- return -1;
- }
- return 0;
-}
-
static int name2attrs(char *name, __u64 *attrs, __u64 *neg_attrs)
{
char *ptr, *attr_name = name;
param.fp_lazy = 1;
break;
case 'L':
- ret = name2layout(¶m.fp_layout, optarg);
+ ret = llapi_lov_string_pattern(optarg, ¶m.fp_layout);
if (ret)
goto err;
param.fp_exclude_layout = !!neg_opt;
int llapi_file_open_pool(const char *name, int flags, int mode,
unsigned long long stripe_size, int stripe_offset,
- int stripe_count, int stripe_pattern, char *pool_name)
+ int stripe_count, enum lov_pattern stripe_pattern,
+ char *pool_name)
{
const struct llapi_stripe_param param = {
.lsp_stripe_size = stripe_size,
int llapi_file_open(const char *name, int flags, int mode,
unsigned long long stripe_size, int stripe_offset,
- int stripe_count, int stripe_pattern)
+ int stripe_count, enum lov_pattern stripe_pattern)
{
return llapi_file_open_pool(name, flags, mode, stripe_size,
stripe_offset, stripe_count,
}
int llapi_file_create(const char *name, unsigned long long stripe_size,
- int stripe_offset, int stripe_count, int stripe_pattern)
+ int stripe_offset, int stripe_count,
+ enum lov_pattern stripe_pattern)
{
int fd;
int llapi_file_create_pool(const char *name, unsigned long long stripe_size,
int stripe_offset, int stripe_count,
- int stripe_pattern, char *pool_name)
+ enum lov_pattern stripe_pattern, char *pool_name)
{
int fd;
}
int llapi_dir_create_pool(const char *name, int mode, int stripe_offset,
- int stripe_count, int stripe_pattern,
+ int stripe_count, enum lov_pattern stripe_pattern,
const char *pool_name)
{
const struct llapi_stripe_param param = {
return 0;
}
-static char *layout2name(__u32 layout_pattern)
-{
- if (layout_pattern & LOV_PATTERN_F_RELEASED)
- return "released";
- else if (layout_pattern & LOV_PATTERN_FOREIGN)
- return "foreign";
- else if (layout_pattern == LOV_PATTERN_MDT)
- return "mdt";
- else if (layout_pattern == LOV_PATTERN_RAID0)
- return "raid0";
- else if (layout_pattern ==
- (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING))
- return "raid0,overstriped";
- else
- return "unknown";
-}
-
enum lov_dump_flags {
LDF_IS_DIR = 0x0001,
LDF_IS_RAW = 0x0002,
}
if ((verbose & VERBOSE_PATTERN)) {
+ char buf[128];
+
llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_PATTERN)
llapi_printf(LLAPI_MSG_NORMAL, "%s%spattern: ",
space, prefix);
if (lov_pattern_supported(lum->lmm_pattern))
llapi_printf(LLAPI_MSG_NORMAL, "%s",
- layout2name(lum->lmm_pattern));
+ llapi_lov_pattern_string(lum->lmm_pattern,
+ buf, sizeof(buf)) ?:
+ "overflow");
else
llapi_printf(LLAPI_MSG_NORMAL, "%x", lum->lmm_pattern);
separator = (!yaml && is_dir) ? " " : "\n";
*/
int llapi_hsm_import(const char *dst, int archive, const struct stat *st,
unsigned long long stripe_size, int stripe_offset,
- int stripe_count, int stripe_pattern, char *pool_name,
- struct lu_fid *newfid)
+ int stripe_count, enum lov_pattern stripe_pattern,
+ char *pool_name, struct lu_fid *newfid)
{
struct hsm_user_import hui;
int fd;
goto out;
}
-__u32 llapi_pattern_to_lov(uint64_t pattern)
+enum lov_pattern llapi_pattern_to_lov(uint64_t llapi_pattern)
{
- __u32 lov_pattern;
+ enum lov_pattern lov_pattern;
- switch (pattern) {
+ switch (llapi_pattern) {
case LLAPI_LAYOUT_DEFAULT:
lov_pattern = LOV_PATTERN_RAID0;
break;
return 0;
}
+static struct {
+ enum lov_pattern llpn_pattern;
+ const char *llpn_pattern_name;
+} lov_pattern_names[] = {
+ { LOV_PATTERN_RAID0, "raid0" },
+ { LOV_PATTERN_RAID1, "raid1" },
+ { LOV_PATTERN_MDT, "mdt" },
+ { LOV_PATTERN_OVERSTRIPING, "overstriped" }, /* getstripe */
+ { LOV_PATTERN_OVERSTRIPING, "overstriping" }, /* setstripe compat */
+ { LOV_PATTERN_BAD, "bad" },
+ { LOV_PATTERN_FOREIGN, "foreign" },
+ { LOV_PATTERN_COMPRESS, "compress" },
+ { LOV_PATTERN_F_HOLE, "hole" },
+ { LOV_PATTERN_F_RELEASED, "released" },
+ { LOV_PATTERN_DEFAULT, "default" },
+ { 0, NULL }
+};
+
+int llapi_lov_string_pattern(const char *string, enum lov_pattern *pattern)
+{
+ const char *p;
+
+ *pattern = 0;
+ for (p = string; p != NULL; p = strchr(p, ',')) {
+ int i;
+
+ while (*p == ',')
+ p++;
+ if (*p == '\0')
+ break;
+ for (i = 0; lov_pattern_names[i].llpn_pattern != 0; i++) {
+ int l;
+
+ l = strlen(lov_pattern_names[i].llpn_pattern_name);
+ if (strncmp(p, lov_pattern_names[i].llpn_pattern_name,
+ l))
+ continue;
+ *pattern |= lov_pattern_names[i].llpn_pattern;
+ break;
+ }
+ if (lov_pattern_names[i].llpn_pattern == 0) {
+ errno = EINVAL;
+ return -errno;
+ }
+ }
+
+ return 0;
+}
+
+char *llapi_lov_pattern_string(enum lov_pattern pattern, char *buf,
+ size_t buflen)
+{
+ char *p = buf;
+ int l = 0;
+ int i;
+
+ p[0] = '\0';
+ for (i = 0; lov_pattern_names[i].llpn_pattern && pattern; i++) {
+ if ((lov_pattern_names[i].llpn_pattern & pattern) ==
+ lov_pattern_names[i].llpn_pattern) {
+ l += snprintf(p, buflen - l, "%s%s", buf[0] ? "," : "",
+ lov_pattern_names[i].llpn_pattern_name);
+ pattern &= ~lov_pattern_names[i].llpn_pattern;
+ if (l >= buflen) {
+ errno = EOVERFLOW;
+ return NULL;
+ }
+ p = buf + l;
+ }
+ }
+
+ if (pattern)
+ snprintf(buf, buflen, "%sunknown_%x", buf[0] ? "," : "",
+ pattern);
+
+ return buf;
+}
+
/**
* llapi_layout_mirror_count_is_valid() - Check the validity of mirror count.
* @count: Mirror count value to be checked.