#define XATTR_TRUSTED_PREFIX "trusted."
#define XATTR_SECURITY_PREFIX "security."
+#define XATTR_NAME_SOM "trusted.som"
#define XATTR_NAME_LOV "trusted.lov"
#define XATTR_NAME_LMA "trusted.lma"
#define XATTR_NAME_LMV "trusted.lmv"
*/
#define LMA_OLD_SIZE (sizeof(struct lustre_mdt_attrs) + 5 * sizeof(__u64))
+enum {
+ LSOM_FL_VALID = 1 << 0,
+};
+
+struct lustre_som_attrs {
+ __u16 lsa_valid;
+ __u16 lsa_reserved[3];
+ __u64 lsa_size;
+ __u64 lsa_blocks;
+};
+
/**
* OST object IDentifier.
*/
ll_prepare_close(inode, op_data, och);
switch (bias) {
case MDS_CLOSE_LAYOUT_MERGE:
+ /* merge blocks from the victim inode */
+ op_data->op_attr_blocks += ((struct inode *)data)->i_blocks;
+ op_data->op_attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS;
case MDS_CLOSE_LAYOUT_SWAP:
LASSERT(data != NULL);
op_data->op_bias |= bias;
}
case CIT_GLIMPSE:
+ lio->lis_pos = 0;
+ lio->lis_endpos = OBD_OBJECT_EOF;
+
+ if ((obj->lo_lsm->lsm_flags & LCM_FL_FLR_MASK) == LCM_FL_RDONLY)
+ RETURN(1); /* SoM is accurate, no need glimpse */
+ break;
+
case CIT_MISC:
lio->lis_pos = 0;
lio->lis_endpos = OBD_OBJECT_EOF;
{
struct lov_io *lio = lov_env_io(env);
struct lov_object *lov = cl2lov(obj);
-
+ int result;
ENTRY;
+
INIT_LIST_HEAD(&lio->lis_active);
- io->ci_result = lov_io_slice_init(lio, lov, io);
- if (io->ci_result != 0)
- RETURN(io->ci_result);
-
- if (io->ci_result == 0) {
- io->ci_result = lov_io_subio_init(env, lio, io);
- if (io->ci_result == 0) {
- cl_io_slice_add(io, &lio->lis_cl, obj, &lov_io_ops);
- atomic_inc(&lov->lo_active_ios);
- }
+ result = lov_io_slice_init(lio, lov, io);
+ if (result)
+ GOTO(out, result);
+
+ result = lov_io_subio_init(env, lio, io);
+ if (!result) {
+ cl_io_slice_add(io, &lio->lis_cl, obj, &lov_io_ops);
+ atomic_inc(&lov->lo_active_ios);
}
- RETURN(io->ci_result);
+ EXIT;
+out:
+ io->ci_result = result < 0 ? result : 0;
+ return result;
}
int lov_io_init_empty(const struct lu_env *env, struct cl_object *obj,
MODULES := mdt
mdt-objs := mdt_handler.o mdt_lib.o mdt_reint.o mdt_xattr.o mdt_recovery.o
-mdt-objs += mdt_open.o mdt_identity.o mdt_lproc.o mdt_fs.o
+mdt-objs += mdt_open.o mdt_identity.o mdt_lproc.o mdt_fs.o mdt_som.o
mdt-objs += mdt_lvb.o mdt_hsm.o mdt_mds.o mdt_io.o
mdt-objs += mdt_hsm_cdt_actions.o
mdt-objs += mdt_hsm_cdt_requests.o
else
b->mbo_blocks = 1;
b->mbo_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
+ } else if (info->mti_som_valid) { /* som is valid */
+ b->mbo_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
}
}
rc = mo_attr_get(env, next, ma);
if (rc)
GOTO(out, rc);
+
+ if (S_ISREG(mode))
+ (void) mdt_get_som(info, o, &ma->ma_attr);
ma->ma_valid |= MA_INODE;
}
info->mti_opdata = 0;
info->mti_big_lmm_used = 0;
info->mti_big_acl_used = 0;
+ info->mti_som_valid = 0;
info->mti_spec.no_create = 0;
info->mti_spec.sp_rm_entry = 0;
mti_cross_ref:1,
/* big_lmm buffer was used and must be used in reply */
mti_big_lmm_used:1,
- mti_big_acl_used:1;
+ mti_big_acl_used:1,
+ mti_som_valid:1;
/* opdata for mdt_reint_open(), has the same as
* ldlm_reply:lock_policy_res1. mdt_update_last_rcvd() stores this
char mti_xattr_buf[128];
struct ldlm_enqueue_info mti_einfo;
struct tg_reply_data *mti_reply_data;
+
+ struct lustre_som_attrs mti_som;
};
extern struct lu_context_key mdt_thread_key;
return mdt_dlm_lock_modes[mode];
}
+/* mdt_som.c */
+int mdt_set_som(struct mdt_thread_info *info, struct mdt_object *obj,
+ struct lu_attr *attr);
+int mdt_get_som(struct mdt_thread_info *info, struct mdt_object *obj,
+ struct lu_attr *attr);
+
/* mdt_lvb.c */
extern struct ldlm_valblock_ops mdt_lvbo;
int mdt_dom_lvb_is_valid(struct ldlm_resource *res);
buf->lb_buf = mdt_object_child(o == o1 ? o2 : o1);
rc = mo_xattr_set(info->mti_env, mdt_object_child(o), buf,
XATTR_LUSTRE_LOV, LU_XATTR_MERGE);
+ if (rc == 0 && ma->ma_attr.la_valid & (LA_SIZE | LA_BLOCKS)) {
+ int rc2;
+
+ rc2 = mdt_set_som(info, o, &ma->ma_attr);
+ if (rc2 < 0)
+ CERROR(DFID": Setting i_blocks error: %d, "
+ "i_blocks will be reported wrongly and "
+ "can only be fixed in next resync\n",
+ PFID(mdt_object_fid(o)), rc2);
+ }
}
if (rc < 0)
GOTO(out_unlock2, rc);
--- /dev/null
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details. A copy is
+ * included in the COPYING file that accompanied this code.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2017, Intel Corporation.
+ */
+/*
+ * lustre/mdt/mdt_som.c
+ *
+ * Size on MDS revival
+ *
+ * Author: Jinshan Xiong <jinshan.xiong@intel.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_MDS
+
+#include "mdt_internal.h"
+
+int mdt_get_som(struct mdt_thread_info *info, struct mdt_object *obj,
+ struct lu_attr *attr)
+{
+ struct lu_buf *buf = &info->mti_buf;
+ struct lustre_som_attrs *som;
+ int rc;
+
+ som = buf->lb_buf = info->mti_xattr_buf;
+ buf->lb_len = sizeof(info->mti_xattr_buf);
+ rc = mo_xattr_get(info->mti_env, mdt_object_child(obj), buf,
+ XATTR_NAME_SOM);
+ if (rc >= (int)sizeof(*som) && (som->lsa_valid & LSOM_FL_VALID)) {
+ attr->la_valid |= LA_SIZE | LA_BLOCKS;
+ attr->la_size = som->lsa_size;
+ attr->la_blocks = som->lsa_blocks;
+
+ /* Size on MDS is valid and could be returned to client */
+ info->mti_som_valid = 1;
+
+ CDEBUG(D_INODE, DFID": Reading som attrs: "
+ "valid: %x, size: %lld, blocks: %lld, rc: %d.\n",
+ PFID(mdt_object_fid(obj)), som->lsa_valid,
+ som->lsa_size, som->lsa_blocks, rc);
+ }
+
+ return (rc > 0 || rc == -ENODATA) ? 0 : rc;
+}
+
+int mdt_set_som(struct mdt_thread_info *info, struct mdt_object *obj,
+ struct lu_attr *attr)
+{
+ struct md_object *next = mdt_object_child(obj);
+ struct lu_buf *buf = &info->mti_buf;
+ struct lustre_som_attrs *som;
+ int rc;
+ ENTRY;
+
+ buf->lb_buf = info->mti_xattr_buf;
+ buf->lb_len = sizeof(info->mti_xattr_buf);
+ rc = mo_xattr_get(info->mti_env, next, buf, XATTR_NAME_SOM);
+ if (rc < 0 && rc != -ENODATA)
+ RETURN(rc);
+
+ som = buf->lb_buf;
+
+ CDEBUG(D_INODE,
+ DFID": Set som attrs: " "size: %lld, blocks: %lld, rc: %d\n",
+ PFID(mdt_object_fid(obj)), som->lsa_size, som->lsa_blocks, rc);
+
+ if (rc == -ENODATA)
+ memset(som, 0, sizeof(*som));
+ if (attr->la_valid & (LA_SIZE | LA_BLOCKS)) {
+ som->lsa_valid |= LSOM_FL_VALID;
+ som->lsa_size = attr->la_size;
+ som->lsa_blocks = attr->la_blocks;
+ }
+ buf->lb_len = sizeof(*som);
+ rc = mo_xattr_set(info->mti_env, next, buf, XATTR_NAME_SOM, 0);
+ RETURN(rc);
+}
}
run_test 3 "create components from files located on different MDTs"
+test_21() {
+ local tf=$DIR/$tfile
+ local tf2=$DIR/$tfile-2
+
+ [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
+
+ $LFS setstripe -E EOF -o 0 $tf
+ $LFS setstripe -E EOF -o 1 $tf2
+
+ local dd_count=$((RANDOM % 20 + 1))
+ dd if=/dev/zero of=$tf bs=1M count=$dd_count
+ dd if=/dev/zero of=$tf2 bs=1M count=1 seek=$((dd_count - 1))
+ cancel_lru_locks osc
+
+ local blocks=$(du -kc $tf $tf2 | awk '/total/{print $1}')
+
+ # add component
+ $LFS setstripe --component-add --mirror=$tf2 $tf
+
+ # cancel layout lock
+ cancel_lru_locks mdc
+
+ local new_blocks=$(du -k $tf | awk '{print $1}')
+ [ $new_blocks -eq $blocks ] ||
+ error "i_blocks error expected: $blocks, actual: $new_blocks"
+}
+run_test 21 "glimpse should report accurate i_blocks"
+
+test_22() {
+ local tf=$DIR/$tfile
+
+ $LFS setstripe -E EOF -o 0 $tf
+ dd if=/dev/zero of=$tf bs=1M count=$((RANDOM % 20 + 1))
+
+ # add component, two mirrors located on the same OST ;-)
+ $LFS setstripe --component-add --mirror -o 0 $tf
+
+ size_blocks=$(stat --format="%b %s" $tf)
+
+ cancel_lru_locks mdc
+ cancel_lru_locks osc
+
+ local new_size_blocks=$(stat --format="%b %s" $tf)
+
+ # make sure there is no lock cached
+ local lock_count=$($LCTL get_param -n \
+ ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count)
+ [ $lock_count -eq 0 ] || error "glimpse requests were sent"
+
+ [ "$new_size_blocks" = "$size_blocks" ] ||
+ echo "size expected: $size_blocks, actual: $new_size_blocks"
+
+ rm -f $tmpfile
+}
+run_test 22 "no glimpse to OSTs for READ_ONLY files"
+
complete $SECONDS
check_and_cleanup_lustre
exit_status