bool page_access_allowed = true;
bool enable_checksum = true;
bool compressed = false;
+ int chunk_size;
+ struct osc_async_page *oap = brw_page2oap(pga[0]);
bool directio = false;
int short_io_size = 0;
void *short_io_buf;
RETURN(-EINVAL);
if (opc == OST_WRITE && compressed) {
- rc = compress_request(obd_name, oa, pga, &pga, &page_count);
+ struct brw_page **cpga = NULL;
+ __u64 kms = -1;
+
+ clpage = oap2cl_page(oap);
+
+ /* if a write is beyond the current known minimum size, we
+ * know there is no data in the chunk, so no possibility of
+ * read-modify write. this means we can compress that chunk
+ * of data even it is unaligned (this is critical because it
+ * lets the client compress the last chunk of a file)
+ *
+ * Note: direct IO (CPT_TRANSIENT) is usually lockless, so the
+ * client does not get a current KMS, so we can't do this for
+ * direct I/O
+ */
+ if (clpage->cp_type != CPT_TRANSIENT) {
+ struct brw_page *brwpg = pga[page_count - 1];
+ struct osc_async_page *last = brw_page2oap(brwpg);
+ struct cl_object *clobj = osc2cl(last->oap_obj);
+ struct lov_oinfo *loi = cl2osc(clobj)->oo_oinfo;
+
+ cl_object_attr_lock(clobj);
+ if (loi->loi_kms_valid)
+ kms = loi->loi_kms;
+ cl_object_attr_unlock(clobj);
+ }
+
+ chunk_size = (1 << cl_page_compr_bits(clpage));
+
+ rc = compress_request(obd_name, oa, pga, &cpga, &page_count,
+ kms);
if (rc) {
/*
* TDB: disable for a file if e.g. 512KB+ of
compressed = 0;
} else /* success */ {
*pcount = page_count;
- *orig_pga = pga;
+ *orig_pga = cpga;
+ pga = cpga;
}
} else if (opc == OST_READ && compressed) {
for (i = 0; i < page_count; i++) {
if (pa)
OBD_FREE_PTR_ARRAY_LARGE(pa, page_count);
} else if (opc == OST_WRITE && inode && IS_ENCRYPTED(inode)) {
- struct osc_async_page *oap = brw_page2oap(pga[0]);
- struct cl_page *clpage = oap2cl_page(oap);
- struct cl_object *clobj = clpage->cp_obj;
struct cl_attr attr = { 0 };
+ struct cl_object *clobj;
struct lu_env *env;
__u16 refcheck;
+ clpage = oap2cl_page(oap);
+ clobj = clpage->cp_obj;
env = cl_env_get(&refcheck);
if (IS_ERR(env)) {
rc = PTR_ERR(env);