p->tp_credits = credits;
}
+static inline void txn_param_credit_add(struct txn_param *p,
+ unsigned int credits)
+{
+ p->tp_credits += credits;
+}
+
+static inline void txn_param_sync(struct txn_param *p)
+{
+ p->tp_sync = 1;
+}
+
/**
* This is the general purpose transaction handle.
* 1. Transaction Life Cycle
mdd->mdd_txn_cb.dtc_tag = LCT_MD_THREAD;
CFS_INIT_LIST_HEAD(&mdd->mdd_txn_cb.dtc_linkage);
mdd->mdd_atime_diff = MAX_ATIME_DIFF;
+ /* sync permission changes */
+ mdd->mdd_sync_permission = 1;
rc = mdd_procfs_init(mdd, name);
RETURN(rc);
unsigned long mdd_atime_diff;
struct mdd_object *mdd_dot_lustre;
struct mdd_dot_lustre_objs mdd_dot_lustre_objs;
+ unsigned int mdd_sync_permission;
};
enum mod_flags {
}
#endif
+static int lprocfs_rd_sync_perm(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ struct mdd_device *mdd = data;
+
+ LASSERT(mdd != NULL);
+ return snprintf(page, count, "%d\n", mdd->mdd_sync_permission);
+}
+
+static int lprocfs_wr_sync_perm(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ struct mdd_device *mdd = data;
+ int val, rc;
+
+ LASSERT(mdd != NULL);
+ rc = lprocfs_write_helper(buffer, count, &val);
+ if (rc)
+ return rc;
+
+ mdd->mdd_sync_permission = !!val;
+ return count;
+}
+
static struct lprocfs_vars lprocfs_mdd_obd_vars[] = {
{ "atime_diff", lprocfs_rd_atime_diff, lprocfs_wr_atime_diff, 0 },
{ "changelog_mask", lprocfs_rd_changelog_mask,
{ "quota_type", mdd_lprocfs_quota_rd_type,
mdd_lprocfs_quota_wr_type, 0 },
#endif
+ { "sync_permission", lprocfs_rd_sync_perm, lprocfs_wr_sync_perm, 0 },
{ 0 }
};
RETURN(rc);
mdd_txn_param_build(env, mdd, MDD_TXN_XATTR_SET_OP);
+ /* security-replated changes may require sync */
+ if (!strcmp(name, XATTR_NAME_ACL_ACCESS) &&
+ mdd->mdd_sync_permission == 1)
+ txn_param_sync(&mdd_env_info(env)->mti_param);
+
handle = mdd_trans_start(env, mdd);
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
stripe = le32_to_cpu(ma->ma_lmm->lmm_stripe_count);
log_credits = stripe * dto_txn_credits[DTO_LOG_REC];
- mdd_env_info(env)->mti_param.tp_credits += log_credits;
+ txn_param_credit_add(&mdd_env_info(env)->mti_param, log_credits);
RETURN(rc);
}
mdd_txn_param_build(env, mdd, op);
if (ma->ma_attr.la_valid & (LA_UID | LA_GID))
- mdd_env_info(env)->mti_param.tp_credits =
- dto_txn_credits[DTO_ATTR_SET_CHOWN];
+ txn_param_credit_add(&mdd_env_info(env)->mti_param,
+ dto_txn_credits[DTO_ATTR_SET_CHOWN]);
+
+ /* permission changes may require sync operation */
+ if (ma->ma_attr.la_valid & (LA_MODE|LA_UID|LA_GID) &&
+ mdd->mdd_sync_permission == 1)
+ txn_param_sync(&mdd_env_info(env)->mti_param);
RETURN(0);
}
{
struct txn_param *p = &mdd_env_info(env)->mti_param;
struct thandle *th;
-
+
th = mdd_child_ops(mdd)->dt_trans_start(env, mdd->mdd_child, p);
return th;
}
/**
* Xattr set. The same as xattr of EXT3.
* DATA_TRANS_BLOCKS(14)
- * XXX Note: in original MDS implmentation INDEX_EXTRA_TRANS_BLOCKS are
- * also counted in. Do not know why?
+ * XXX Note: in original MDS implmentation INDEX_EXTRA_TRANS_BLOCKS
+ * are also counted in. Do not know why?
*/
[DTO_XATTR_SET] = 14,
[DTO_LOG_REC] = 14,
[DTO_WRITE_BLOCK] = 14,
/**
* Attr set credits for chown.
- * 3 (inode bit, group, GDT)
+ * This is extra credits for setattr, and it is null without quota
*/
- [DTO_ATTR_SET_CHOWN]= 3
+ [DTO_ATTR_SET_CHOWN]= 0
};
/**
[DTO_WRITE_BLOCK] = 16,
/**
* Attr set credits for chown.
- * 3 (inode bit, group, GDT) +
+ * It is added to already set setattr credits
* 2 * QUOTA_INIT_BLOCKS(25) +
* 2 * QUOTA_DEL_BLOCKS(9)
*/
- [DTO_ATTR_SET_CHOWN]= 71
+ [DTO_ATTR_SET_CHOWN]= 68,
};
static int osd_credit_get(const struct lu_env *env, struct dt_device *d,