* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2014, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#include <lustre_acl.h>
#include <lustre_mds.h>
#include "mdt_internal.h"
+#include <lustre_nodemap.h>
/* we do nothing because we do not have refcount now */
static void mdt_mfd_get(void *mfdp)
OBD_ALLOC_PTR(mfd);
if (mfd != NULL) {
- CFS_INIT_LIST_HEAD(&mfd->mfd_handle.h_link);
+ INIT_LIST_HEAD(&mfd->mfd_handle.h_link);
mfd->mfd_handle.h_owner = med;
- CFS_INIT_LIST_HEAD(&mfd->mfd_list);
+ INIT_LIST_HEAD(&mfd->mfd_list);
class_handle_hash(&mfd->mfd_handle, &mfd_handle_ops);
}
mfd = class_handle2object(handle->cookie, med);
/* during dw/setattr replay the mfd can be found by old handle */
if (mfd == NULL && is_replay_or_resent) {
- cfs_list_for_each_entry(mfd, &med->med_open_head, mfd_list) {
+ list_for_each_entry(mfd, &med->med_open_head, mfd_list) {
if (mfd->mfd_old_handle.cookie == handle->cookie)
RETURN(mfd);
}
/* free mfd */
void mdt_mfd_free(struct mdt_file_data *mfd)
{
- LASSERT(cfs_list_empty(&mfd->mfd_list));
- OBD_FREE_RCU(mfd, sizeof *mfd, &mfd->mfd_handle);
+ LASSERT(list_empty(&mfd->mfd_list));
+ OBD_FREE_RCU(mfd, sizeof *mfd, &mfd->mfd_handle);
}
static int mdt_create_data(struct mdt_thread_info *info,
ma->ma_valid = 0;
mutex_lock(&o->mot_lov_mutex);
if (!(o->mot_flags & MOF_LOV_CREATED)) {
- if (p != NULL && !fid_is_md_operative(mdt_object_fid(p)))
- GOTO(unlock, rc = -EPERM);
-
rc = mdo_create_data(info->mti_env,
p ? mdt_object_child(p) : NULL,
mdt_object_child(o), spec, ma);
if (rc == 0 && ma->ma_valid & MA_LOV)
o->mot_flags |= MOF_LOV_CREATED;
}
-unlock:
+
mutex_unlock(&o->mot_lov_mutex);
RETURN(rc);
}
* Apply obtained attributes for the 1st case, wipe out the on-disk SOM
* cache otherwise.
*/
-int mdt_som_au_close(struct mdt_thread_info *info, struct mdt_object *o)
+static int mdt_som_au_close(struct mdt_thread_info *info, struct mdt_object *o)
{
struct ptlrpc_request *req = mdt_info_req(info);
__u64 ioepoch = 0;
/**
* prep ma_lmm/ma_lmv for md_attr from reply
*/
-void mdt_prep_ma_buf_from_rep(struct mdt_thread_info *info,
- struct mdt_object *obj,
- struct md_attr *ma)
+static void mdt_prep_ma_buf_from_rep(struct mdt_thread_info *info,
+ struct mdt_object *obj,
+ struct md_attr *ma)
{
LASSERT(ma->ma_lmv == NULL && ma->ma_lmm == NULL);
if (S_ISDIR(obj->mot_header.loh_attr)) {
rc = mo_open(info->mti_env, mdt_object_child(o),
created ? flags | MDS_OPEN_CREATED : flags);
- if (rc)
- GOTO(err_out, rc);
+ if (rc != 0) {
+ /* If we allow the client to chgrp (CFS_SETGRP_PERM), but the
+ * client does not know which suppgid should be sent to the MDS,
+ * or some other(s) changed the target file's GID after this RPC
+ * sent to the MDS with the suppgid as the original GID, then we
+ * give the client another chance to send the right suppgid. */
+ if (rc == -EACCES &&
+ allow_client_chgrp(info, lu_ucred(info->mti_env)))
+ mdt_set_disposition(info, rep, DISP_OPEN_DENY);
+
+ GOTO(err_out, rc);
+ }
mfd = mdt_mfd_new(med);
if (mfd == NULL)
PFID(mdt_object_fid(mfd->mfd_object)),
info->mti_rr.rr_handle->cookie);
class_handle_unhash(&old_mfd->mfd_handle);
- cfs_list_del_init(&old_mfd->mfd_list);
+ list_del_init(&old_mfd->mfd_list);
spin_unlock(&med->med_open_lock);
/* no attr update for that close */
la->la_valid = 0;
if (req->rq_export->exp_disconnected) {
spin_lock(&med->med_open_lock);
class_handle_unhash(&mfd->mfd_handle);
- cfs_list_del_init(&mfd->mfd_list);
+ list_del_init(&mfd->mfd_list);
spin_unlock(&med->med_open_lock);
mdt_mfd_close(info, mfd);
} else {
spin_lock(&med->med_open_lock);
- cfs_list_add(&mfd->mfd_list, &med->med_open_head);
+ list_add(&mfd->mfd_list, &med->med_open_head);
spin_unlock(&med->med_open_lock);
}
return rc;
}
-int mdt_finish_open(struct mdt_thread_info *info,
- struct mdt_object *p, struct mdt_object *o,
- __u64 flags, int created, struct ldlm_reply *rep)
+static int mdt_finish_open(struct mdt_thread_info *info,
+ struct mdt_object *p, struct mdt_object *o,
+ __u64 flags, int created, struct ldlm_reply *rep)
{
- struct ptlrpc_request *req = mdt_info_req(info);
- struct obd_export *exp = req->rq_export;
- struct mdt_export_data *med = &req->rq_export->exp_mdt_data;
- struct md_attr *ma = &info->mti_attr;
- struct lu_attr *la = &ma->ma_attr;
- struct mdt_file_data *mfd;
- struct mdt_body *repbody;
- int rc = 0;
- int isreg, isdir, islnk;
- cfs_list_t *t;
- ENTRY;
+ struct ptlrpc_request *req = mdt_info_req(info);
+ struct obd_export *exp = req->rq_export;
+ struct mdt_export_data *med = &req->rq_export->exp_mdt_data;
+ struct md_attr *ma = &info->mti_attr;
+ struct lu_attr *la = &ma->ma_attr;
+ struct mdt_file_data *mfd;
+ struct mdt_body *repbody;
+ int rc = 0;
+ int isreg, isdir, islnk;
+ struct list_head *t;
+ ENTRY;
LASSERT(ma->ma_valid & MA_INODE);
}
}
#ifdef CONFIG_FS_POSIX_ACL
- else if (exp_connect_flags(exp) & OBD_CONNECT_ACL) {
- const struct lu_env *env = info->mti_env;
- struct md_object *next = mdt_object_child(o);
- struct lu_buf *buf = &info->mti_buf;
-
- buf->lb_buf = req_capsule_server_get(info->mti_pill, &RMF_ACL);
- buf->lb_len = req_capsule_get_size(info->mti_pill, &RMF_ACL,
- RCL_SERVER);
- if (buf->lb_len > 0) {
- rc = mo_xattr_get(env, next, buf,
- XATTR_NAME_ACL_ACCESS);
- if (rc < 0) {
- if (rc == -ENODATA) {
- repbody->mbo_aclsize = 0;
- repbody->mbo_valid |= OBD_MD_FLACL;
- rc = 0;
- } else if (rc == -EOPNOTSUPP) {
- rc = 0;
- } else {
- CERROR("got acl size: %d\n", rc);
- }
- } else {
- repbody->mbo_aclsize = rc;
- repbody->mbo_valid |= OBD_MD_FLACL;
- rc = 0;
- }
- }
- }
+ else if (exp_connect_flags(exp) & OBD_CONNECT_ACL)
+ rc = mdt_pack_acl2body(info, repbody, o,
+ exp->exp_target_data.ted_nodemap);
#endif
if (info->mti_mdt->mdt_lut.lut_mds_capa &&
RETURN(-EAGAIN);
}
- mfd = NULL;
- if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) {
+ mfd = NULL;
+ if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) {
spin_lock(&med->med_open_lock);
- cfs_list_for_each(t, &med->med_open_head) {
- mfd = cfs_list_entry(t, struct mdt_file_data, mfd_list);
+ list_for_each(t, &med->med_open_head) {
+ mfd = list_entry(t, struct mdt_file_data, mfd_list);
if (mfd->mfd_xid == req->rq_xid)
break;
mfd = NULL;
RETURN(rc);
}
-extern void mdt_req_from_lcd(struct ptlrpc_request *req,
- struct lsd_client_data *lcd);
-
void mdt_reconstruct_open(struct mdt_thread_info *info,
struct mdt_lock_handle *lhc)
{
LASSERT(ergo(rc < 0, lustre_msg_get_transno(req->rq_repmsg) == 0));
}
-int mdt_open_by_fid(struct mdt_thread_info *info, struct ldlm_reply *rep)
+static int mdt_open_by_fid(struct mdt_thread_info *info, struct ldlm_reply *rep)
{
__u64 flags = info->mti_spec.sp_cr_flags;
struct mdt_reint_record *rr = &info->mti_rr;
up_read(&obj->mot_open_sem);
/* Cross-ref case, the lock should be returned to the client */
- if (ibits == 0 || rc == -EREMOTE)
+ if (ibits == 0 || rc == -MDT_EREMOTE_OPEN)
RETURN_EXIT;
if (!(open_flags & MDS_OPEN_LOCK) && !(ibits & MDS_INODELOCK_LAYOUT)) {
return true;
}
-int mdt_open_by_fid_lock(struct mdt_thread_info *info, struct ldlm_reply *rep,
- struct mdt_lock_handle *lhc)
+static int mdt_open_by_fid_lock(struct mdt_thread_info *info,
+ struct ldlm_reply *rep,
+ struct mdt_lock_handle *lhc)
{
const struct lu_env *env = info->mti_env;
struct mdt_device *mdt = info->mti_mdt;
struct mdt_object *parent= NULL;
struct mdt_object *o;
int rc;
+ int object_locked = 0;
__u64 ibits = 0;
ENTRY;
GOTO(out, rc);
} else if (rc > 0) {
rc = mdt_object_open_lock(info, o, lhc, &ibits);
+ object_locked = 1;
if (rc)
GOTO(out_unlock, rc);
}
GOTO(out_unlock, rc);
out_unlock:
- mdt_object_open_unlock(info, o, lhc, ibits, rc);
+ if (object_locked)
+ mdt_object_open_unlock(info, o, lhc, ibits, rc);
out:
mdt_object_put(env, o);
out_parent_put:
if (rc != 0)
GOTO(out, rc);
- /* Do not create lov object if the fid is opened
- * under OBF */
- if (S_ISREG(ma->ma_attr.la_mode) &&
- !(ma->ma_valid & MA_LOV) && (flags & FMODE_WRITE) &&
- fid_is_obf(parent_fid))
- GOTO(out, rc = -EPERM);
-
rc = mdt_finish_open(info, NULL, o, flags, 0, rep);
} else {
/*
struct mdt_reint_record *rr = &info->mti_rr;
int result, rc;
int created = 0;
+ int object_locked = 0;
__u32 msg_flags;
ENTRY;
if (rc != 0)
result = rc;
else
- result = -EREMOTE;
+ result = -MDT_EREMOTE_OPEN;
GOTO(out_child, result);
} else if (mdt_object_exists(child)) {
/* We have to get attr & LOV EA & HSM for this
mdt_prep_ma_buf_from_rep(info, child, ma);
ma->ma_need |= MA_HSM;
result = mdt_attr_get_complex(info, child, ma);
+ if (result != 0)
+ GOTO(out_child, result);
} else {
/* Object does not exist. Likely FS corruption. */
CERROR("%s: name '"DNAME"' present, but FID "
/* get openlock if this isn't replay and client requested it */
if (!req_is_replay(req)) {
rc = mdt_object_open_lock(info, child, lhc, &ibits);
+ object_locked = 1;
if (rc != 0)
GOTO(out_child_unlock, result = rc);
else if (create_flags & MDS_OPEN_LOCK)
}
EXIT;
out_child_unlock:
- mdt_object_open_unlock(info, child, lhc, ibits, result);
+ if (object_locked)
+ mdt_object_open_unlock(info, child, lhc, ibits, result);
out_child:
mdt_object_put(info->mti_env, child);
out_parent:
mdt_mfd_set_mode(mfd, ret == MDT_IOEPOCH_OPENED ?
MDS_FMODE_EPOCH : MDS_FMODE_SOM);
- LASSERT(mdt_info_req(info));
- med = &mdt_info_req(info)->rq_export->exp_mdt_data;
+ LASSERT(mdt_info_req(info));
+ med = &mdt_info_req(info)->rq_export->exp_mdt_data;
spin_lock(&med->med_open_lock);
- cfs_list_add(&mfd->mfd_list, &med->med_open_head);
+ list_add(&mfd->mfd_list, &med->med_open_head);
class_handle_hash_back(&mfd->mfd_handle);
spin_unlock(&med->med_open_lock);
rc = -ESTALE;
} else {
class_handle_unhash(&mfd->mfd_handle);
- cfs_list_del_init(&mfd->mfd_list);
+ list_del_init(&mfd->mfd_list);
spin_unlock(&med->med_open_lock);
/* Do not lose object before last unlink. */
} else
rc = -ESTALE;
GOTO(error_ucred, rc);
- }
+ }
- LASSERT(mfd->mfd_mode == MDS_FMODE_EPOCH ||
- mfd->mfd_mode == MDS_FMODE_TRUNC);
- class_handle_unhash(&mfd->mfd_handle);
- cfs_list_del_init(&mfd->mfd_list);
+ LASSERT(mfd->mfd_mode == MDS_FMODE_EPOCH ||
+ mfd->mfd_mode == MDS_FMODE_TRUNC);
+ class_handle_unhash(&mfd->mfd_handle);
+ list_del_init(&mfd->mfd_list);
spin_unlock(&med->med_open_lock);
/* Set EPOCH CLOSE flag if not set by client. */