static int mdd_changelog_data_store_by_fid(const struct lu_env *env,
struct mdd_device *mdd,
enum changelog_rec_type type,
- int flags, const struct lu_fid *fid,
+ enum changelog_rec_flags clf_flags,
+ const struct lu_fid *fid,
const char *xattr_name,
struct thandle *handle);
__u32 gid = mou->mou_uidgid & ((1UL << 32) - 1);
ENTRY;
-
tmp = mdd_obj_user_find(mdd_obj, uid, gid, mou->mou_open_flags);
if (tmp != NULL)
RETURN(-EEXIST);
static int mdd_changelog_data_store_by_fid(const struct lu_env *env,
struct mdd_device *mdd,
enum changelog_rec_type type,
- int flags, const struct lu_fid *fid,
+ enum changelog_rec_flags clf_flags,
+ const struct lu_fid *fid,
const char *xattr_name,
struct thandle *handle)
{
const struct lu_ucred *uc = lu_ucred(env);
+ enum changelog_rec_extra_flags xflags = CLFE_INVALID;
struct llog_changelog_rec *rec;
struct lu_buf *buf;
int reclen;
- int xflags = CLFE_INVALID;
int rc;
- flags = (flags & CLF_FLAGMASK) | CLF_VERSION | CLF_EXTRA_FLAGS;
+ clf_flags = (clf_flags & CLF_FLAGMASK) | CLF_VERSION | CLF_EXTRA_FLAGS;
if (uc) {
if (uc->uc_jobid[0] != '\0')
- flags |= CLF_JOBID;
+ clf_flags |= CLF_JOBID;
xflags |= CLFE_UIDGID;
xflags |= CLFE_NID;
}
xflags |= CLFE_XATTR;
reclen = llog_data_len(LLOG_CHANGELOG_HDR_SZ +
- changelog_rec_offset(flags & CLF_SUPPORTED,
+ changelog_rec_offset(clf_flags & CLF_SUPPORTED,
xflags & CLFE_SUPPORTED));
buf = lu_buf_check_and_alloc(&mdd_env_info(env)->mti_big_buf, reclen);
if (buf->lb_buf == NULL)
rec = buf->lb_buf;
rec->cr_hdr.lrh_len = reclen;
- rec->cr.cr_flags = flags;
+ rec->cr.cr_flags = clf_flags;
rec->cr.cr_type = (__u32)type;
rec->cr.cr_tfid = *fid;
rec->cr.cr_namelen = 0;
- if (flags & CLF_JOBID)
+ if (clf_flags & CLF_JOBID)
mdd_changelog_rec_ext_jobid(&rec->cr, uc->uc_jobid);
- if (flags & CLF_EXTRA_FLAGS) {
+ if (clf_flags & CLF_EXTRA_FLAGS) {
mdd_changelog_rec_ext_extra_flags(&rec->cr, xflags);
if (xflags & CLFE_UIDGID)
mdd_changelog_rec_extra_uidgid(&rec->cr,
if (xflags & CLFE_NID)
mdd_changelog_rec_extra_nid(&rec->cr, uc->uc_nid);
if (xflags & CLFE_OPEN)
- mdd_changelog_rec_extra_omode(&rec->cr, flags);
+ mdd_changelog_rec_extra_omode(&rec->cr, clf_flags);
if (xflags & CLFE_XATTR) {
if (xattr_name == NULL)
RETURN(-EINVAL);
* \param handle - transaction handle
*/
int mdd_changelog_data_store(const struct lu_env *env, struct mdd_device *mdd,
- enum changelog_rec_type type, int flags,
+ enum changelog_rec_type type,
+ enum changelog_rec_flags clf_flags,
struct mdd_object *mdd_obj, struct thandle *handle)
{
int rc;
RETURN(0);
}
- rc = mdd_changelog_data_store_by_fid(env, mdd, type, flags,
+ rc = mdd_changelog_data_store_by_fid(env, mdd, type, clf_flags,
mdo2fid(mdd_obj), NULL, handle);
if (rc == 0)
mdd_obj->mod_cltime = ktime_get();
int mdd_changelog_data_store_xattr(const struct lu_env *env,
struct mdd_device *mdd,
enum changelog_rec_type type,
- int flags, struct mdd_object *mdd_obj,
+ enum changelog_rec_flags clf_flags,
+ struct mdd_object *mdd_obj,
const char *xattr_name,
struct thandle *handle)
{
- int rc;
+ int rc;
LASSERT(mdd_obj != NULL);
LASSERT(handle != NULL);
RETURN(0);
}
- rc = mdd_changelog_data_store_by_fid(env, mdd, type, flags,
+ rc = mdd_changelog_data_store_by_fid(env, mdd, type, clf_flags,
mdo2fid(mdd_obj), xattr_name,
handle);
if (rc == 0)
RETURN(rc);
}
+/* only the bottom CLF_FLAGSHIFT bits of @flags are stored in the record,
+ * except for open flags have a dedicated record to store 32 bits of flags */
static int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type,
- int flags, struct md_device *m, const struct lu_fid *fid)
+ enum changelog_rec_flags clf_flags,
+ struct md_device *m, const struct lu_fid *fid)
{
struct thandle *handle;
struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev);
if (rc)
GOTO(stop, rc);
- rc = mdd_changelog_data_store_by_fid(env, mdd, type, flags,
+ rc = mdd_changelog_data_store_by_fid(env, mdd, type, clf_flags,
fid, NULL, handle);
stop:
/* The record type is the lowest non-masked set bit */
type = __ffs(bits);
- /* FYI we only store the first CLF_FLAGMASK bits of la_valid */
- return mdd_changelog_data_store(env, mdd, type, (int)valid,
+ /* XXX: we only store the low CLF_FLAGMASK bits of la_valid */
+ return mdd_changelog_data_store(env, mdd, type, valid,
md2mdd_obj(obj), handle);
}
/*
* LU-3671
+ * LU-7239
*
* permission changes may require sync operation, to mitigate performance
* impact, only do this for dir and when permission is reduced.
if (!S_ISDIR(old->la_mode))
return false;
- if (new->la_valid & (LA_UID | LA_GID))
+ if (new->la_valid & LA_UID && old->la_uid != new->la_uid)
return true;
- if (new->la_valid & LA_MODE &&
- new->la_mode & (S_ISUID | S_ISGID | S_ISVTX))
+ if (new->la_valid & LA_GID && old->la_gid != new->la_gid)
return true;
- if ((new->la_valid & LA_MODE) &&
- ((new->la_mode & old->la_mode) & S_IRWXUGO) !=
- (old->la_mode & S_IRWXUGO))
- return true;
+ if (new->la_valid & LA_MODE) {
+ /* turned on sticky bit */
+ if (!(old->la_mode & S_ISVTX) && (new->la_mode & S_ISVTX))
+ return true;
+
+ /* set-GID has no impact on what is allowed, not checked */
+
+ /* turned off setuid bit, or one of rwx for someone */
+ if (((new->la_mode & old->la_mode) & (0777 | S_ISUID)) !=
+ (old->la_mode & (0777 | S_ISUID)))
+ return true;
+ }
return false;
}
struct lu_attr *attr = MDD_ENV_VAR(env, cattr);
const struct lu_attr *la = &ma->ma_attr;
struct lu_ucred *uc;
+ bool chrgrp_by_unprivileged_user = false;
int rc;
ENTRY;
uc = lu_ucred_check(env);
if (S_ISREG(attr->la_mode) && la->la_valid & LA_GID &&
la->la_gid != attr->la_gid && uc != NULL && uc->uc_fsuid != 0) {
+ /* LU-10048: disable synchronous chgrp operation for it will
+ * cause deadlock between MDT and OST.
la_copy->la_valid |= LA_FLAGS;
la_copy->la_flags |= LUSTRE_SET_SYNC_FL;
+ */
+ chrgrp_by_unprivileged_user = true;
- /* Flush the possible existing sync requests to OSTs to
- * keep the order of sync for the current setattr operation
+ /* Flush the possible existing client setattr requests to OSTs
+ * to keep the order with the current setattr operation that
* will be sent directly to OSTs. see LU-5152 */
+ /* LU-11303 disable sync as this is too heavyweight.
+ * This should be replaced with a sync only for the object
+ * being modified here, not the whole filesystem.
rc = dt_sync(env, mdd->mdd_child);
if (rc)
GOTO(out, rc);
+ */
}
handle = mdd_trans_create(env, mdd);
if (rc)
GOTO(out, rc);
- if (mdd->mdd_sync_permission && permission_needs_sync(attr, la))
+ if (!chrgrp_by_unprivileged_user && mdd->mdd_sync_permission &&
+ permission_needs_sync(attr, la))
handle->th_sync = 1;
if (la->la_valid & (LA_MTIME | LA_CTIME))
static int mdd_hsm_update_locked(const struct lu_env *env,
struct md_object *obj,
const struct lu_buf *buf,
- struct thandle *handle, int *cl_flags)
+ struct thandle *handle,
+ enum changelog_rec_flags *clf_flags)
{
struct mdd_thread_info *info = mdd_env_info(env);
- struct mdd_object *mdd_obj = md2mdd_obj(obj);
- struct lu_buf *current_buf;
- struct md_hsm *current_mh;
- struct md_hsm *new_mh;
- int rc;
- ENTRY;
+ struct mdd_object *mdd_obj = md2mdd_obj(obj);
+ struct lu_buf *current_buf;
+ struct md_hsm *current_mh;
+ struct md_hsm *new_mh;
+ int rc;
+ ENTRY;
OBD_ALLOC_PTR(current_mh);
if (current_mh == NULL)
RETURN(-ENOMEM);
/* Read HSM attrs from disk */
current_buf = lu_buf_check_and_alloc(&info->mti_xattr_buf,
- mdo2mdd(obj)->mdd_dt_conf.ddp_max_ea_size);
+ MIN(mdd_obj2mdd_dev(mdd_obj)->mdd_dt_conf.ddp_max_ea_size,
+ XATTR_SIZE_MAX));
rc = mdo_xattr_get(env, mdd_obj, current_buf, XATTR_NAME_HSM);
rc = lustre_buf2hsm(current_buf->lb_buf, rc, current_mh);
if (rc < 0 && rc != -ENODATA)
/* Flags differ, set flags for the changelog that will be added */
if (current_mh->mh_flags != new_mh->mh_flags) {
- hsm_set_cl_event(cl_flags, HE_STATE);
+ hsm_set_cl_event(clf_flags, HE_STATE);
if (new_mh->mh_flags & HS_DIRTY)
- hsm_set_cl_flags(cl_flags, CLF_HSM_DIRTY);
+ hsm_set_cl_flags(clf_flags, CLF_HSM_DIRTY);
}
OBD_FREE_PTR(new_mh);
const struct lu_buf *buf, const char *name,
int fl)
{
- struct mdd_object *mdd_obj = md2mdd_obj(obj);
- struct lu_attr *attr = MDD_ENV_VAR(env, cattr);
- struct mdd_device *mdd = mdo2mdd(obj);
- struct thandle *handle;
+ struct mdd_object *mdd_obj = md2mdd_obj(obj);
+ struct lu_attr *attr = MDD_ENV_VAR(env, cattr);
+ struct mdd_device *mdd = mdo2mdd(obj);
+ struct thandle *handle;
enum changelog_rec_type cl_type;
- int cl_flags = 0;
- int rc;
+ enum changelog_rec_flags clf_flags = 0;
+ int rc;
ENTRY;
rc = mdd_la_get(env, mdd_obj, attr);
mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
if (strcmp(XATTR_NAME_HSM, name) == 0) {
- rc = mdd_hsm_update_locked(env, obj, buf, handle, &cl_flags);
+ rc = mdd_hsm_update_locked(env, obj, buf, handle, &clf_flags);
if (rc) {
mdd_write_unlock(env, mdd_obj);
GOTO(stop, rc);
if (cl_type < 0)
GOTO(stop, rc = 0);
- rc = mdd_changelog_data_store_xattr(env, mdd, cl_type, cl_flags,
+ rc = mdd_changelog_data_store_xattr(env, mdd, cl_type, clf_flags,
mdd_obj, name, handle);
EXIT;
struct thandle *handle)
{
struct hsm_attrs *attrs;
- __u32 hsm_flags;
- int flags = 0;
+ enum hsm_states hsm_flags;
+ enum changelog_rec_flags clf_flags = 0;
int rc;
ENTRY;
RETURN(0);
/* Add a changelog record for release. */
- hsm_set_cl_event(&flags, HE_RELEASE);
+ hsm_set_cl_event(&clf_flags, HE_RELEASE);
rc = mdd_changelog_data_store(env, mdo2mdd(&o->mod_obj), CL_HSM,
- flags, o, handle);
+ clf_flags, o, handle);
RETURN(rc);
}
}
}
+ /* FYI, only the bottom 32 bits of open_flags are recorded */
mdd_changelog(env, type, open_flags, md_dev, mdo2fid(mdd_obj));
EXIT;
int is_orphan = 0;
int rc;
bool blocked = false;
- int last_close_by_uid = 0;
+ bool last_close_by_uid = false;
const struct lu_ucred *uc = lu_ucred(env);
ENTRY;
mdd_obj->mod_count--; /*release open count */
/* under mdd write lock */
- /* If recording, see if we need to remove UID from list */
- if (mdd_changelog_enabled(env, mdd, CL_OPEN)) {
+ /* If recording, see if we need to remove UID from list. uc is not
+ * initialized if the client has been evicted. */
+ if (mdd_changelog_enabled(env, mdd, CL_OPEN) && uc) {
struct mdd_object_user *mou;
/* look for UID in list */
mou->mou_opencount--;
if (mou->mou_opencount == 0) {
mdd_obj_user_remove(mdd_obj, mou);
- last_close_by_uid = 1;
+ last_close_by_uid = true;
}
}
}
GOTO(stop, rc);
}
+ /* FYI, only the bottom 32 bits of open_flags are recorded */
mdd_changelog_data_store(env, mdd, CL_CLOSE, open_flags,
- mdd_obj, handle);
+ mdd_obj, handle);
}
stop: