#endif
#define LP_POISON ((void *)LL_POISON)
+extern int llite_enable_compression;
+
#ifdef HAVE_SERVER_SUPPORT
int rev_import_init(struct obd_export *exp);
int target_handle_connect(struct ptlrpc_request *req);
static inline bool lov_pattern_supported(__u32 pattern)
{
- pattern &= ~LOV_PATTERN_F_RELEASED;
- return pattern == LOV_PATTERN_RAID0 ||
- pattern == (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING) ||
- pattern == LOV_PATTERN_MDT;
+ __u32 pattern_base = pattern & ~LOV_PATTERN_F_RELEASED;
+
+ return pattern_base == LOV_PATTERN_RAID0 ||
+ pattern_base == (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING) ||
+ pattern_base == (LOV_PATTERN_RAID0 | LOV_PATTERN_COMPRESS) ||
+ pattern_base == LOV_PATTERN_MDT;
}
/* RELEASED and MDT patterns are not valid in many places, so rather than
#define LCME_KNOWN_FLAGS (LCME_FL_NEG | LCME_FL_INIT | LCME_FL_STALE | \
LCME_FL_PREF_RW | LCME_FL_NOSYNC | \
- LCME_FL_EXTENSION)
+ LCME_FL_EXTENSION | LCME_FL_NOCOMPR)
/* The component flags can be set by users at creation/modification time. */
#define LCME_USER_COMP_FLAGS (LCME_FL_PREF_RW | LCME_FL_NOSYNC | \
#define LCME_USER_MIRROR_FLAGS (LCME_FL_PREF_RW)
/* The allowed flags obtained from the client at component creation time. */
-#define LCME_CL_COMP_FLAGS (LCME_USER_MIRROR_FLAGS | LCME_FL_EXTENSION)
+#define LCME_CL_COMP_FLAGS (LCME_USER_MIRROR_FLAGS | LCME_FL_EXTENSION | \
+ LCME_FL_NOCOMPR)
/* The mirror flags sent by client */
#define LCME_MIRROR_FLAGS (LCME_FL_NOSYNC)
* from the default/template layout set on a directory.
*/
#define LCME_TEMPLATE_FLAGS (LCME_FL_PREF_RW | LCME_FL_NOSYNC | \
- LCME_FL_EXTENSION)
+ LCME_FL_EXTENSION | LCME_FL_NOCOMPR)
/* lcme_id can be specified as certain flags, and the the first
* bit of lcme_id is used to indicate that the ID is representing
}
LDEBUGFS_SEQ_FOPS(ll_pcc);
+static int ll_enable_compression_seq_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "%d\n", llite_enable_compression ? 1 : 0);
+ return 0;
+}
+
+static ssize_t ll_enable_compression_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
+{
+ int val;
+ int rc;
+
+ rc = kstrtoint_from_user(buffer, count, 0, &val);
+ if (rc < 0)
+ return rc;
+
+ llite_enable_compression = !!val;
+
+ return count;
+}
+LDEBUGFS_SEQ_FOPS(ll_enable_compression);
+
struct ldebugfs_vars lprocfs_llite_obd_vars[] = {
{ .name = "site",
.fops = &ll_site_stats_fops },
.fops = &ll_nosquash_nids_fops },
{ .name = "pcc",
.fops = &ll_pcc_fops, },
+ { .name = "enable_compression",
+ .fops = &ll_enable_compression_fops, },
{ NULL }
};
__u32 llc_flags;
__u32 llc_magic;
__u64 llc_timestamp; /* snapshot time */
+ __u8 llc_compr_type;
+ __u8 llc_compr_lvl:4;
+ __u16 llc_compr_chunk_log_bits; /* chunk_size =
+ * 2^chunk_log_bits
+ */
union {
struct { /* plain layout V1/V3. */
__u32 llc_pattern;
cpu_to_le64(lod_comp->llc_extent.e_end);
lcme->lcme_offset = cpu_to_le32(offset);
+ if (lod_comp->llc_pattern & LOV_PATTERN_COMPRESS) {
+ lcme->lcme_compr_type = lod_comp->llc_compr_type;
+ lcme->lcme_compr_lvl = lod_comp->llc_compr_lvl;
+ lcme->lcme_compr_chunk_log_bits =
+ lod_comp->llc_compr_chunk_log_bits - 16;
+ }
+
sub_md = (struct lov_mds_md *)((char *)lcm + offset);
if (lod_comp->llc_magic == LOV_MAGIC_FOREIGN) {
if (!lov_hsm_type_supported(lod_comp->llc_type)) {
&lo->ldo_layout_mutex);
RETURN(-EUCLEAN);
}
+ if (flags & LCME_FL_NOCOMPR &&
+ lod_comp->llc_compr_type != 0) {
+ mutex_unlock(
+ &lo->ldo_layout_mutex);
+ RETURN(-EINVAL);
+ }
lod_comp->llc_flags |= flags;
}
if (mirror_flag) {
LASSERT(lo->ldo_comp_entries);
for (i = 0; i < comp_cnt; i++) {
- struct pool_desc *pool;
- struct lu_extent *ext;
- char *pool_name;
+ struct pool_desc *pool;
+ struct lu_extent *ext;
+ char *pool_name;
+ struct lov_comp_md_entry_v1 *lcme = NULL;
lod_comp = &lo->ldo_comp_entries[i];
if (lo->ldo_is_composite) {
- v1 = (struct lov_user_md *)((char *)comp_v1 +
- comp_v1->lcm_entries[i].lcme_offset);
- ext = &comp_v1->lcm_entries[i].lcme_extent;
+ lcme = &comp_v1->lcm_entries[i];
+ v1 = (struct lov_user_md *)
+ ((char *)comp_v1 + lcme->lcme_offset);
+ ext = &lcme->lcme_extent;
lod_comp->llc_extent = *ext;
- lod_comp->llc_flags =
- comp_v1->lcm_entries[i].lcme_flags &
- LCME_CL_COMP_FLAGS;
+ lod_comp->llc_flags = lcme->lcme_flags &
+ LCME_CL_COMP_FLAGS;
}
pool_name = NULL;
if (lov_pattern(v1->lmm_pattern) != LOV_PATTERN_RAID0 &&
lov_pattern(v1->lmm_pattern) != LOV_PATTERN_MDT &&
lov_pattern(v1->lmm_pattern) !=
+ (LOV_PATTERN_RAID0 | LOV_PATTERN_COMPRESS) &&
+ lov_pattern(v1->lmm_pattern) !=
(LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING)) {
CDEBUG(D_LAYOUT, "%s: invalid pattern: %x\n",
lod2obd(d)->obd_name, v1->lmm_pattern);
GOTO(free_comp, rc = -EINVAL);
}
+ if (lov_pattern(lod_comp->llc_pattern) & LOV_PATTERN_COMPRESS) {
+ lod_comp->llc_compr_type = lcme->lcme_compr_type;
+ lod_comp->llc_compr_lvl = lcme->lcme_compr_lvl;
+ lod_comp->llc_compr_chunk_log_bits =
+ lcme->lcme_compr_chunk_log_bits + 16;
+ }
+
lod_comp->llc_stripe_offset = v1->lmm_stripe_offset;
lod_obj_set_pool(lo, i, pool_name);
#include <libcfs/libcfs.h>
#include <obd_class.h>
+#include <lustre_lib.h>
#include "lov_internal.h"
+int llite_enable_compression;
+EXPORT_SYMBOL(llite_enable_compression);
+
static inline void
lu_extent_le_to_cpu(struct lu_extent *dst, const struct lu_extent *src)
{
goto out;
}
+ if ((lov_pattern(pattern) & ~LOV_PATTERN_F_RELEASED &
+ LOV_PATTERN_COMPRESS) && !llite_enable_compression) {
+ rc = -EINVAL;
+ CERROR("lov: file compression not enabled: rc = %d\n", rc);
+ lov_dump_lmm_common(D_WARNING, lmm);
+ goto out;
+ }
+
if (lmm->lmm_stripe_size == 0 ||
(le32_to_cpu(lmm->lmm_stripe_size)&(LOV_MIN_STRIPE_SIZE-1)) != 0) {
rc = -EINVAL;
le64_to_cpu(lcme->lcme_timestamp);
lu_extent_le_to_cpu(&lsme->lsme_extent, &lcme->lcme_extent);
+ if (lsme->lsme_pattern & LOV_PATTERN_COMPRESS) {
+ lsme->lsme_compr_type = lcme->lcme_compr_type;
+ lsme->lsme_compr_lvl = lcme->lcme_compr_lvl;
+ lsme->lsme_compr_chunk_log_bits =
+ lcme->lcme_compr_chunk_log_bits;
+ }
+
if (i == entry_count - 1) {
lsm->lsm_maxbytes = (loff_t)lsme->lsme_extent.e_start +
maxbytes;
u32 lsme_flags;
u32 lsme_pattern;
u64 lsme_timestamp;
+ u8 lsme_compr_type;
+ u8 lsme_compr_lvl;
+ u8 lsme_compr_chunk_log_bits;
+ /* chunk_size = 2^(16+chunk_log_bits) */
union {
struct { /* For stripe objects */
u32 lsme_stripe_size;
v1 = (struct lov_user_md *)((char *)comp_v1 +
comp_v1->lcm_entries[i].lcme_offset);
+
+ if (v1->lmm_pattern & LOV_PATTERN_COMPRESS) {
+ CDEBUG(lvl, "\tlcme_compr_type: %u\n",
+ ent->lcme_compr_type);
+ CDEBUG(lvl, "\tlcme_compr_lvl: %u\n",
+ ent->lcme_compr_lvl);
+ CDEBUG(lvl, "\tlcme_compr_chunk_log_bits: %u\n",
+ ent->lcme_compr_chunk_log_bits);
+ }
if (v1->lmm_magic == LOV_MAGIC_FOREIGN)
lustre_print_foreign(lvl, (struct lov_foreign_md *)v1,
msg);
__swab32s(&ent->lcme_size);
__swab32s(&ent->lcme_layout_gen);
BUILD_BUG_ON(offsetof(typeof(*ent), lcme_padding_1) == 0);
+ /* no need to swab lcme_compr_type */
+ /* no need to swab lcme_compr_lvl */
+ /* no need to swab lcme_compr_chunk_log_bits */
v1 = (struct lov_user_md_v1 *)((char *)lum + off);
if (v1->lmm_magic == __swab32(LOV_USER_MAGIC_FOREIGN) ||
}
run_test 25 "Verify old lov stripe API with PFL files"
+test_100a() {
+ (( $MDS1_VERSION >= $(version_code 2.14.0.85) )) ||
+ skip "Need MDS >= 2.14.0.85 for compression support"
+
+ local tf=$DIR/$tdir/$tfile
+ local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
+
+ test_mkdir $DIR/$tdir
+ save_lustre_params client "llite.*.enable_compression" > $p
+ stack_trap "restore_lustre_params < $p" EXIT
+
+ $LCTL set_param llite.*.enable_compression=1
+
+ $LFS setstripe -Eeof --comp-flags=nocompr $tf ||
+ error "set a component with nocompr failed"
+ $LFS setstripe --comp-set -I1 --comp-flags=compress $tf &&
+ error "setstrpe to set a compress component should not be allowed"
+ $LFS setstripe --comp-set -I1 --comp-flags=partial $tf &&
+ error "setstrpe to set a partial compress component should not be allowed"
+
+ $LFS getstripe $tf
+
+ local comp_flags=$($LFS getstripe -I1 --comp-flags $tf)
+
+ [[ "$comp_flags" =~ "nocompr" ]] || error "$comp_flags do not have nocompr"
+}
+run_test 100a "set stripe coponent with nocompr"
+
complete $SECONDS
check_and_cleanup_lustre
exit_status
args->lsa_rc = LSE_FLAGS;
} else {
if (comp->llc_flags &
- ~(LCME_FL_EXTENSION | LCME_FL_PREF_RW))
+ ~(LCME_FL_EXTENSION | LCME_FL_PREF_RW |
+ LCME_FL_NOCOMPR))
args->lsa_rc = LSE_FLAGS;
}
}