RETURN(class_handle2object(handle->cookie));
}
-static void mds_mfd_put(struct mds_file_data *mfd)
+void mds_mfd_put(struct mds_file_data *mfd)
{
CDEBUG(D_INFO, "PUTting mfd %p : new refcount %d\n", mfd,
atomic_read(&mfd->mfd_refcount) - 1);
rc = -ENOMEM;
goto out;
}
- if (epoch > mds->mds_io_epoch)
+ if (epoch > mds->mds_io_epoch) {
mds->mds_io_epoch = epoch;
- else
+ CDEBUG(D_INODE, "repair MDS epoch "LPU64" for ino %lu/%u\n",
+ mds->mds_io_epoch, inode->i_ino, inode->i_generation);
+ } else {
mds->mds_io_epoch++;
+ CDEBUG(D_INODE, "starting MDS epoch "LPU64" for ino %lu/%u\n",
+ mds->mds_io_epoch, inode->i_ino, inode->i_generation);
+ }
MDS_FILTERDATA(inode)->io_epoch = mds->mds_io_epoch;
- CDEBUG(D_INODE, "starting MDS epoch "LPU64" for ino %lu/%u\n",
- mds->mds_io_epoch, inode->i_ino, inode->i_generation);
out:
if (rc == 0)
atomic_inc(&inode->i_writecount);
/* This replaces the VFS dentry_open, it manages mfd and writecount */
static struct mds_file_data *mds_dentry_open(struct dentry *dentry,
struct vfsmount *mnt, int flags,
- struct ptlrpc_request *req)
+ struct ptlrpc_request *req,
+ struct mds_update_record *rec)
{
struct mds_export_data *med = &req->rq_export->exp_mds_data;
struct mds_obd *mds = mds_req2mds(req);
if (flags & FMODE_WRITE) {
/* FIXME: in recovery, need to pass old epoch here */
- rc = mds_get_write_access(mds, dentry->d_inode, 0);
+ rc = mds_get_write_access(mds, dentry->d_inode, rec->ur_ioepoch);
if (rc)
GOTO(cleanup_mfd, rc);
body->io_epoch = MDS_FILTERDATA(dentry->d_inode)->io_epoch;
obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
OBD_MD_FLMTIME | OBD_MD_FLCTIME | OBD_MD_FLSIZE);
- rc = obd_setattr(mds->mds_dt_exp, oa, lsm, &oti);
+ /* pack lustre id to oss */
+ *(obdo_id(oa)) = body->id1;
+ oa->o_valid |= OBD_MD_FLIFID;
+
+ rc = obd_setattr(mds->mds_dt_exp, oa, lsm, &oti, NULL);
if (rc) {
CERROR("error setting attrs for inode %lu: rc %d\n",
inode->i_ino, rc);
return; /* error looking up parent or child */
}
- if (rec->ur_namelen == 1) {
+ /* first, we try to open the file by fid. by the time of this
+ * request, inode can be an orphan and parent can disappear */
+ if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY) {
+ CDEBUG(D_HA, "OPEN by fid "DLID4" (RESENT|REPLAY)\n",
+ OLID4(rec->ur_id2));
+ dchild = mds_id2dentry(obd, rec->ur_id2, NULL);
+ } else if (rec->ur_namelen == 1) {
CDEBUG(D_HA, "OPEN by fid "DLID4" (RESENT)\n",
OLID4(rec->ur_id1));
dchild = mds_id2dentry(obd, rec->ur_id1, NULL);
if (!(body->valid & OBD_MD_FLEASIZE))
body->valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
OBD_MD_FLATIME | OBD_MD_FLMTIME);
+ DEBUG_REQ(D_ERROR, req, "no capa for "DLID4, OLID4(&body->id1));
}
/* If we have -EEXIST as the status, and we were asked to create
mntget(mds->mds_vfsmnt);
CERROR("Re-opened file \n");
mfd = mds_dentry_open(dchild, mds->mds_vfsmnt,
- rec->ur_flags & ~MDS_OPEN_TRUNC, req);
+ rec->ur_flags & ~MDS_OPEN_TRUNC, req, rec);
if (!mfd) {
CERROR("mds: out of memory\n");
GOTO(out_dput, req->rq_status = -ENOMEM);
{
struct obd_device *obd = req->rq_export->exp_obd;
struct mds_obd *mds = mds_req2mds(req);
+ struct mds_export_data *med = &req->rq_export->u.eu_mds_data;
struct mds_file_data *mfd = NULL;
obd_id *ids = NULL;
unsigned mode;
}
reply_off = 3;
- rc = mds_pack_acl(req, &reply_off, body, dchild->d_inode);
+ rc = mds_pack_acl(req, reply_off, body, dchild->d_inode);
+ reply_off += 2;
if (rc < 0) {
CERROR("pack posix acl: rc = %d\n", rc);
.lc_uid = rec->ur_uc.luc_uid,
.lc_op = capa_op(rec->ur_flags),
.lc_ino = dchild->d_inode->i_ino,
+ .lc_igen = dchild->d_inode->i_generation,
.lc_mdsid = mds->mds_num,
};
- rc = mds_pack_capa(obd, NULL, &capa, req->rq_repmsg,
+ rc = mds_pack_capa(obd, med, NULL, &capa, req,
&reply_off, body);
if (rc < 0) {
CERROR("mds_pack_capa: rc = %d\n", rc);
up(&dchild->d_inode->i_sem);
intent_set_disposition(rep, DISP_OPEN_OPEN);
- mfd = mds_dentry_open(dchild, mds->mds_vfsmnt, flags, req);
+ mfd = mds_dentry_open(dchild, mds->mds_vfsmnt, flags, req, rec);
if (IS_ERR(mfd))
RETURN(PTR_ERR(mfd));
}
}
- if (!(rec->ur_flags & O_EXCL)) { /* bug 3313 */
- rc = fsfilt_commit(obd, dchild->d_inode->i_sb,
- dchild->d_inode, handle,
- req->rq_export->exp_sync);
- handle = NULL;
- }
-
+ rc = fsfilt_commit(obd, dchild->d_inode->i_sb, dchild->d_inode, handle, 0);
+ handle = NULL;
acc_mode = 0; /* Don't check for permissions */
}
mds_pack_inode2body(obd, body, dchild->d_inode, 1);
}
#else
/* re-enable test 24n in sanity.sh: it needs LOOKUP lock on open */
-#warning "disable opencache lock for CMD2"
#endif
/* Step 5: mds_open it */
} else if (created) {
mds_lock_new_child(obd, dchild->d_inode, NULL);
}
+ /* audit stuff for OPEN */
+ if (offset == 3) {
+ mds_audit(req, dchild, rec->ur_name,
+ rec->ur_namelen - 1, AUDIT_OPEN, rc);
+ }
+
l_dput(dchild);
case 1:
if (dparent == NULL)
* them until all write references are dropped.
* btw, we hold one reference */
LASSERT(mfd->mfd_mode & FMODE_WRITE);
+ LASSERT(request_body->valid & OBD_MD_FLEPOCH);
+ LASSERT(MDS_FILTERDATA(inode));
+ if (MDS_FILTERDATA(inode)->io_epoch != request_body->io_epoch)
+ CDEBUG(D_ERROR, "try to update attr. for old epoch "
+ LPD64" while current "LPD64"\n",
+ MDS_FILTERDATA(inode)->io_epoch,
+ request_body->io_epoch);
i_size_write(inode, request_body->size);
inode->i_blocks = request_body->blocks;
+ LTIME_S(inode->i_mtime) = (request_body->mtime);
+
+ LTIME_S(iattr.ia_mtime) = request_body->mtime;
iattr.ia_size = inode->i_size;
- iattr.ia_valid |= ATTR_SIZE;
+ iattr.ia_valid |= ATTR_SIZE|ATTR_MTIME;
mds_inode_unset_attrs_old(inode);
}
}
__u64 lov_merge_size(struct lov_stripe_md *lsm, int kms);
__u64 lov_merge_blocks(struct lov_stripe_md *lsm);
+__u64 lov_merge_mtime(struct lov_stripe_md *lsm, __u64 current_time);
int mds_validate_size(struct obd_device *obd, struct inode *inode,
struct mds_body *body, struct iattr *iattr)
i_size_write(inode, lov_merge_size(lsm, 0));
inode->i_blocks = lov_merge_blocks(lsm);
+ LTIME_S(inode->i_mtime) = lov_merge_mtime(lsm, LTIME_S(inode->i_mtime));
iattr->ia_size = inode->i_size;
- iattr->ia_valid |= ATTR_SIZE;
+ LTIME_S(iattr->ia_mtime) = LTIME_S(inode->i_mtime);
+ iattr->ia_valid |= ATTR_SIZE | ATTR_MTIME;
+
DOWN_WRITE_I_ALLOC_SEM(inode);
mds_inode_unset_attrs_old(inode);
UP_WRITE_I_ALLOC_SEM(inode);