GOTO(out, rc = -EINVAL);
cmobd->master_group = oa->o_gr;
}
- rc = obd_create(exp, oa, &lsm, &oti);
+ rc = obd_create(exp, oa, NULL, 0, &lsm, &oti);
cmobd_free_lsm(&lsm);
out:
}
static int cobd_create(struct obd_export *exp, struct obdo *obdo,
+ void *acl, int acl_size,
struct lov_stripe_md **ea,
struct obd_trans_info *oti)
{
return -EINVAL;
}
cobd_exp = cobd_get_exp(obd);
- return obd_create(cobd_exp, obdo, ea, oti);
+ return obd_create(cobd_exp, obdo, acl, acl_size, ea, oti);
}
static int cobd_destroy(struct obd_export *exp, struct obdo *obdo,
int (*o_preallocate)(struct lustre_handle *, obd_count *req,
obd_id *ids);
int (*o_create)(struct obd_export *exp, struct obdo *oa,
+ void *acl, int acl_size,
struct lov_stripe_md **ea, struct obd_trans_info *oti);
int (*o_destroy)(struct obd_export *exp, struct obdo *oa,
struct lov_stripe_md *ea, struct obd_trans_info *oti);
}
static inline int obd_create(struct obd_export *exp, struct obdo *obdo,
+ void *acl, int acl_size,
struct lov_stripe_md **ea,
struct obd_trans_info *oti)
{
EXP_CHECK_OP(exp, create);
OBD_COUNTER_INCREMENT(exp->exp_obd, create);
- rc = OBP(exp->exp_obd, create)(exp, obdo, ea, oti);
+ rc = OBP(exp->exp_obd, create)(exp, obdo, acl, acl_size, ea, oti);
RETURN(rc);
}
oti.oti_objid = NULL;
memcpy(lsm2, lsm, lsm_size);
- rc = obd_create(exp, oa, &lsm2, &oti);
+ rc = obd_create(exp, oa, NULL, 0, &lsm2, &oti);
OBD_FREE(lsm2, lsm_size);
GOTO(out, rc);
}
int lmv_obd_create_single(struct obd_export *exp, struct obdo *oa,
+ void *acl, int acl_size,
struct lov_stripe_md **ea, struct obd_trans_info *oti)
{
struct obd_device *obd = exp->exp_obd;
LASSERT(ea == NULL);
LASSERT(oa->o_mds < lmv->desc.ld_tgt_count);
- rc = obd_create(lmv->tgts[oa->o_mds].ltd_exp,
- oa, &obj_mdp, oti);
+ rc = obd_create(lmv->tgts[oa->o_mds].ltd_exp, oa,
+ acl, acl_size, &obj_mdp, oti);
RETURN(rc);
}
* values for "master" object, as it will be used.
*/
int lmv_obd_create(struct obd_export *exp, struct obdo *oa,
+ void *acl, int acl_size,
struct lov_stripe_md **ea, struct obd_trans_info *oti)
{
struct obd_device *obd = exp->exp_obd;
LASSERT(oa != NULL);
if (ea == NULL) {
- rc = lmv_obd_create_single(exp, oa, NULL, oti);
+ rc = lmv_obd_create_single(exp, oa, acl, acl_size, NULL, oti);
if (rc)
CERROR("Can't create object, rc = %d\n", rc);
RETURN(rc);
}
+ /* acl is only suppied when mds create single remote obj */
+ LASSERT(acl == NULL && acl_size == 0);
+
if (*ea == NULL) {
rc = obd_alloc_diskmd(exp, (struct lov_mds_md **)ea);
if (rc < 0) {
oa->o_valid = OBD_MD_FLGENER | OBD_MD_FLTYPE | OBD_MD_FLMODE |
OBD_MD_FLUID | OBD_MD_FLGID | OBD_MD_FLID;
- rc = obd_create(lmv->tgts[c].ltd_exp, oa, &obj_mdp, oti);
+ rc = obd_create(lmv->tgts[c].ltd_exp, oa, NULL, 0,
+ &obj_mdp, oti);
if (rc) {
CERROR("obd_create() failed on MDT target %d, "
"error %d\n", c, rc);
memcpy(tmp_oa, src_oa, sizeof(*tmp_oa));
/* XXX: LOV STACKING: use real "obj_mdp" sub-data */
- err = obd_create(lov->tgts[i].ltd_exp, tmp_oa, &obj_mdp, oti);
+ err = obd_create(lov->tgts[i].ltd_exp, tmp_oa, NULL, 0,
+ &obj_mdp, oti);
if (err)
/* This export will be disabled until it is recovered,
and then orphan recovery will be completed. */
}
static int lov_recreate(struct obd_export *exp, struct obdo *src_oa,
+ void *acl, int acl_size,
struct lov_stripe_md **ea, struct obd_trans_info *oti)
{
struct lov_stripe_md *obj_mdp, *lsm;
if (i == lsm->lsm_stripe_count)
GOTO(out, rc = -EINVAL);
- rc = obd_create(lov->tgts[ost_idx].ltd_exp, src_oa, &obj_mdp, oti);
+ rc = obd_create(lov->tgts[ost_idx].ltd_exp, src_oa, acl, acl_size,
+ &obj_mdp, oti);
out:
OBD_FREE(obj_mdp, sizeof(*obj_mdp));
RETURN(rc);
/* the LOV expects oa->o_id to be set to the LOV object id */
static int lov_create(struct obd_export *exp, struct obdo *src_oa,
+ void *acl, int acl_size,
struct lov_stripe_md **ea, struct obd_trans_info *oti)
{
struct lov_request_set *set = NULL;
/* Recreate a specific object id at the given OST index */
if ((src_oa->o_valid & OBD_MD_FLFLAGS) &&
(src_oa->o_flags & OBD_FL_RECREATE_OBJS)) {
- rc = lov_recreate(exp, src_oa, ea, oti);
+ rc = lov_recreate(exp, src_oa, acl, acl_size, ea, oti);
RETURN(rc);
}
list_entry(pos, struct lov_request, rq_link);
/* XXX: LOV STACKING: use real "obj_mdp" sub-data */
- rc = obd_create(lov->tgts[req->rq_idx].ltd_exp,
- req->rq_oa, &req->rq_md, oti);
+ rc = obd_create(lov->tgts[req->rq_idx].ltd_exp, req->rq_oa,
+ acl, acl_size, &req->rq_md, oti);
lov_update_create_set(set, req, rc);
}
rc = lov_fini_create_set(set, ea);
memcpy(tmp_oa, src_oa, sizeof(*tmp_oa));
/* XXX: LOV STACKING: use real "obj_mdp" sub-data */
osc_exp = lov->tgts[ost_idx].ltd_exp;
- rc = obd_create(osc_exp, tmp_oa, &obj_mdp, oti);
+ rc = obd_create(osc_exp, tmp_oa, NULL, 0, &obj_mdp, oti);
if (rc) {
CERROR("error creating new subobj at idx %d; "
"rc = %d\n", ost_idx, rc);
oa->o_generation = lgh_id->lgl_ogen;
oa->o_gr = lgh_id->lgl_ogr;
oa->o_valid = OBD_MD_FLGENER | OBD_MD_FLGROUP;
- rc = obd_create(ctxt->loc_exp, oa, NULL, NULL);
+ rc = obd_create(ctxt->loc_exp, oa, NULL, 0, NULL, NULL);
if (rc) {
CDEBUG(D_INODE, "err during create: %d\n", rc);
GOTO(out_free_oa, rc);
oa->o_gr = FILTER_GROUP_LLOG;
oa->o_valid = OBD_MD_FLGENER | OBD_MD_FLGROUP;
- rc = obd_create(ctxt->loc_exp, oa, NULL, NULL);
+ rc = obd_create(ctxt->loc_exp, oa, NULL, 0, NULL, NULL);
if (rc)
GOTO(out_free_oa, rc);
}
int mdc_obj_create(struct obd_export *exp, struct obdo *oa,
- struct lov_stripe_md **ea, struct obd_trans_info *oti)
+ void *acl, int acl_size,
+ struct lov_stripe_md **ea, struct obd_trans_info *oti)
{
struct ptlrpc_request *request;
struct ost_body *body;
- int rc, size = sizeof(*body);
+ char *acl_buf;
+ int rc, size[2] = { sizeof(*body), acl_size };
ENTRY;
LASSERT(oa);
request = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_OBD_VERSION,
- OST_CREATE, 1, &size, NULL);
+ OST_CREATE, 2, size, NULL);
if (!request)
GOTO(out_req, rc = -ENOMEM);
body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof (*body));
memcpy(&body->oa, oa, sizeof(body->oa));
- request->rq_replen = lustre_msg_size(1, &size);
+ if (acl_size) {
+ acl_buf = lustre_msg_buf(request->rq_reqmsg, 1, acl_size);
+ memcpy(acl_buf, acl, acl_size);
+ }
+
+ request->rq_replen = lustre_msg_size(1, size);
rc = ptlrpc_queue_wait(request);
if (rc)
GOTO(out_req, rc);
EXIT;
}
+static int mds_inode_init_acl(struct obd_device *obd, void *handle,
+ struct dentry *de, void *xattr, int xattr_size)
+{
+ struct inode *inode = de->d_inode;
+ struct posix_acl *acl;
+ mode_t mode;
+ int rc;
+
+ LASSERT(handle);
+ LASSERT(inode);
+ LASSERT(xattr);
+ LASSERT(xattr_size > 0);
+
+ if (!inode->i_op->getxattr || !inode->i_op->setxattr) {
+ CERROR("backend fs dosen't support xattr\n");
+ return -EOPNOTSUPP;
+ }
+
+ /* set default acl */
+ if (S_ISDIR(inode->i_mode)) {
+ rc = inode->i_op->setxattr(de, XATTR_NAME_ACL_DEFAULT,
+ xattr, xattr_size, 0);
+ if (rc) {
+ CERROR("set default acl err: %d\n", rc);
+ return rc;
+ }
+ }
+
+ /* set access acl */
+ acl = posix_acl_from_xattr(xattr, xattr_size);
+ if (acl == NULL || IS_ERR(acl)) {
+ CERROR("insane attr data\n");
+ return PTR_ERR(acl);
+ }
+
+ if (posix_acl_valid(acl)) {
+ CERROR("default acl not valid: %d\n", rc);
+ rc = -EFAULT;
+ goto out;
+ }
+
+ mode = inode->i_mode;
+ rc = posix_acl_create_masq(acl, &mode);
+ if (rc < 0) {
+ CERROR("create masq err %d\n", rc);
+ goto out;
+ }
+
+ if (inode->i_mode != mode) {
+ struct iattr iattr = { .ia_valid = ATTR_MODE,
+ .ia_mode = mode };
+ int rc2;
+
+ rc2 = fsfilt_setattr(obd, de, handle, &iattr, 0);
+ if (rc2) {
+ CERROR("setattr mode err: %d\n", rc2);
+ rc = rc2;
+ goto out;
+ }
+ }
+
+ if (rc > 0) {
+ /* we didn't change acl except mode bits of some
+ * entries, so should be fit into original size.
+ */
+ rc = posix_acl_to_xattr(acl, xattr, xattr_size);
+ LASSERT(rc > 0);
+
+ rc = inode->i_op->setxattr(de, XATTR_NAME_ACL_ACCESS,
+ xattr, xattr_size, 0);
+ if (rc)
+ CERROR("set access acl err: %d\n", rc);
+ }
+out:
+ posix_acl_release(acl);
+ return rc;
+}
+
static int mdt_obj_create(struct ptlrpc_request *req)
{
struct obd_device *obd = req->rq_export->exp_obd;
struct mds_obd *mds = &obd->u.mds;
struct ost_body *body, *repbody;
+ void *acl = NULL;
+ int acl_size;
char idname[LL_ID_NAMELEN];
int size = sizeof(*repbody);
struct inode *parent_inode;
if (body == NULL)
RETURN(-EFAULT);
+ /* acl data is packed transparently, no swab here */
+ LASSERT(req->rq_reqmsg->bufcount >= 2);
+ acl_size = req->rq_reqmsg->buflens[1];
+ if (acl_size) {
+ acl = lustre_msg_buf(req->rq_reqmsg, 1, acl_size);
+ if (!acl) {
+ CERROR("No default acl buf?\n");
+ RETURN(-EFAULT);
+ }
+ }
+
rc = lustre_pack_reply(req, 1, &size, NULL);
if (rc)
RETURN(rc);
rc = vfs_mkdir(parent_inode, new, body->oa.o_mode);
if (rc == 0) {
+ if (acl) {
+ rc = mds_inode_init_acl(obd, handle, new,
+ acl, acl_size);
+ if (rc) {
+ up(&parent_inode->i_sem);
+ GOTO(cleanup, rc);
+ }
+ }
if ((body->oa.o_flags & OBD_FL_RECREATE_OBJS) ||
lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY) {
new->d_inode->i_generation = body->oa.o_generation;
* performance sensitive, it is accomplished by creating a file, checking the
* id, and renaming it. */
int mds_obd_create(struct obd_export *exp, struct obdo *oa,
+ void *acl, int acl_size,
struct lov_stripe_md **ea, struct obd_trans_info *oti)
{
struct mds_obd *mds = &exp->exp_obd->u.mds;
struct mds_export_data *med, int cl_off);
int mds_client_free(struct obd_export *exp, int clear_client);
int mds_obd_create(struct obd_export *exp, struct obdo *oa,
- struct lov_stripe_md **ea, struct obd_trans_info *oti);
+ void *acl, int acl_size,
+ struct lov_stripe_md **ea, struct obd_trans_info *oti);
int mds_obd_destroy(struct obd_export *exp, struct obdo *oa,
struct lov_stripe_md *ea, struct obd_trans_info *oti);
CDEBUG(D_OTHER, "%s: create subdirs with mode %o, uid %u, gid %u\n",
obd->obd_name, dir->i_mode, dir->i_uid, dir->i_gid);
- rc = obd_create(mds->mds_md_exp, oa,
+ rc = obd_create(mds->mds_md_exp, oa, NULL, 0,
(struct lov_stripe_md **)mea, NULL);
if (rc) {
CERROR("Can't create remote inode, rc = %d\n", rc);
memcpy(&oa->o_inline, ost_uuid, sizeof(*ost_uuid));
oa->o_valid |= OBD_MD_FLINLINE;
}
- rc = obd_create(mds->mds_dt_exp, oa, &empty_ea, &oti);
+ rc = obd_create(mds->mds_dt_exp, oa, NULL, 0, &empty_ea, &oti);
obdo_free(oa);
RETURN(rc);
}
GOTO(out_oa, rc);
}
LASSERT(oa->o_gr >= FILTER_GROUP_FIRST_MDS);
- rc = obd_create(mds->mds_dt_exp, oa, &lsm, &oti);
+ rc = obd_create(mds->mds_dt_exp, oa, NULL, 0, &lsm, &oti);
if (rc) {
int level = D_ERROR;
if (rc == -ENOSPC)
#include <linux/lustre_dlm.h>
#include <linux/lustre_log.h>
#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_acl.h>
#include <linux/lustre_lite.h>
#include "mds_internal.h"
EXIT;
}
+static int mds_get_default_acl(struct inode *dir, void **pacl)
+{
+ struct dentry de = { .d_inode = dir };
+ int size, size2;
+
+ LASSERT(S_ISDIR(dir->i_mode));
+
+ if (!dir->i_op->getxattr)
+ return 0;
+
+ size = dir->i_op->getxattr(&de, XATTR_NAME_ACL_DEFAULT, NULL, 0);
+ if (size == 0 || size == -ENODATA || size == -EOPNOTSUPP)
+ return 0;
+ else if (size < 0)
+ return size;
+
+ OBD_ALLOC(*pacl, size);
+ if (!*pacl)
+ return -ENOMEM;
+
+ size2 = dir->i_op->getxattr(&de, XATTR_NAME_ACL_DEFAULT, *pacl, size);
+ if (size2 != size) {
+ /* since we already locked the dir, it should not change
+ * between the 2 getxattr calls
+ */
+ CERROR("2'nd getxattr got %d, expect %d\n", size2, size);
+ OBD_FREE(*pacl, size);
+ return -EIO;
+ }
+
+ return size;
+}
+
static int mds_reint_create(struct mds_update_record *rec, int offset,
struct ptlrpc_request *req,
struct lustre_handle *lh)
/* inode will be created on another MDS */
struct obdo *oa = NULL;
struct mds_body *body;
-
+ void *acl = NULL;
+ int acl_size;
+
/* first, create that inode */
oa = obdo_alloc();
if (!oa)
LASSERT(oa->o_fid != 0);
}
+ /* obtain default ACL */
+ acl_size = mds_get_default_acl(dir, &acl);
+ if (acl_size < 0) {
+ obdo_free(oa);
+ GOTO(cleanup, rc = -ENOMEM);
+ }
+
/*
* before obd_create() is called, o_fid is not known if
* this is not recovery of cause.
*/
- rc = obd_create(mds->mds_md_exp, oa, NULL, NULL);
+ rc = obd_create(mds->mds_md_exp, oa, acl, acl_size,
+ NULL, NULL);
+
+ if (acl)
+ OBD_FREE(acl, acl_size);
+
if (rc) {
CERROR("can't create remote inode: %d\n", rc);
DEBUG_REQ(D_ERROR, req, "parent "LPU64"/%u name %s mode %o",
}
int echo_create(struct obd_export *exp, struct obdo *oa,
+ void *acl, int acl_size,
struct lov_stripe_md **ea, struct obd_trans_info *oti)
{
struct obd_device *obd = class_exp2obd(exp);
if (on_target) {
oa->o_gr = FILTER_GROUP_ECHO;
oa->o_valid |= OBD_MD_FLGROUP;
- rc = obd_create(ec->ec_exp, oa, &lsm, oti);
+ rc = obd_create(ec->ec_exp, oa, NULL, 0, &lsm, oti);
if (rc != 0)
goto failed;
}
static int filter_create(struct obd_export *exp, struct obdo *oa,
+ void *acl, int acl_size,
struct lov_stripe_md **ea, struct obd_trans_info *oti)
{
struct obd_device *obd = NULL;
int group = oa->o_gr, rc = 0, diff, recreate_objs = 0;
ENTRY;
+ LASSERT(acl == NULL && acl_size == 0);
+
if (!(oa->o_valid & OBD_MD_FLGROUP) || group == 0) {
portals_nid2str(exp->exp_connection->c_peer.peer_ni->pni_number,
exp->exp_connection->c_peer.peer_id.nid, str);
}
int osc_create(struct obd_export *exp, struct obdo *oa,
+ void *acl, int acl_size,
struct lov_stripe_md **ea, struct obd_trans_info *oti)
{
struct lov_stripe_md *lsm;
LASSERT(ea);
LASSERT(oa->o_valid & OBD_MD_FLGROUP);
LASSERT(oa->o_gr > 0);
+ LASSERT(acl == NULL && acl_size == 0);
if ((oa->o_valid & OBD_MD_FLFLAGS) &&
oa->o_flags == OBD_FL_RECREATE_OBJS) {
#define OSCC_FLAG_EXITING 0x20
int osc_create(struct obd_export *exp, struct obdo *oa,
+ void *acl, int acl_size,
struct lov_stripe_md **ea, struct obd_trans_info *oti);
int osc_real_create(struct obd_export *exp, struct obdo *oa,
struct lov_stripe_md **ea, struct obd_trans_info *oti);
repbody = lustre_msg_buf (req->rq_repmsg, 0, sizeof(*repbody));
memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
oti->oti_logcookies = obdo_logcookie(&repbody->oa);
- req->rq_status = obd_create(exp, &repbody->oa, NULL, oti);
+ req->rq_status = obd_create(exp, &repbody->oa, NULL, 0, NULL, oti);
//obd_log_cancel(conn, NULL, 1, oti->oti_logcookies, 0);
RETURN(0);
}