Whamcloud - gitweb
git://git.whamcloud.com
/
fs
/
lustre-release.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
| inline |
side by side
LU-11549 mdd: set LUSTRE_ORPHAN_FL for non-dirs
[fs/lustre-release.git]
/
lustre
/
mdt
/
mdt_open.c
diff --git
a/lustre/mdt/mdt_open.c
b/lustre/mdt/mdt_open.c
index
5f2d340
..
bcb7c2f
100644
(file)
--- a/
lustre/mdt/mdt_open.c
+++ b/
lustre/mdt/mdt_open.c
@@
-49,7
+49,7
@@
static void mdt_mfd_get(void *mfdp)
{
}
-static
struct portals_handle_ops mfd
_handle_ops = {
+static
const struct portals_handle_ops mfd_open
_handle_ops = {
.hop_addref = mdt_mfd_get,
.hop_free = NULL,
};
@@
-63,10
+63,10
@@
struct mdt_file_data *mdt_mfd_new(const struct mdt_export_data *med)
OBD_ALLOC_PTR(mfd);
if (mfd != NULL) {
- INIT_LIST_HEAD
(&mfd->mfd
_handle.h_link);
- mfd->mfd_
handle.h_
owner = med;
+ INIT_LIST_HEAD
_RCU(&mfd->mfd_open
_handle.h_link);
+ mfd->mfd_owner = med;
INIT_LIST_HEAD(&mfd->mfd_list);
- class_handle_hash(&mfd->mfd_
handle, &mfd
_handle_ops);
+ class_handle_hash(&mfd->mfd_
open_handle, &mfd_open
_handle_ops);
}
RETURN(mfd);
@@
-78,19
+78,20
@@
struct mdt_file_data *mdt_mfd_new(const struct mdt_export_data *med)
* but mfd can be found in mfd list by that handle.
* Callers need to be holding med_open_lock.
*/
-struct mdt_file_data *mdt_handle2mfd(struct mdt_export_data *med,
-
const struct lustre_handle *
handle,
- bool is_replay_or_resent)
+struct mdt_file_data *mdt_
open_
handle2mfd(struct mdt_export_data *med,
+
const struct lustre_handle *open_
handle,
+
bool is_replay_or_resent)
{
struct mdt_file_data *mfd;
ENTRY;
- LASSERT(handle != NULL);
- mfd = class_handle2object(
handle->cookie, med
);
+ LASSERT(
open_
handle != NULL);
+ mfd = class_handle2object(
open_handle->cookie, &mfd_open_handle_ops
);
/* during dw/setattr replay the mfd can be found by old handle */
- if (
mfd == NULL
&& is_replay_or_resent) {
+ if (
(!mfd || mfd->mfd_owner != med)
&& is_replay_or_resent) {
list_for_each_entry(mfd, &med->med_open_head, mfd_list) {
- if (mfd->mfd_old_handle.cookie == handle->cookie)
+ if (mfd->mfd_open_handle_old.cookie ==
+ open_handle->cookie)
RETURN(mfd);
}
mfd = NULL;
@@
-103,7
+104,7
@@
struct mdt_file_data *mdt_handle2mfd(struct mdt_export_data *med,
void mdt_mfd_free(struct mdt_file_data *mfd)
{
LASSERT(list_empty(&mfd->mfd_list));
- OBD_FREE_RCU(mfd, sizeof *mfd, &mfd->mfd_handle);
+ OBD_FREE_RCU(mfd, sizeof *mfd, &mfd->mfd_
open_
handle);
}
static int mdt_create_data(struct mdt_thread_info *info,
@@
-226,8
+227,7
@@
static void mdt_empty_transno(struct mdt_thread_info *info, int rc)
CERROR("%s: replay trans %llu NID %s: rc = %d\n",
mdt_obd_name(mdt), info->mti_transno,
- libcfs_nid2str(exp->exp_connection->c_peer.nid),
- rc);
+ obd_export_nid2str(exp), rc);
spin_unlock(&mdt->mdt_lut.lut_translock);
RETURN_EXIT;
}
@@
-291,14
+291,15
@@
static void mdt_empty_transno(struct mdt_thread_info *info, int rc)
EXIT;
}
-void mdt_mfd_set_mode(struct mdt_file_data *mfd,
__u64 mode
)
+void mdt_mfd_set_mode(struct mdt_file_data *mfd,
u64 open_flags
)
{
LASSERT(mfd != NULL);
- CDEBUG(D_DENTRY, DFID " Change mfd mode %#llo -> %#llo.\n",
- PFID(mdt_object_fid(mfd->mfd_object)), mfd->mfd_mode, mode);
+ CDEBUG(D_DENTRY, DFID " Change mfd open_flags %#llo -> %#llo.\n",
+ PFID(mdt_object_fid(mfd->mfd_object)), mfd->mfd_open_flags,
+ open_flags);
- mfd->mfd_
mode = mode
;
+ mfd->mfd_
open_flags = open_flags
;
}
/**
@@
-329,45
+330,47
@@
static void mdt_prep_ma_buf_from_rep(struct mdt_thread_info *info,
}
static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p,
- struct mdt_object *o,
__u64
flags, int created,
+ struct mdt_object *o,
u64 open_
flags, int created,
struct ldlm_reply *rep)
{
-
struct ptlrpc_request
*req = mdt_info_req(info);
-
struct mdt_export_data
*med = &req->rq_export->exp_mdt_data;
-
struct mdt_file_data
*mfd;
-
struct md_attr
*ma = &info->mti_attr;
-
struct lu_attr
*la = &ma->ma_attr;
-
struct mdt_body
*repbody;
-
int rc = 0,
isdir, isreg;
-
ENTRY
;
+
struct ptlrpc_request
*req = mdt_info_req(info);
+
struct mdt_export_data
*med = &req->rq_export->exp_mdt_data;
+
struct mdt_file_data
*mfd;
+
struct md_attr
*ma = &info->mti_attr;
+
struct lu_attr
*la = &ma->ma_attr;
+
struct mdt_body
*repbody;
+
bool
isdir, isreg;
+
int rc = 0
;
- repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
+ ENTRY;
+ repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
- isreg = S_ISREG(la->la_mode);
- isdir = S_ISDIR(la->la_mode);
- if (isreg && !(ma->ma_valid & MA_LOV) && !(flags & MDS_OPEN_RELEASE)) {
- /*
- * No EA, check whether it is will set regEA and dirEA since in
- * above attr get, these size might be zero, so reset it, to
- * retrieve the MD after create obj.
- */
- ma->ma_lmm_size = req_capsule_get_size(info->mti_pill,
- &RMF_MDT_MD,
- RCL_SERVER);
- /* in replay case, p == NULL */
- rc = mdt_create_data(info, p, o);
- if (rc)
- RETURN(rc);
+ isreg = S_ISREG(la->la_mode);
+ isdir = S_ISDIR(la->la_mode);
+ if (isreg && !(ma->ma_valid & MA_LOV) &&
+ !(open_flags & MDS_OPEN_RELEASE)) {
+ /*
+ * No EA, check whether it is will set regEA and dirEA since in
+ * above attr get, these size might be zero, so reset it, to
+ * retrieve the MD after create obj.
+ */
+ ma->ma_lmm_size = req_capsule_get_size(info->mti_pill,
+ &RMF_MDT_MD,
+ RCL_SERVER);
+ /* in replay case, p == NULL */
+ rc = mdt_create_data(info, p, o);
+ if (rc)
+ RETURN(rc);
if (exp_connect_flags(req->rq_export) & OBD_CONNECT_DISP_STRIPE)
mdt_set_disposition(info, rep, DISP_OPEN_STRIPE);
-
}
+ }
CDEBUG(D_INODE, "after open, ma_valid bit = %#llx lmm_size = %d\n",
ma->ma_valid, ma->ma_lmm_size);
-
if (ma->ma_valid & MA_LOV) {
-
LASSERT(ma->ma_lmm_size != 0);
+ if (ma->ma_valid & MA_LOV) {
+ LASSERT(ma->ma_lmm_size != 0);
repbody->mbo_eadatasize = ma->ma_lmm_size;
if (isdir)
repbody->mbo_valid |= OBD_MD_FLDIREA;
@@
-382,16
+385,17
@@
static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p,
repbody->mbo_valid |= OBD_MD_FLDIREA | OBD_MD_MEA;
}
- if (
flags &
FMODE_WRITE)
+ if (
open_flags & MDS_
FMODE_WRITE)
rc = mdt_write_get(o);
- else if (flags & MDS_FMODE_EXEC)
+ else if (
open_
flags & MDS_FMODE_EXEC)
rc = mdt_write_deny(o);
-
if (rc)
-
RETURN(rc);
+ if (rc)
+ RETURN(rc);
- rc = mo_open(info->mti_env, mdt_object_child(o),
- created ? flags | MDS_OPEN_CREATED : flags);
+ rc = mo_open(info->mti_env, mdt_object_child(o),
+ created ? open_flags | MDS_OPEN_CREATED : open_flags,
+ &info->mti_spec);
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,
@@
-418,16
+422,16
@@
static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p,
mfd->mfd_xid = req->rq_xid;
/*
- * @flags is always not zero. At least it should be FMODE_READ,
+ * @
open_
flags is always not zero. At least it should be FMODE_READ,
* FMODE_WRITE or MDS_FMODE_EXEC.
*/
- LASSERT(flags != 0);
+ LASSERT(
open_
flags != 0);
/* Open handling. */
- mdt_mfd_set_mode(mfd, flags);
+ mdt_mfd_set_mode(mfd,
open_
flags);
atomic_inc(&o->mot_open_count);
- if (flags & MDS_OPEN_LEASE)
+ if (
open_
flags & MDS_OPEN_LEASE)
atomic_inc(&o->mot_lease_count);
/* replay handle */
@@
-438,15
+442,16
@@
static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p,
* might be disconnected from server, and
* restart replay, so there maybe some orphan
* mfd here, we should remove them */
- LASSERT(info->mti_rr.rr_handle != NULL);
+ LASSERT(info->mti_rr.rr_
open_
handle != NULL);
spin_lock(&med->med_open_lock);
- old_mfd = mdt_handle2mfd(med, info->mti_rr.rr_handle, true);
+ old_mfd = mdt_open_handle2mfd(med, info->mti_rr.rr_open_handle,
+ true);
if (old_mfd != NULL) {
CDEBUG(D_HA, "delete orphan mfd = %p, fid = "DFID", "
"cookie = %#llx\n", mfd,
PFID(mdt_object_fid(mfd->mfd_object)),
- info->mti_rr.rr_handle->cookie);
- class_handle_unhash(&old_mfd->mfd_handle);
+ info->mti_rr.rr_
open_
handle->cookie);
+ class_handle_unhash(&old_mfd->mfd_
open_
handle);
list_del_init(&old_mfd->mfd_list);
spin_unlock(&med->med_open_lock);
/* no attr update for that close */
@@
-461,20
+466,20
@@
static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p,
CDEBUG(D_HA, "orphan mfd not found, fid = "DFID", "
"cookie = %#llx\n",
PFID(mdt_object_fid(mfd->mfd_object)),
- info->mti_rr.rr_handle->cookie);
+ info->mti_rr.rr_
open_
handle->cookie);
}
CDEBUG(D_HA, "Store old cookie %#llx in new mfd\n",
- info->mti_rr.rr_handle->cookie);
+ info->mti_rr.rr_
open_
handle->cookie);
- mfd->mfd_o
ld_handle.cookie = info->mti_rr.rr_handle->cooki
e;
+ mfd->mfd_o
pen_handle_old = *info->mti_rr.rr_open_handl
e;
}
- repbody->mbo_
handle.cookie = mfd->mfd
_handle.h_cookie;
+ repbody->mbo_
open_handle.cookie = mfd->mfd_open
_handle.h_cookie;
if (req->rq_export->exp_disconnected) {
spin_lock(&med->med_open_lock);
- class_handle_unhash(&mfd->mfd_handle);
+ class_handle_unhash(&mfd->mfd_
open_
handle);
list_del_init(&mfd->mfd_list);
spin_unlock(&med->med_open_lock);
mdt_mfd_close(info, mfd);
@@
-486,12
+491,12
@@
static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p,
mdt_empty_transno(info, rc);
-
RETURN(rc);
+ RETURN(rc);
err_out:
- if (
flags &
FMODE_WRITE)
+ if (
open_flags & MDS_
FMODE_WRITE)
mdt_write_put(o);
- else if (flags & MDS_FMODE_EXEC)
+ else if (
open_
flags & MDS_FMODE_EXEC)
mdt_write_allow(o);
return rc;
@@
-499,7
+504,8
@@
err_out:
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)
+ u64 open_flags, int created,
+ struct ldlm_reply *rep)
{
struct ptlrpc_request *req = mdt_info_req(info);
struct obd_export *exp = req->rq_export;
@@
-537,6
+543,11
@@
static int mdt_finish_open(struct mdt_thread_info *info,
RETURN(-EOPNOTSUPP);
}
+ /* Overstriped files can crash older clients */
+ if (isreg && !exp_connect_overstriping(exp) &&
+ mdt_lmm_is_overstriping(ma->ma_lmm))
+ RETURN(-EOPNOTSUPP);
+
/* LU-2275, simulate broken behaviour (esp. prevalent in
* pre-2.4 servers where a very strange reply is sent on error
* that looks like it was actually almost successful and a
@@
-546,7
+557,7
@@
static int mdt_finish_open(struct mdt_thread_info *info,
DISP_LOOKUP_NEG |
DISP_LOOKUP_POS);
- if (flags & MDS_OPEN_LOCK)
+ if (
open_
flags & MDS_OPEN_LOCK)
mdt_set_disposition(info, rep, DISP_OPEN_LOCK);
RETURN(-ENOENT);
@@
-565,36
+576,36
@@
static int mdt_finish_open(struct mdt_thread_info *info,
}
#endif
-
/*
-
* If we are following a symlink, don't open; and do not return open
-
* handle for special nodes as client required.
-
*/
+ /*
+ * If we are following a symlink, don't open; and do not return open
+ * handle for special nodes as client required.
+ */
if (islnk || (!isreg && !isdir &&
(exp_connect_flags(req->rq_export) & OBD_CONNECT_NODEVOH))) {
lustre_msg_set_transno(req->rq_repmsg, 0);
RETURN(0);
}
- /*
- * We need to return the existing object's fid back, so it is done here,
- * after preparing the reply.
- */
- if (!created && (flags & MDS_OPEN_EXCL) && (flags & MDS_OPEN_CREAT))
- RETURN(-EEXIST);
+ /*
+ * We need to return the existing object's fid back, so it is done here,
+ * after preparing the reply.
+ */
+ if (!created && (open_flags & MDS_OPEN_EXCL) &&
+ (open_flags & MDS_OPEN_CREAT))
+ RETURN(-EEXIST);
+
+ /* This can't be done earlier, we need to return reply body */
+ if (isdir) {
+ if (open_flags & (MDS_OPEN_CREAT | MDS_FMODE_WRITE)) {
+ /* We are trying to create or write an existing dir. */
+ RETURN(-EISDIR);
+ }
+ } else if (open_flags & MDS_OPEN_DIRECTORY)
+ RETURN(-ENOTDIR);
- /* This can't be done earlier, we need to return reply body */
- if (isdir) {
- if (flags & (MDS_OPEN_CREAT | FMODE_WRITE)) {
- /* We are trying to create or write an existing dir. */
- RETURN(-EISDIR);
- }
- } else if (flags & MDS_OPEN_DIRECTORY)
- RETURN(-ENOTDIR);
-
- if (OBD_FAIL_CHECK_RESET(OBD_FAIL_MDS_OPEN_CREATE,
- OBD_FAIL_LDLM_REPLY | OBD_FAIL_ONCE)) {
- RETURN(-EAGAIN);
- }
+ if (OBD_FAIL_CHECK_RESET(OBD_FAIL_MDS_OPEN_CREATE,
+ OBD_FAIL_MDS_LDLM_REPLY_NET | OBD_FAIL_ONCE))
+ RETURN(-EAGAIN);
mfd = NULL;
if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) {
@@
-607,8
+618,9
@@
static int mdt_finish_open(struct mdt_thread_info *info,
}
spin_unlock(&med->med_open_lock);
- if (mfd != NULL) {
- repbody->mbo_handle.cookie = mfd->mfd_handle.h_cookie;
+ if (mfd != NULL) {
+ repbody->mbo_open_handle.cookie =
+ mfd->mfd_open_handle.h_cookie;
/* set repbody->ea_size for resent case */
if (ma->ma_valid & MA_LOV) {
LASSERT(ma->ma_lmm_size != 0);
@@
-623,7
+635,7
@@
static int mdt_finish_open(struct mdt_thread_info *info,
}
}
- rc = mdt_mfd_open(info, p, o, flags, created, rep);
+ rc = mdt_mfd_open(info, p, o,
open_
flags, created, rep);
if (!rc)
mdt_set_disposition(info, rep, DISP_OPEN_OPEN);
@@
-631,26
+643,26
@@
static int mdt_finish_open(struct mdt_thread_info *info,
}
void mdt_reconstruct_open(struct mdt_thread_info *info,
-
struct mdt_lock_handle *lhc)
+ struct mdt_lock_handle *lhc)
{
-
const struct lu_env *env = info->mti_env;
-
struct mdt_device *mdt
= info->mti_mdt;
-
struct req_capsule
*pill = info->mti_pill;
-
struct ptlrpc_request *req
= mdt_info_req(info);
-
struct md_attr *ma
= &info->mti_attr;
-
struct mdt_reint_record *rr
= &info->mti_rr;
-
__u64
flags = info->mti_spec.sp_cr_flags;
-
struct ldlm_reply
*ldlm_rep;
-
struct mdt_object
*parent;
-
struct mdt_object
*child;
-
struct mdt_body
*repbody;
-
int rc
;
-
__u64 opdata
;
+ const struct lu_env *env = info->mti_env;
+
struct mdt_device *mdt
= info->mti_mdt;
+
struct req_capsule
*pill = info->mti_pill;
+
struct ptlrpc_request *req
= mdt_info_req(info);
+
struct md_attr *ma
= &info->mti_attr;
+
struct mdt_reint_record *rr
= &info->mti_rr;
+
u64 open_
flags = info->mti_spec.sp_cr_flags;
+
struct ldlm_reply
*ldlm_rep;
+
struct mdt_object
*parent;
+
struct mdt_object
*child;
+
struct mdt_body
*repbody;
+
u64 opdata
;
+
int rc
;
ENTRY;
-
LASSERT(pill->rc_fmt == &RQF_LDLM_INTENT_OPEN);
-
ldlm_rep = req_capsule_server_get(pill, &RMF_DLM_REP);
-
repbody = req_capsule_server_get(pill, &RMF_MDT_BODY);
+ LASSERT(pill->rc_fmt == &RQF_LDLM_INTENT_OPEN);
+ ldlm_rep = req_capsule_server_get(pill, &RMF_DLM_REP);
+ repbody = req_capsule_server_get(pill, &RMF_MDT_BODY);
ma->ma_need = MA_INODE | MA_HSM;
ma->ma_valid = 0;
@@
-698,72
+710,66
@@
void mdt_reconstruct_open(struct mdt_thread_info *info,
}
if (unlikely(mdt_object_remote(child))) {
+ mdt_object_put(env, parent);
+ mdt_object_put(env, child);
/* the child object was created on remote server */
- if (!mdt_is_dne_client(exp))
{
+ if (!mdt_is_dne_client(exp))
/* Return -EIO for old client */
- mdt_object_put(env, parent);
- mdt_object_put(env, child);
GOTO(out, rc = -EIO);
- }
repbody->mbo_fid1 = *rr->rr_fid2;
repbody->mbo_valid |= (OBD_MD_FLID | OBD_MD_MDS);
- rc = 0;
- } else {
- if (mdt_object_exists(child)) {
- mdt_prep_ma_buf_from_rep(info, child, ma);
- rc = mdt_attr_get_complex(info, child, ma);
- if (rc == 0)
- rc = mdt_finish_open(info, parent,
- child, flags,
- 1, ldlm_rep);
- } else {
- /* the child does not exist, we should do
- * regular open */
- mdt_object_put(env, parent);
- mdt_object_put(env, child);
- GOTO(regular_open, 0);
- }
+ GOTO(out, rc = 0);
}
- mdt_object_put(env, parent);
- mdt_object_put(env, child);
- GOTO(out, rc);
- } else {
-regular_open:
- /* We did not try to create, so we are a pure open */
- rc = mdt_reint_open(info, lhc);
- }
-
- EXIT;
+ if (mdt_object_exists(child)) {
+ mdt_prep_ma_buf_from_rep(info, child, ma);
+ rc = mdt_attr_get_complex(info, child, ma);
+ if (!rc)
+ rc = mdt_finish_open(info, parent, child,
+ open_flags, 1, ldlm_rep);
+ mdt_object_put(env, parent);
+ mdt_object_put(env, child);
+ if (!rc)
+ mdt_pack_size2body(info, rr->rr_fid2,
+ &lhc->mlh_reg_lh);
+ GOTO(out, rc);
+ }
+ /* the child does not exist, we should do regular open */
+ mdt_object_put(env, parent);
+ mdt_object_put(env, child);
+ }
+ /* We did not try to create, so we are a pure open */
+ rc = mdt_reint_open(info, lhc);
+ EXIT;
out:
-
req->rq_status = rc;
-
lustre_msg_set_status(req->rq_repmsg, req->rq_status);
-
LASSERT(ergo(rc < 0, lustre_msg_get_transno(req->rq_repmsg) == 0));
+ req->rq_status = rc;
+ lustre_msg_set_status(req->rq_repmsg, req->rq_status);
+ LASSERT(ergo(rc < 0, lustre_msg_get_transno(req->rq_repmsg) == 0));
}
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;
- struct md_attr *ma = &info->mti_attr;
- struct mdt_object *o;
- int rc;
- ENTRY;
+ u64 open_flags = info->mti_spec.sp_cr_flags;
+ struct mdt_reint_record *rr = &info->mti_rr;
+ struct md_attr *ma = &info->mti_attr;
+ struct mdt_object *o;
+ int rc;
- o = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid2);
- if (IS_ERR(o))
- RETURN(rc = PTR_ERR(o));
+ ENTRY;
+ o = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid2);
+ if (IS_ERR(o))
+ RETURN(rc = PTR_ERR(o));
if (unlikely(mdt_object_remote(o))) {
-
/* the child object was created on remote server */
-
struct mdt_body *repbody;
+ /* the child object was created on remote server */
+ struct mdt_body *repbody;
mdt_set_disposition(info, rep, (DISP_IT_EXECD |
DISP_LOOKUP_EXECD |
DISP_LOOKUP_POS));
-
repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
+ repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
repbody->mbo_fid1 = *rr->rr_fid2;
repbody->mbo_valid |= (OBD_MD_FLID | OBD_MD_MDS);
-
rc = 0;
+ rc = 0;
} else {
if (mdt_object_exists(o)) {
mdt_set_disposition(info, rep, (DISP_IT_EXECD |
@@
-772,15
+778,15
@@
static int mdt_open_by_fid(struct mdt_thread_info *info, struct ldlm_reply *rep)
mdt_prep_ma_buf_from_rep(info, o, ma);
rc = mdt_attr_get_complex(info, o, ma);
if (rc == 0)
- rc = mdt_finish_open(info, NULL, o,
flags, 0
,
- rep);
+ rc = mdt_finish_open(info, NULL, o,
open_flags
,
+
0,
rep);
} else {
rc = -ENOENT;
}
}
-
mdt_object_put(info->mti_env, o);
-
RETURN(rc);
+ mdt_object_put(info->mti_env, o);
+ RETURN(rc);
}
/* lock object for open */
@@
-830,7
+836,7
@@
static int mdt_object_open_lock(struct mdt_thread_info *info,
dom_stripes = mdt_lmm_dom_entry(ma->ma_lmm);
if (dom_stripes == LMM_DOM_ONLY &&
- info->mti_mdt->mdt_opts.mo_dom_lock
!=
0 &&
+ info->mti_mdt->mdt_opts.mo_dom_lock
>
0 &&
!mdt_dom_client_has_lock(info, mdt_object_fid(obj)))
dom_lock = true;
}
@@
-866,7
+872,7
@@
static int mdt_object_open_lock(struct mdt_thread_info *info,
down_read(&obj->mot_open_sem);
if (open_flags & MDS_OPEN_LOCK) {
- if (open_flags & FMODE_WRITE)
+ if (open_flags &
MDS_
FMODE_WRITE)
lm = LCK_CW;
else if (open_flags & MDS_FMODE_EXEC)
lm = LCK_PR;
@@
-875,7
+881,7
@@
static int mdt_object_open_lock(struct mdt_thread_info *info,
*ibits = MDS_INODELOCK_LOOKUP | MDS_INODELOCK_OPEN;
} else if (atomic_read(&obj->mot_lease_count) > 0) {
- if (open_flags & FMODE_WRITE)
+ if (open_flags &
MDS_
FMODE_WRITE)
lm = LCK_CW;
else
lm = LCK_CR;
@@
-886,20
+892,36
@@
static int mdt_object_open_lock(struct mdt_thread_info *info,
lhc = &info->mti_lh[MDT_LH_LOCAL];
} else if (dom_lock) {
- lm = (open_flags & FMODE_WRITE) ? LCK_PW : LCK_PR;
- *ibits = MDS_INODELOCK_DOM;
+ lm = (open_flags & MDS_FMODE_WRITE) ? LCK_PW : LCK_PR;
+ if (info->mti_mdt->mdt_opts.mo_dom_lock ==
+ TRYLOCK_DOM_ON_OPEN) {
+ trybits |= MDS_INODELOCK_DOM |
+ MDS_INODELOCK_LAYOUT;
+ } else {
+ /* mo_dom_lock == ALWAYS_DOM_LOCK_ON_OPEN */
+ *ibits = MDS_INODELOCK_DOM;
+ if (info->mti_mdt->mdt_opts.mo_dom_read_open) {
+ trybits |= MDS_INODELOCK_LAYOUT;
+ }
+ }
}
CDEBUG(D_INODE, "normal open:"DFID" lease count: %d, lm: %d\n",
PFID(mdt_object_fid(obj)),
- atomic_read(&obj->mot_
open
_count), lm);
+ atomic_read(&obj->mot_
lease
_count), lm);
}
mdt_lock_reg_init(lhc, lm);
- /* one problem to return layout lock on open is that it may result
- * in too many layout locks cached on the client side. */
+ /* Return lookup lock to validate inode at the client side.
+ * This is pretty important otherwise MDT will return layout
+ * lock for each open.
+ * However this is a double-edged sword because changing
+ * permission will revoke a huge number of LOOKUP locks.
+ */
if (!OBD_FAIL_CHECK(OBD_FAIL_MDS_NO_LL_OPEN) && try_layout) {
+ if (!(*ibits & MDS_INODELOCK_LOOKUP))
+ trybits |= MDS_INODELOCK_LOOKUP;
trybits |= MDS_INODELOCK_LAYOUT;
}
@@
-956,11
+978,11
@@
static int mdt_object_open_lock(struct mdt_thread_info *info,
is_replay_or_resent = req_is_replay(req) ||
lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT;
- /* if the request is _not_ a replay request, rr_handle
- * may be used to hold an openhandle which is issuing the
+ /* if the request is _not_ a replay request, rr_
open_
handle
+ * may be used to hold an open
file
handle which is issuing the
* lease request, so that this openhandle doesn't count. */
- mfd = mdt_
handle2mfd(med, info->mti_rr.rr
_handle,
- is_replay_or_resent);
+ mfd = mdt_
open_handle2mfd(med, info->mti_rr.rr_open
_handle,
+
is_replay_or_resent);
if (mfd != NULL)
++open_count;
@@
-1049,32
+1071,32
@@
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;
- __u64 flags = info->mti_spec.sp_cr_flags;
- struct mdt_reint_record *rr = &info->mti_rr;
- struct md_attr *ma = &info->mti_attr;
- struct mdt_object *parent= NULL;
- struct mdt_object *o;
- int rc;
- bool object_locked = false;
- __u64 ibits = 0;
- ENTRY;
+ const struct lu_env *env = info->mti_env;
+ struct mdt_device *mdt = info->mti_mdt;
+ u64 open_flags = info->mti_spec.sp_cr_flags;
+ struct mdt_reint_record *rr = &info->mti_rr;
+ struct md_attr *ma = &info->mti_attr;
+ struct mdt_object *parent = NULL;
+ struct mdt_object *o;
+ bool object_locked = false;
+ u64 ibits = 0;
+ int rc;
- if (md_should_create(flags)) {
- if (!lu_fid_eq(rr->rr_fid1, rr->rr_fid2)) {
- parent = mdt_object_find(env, mdt, rr->rr_fid1);
- if (IS_ERR(parent)) {
- CDEBUG(D_INODE, "Fail to find parent "DFID
- " for anonymous created %ld, try to"
- " use server-side parent.\n",
- PFID(rr->rr_fid1), PTR_ERR(parent));
- parent = NULL;
- }
- }
- if (parent == NULL)
- ma->ma_need |= MA_PFID;
- }
+ ENTRY;
+ if (md_should_create(open_flags)) {
+ if (!lu_fid_eq(rr->rr_fid1, rr->rr_fid2)) {
+ parent = mdt_object_find(env, mdt, rr->rr_fid1);
+ if (IS_ERR(parent)) {
+ CDEBUG(D_INODE, "Fail to find parent "DFID
+ " for anonymous created %ld, try to"
+ " use server-side parent.\n",
+ PFID(rr->rr_fid1), PTR_ERR(parent));
+ parent = NULL;
+ }
+ }
+ if (parent == NULL)
+ ma->ma_need |= MA_PFID;
+ }
o = mdt_object_find(env, mdt, rr->rr_fid2);
if (IS_ERR(o))
@@
-1096,7
+1118,7
@@
static int mdt_open_by_fid_lock(struct mdt_thread_info *info,
mdt_set_disposition(info, rep, (DISP_IT_EXECD | DISP_LOOKUP_EXECD));
mdt_prep_ma_buf_from_rep(info, o, ma);
- if (flags & MDS_OPEN_RELEASE)
+ if (
open_
flags & MDS_OPEN_RELEASE)
ma->ma_need |= MA_HSM;
rc = mdt_attr_get_complex(info, o, ma);
if (rc)
@@
-1104,12
+1126,12
@@
static int mdt_open_by_fid_lock(struct mdt_thread_info *info,
/* We should not change file's existing LOV EA */
if (S_ISREG(lu_object_attr(&o->mot_obj)) &&
- flags & MDS_OPEN_HAS_EA && ma->ma_valid & MA_LOV)
+
open_
flags & MDS_OPEN_HAS_EA && ma->ma_valid & MA_LOV)
GOTO(out, rc = -EEXIST);
- /* If a release request, check file flags are fine and ask for an
+ /* If a release request, check file
open
flags are fine and ask for an
* exclusive open access. */
- if (flags & MDS_OPEN_RELEASE && !mdt_hsm_release_allow(ma))
+ if (
open_
flags & MDS_OPEN_RELEASE && !mdt_hsm_release_allow(ma))
GOTO(out, rc = -EPERM);
rc = mdt_check_resent_lock(info, o, lhc);
@@
-1122,23
+1144,23
@@
static int mdt_open_by_fid_lock(struct mdt_thread_info *info,
GOTO(out_unlock, rc);
}
-
if (ma->ma_valid & MA_PFID) {
-
parent = mdt_object_find(env, mdt, &ma->ma_pfid);
-
if (IS_ERR(parent)) {
-
CDEBUG(D_INODE, "Fail to find parent "DFID
-
" for anonymous created %ld, try to"
-
" use system default.\n",
-
PFID(&ma->ma_pfid), PTR_ERR(parent));
-
parent = NULL;
-
}
-
}
+ if (ma->ma_valid & MA_PFID) {
+ parent = mdt_object_find(env, mdt, &ma->ma_pfid);
+ if (IS_ERR(parent)) {
+ CDEBUG(D_INODE, "Fail to find parent "DFID
+ " for anonymous created %ld, try to"
+ " use system default.\n",
+ PFID(&ma->ma_pfid), PTR_ERR(parent));
+ parent = NULL;
+ }
+ }
-
rc = mdt_finish_open(info, parent, o,
flags, 0, rep);
+
rc = mdt_finish_open(info, parent, o, open_
flags, 0, rep);
if (!rc) {
mdt_set_disposition(info, rep, DISP_LOOKUP_POS);
- if (flags & MDS_OPEN_LOCK)
+ if (
open_
flags & MDS_OPEN_LOCK)
mdt_set_disposition(info, rep, DISP_OPEN_LOCK);
- if (flags & MDS_OPEN_LEASE)
+ if (
open_
flags & MDS_OPEN_LEASE)
mdt_set_disposition(info, rep, DISP_OPEN_LEASE);
}
GOTO(out_unlock, rc);
@@
-1149,8
+1171,7
@@
out_unlock:
out:
mdt_object_put(env, o);
if (rc == 0)
- mdt_pack_size2body(info, rr->rr_fid2,
- ibits & MDS_INODELOCK_DOM);
+ mdt_pack_size2body(info, rr->rr_fid2, &lhc->mlh_reg_lh);
out_parent_put:
if (parent != NULL)
mdt_object_put(env, parent);
@@
-1161,16
+1182,16
@@
out_parent_put:
static int mdt_cross_open(struct mdt_thread_info *info,
const struct lu_fid *parent_fid,
const struct lu_fid *fid,
- struct ldlm_reply *rep,
__u32
flags)
+ struct ldlm_reply *rep,
u64 open_
flags)
{
-
struct md_attr
*ma = &info->mti_attr;
-
struct mdt_object *o;
-
int
rc;
-
ENTRY;
+
struct md_attr
*ma = &info->mti_attr;
+ struct mdt_object *o;
+
int
rc;
+ ENTRY;
-
o = mdt_object_find(info->mti_env, info->mti_mdt, fid);
-
if (IS_ERR(o))
-
RETURN(rc = PTR_ERR(o));
+ o = mdt_object_find(info->mti_env, info->mti_mdt, fid);
+ if (IS_ERR(o))
+ RETURN(rc = PTR_ERR(o));
if (mdt_object_remote(o)) {
/* Something is wrong here, the object is on another MDS! */
@@
-1179,13
+1200,18
@@
static int mdt_cross_open(struct mdt_thread_info *info,
LU_OBJECT_DEBUG(D_WARNING, info->mti_env,
&o->mot_obj,
"Object isn't on this server! FLD error?");
-
rc = -EFAULT;
+ rc = -EFAULT;
} else {
if (mdt_object_exists(o)) {
- /* Do permission check for cross-open. */
+ int mask;
+
+ /* Do permission check for cross-open after converting
+ * MDS_OPEN_* flags to MAY_* permission mask.
+ */
+ mask = mds_accmode(open_flags);
+
rc = mo_permission(info->mti_env, NULL,
- mdt_object_child(o),
- NULL, flags | MDS_OPEN_CROSS);
+ mdt_object_child(o), NULL, mask);
if (rc)
goto out;
@@
-1194,7
+1220,9
@@
static int mdt_cross_open(struct mdt_thread_info *info,
if (rc != 0)
GOTO(out, rc);
- rc = mdt_finish_open(info, NULL, o, flags, 0, rep);
+ mdt_pack_secctx_in_reply(info, o);
+
+ rc = mdt_finish_open(info, NULL, o, open_flags, 0, rep);
} else {
/*
* Something is wrong here. lookup was positive but
@@
-1204,10
+1232,11
@@
static int mdt_cross_open(struct mdt_thread_info *info,
mdt_obd_name(info->mti_mdt), PFID(fid), -EFAULT);
rc = -EFAULT;
}
-
}
+ }
out:
- mdt_object_put(info->mti_env, o);
- RETURN(rc);
+ mdt_object_put(info->mti_env, o);
+
+ RETURN(rc);
}
/*
@@
-1266,55
+1295,54
@@
static int mdt_lock_root_xattr(struct mdt_thread_info *info,
int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
{
- struct mdt_device *mdt = info->mti_mdt;
- struct ptlrpc_request *req = mdt_info_req(info);
- struct mdt_object *parent;
- struct mdt_object *child;
- struct mdt_lock_handle *lh;
- struct ldlm_reply *ldlm_rep;
- struct mdt_body *repbody;
- struct lu_fid *child_fid = &info->mti_tmp_fid1;
- struct md_attr *ma = &info->mti_attr;
- __u64 create_flags = info->mti_spec.sp_cr_flags;
- __u64 ibits = 0;
- struct mdt_reint_record *rr = &info->mti_rr;
- int result, rc;
- int created = 0;
- int object_locked = 0;
- __u32 msg_flags;
- ENTRY;
+ struct mdt_device *mdt = info->mti_mdt;
+ struct ptlrpc_request *req = mdt_info_req(info);
+ struct mdt_object *parent;
+ struct mdt_object *child;
+ struct mdt_lock_handle *lh;
+ struct ldlm_reply *ldlm_rep;
+ struct mdt_body *repbody;
+ struct lu_fid *child_fid = &info->mti_tmp_fid1;
+ struct md_attr *ma = &info->mti_attr;
+ u64 open_flags = info->mti_spec.sp_cr_flags;
+ u64 ibits = 0;
+ struct mdt_reint_record *rr = &info->mti_rr;
+ int result, rc;
+ int created = 0;
+ int object_locked = 0;
+ u32 msg_flags;
- OBD_FAIL_TIMEOUT_ORSET(OBD_FAIL_MDS_PAUSE_OPEN, OBD_FAIL_ONCE,
- (obd_timeout + 1) / 4);
+ ENTRY;
+ OBD_FAIL_TIMEOUT_ORSET(OBD_FAIL_MDS_PAUSE_OPEN, OBD_FAIL_ONCE,
+ (obd_timeout + 1) / 4);
mdt_counter_incr(req, LPROC_MDT_OPEN);
-
repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
+ repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
-
ma->ma_need = MA_INODE;
-
ma->ma_valid = 0;
+ ma->ma_need = MA_INODE;
+ ma->ma_valid = 0;
-
LASSERT(info->mti_pill->rc_fmt == &RQF_LDLM_INTENT_OPEN);
-
ldlm_rep = req_capsule_server_get(info->mti_pill, &RMF_DLM_REP);
+ LASSERT(info->mti_pill->rc_fmt == &RQF_LDLM_INTENT_OPEN);
+ ldlm_rep = req_capsule_server_get(info->mti_pill, &RMF_DLM_REP);
-
if (unlikely(create
_flags & MDS_OPEN_JOIN_FILE)) {
-
CERROR("file join is not supported anymore.\n");
-
GOTO(out, result = err_serious(-EOPNOTSUPP));
-
}
-
msg_flags = lustre_msg_get_flags(req->rq_reqmsg);
+
if (unlikely(open
_flags & MDS_OPEN_JOIN_FILE)) {
+ CERROR("file join is not supported anymore.\n");
+ GOTO(out, result = err_serious(-EOPNOTSUPP));
+ }
+ msg_flags = lustre_msg_get_flags(req->rq_reqmsg);
-
if ((create
_flags & (MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS)) &&
-
info->mti_spec.u.sp_ea.eadata == NULL)
-
GOTO(out, result = err_serious(-EINVAL));
+
if ((open
_flags & (MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS)) &&
+ info->mti_spec.u.sp_ea.eadata == NULL)
+ GOTO(out, result = err_serious(-EINVAL));
- if (
create_flags &
FMODE_WRITE &&
+ if (
open_flags & MDS_
FMODE_WRITE &&
exp_connect_flags(req->rq_export) & OBD_CONNECT_RDONLY)
GOTO(out, result = -EROFS);
CDEBUG(D_INODE, "I am going to open "DFID"/("DNAME"->"DFID") "
"cr_flag=%#llo mode=0%06o msg_flag=0x%x\n",
- PFID(rr->rr_fid1), PNAME(&rr->rr_name),
- PFID(rr->rr_fid2), create_flags,
- ma->ma_attr.la_mode, msg_flags);
+ PFID(rr->rr_fid1), PNAME(&rr->rr_name), PFID(rr->rr_fid2),
+ open_flags, ma->ma_attr.la_mode, msg_flags);
if (info->mti_cross_ref) {
/* This is cross-ref open */
@@
-1322,7
+1350,7
@@
int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
(DISP_IT_EXECD | DISP_LOOKUP_EXECD |
DISP_LOOKUP_POS));
result = mdt_cross_open(info, rr->rr_fid2, rr->rr_fid1,
- ldlm_rep,
create
_flags);
+ ldlm_rep,
open
_flags);
GOTO(out, result);
} else if (req_is_replay(req)) {
result = mdt_open_by_fid(info, ldlm_rep);
@@
-1332,17
+1360,13
@@
int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
/* We didn't find the correct object, so we need to re-create it
* via a regular replay. */
- if (!(
create
_flags & MDS_OPEN_CREAT)) {
+ if (!(
open
_flags & MDS_OPEN_CREAT)) {
DEBUG_REQ(D_ERROR, req,
"OPEN & CREAT not in open replay/by_fid.");
GOTO(out, result = -EFAULT);
}
CDEBUG(D_INFO, "No object(1), continue as regular open.\n");
- } else if (create_flags & (MDS_OPEN_BY_FID | MDS_OPEN_LOCK)) {
- /*
- * MDS_OPEN_LOCK is checked for backward compatibility with 2.1
- * client.
- */
+ } else if (open_flags & MDS_OPEN_BY_FID) {
result = mdt_open_by_fid_lock(info, ldlm_rep, lhc);
if (result < 0)
CDEBUG(D_INFO, "no object for "DFID": %d\n",
@@
-1365,8
+1389,7
@@
int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
again:
lh = &info->mti_lh[MDT_LH_PARENT];
- mdt_lock_pdo_init(lh,
- (create_flags & MDS_OPEN_CREAT) ? LCK_PW : LCK_PR,
+ mdt_lock_pdo_init(lh, (open_flags & MDS_OPEN_CREAT) ? LCK_PW : LCK_PR,
&rr->rr_name);
parent = mdt_object_find(info->mti_env, mdt, rr->rr_fid1);
@@
-1379,23
+1402,25
@@
again:
GOTO(out, result);
}
-
/* get and check version of parent */
-
result = mdt_version_get_check(info, parent, 0);
-
if (result)
-
GOTO(out_parent, result);
+ /* get and check version of parent */
+ result = mdt_version_get_check(info, parent, 0);
+ if (result)
+ GOTO(out_parent, result);
-
fid_zero(child_fid);
+ fid_zero(child_fid);
- result = mdo_lookup(info->mti_env, mdt_object_child(parent),
- &rr->rr_name, child_fid, &info->mti_spec);
+ result = -ENOENT;
+ if ((open_flags & MDS_OPEN_VOLATILE) == 0)
+ result = mdo_lookup(info->mti_env, mdt_object_child(parent),
+ &rr->rr_name, child_fid, &info->mti_spec);
LASSERTF(ergo(result == 0, fid_is_sane(child_fid)),
"looking for "DFID"/"DNAME", found FID = "DFID"\n",
PFID(mdt_object_fid(parent)), PNAME(&rr->rr_name),
PFID(child_fid));
-
if (result != 0 && result != -ENOENT && result != -ESTALE)
-
GOTO(out_parent, result);
+ if (result != 0 && result != -ENOENT && result != -ESTALE)
+ GOTO(out_parent, result);
if (result == -ENOENT || result == -ESTALE) {
/* If the object is dead, let's check if the object
@@
-1436,36
+1461,37
@@
again:
GOTO(out_parent, result = -ENOENT);
}
-
if (!(create
_flags & MDS_OPEN_CREAT))
-
GOTO(out_parent, result);
+
if (!(open
_flags & MDS_OPEN_CREAT))
+ GOTO(out_parent, result);
if (mdt_rdonly(req->rq_export))
GOTO(out_parent, result = -EROFS);
-
*child_fid = *info->mti_rr.rr_fid2;
-
LASSERTF(fid_is_sane(child_fid), "fid="DFID"\n",
-
PFID(child_fid));
+ *child_fid = *info->mti_rr.rr_fid2;
+ LASSERTF(fid_is_sane(child_fid), "fid="DFID"\n",
+ PFID(child_fid));
/* In the function below, .hs_keycmp resolves to
* lu_obj_hop_keycmp() */
/* coverity[overrun-buffer-val] */
child = mdt_object_new(info->mti_env, mdt, child_fid);
} else {
/*
- * Check for O_EXCL is moved to the mdt_finish_open(),
we need to
- * return FID back in that case.
+ * Check for O_EXCL is moved to the mdt_finish_open(),
+ *
we need to
return FID back in that case.
*/
mdt_set_disposition(info, ldlm_rep, DISP_LOOKUP_POS);
child = mdt_object_find(info->mti_env, mdt, child_fid);
}
-
if (IS_ERR(child))
-
GOTO(out_parent, result = PTR_ERR(child));
+ if (IS_ERR(child))
+ GOTO(out_parent, result = PTR_ERR(child));
-
/** check version of child */
-
rc = mdt_version_get_check(info, child, 1);
-
if (rc)
-
GOTO(out_child, result = rc);
+ /** check version of child */
+ rc = mdt_version_get_check(info, child, 1);
+ if (rc)
+ GOTO(out_child, result = rc);
-
if (result == -ENOENT) {
+ if (result == -ENOENT) {
/* Create under OBF and .lustre is not permitted */
- if (!fid_is_md_operative(rr->rr_fid1))
+ if (!fid_is_md_operative(rr->rr_fid1) &&
+ (open_flags & MDS_OPEN_VOLATILE) == 0)
GOTO(out_child, result = -EPERM);
/* save versions in reply */
@@
-1547,7
+1573,9
@@
again:
PNAME(&rr->rr_name), PFID(child_fid));
GOTO(out_child, result = -EIO);
}
- }
+ }
+
+ mdt_pack_secctx_in_reply(info, child);
rc = mdt_check_resent_lock(info, child, lhc);
if (rc < 0) {
@@
-1556,7
+1584,7
@@
again:
/* the open lock might already be gotten in
* ldlm_handle_enqueue() */
LASSERT(lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT);
- if (
create
_flags & MDS_OPEN_LOCK)
+ if (
open
_flags & MDS_OPEN_LOCK)
mdt_set_disposition(info, ldlm_rep, DISP_OPEN_LOCK);
} else {
/* get openlock if this isn't replay and client requested it */
@@
-1565,20
+1593,20
@@
again:
object_locked = 1;
if (rc != 0)
GOTO(out_child_unlock, result = rc);
- else if (
create
_flags & MDS_OPEN_LOCK)
+ else if (
open
_flags & MDS_OPEN_LOCK)
mdt_set_disposition(info, ldlm_rep,
DISP_OPEN_LOCK);
}
}
/* Try to open it now. */
- rc = mdt_finish_open(info, parent, child,
create
_flags,
+ rc = mdt_finish_open(info, parent, child,
open
_flags,
created, ldlm_rep);
if (rc) {
result = rc;
- /* openlock will be released if mdt_finish_open failed */
+ /* openlock will be released if mdt_finish_open
()
failed */
mdt_clear_disposition(info, ldlm_rep, DISP_OPEN_LOCK);
- if (created &&
create_flags & MDS_OPEN_VOLATILE
) {
+ if (created &&
(open_flags & MDS_OPEN_VOLATILE)
) {
CERROR("%s: cannot open volatile file "DFID", orphan "
"file will be left in PENDING directory until "
"next reboot, rc = %d\n", mdt_obd_name(mdt),
@@
-1608,7
+1636,7
@@
out_child_unlock:
out_child:
mdt_object_put(info->mti_env, child);
if (result == 0)
- mdt_pack_size2body(info, child_fid,
ibits & MDS_INODELOCK_DOM
);
+ mdt_pack_size2body(info, child_fid,
&lhc->mlh_reg_lh
);
out_parent:
mdt_object_unlock_put(info, parent, lh, result || !created);
out:
@@
-1675,7
+1703,7
@@
static struct mdt_object *mdt_orphan_open(struct mdt_thread_info *info,
GOTO(out, rc);
}
- rc = mo_open(env, mdt_object_child(obj), MDS_OPEN_CREATED);
+ rc = mo_open(env, mdt_object_child(obj), MDS_OPEN_CREATED
, spec
);
if (rc < 0)
CERROR("%s: cannot open volatile file "DFID", orphan "
"file will be left in PENDING directory until "
@@
-1718,6
+1746,22
@@
static inline int mdt_hsm_set_released(struct lov_mds_md *lmm)
return 0;
}
+static inline int mdt_get_lmm_gen(struct lov_mds_md *lmm, __u32 *gen)
+{
+ struct lov_comp_md_v1 *comp_v1;
+
+ if (le32_to_cpu(lmm->lmm_magic == LOV_MAGIC_COMP_V1)) {
+ comp_v1 = (struct lov_comp_md_v1 *)lmm;
+ *gen = le32_to_cpu(comp_v1->lcm_layout_gen);
+ } else if (le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC_V1 ||
+ le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC_V3) {
+ *gen = le16_to_cpu(lmm->lmm_layout_gen);
+ } else {
+ return -EINVAL;
+ }
+ return 0;
+}
+
static int mdt_hsm_release(struct mdt_thread_info *info, struct mdt_object *o,
struct md_attr *ma)
{
@@
-1777,19
+1821,66
@@
static int mdt_hsm_release(struct mdt_thread_info *info, struct mdt_object *o,
if (rc != 0)
GOTO(out_unlock, rc);
- if (!mdt_hsm_release_allow(ma))
- GOTO(out_unlock, rc = -EPERM);
-
- /* already released? */
- if (ma->ma_hsm.mh_flags & HS_RELEASED)
- GOTO(out_unlock, rc = 0);
+ if (ma->ma_attr_flags & MDS_PCC_ATTACH) {
+ if (ma->ma_valid & MA_HSM) {
+ if (ma->ma_hsm.mh_flags & HS_RELEASED)
+ GOTO(out_unlock, rc = -EALREADY);
+
+ if (ma->ma_hsm.mh_arch_id != data->cd_archive_id)
+ CDEBUG(D_CACHE,
+ DFID" archive id diff: %llu:%u\n",
+ PFID(mdt_object_fid(o)),
+ ma->ma_hsm.mh_arch_id,
+ data->cd_archive_id);
+
+ if (!(ma->ma_hsm.mh_flags & HS_DIRTY) &&
+ ma->ma_hsm.mh_arch_ver == data->cd_data_version) {
+ CDEBUG(D_CACHE,
+ DFID" data version matches: packed=%llu "
+ "and on-disk=%llu\n",
+ PFID(mdt_object_fid(o)),
+ data->cd_data_version,
+ ma->ma_hsm.mh_arch_ver);
+ ma->ma_hsm.mh_flags = HS_ARCHIVED | HS_EXISTS;
+ }
- /* Compare on-disk and packed data_version */
- if (data->cd_data_version != ma->ma_hsm.mh_arch_ver) {
- CDEBUG(D_HSM, DFID" data_version mismatches: packed=%llu"
- " and on-disk=%llu\n", PFID(mdt_object_fid(o)),
- data->cd_data_version, ma->ma_hsm.mh_arch_ver);
- GOTO(out_unlock, rc = -EPERM);
+ if (ma->ma_hsm.mh_flags & HS_DIRTY)
+ ma->ma_hsm.mh_flags = HS_ARCHIVED | HS_EXISTS;
+ } else {
+ /* Set up HSM attribte for PCC archived object */
+ BUILD_BUG_ON(sizeof(struct hsm_attrs) >
+ sizeof(info->mti_xattr_buf));
+ buf = &info->mti_buf;
+ buf->lb_buf = info->mti_xattr_buf;
+ buf->lb_len = sizeof(struct hsm_attrs);
+ memset(&ma->ma_hsm, 0, sizeof(ma->ma_hsm));
+ ma->ma_hsm.mh_flags = HS_ARCHIVED | HS_EXISTS;
+ ma->ma_hsm.mh_arch_id = data->cd_archive_id;
+ ma->ma_hsm.mh_arch_ver = data->cd_data_version;
+ lustre_hsm2buf(buf->lb_buf, &ma->ma_hsm);
+
+ rc = mo_xattr_set(info->mti_env, mdt_object_child(o),
+ buf, XATTR_NAME_HSM, 0);
+ if (rc)
+ GOTO(out_unlock, rc);
+ }
+ } else {
+ if (!mdt_hsm_release_allow(ma))
+ GOTO(out_unlock, rc = -EPERM);
+
+ /* already released? */
+ if (ma->ma_hsm.mh_flags & HS_RELEASED)
+ GOTO(out_unlock, rc = 0);
+
+ /* Compare on-disk and packed data_version */
+ if (data->cd_data_version != ma->ma_hsm.mh_arch_ver) {
+ CDEBUG(D_HSM, DFID" data_version mismatches: "
+ "packed=%llu and on-disk=%llu\n",
+ PFID(mdt_object_fid(o)),
+ data->cd_data_version,
+ ma->ma_hsm.mh_arch_ver);
+ GOTO(out_unlock, rc = -EPERM);
+ }
}
ma->ma_valid = MA_INODE;
@@
-1798,6
+1889,17
@@
static int mdt_hsm_release(struct mdt_thread_info *info, struct mdt_object *o,
if (rc < 0)
GOTO(out_unlock, rc);
+ mutex_lock(&o->mot_som_mutex);
+ rc2 = mdt_set_som(info, o, SOM_FL_STRICT, ma->ma_attr.la_size,
+ ma->ma_attr.la_blocks);
+ mutex_unlock(&o->mot_som_mutex);
+ if (rc2 < 0)
+ CDEBUG(D_INODE,
+ "%s: File "DFID" SOM update failed: rc = %d\n",
+ mdt_obd_name(info->mti_mdt),
+ PFID(mdt_object_fid(o)), rc2);
+
+
ma->ma_need = MA_INODE | MA_LOV;
rc = mdt_attr_get_complex(info, o, ma);
if (rc < 0)
@@
-1837,7
+1939,7
@@
static int mdt_hsm_release(struct mdt_thread_info *info, struct mdt_object *o,
orp_ma->ma_lmm_size = ma->ma_lmm_size;
orp_ma->ma_valid = MA_INODE | MA_LOV;
orphan = mdt_orphan_open(info, info->mti_mdt, &data->cd_fid, orp_ma,
- FMODE_WRITE);
+
MDS_
FMODE_WRITE);
if (IS_ERR(orphan)) {
CERROR("%s: cannot open orphan file "DFID": rc = %ld\n",
mdt_obd_name(info->mti_mdt), PFID(&data->cd_fid),
@@
-1846,7
+1948,7
@@
static int mdt_hsm_release(struct mdt_thread_info *info, struct mdt_object *o,
}
/* Set up HSM attribute for orphan object */
-
CLASSERT(sizeof(struct hsm_attrs) <=
sizeof(info->mti_xattr_buf));
+
BUILD_BUG_ON(sizeof(struct hsm_attrs) >
sizeof(info->mti_xattr_buf));
buf = &info->mti_buf;
buf->lb_buf = info->mti_xattr_buf;
buf->lb_len = sizeof(struct hsm_attrs);
@@
-1874,6
+1976,12
@@
static int mdt_hsm_release(struct mdt_thread_info *info, struct mdt_object *o,
rc = mo_swap_layouts(info->mti_env, mdt_object_child(o),
mdt_object_child(orphan),
SWAP_LAYOUTS_MDS_HSM);
+
+ if (!rc && ma->ma_attr_flags & MDS_PCC_ATTACH) {
+ ma->ma_need = MA_LOV;
+ rc = mdt_attr_get_complex(info, o, ma);
+ }
+
EXIT;
out_layout_lock:
@@
-1882,7
+1990,7
@@
out_layout_lock:
out_close:
/* Close orphan object anyway */
rc2 = mo_close(info->mti_env, mdt_object_child(orphan), orp_ma,
- FMODE_WRITE);
+
MDS_
FMODE_WRITE);
if (rc2 < 0)
CERROR("%s: error closing volatile file "DFID": rc = %d\n",
mdt_obd_name(info->mti_mdt), PFID(&data->cd_fid), rc2);
@@
-1900,10
+2008,17
@@
out_unlock:
repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
LASSERT(repbody != NULL);
repbody->mbo_valid |= OBD_MD_CLOSE_INTENT_EXECED;
+ if (ma->ma_attr_flags & MDS_PCC_ATTACH) {
+ LASSERT(ma->ma_valid & MA_LOV);
+ rc = mdt_get_lmm_gen(ma->ma_lmm,
+ &repbody->mbo_layout_gen);
+ if (!rc)
+ repbody->mbo_valid |= OBD_MD_LAYOUT_VERSION;
+ }
}
out_reprocess:
- ldlm_reprocess_all(lease->l_resource);
+ ldlm_reprocess_all(lease->l_resource
, lease
);
LDLM_LOCK_PUT(lease);
ma->ma_valid = 0;
@@
-2027,7
+2142,11
@@
int mdt_close_handle_layouts(struct mdt_thread_info *info,
if (rc == 0 && ma->ma_attr.la_valid & (LA_SIZE | LA_BLOCKS)) {
int rc2;
- rc2 = mdt_set_som(info, o, &ma->ma_attr);
+ mutex_lock(&o->mot_som_mutex);
+ rc2 = mdt_set_som(info, o, SOM_FL_STRICT,
+ ma->ma_attr.la_size,
+ ma->ma_attr.la_blocks);
+ mutex_unlock(&o->mot_som_mutex);
if (rc2 < 0)
CERROR(DFID": Setting i_blocks error: %d, "
"i_blocks will be reported wrongly and "
@@
-2062,7
+2181,7
@@
out_unlock_sem:
out_obj:
mdt_object_put(info->mti_env, swap_objects ? o1 : o2);
- ldlm_reprocess_all(lease->l_resource);
+ ldlm_reprocess_all(lease->l_resource
, lease
);
out_lease:
LDLM_LOCK_PUT(lease);
@@
-2153,7
+2272,7
@@
static int mdt_close_resync_done(struct mdt_thread_info *info,
layout.mlc_opc = MD_LAYOUT_RESYNC_DONE;
layout.mlc_resync_count = resync_count;
if (ma->ma_attr.la_valid & (LA_SIZE | LA_BLOCKS)) {
- layout.mlc_som.lsa_valid =
LSOM_FL_VALID
;
+ layout.mlc_som.lsa_valid =
SOM_FL_STRICT
;
layout.mlc_som.lsa_size = ma->ma_attr.la_size;
layout.mlc_som.lsa_blocks = ma->ma_attr.la_blocks;
}
@@
-2179,7
+2298,7
@@
out_unlock:
OBD_FREE(resync_ids, resync_count * sizeof(__u32));
out_reprocess:
- ldlm_reprocess_all(lease->l_resource);
+ ldlm_reprocess_all(lease->l_resource
, lease
);
LDLM_LOCK_PUT(lease);
ma->ma_valid = 0;
@@
-2188,28
+2307,31
@@
out_reprocess:
return rc;
}
-#define MFD_CLOSED(mode) ((mode) == MDS_FMODE_CLOSED)
+#define MFD_CLOSED(open_flags) ((open_flags) == MDS_FMODE_CLOSED)
+
static int mdt_mfd_closed(struct mdt_file_data *mfd)
{
-
return ((mfd == NULL) || MFD_CLOSED(mfd->mfd_mode
));
+
return ((mfd == NULL) || MFD_CLOSED(mfd->mfd_open_flags
));
}
int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd)
{
-
struct mdt_object *o = mfd->mfd_object;
-
struct md_object *next = mdt_object_child(o);
-
struct md_attr *ma = &info->mti_attr;
-
int rc = 0
;
-
__u64 mode
;
-
__u64 intent
;
-
ENTRY
;
+ struct mdt_object *o = mfd->mfd_object;
+ struct md_object *next = mdt_object_child(o);
+ struct md_attr *ma = &info->mti_attr;
+
struct lu_fid *ofid = &info->mti_tmp_fid1
;
+
int rc = 0
;
+
u64 open_flags
;
+
u64 intent
;
-
mode = mfd->mfd_mode
;
+
ENTRY
;
+ open_flags = mfd->mfd_open_flags;
intent = ma->ma_attr_flags & MDS_CLOSE_INTENT;
+ *ofid = *mdt_object_fid(o);
CDEBUG(D_INODE, "%s: close file "DFID" with intent: %llx\n",
- mdt_obd_name(info->mti_mdt), PFID(
mdt_object_fid(o)
), intent);
+ mdt_obd_name(info->mti_mdt), PFID(
ofid
), intent);
switch (intent) {
case MDS_HSM_RELEASE: {
@@
-2217,7
+2339,7
@@
int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd)
if (rc < 0) {
CDEBUG(D_HSM, "%s: File " DFID " release failed: %d\n",
mdt_obd_name(info->mti_mdt),
- PFID(
mdt_object_fid(o)
), rc);
+ PFID(
ofid
), rc);
/* continue to close even error occurred. */
}
break;
@@
-2228,9
+2350,9
@@
int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd)
rc = mdt_close_handle_layouts(info, o, ma);
if (rc < 0) {
CDEBUG(D_INODE,
- "%s: cannot swap layout of "DFID": rc
=
%d\n",
+ "%s: cannot swap layout of "DFID": rc
=
%d\n",
mdt_obd_name(info->mti_mdt),
- PFID(
mdt_object_fid(o)
), rc);
+ PFID(
ofid
), rc);
/* continue to close even if error occurred. */
}
break;
@@
-2243,14
+2365,28
@@
int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd)
break;
}
- if (mode & FMODE_WRITE)
+ if (S_ISREG(lu_object_attr(&o->mot_obj)) &&
+ ma->ma_attr.la_valid & (LA_LSIZE | LA_LBLOCKS)) {
+ int rc2;
+
+ rc2 = mdt_lsom_update(info, o, false);
+ if (rc2 < 0)
+ CDEBUG(D_INODE,
+ "%s: File " DFID " LSOM failed: rc = %d\n",
+ mdt_obd_name(info->mti_mdt),
+ PFID(ofid), rc2);
+ /* continue to close even if error occured. */
+ }
+
+ if (open_flags & MDS_FMODE_WRITE)
mdt_write_put(o);
- else if (
mode
& MDS_FMODE_EXEC)
+ else if (
open_flags
& MDS_FMODE_EXEC)
mdt_write_allow(o);
/* Update atime on close only. */
- if ((mode & MDS_FMODE_EXEC || mode & FMODE_READ || mode & FMODE_WRITE)
- && (ma->ma_valid & MA_INODE) && (ma->ma_attr.la_valid & LA_ATIME)) {
+ if ((open_flags & MDS_FMODE_EXEC || open_flags & MDS_FMODE_READ ||
+ open_flags & MDS_FMODE_WRITE) && (ma->ma_valid & MA_INODE) &&
+ (ma->ma_attr.la_valid & LA_ATIME)) {
/* Set the atime only. */
ma->ma_valid = MA_INODE;
ma->ma_attr.la_valid = LA_ATIME;
@@
-2268,13
+2404,14
@@
int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd)
atomic_dec(&o->mot_open_count);
mdt_handle_last_unlink(info, o, ma);
- if (!MFD_CLOSED(mode)) {
- rc = mo_close(info->mti_env, next, ma, mode);
- mdt_dom_check_and_discard(info, o);
+ if (!MFD_CLOSED(open_flags)) {
+ rc = mo_close(info->mti_env, next, ma, open_flags);
+ if (mdt_dom_check_for_discard(info, o))
+ mdt_dom_discard_data(info, o);
}
/* adjust open and lease count */
- if (
mode
& MDS_OPEN_LEASE) {
+ if (
open_flags
& MDS_OPEN_LEASE) {
LASSERT(atomic_read(&o->mot_lease_count) > 0);
atomic_dec(&o->mot_lease_count);
}
@@
-2296,16
+2433,17
@@
int mdt_close_internal(struct mdt_thread_info *info, struct ptlrpc_request *req,
med = &req->rq_export->exp_mdt_data;
spin_lock(&med->med_open_lock);
- mfd = mdt_handle2mfd(med, &info->mti_close_handle, req_is_replay(req));
+ mfd = mdt_open_handle2mfd(med, &info->mti_open_handle,
+ req_is_replay(req));
if (mdt_mfd_closed(mfd)) {
spin_unlock(&med->med_open_lock);
CDEBUG(D_INODE, "no handle for file close: fid = "DFID
": cookie = %#llx\n", PFID(info->mti_rr.rr_fid1),
- info->mti_
close
_handle.cookie);
+ info->mti_
open
_handle.cookie);
/** not serious error since bug 3633 */
rc = -ESTALE;
} else {
- class_handle_unhash(&mfd->mfd_handle);
+ class_handle_unhash(&mfd->mfd_
open_
handle);
list_del_init(&mfd->mfd_list);
spin_unlock(&med->med_open_lock);
ret = mdt_mfd_close(info, mfd);
@@
-2356,9
+2494,9
@@
int mdt_close(struct tgt_session_info *tsi)
ma->ma_need = MA_INODE | MA_LOV;
repbody->mbo_eadatasize = 0;
repbody->mbo_aclsize = 0;
-
} else {
-
rc = err_serious(rc);
-
}
+ } else {
+ rc = err_serious(rc);
+ }
rc = mdt_close_internal(info, req, repbody);
if (rc != -ESTALE)