(according to HLD: https://bugzilla.lustre.org/attachment.cgi?id=15441).
new IO type (CIT_SETATTR) replaces CIT_TRUNC
Eariler patches
https://bugzilla.lustre.org/attachment.cgi?id=7933
https://bugzilla.lustre.org/attachment.cgi?id=7882
are reversed.
i=ericm
i=vitaly
CIT_READ,
/** write system call */
CIT_WRITE,
- /** truncate system call */
- CIT_TRUNC,
+ /** truncate, utime system calls */
+ CIT_SETATTR,
/**
* page fault handling
*/
int wr_append;
} ci_wr;
struct cl_io_rw_common ci_rw;
- struct cl_truncate_io {
- /** new size to which file is truncated */
- loff_t tr_size;
- struct obd_capa *tr_capa;
- } ci_truncate;
+ struct cl_setattr_io {
+ struct ost_lvb sa_attr;
+ unsigned int sa_valid;
+ struct obd_capa *sa_capa;
+ } ci_setattr;
struct cl_fault_io {
/** page index within file. */
pgoff_t ft_index;
return io->ci_type == CIT_WRITE && io->u.ci_wr.wr_append;
}
+/**
+ * True, iff \a io is a truncate(2).
+ */
+static inline int cl_io_is_trunc(const struct cl_io *io)
+{
+ return io->ci_type == CIT_SETATTR &&
+ (io->u.ci_setattr.sa_valid & ATTR_SIZE);
+}
+
struct cl_io *cl_io_top(struct cl_io *io);
void cl_io_print(const struct lu_env *env, void *cookie,
struct inode *inode, struct cl_object *clob);
/**
- * Locking policy for truncate.
+ * Locking policy for setattr.
*/
-enum ccc_trunc_lock_type {
+enum ccc_setattr_lock_type {
/** Locking is done by server */
- TRUNC_NOLOCK,
+ SETATTR_NOLOCK,
/** Extent lock is enqueued */
- TRUNC_EXTENT,
+ SETATTR_EXTENT_LOCK,
/** Existing local extent lock is used */
- TRUNC_MATCH
+ SETATTR_MATCH_LOCK
};
union {
struct {
- int cui_locks_released;
- enum ccc_trunc_lock_type cui_local_lock;
- } trunc;
+ int cui_locks_released;
+ enum ccc_setattr_lock_type cui_local_lock;
+ } setattr;
} u;
/**
* True iff io is processing glimpse right now.
struct inode *ccc_object_inode(const struct cl_object *obj);
struct ccc_object *cl_inode2ccc (struct inode *inode);
-int cl_setattr_do_truncate(struct inode *inode, loff_t size,
- struct obd_capa *capa);
-int cl_setattr_ost(struct inode *inode, struct obd_capa *capa);
+int cl_setattr_ost(struct inode *inode, const struct iattr *attr,
+ struct obd_capa *capa);
struct cl_page *ccc_vmpage_page_transient(cfs_page_t *vmpage);
int ccc_object_invariant(const struct cl_object *obj);
struct obd_info *aa_oi;
};
-struct osc_punch_args {
- struct obdo *pa_oa;
- obd_enqueue_update_f pa_upcall;
- void *pa_cookie;
+struct osc_setattr_args {
+ struct obdo *sa_oa;
+ obd_enqueue_update_f sa_upcall;
+ void *sa_cookie;
};
struct osc_enqueue_args {
.cro_completion = ccc_req_completion
};
-/* Setattr helpers */
-int cl_setattr_do_truncate(struct inode *inode, loff_t size,
- struct obd_capa *capa)
+int cl_setattr_ost(struct inode *inode, const struct iattr *attr,
+ struct obd_capa *capa)
{
struct lu_env *env;
struct cl_io *io;
io = &ccc_env_info(env)->cti_io;
io->ci_obj = cl_i2info(inode)->lli_clob;
- io->u.ci_truncate.tr_size = size;
- io->u.ci_truncate.tr_capa = capa;
- if (cl_io_init(env, io, CIT_TRUNC, io->ci_obj) == 0)
+
+ io->u.ci_setattr.sa_attr.lvb_atime = LTIME_S(attr->ia_atime);
+ io->u.ci_setattr.sa_attr.lvb_mtime = LTIME_S(attr->ia_mtime);
+ io->u.ci_setattr.sa_attr.lvb_ctime = LTIME_S(attr->ia_ctime);
+ io->u.ci_setattr.sa_attr.lvb_size = attr->ia_size;
+ io->u.ci_setattr.sa_valid = attr->ia_valid;
+ io->u.ci_setattr.sa_capa = capa;
+
+ if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0)
result = cl_io_loop(env, io);
else
result = io->ci_result;
RETURN(result);
}
-int cl_setattr_ost(struct inode *inode, struct obd_capa *capa)
-{
- struct cl_inode_info *lli = cl_i2info(inode);
- struct lov_stripe_md *lsm = lli->lli_smd;
- int rc;
- obd_flag flags;
- struct obd_info oinfo = { { { 0 } } };
- struct obdo *oa;
-
- OBDO_ALLOC(oa);
- if (oa) {
- oa->o_id = lsm->lsm_object_id;
- oa->o_gr = lsm->lsm_object_gr;
- oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
-
- flags = OBD_MD_FLTYPE | OBD_MD_FLATIME |
- OBD_MD_FLMTIME | OBD_MD_FLCTIME |
- OBD_MD_FLFID | OBD_MD_FLGENER |
- OBD_MD_FLGROUP;
-
- obdo_from_inode(oa, inode, flags);
-
- oinfo.oi_oa = oa;
- oinfo.oi_md = lsm;
- oinfo.oi_capa = capa;
-
- /* XXX: this looks unnecessary now. */
- rc = obd_setattr_rqset(cl_i2sbi(inode)->ll_dt_exp, &oinfo,
- NULL);
- if (rc)
- CERROR("obd_setattr_async fails: rc=%d\n", rc);
- OBDO_FREE(oa);
- } else {
- rc = -ENOMEM;
- }
- return rc;
-}
-
-
/*****************************************************************************
*
* Type conversions.
if (valid & OBD_MD_FLATIME && src->o_atime > LTIME_S(st->st_atime))
LTIME_S(st->st_atime) = src->o_atime;
-
- /* mtime is always updated with ctime, but can be set in past.
- As write and utime(2) may happen within 1 second, and utime's
- mtime has a priority over write's one, leave mtime from mds
- for the same ctimes. */
- if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(st->st_ctime)) {
+ if (valid & OBD_MD_FLMTIME && src->o_mtime > LTIME_S(st->st_mtime))
+ LTIME_S(st->st_mtime) = src->o_mtime;
+ if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(st->st_ctime))
LTIME_S(st->st_ctime) = src->o_ctime;
- if (valid & OBD_MD_FLMTIME)
- LTIME_S(st->st_mtime) = src->o_mtime;
- }
if (valid & OBD_MD_FLSIZE && src->o_size > st->st_size)
st->st_size = src->o_size;
/* optimum IO size */
}
-static int slp_io_trunc_iter_init(const struct lu_env *env,
- const struct cl_io_slice *ios)
+static int slp_io_setattr_iter_init(const struct lu_env *env,
+ const struct cl_io_slice *ios)
{
return 0;
}
-static int slp_io_trunc_start(const struct lu_env *env,
- const struct cl_io_slice *ios)
+static int slp_io_setattr_start(const struct lu_env *env,
+ const struct cl_io_slice *ios)
{
return 0;
}
.cio_end = ccc_io_end,
.cio_advance = ccc_io_advance
},
- [CIT_TRUNC] = {
+ [CIT_SETATTR] = {
.cio_fini = ccc_io_fini,
- .cio_iter_init = slp_io_trunc_iter_init,
- .cio_start = slp_io_trunc_start
+ .cio_iter_init = slp_io_setattr_iter_init,
+ .cio_start = slp_io_setattr_start
},
[CIT_MISC] = {
.cio_fini = ccc_io_fini
int lli_st_flags;
unsigned long lli_st_generation;
struct cl_object *lli_clob;
+ /* the most recent timestamps obtained from mds */
+ struct ost_lvb lli_lvb;
};
int rc;
ENTRY;
+ lov_stripe_lock(lli->lli_smd);
inode_init_lvb(inode, &lvb);
+ /* merge timestamps the most resently obtained from mds with
+ timestamps obtained from osts */
+ lvb.lvb_atime = lli->lli_lvb.lvb_atime;
+ lvb.lvb_mtime = lli->lli_lvb.lvb_mtime;
+ lvb.lvb_ctime = lli->lli_lvb.lvb_ctime;
rc = obd_merge_lvb(sbi->ll_dt_exp, lli->lli_smd, &lvb, 0);
st->st_size = lvb.lvb_size;
st->st_blocks = lvb.lvb_blocks;
st->st_mtime = lvb.lvb_mtime;
st->st_atime = lvb.lvb_atime;
st->st_ctime = lvb.lvb_ctime;
+ lov_stripe_unlock(lli->lli_smd);
RETURN(rc);
}
}
}
- if (body->valid & OBD_MD_FLMTIME &&
- body->mtime > LTIME_S(st->st_mtime))
- LTIME_S(st->st_mtime) = body->mtime;
- if (body->valid & OBD_MD_FLATIME &&
- body->atime > LTIME_S(st->st_atime))
- LTIME_S(st->st_atime) = body->atime;
-
- /* mtime is always updated with ctime, but can be set in past.
- As write and utime(2) may happen within 1 second, and utime's
- mtime has a priority over write's one, so take mtime from mds
- for the same ctimes. */
- if (body->valid & OBD_MD_FLCTIME &&
- body->ctime >= LTIME_S(st->st_ctime)) {
- LTIME_S(st->st_ctime) = body->ctime;
- if (body->valid & OBD_MD_FLMTIME)
+ if (body->valid & OBD_MD_FLATIME) {
+ if (body->atime > LTIME_S(st->st_atime))
+ LTIME_S(st->st_atime) = body->atime;
+ lli->lli_lvb.lvb_atime = body->atime;
+ }
+ if (body->valid & OBD_MD_FLMTIME) {
+ if (body->mtime > LTIME_S(st->st_mtime))
LTIME_S(st->st_mtime) = body->mtime;
+ lli->lli_lvb.lvb_mtime = body->mtime;
+ }
+ if (body->valid & OBD_MD_FLCTIME) {
+ if (body->ctime > LTIME_S(st->st_ctime))
+ LTIME_S(st->st_ctime) = body->ctime;
+ lli->lli_lvb.lvb_ctime = body->ctime;
}
- if (S_ISREG(st->st_mode))
+ if (S_ISREG(st->st_mode))
st->st_blksize = min(2UL * PTLRPC_MAX_BRW_SIZE, LL_MAX_BLKSIZE);
else
st->st_blksize = 4096;
static int llu_inode_revalidate(struct inode *inode)
{
- struct lov_stripe_md *lsm = NULL;
+ struct llu_inode_info *lli = llu_i2info(inode);
+ struct intnl_stat *st = llu_i2stat(inode);
ENTRY;
if (!inode) {
/* Why don't we update all valid MDS fields here, if we're
* doing an RPC anyways? -phil */
- if (S_ISREG(llu_i2stat(inode)->st_mode)) {
+ if (S_ISREG(st->st_mode)) {
ealen = obd_size_diskmd(sbi->ll_dt_exp, NULL);
valid |= OBD_MD_FLEASIZE;
}
rc = md_getattr(sbi->ll_md_exp, &op_data, &req);
if (rc) {
CERROR("failure %d inode %llu\n", rc,
- (long long)llu_i2stat(inode)->st_ino);
+ (long long)st->st_ino);
RETURN(-abs(rc));
}
rc = md_get_lustre_md(sbi->ll_md_exp, req,
llu_update_inode(inode, &md);
- if (md.lsm != NULL && llu_i2info(inode)->lli_smd != md.lsm)
+ if (md.lsm != NULL && lli->lli_smd != md.lsm)
obd_free_memmd(sbi->ll_dt_exp, &md.lsm);
ptlrpc_req_finished(req);
}
- lsm = llu_i2info(inode)->lli_smd;
- if (!lsm) /* object not yet allocated, don't validate size */
+ if (!lli->lli_smd) {
+ /* object not yet allocated, don't validate size */
+ st->st_atime = lli->lli_lvb.lvb_atime;
+ st->st_mtime = lli->lli_lvb.lvb_mtime;
+ st->st_ctime = lli->lli_lvb.lvb_ctime;
RETURN(0);
+ }
/* ll_glimpse_size will prefer locally cached writes if they extend
* the file */
attr->ia_mtime = CFS_CURRENT_TIME;
attr->ia_valid |= ATTR_MTIME_SET;
}
- if ((attr->ia_valid & ATTR_CTIME) && !(attr->ia_valid & ATTR_MTIME)) {
- /* To avoid stale mtime on mds, obtain it from ost and send
- to mds. */
- rc = cl_glimpse_size(inode);
- if (rc)
- RETURN(rc);
-
- attr->ia_valid |= ATTR_MTIME_SET | ATTR_MTIME;
- attr->ia_mtime = inode->i_stbuf.st_mtime;
- }
if (attr->ia_valid & (ATTR_MTIME | ATTR_CTIME))
CDEBUG(D_INODE, "setting mtime "CFS_TIME_T", ctime "CFS_TIME_T
inode_setattr(inode, attr);
}
- if (ia_valid & ATTR_SIZE) {
- rc = cl_setattr_do_truncate(inode, attr->ia_size, NULL);
- } else if (ia_valid & (ATTR_MTIME | ATTR_MTIME_SET)) {
- CDEBUG(D_INODE, "set mtime on OST inode %llu to %lu\n",
- (long long unsigned)st->st_ino, LTIME_S(attr->ia_mtime));
- rc = cl_setattr_ost(inode, NULL);
+ if (ia_valid & (ATTR_SIZE | ATTR_MTIME | ATTR_MTIME_SET)) {
+ /* mtime is set to past sending setattr op to osts under PW
+ * 0:EOF extent lock (like truncate under PW new_size:EOF), if
+ * mtime is not set to past setattr op is not sent to osts */
+ if ((ia_valid & ATTR_SIZE) ||
+ LTIME_S(attr->ia_mtime) < LTIME_S(attr->ia_ctime))
+ rc = cl_setattr_ost(inode, attr, NULL);
}
EXIT;
out:
ll_inode_size_lock(inode, 1);
inode_init_lvb(inode, &lvb);
+
+ /* merge timestamps the most resently obtained from mds with
+ timestamps obtained from osts */
+ lvb.lvb_atime = lli->lli_lvb.lvb_atime;
+ lvb.lvb_mtime = lli->lli_lvb.lvb_mtime;
+ lvb.lvb_ctime = lli->lli_lvb.lvb_ctime;
rc = obd_merge_lvb(sbi->ll_dt_exp, lli->lli_smd, &lvb, 0);
cl_isize_write_nolock(inode, lvb.lvb_size);
inode->i_blocks = lvb.lvb_blocks;
int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
{
+ struct inode *inode = dentry->d_inode;
int rc;
ENTRY;
MDS_INODELOCK_LOOKUP);
/* if object not yet allocated, don't validate size */
- if (rc == 0 && ll_i2info(dentry->d_inode)->lli_smd == NULL)
+ if (rc == 0 && ll_i2info(dentry->d_inode)->lli_smd == NULL) {
+ LTIME_S(inode->i_atime) = ll_i2info(inode)->lli_lvb.lvb_atime;
+ LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_lvb.lvb_mtime;
+ LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_lvb.lvb_ctime;
RETURN(0);
+ }
/* cl_glimpse_size will prefer locally cached writes if they extend
* the file */
if (rc == 0)
- rc = cl_glimpse_size(dentry->d_inode);
+ rc = cl_glimpse_size(inode);
RETURN(rc);
}
void *lli_opendir_key;
struct ll_statahead_info *lli_sai;
struct cl_object *lli_clob;
+ /* the most recent timestamps obtained from mds */
+ struct ost_lvb lli_lvb;
};
/*
RETURN(rc);
}
-static int ll_setattr_do_truncate(struct inode *inode, loff_t size)
+static int ll_setattr_ost(struct inode *inode, struct iattr *attr)
{
- struct obd_capa *capa = ll_osscapa_get(inode, CAPA_OPC_OSS_TRUNC);
+ struct obd_capa *capa;
int rc;
- rc = cl_setattr_do_truncate(inode, size, capa);
- ll_truncate_free_capa(capa);
- return rc;
-}
+ if (attr->ia_valid & ATTR_SIZE)
+ capa = ll_osscapa_get(inode, CAPA_OPC_OSS_TRUNC);
+ else
+ capa = ll_mdscapa_get(inode);
-static int ll_setattr_ost(struct inode *inode)
-{
- struct obd_capa *capa = ll_mdscapa_get(inode);
- int rc;
+ rc = cl_setattr_ost(inode, attr, capa);
- rc = cl_setattr_ost(inode, capa);
- capa_put(capa);
+ if (attr->ia_valid & ATTR_SIZE)
+ ll_truncate_free_capa(capa);
+ else
+ capa_put(capa);
return rc;
}
attr->ia_mtime = CFS_CURRENT_TIME;
attr->ia_valid |= ATTR_MTIME_SET;
}
- if ((attr->ia_valid & ATTR_CTIME) && !(attr->ia_valid & ATTR_MTIME)) {
- /* To avoid stale mtime on mds, obtain it from ost and send
- to mds. */
- rc = cl_glimpse_size(inode);
- if (rc)
- RETURN(rc);
-
- attr->ia_valid |= ATTR_MTIME_SET | ATTR_MTIME;
- attr->ia_mtime = inode->i_mtime;
- }
if (attr->ia_valid & (ATTR_MTIME | ATTR_CTIME))
CDEBUG(D_INODE, "setting mtime %lu, ctime %lu, now = %lu\n",
memcpy(&op_data->op_attr, attr, sizeof(*attr));
/* Open epoch for truncate. */
- if (exp_connect_som(ll_i2mdexp(inode)) && (ia_valid & ATTR_SIZE))
+ if (exp_connect_som(ll_i2mdexp(inode)) &&
+ (ia_valid & (ATTR_SIZE | ATTR_MTIME | ATTR_MTIME_SET)))
op_data->op_flags = MF_EPOCH_OPEN;
rc = ll_md_setattr(inode, op_data, &mod);
}
if (ia_valid & ATTR_SIZE)
- rc = ll_setattr_do_truncate(inode, attr->ia_size);
- else if (ia_valid & (ATTR_MTIME | ATTR_MTIME_SET)) {
- CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n",
- inode->i_ino, LTIME_S(attr->ia_mtime));
- rc = ll_setattr_ost(inode);
+ attr->ia_valid |= ATTR_SIZE;
+ if (ia_valid & (ATTR_SIZE | ATTR_MTIME | ATTR_MTIME_SET)) {
+ /* mtime is set to past sending setattr op to osts under PW
+ * 0:EOF extent lock (like truncate under PW new_size:EOF), if
+ * mtime is not set to past setattr op is not sent to osts */
+ if ((ia_valid & ATTR_SIZE) ||
+ LTIME_S(attr->ia_mtime) < LTIME_S(attr->ia_ctime))
+ rc = ll_setattr_ost(inode, attr);
}
EXIT;
out:
inode->i_ino = cl_fid_build_ino(&body->fid1);
inode->i_generation = cl_fid_build_gen(&body->fid1);
- if (body->valid & OBD_MD_FLATIME &&
- body->atime > LTIME_S(inode->i_atime))
- LTIME_S(inode->i_atime) = body->atime;
-
- /* mtime is always updated with ctime, but can be set in past.
- As write and utime(2) may happen within 1 second, and utime's
- mtime has a priority over write's one, so take mtime from mds
- for the same ctimes. */
- if (body->valid & OBD_MD_FLCTIME &&
- body->ctime >= LTIME_S(inode->i_ctime)) {
- LTIME_S(inode->i_ctime) = body->ctime;
- if (body->valid & OBD_MD_FLMTIME) {
- CDEBUG(D_INODE, "setting ino %lu mtime "
- "from %lu to "LPU64"\n", inode->i_ino,
+ if (body->valid & OBD_MD_FLATIME) {
+ if (body->atime > LTIME_S(inode->i_atime))
+ LTIME_S(inode->i_atime) = body->atime;
+ lli->lli_lvb.lvb_atime = body->atime;
+ }
+ if (body->valid & OBD_MD_FLMTIME) {
+ if (body->mtime > LTIME_S(inode->i_mtime)) {
+ CDEBUG(D_INODE, "setting ino %lu mtime from %lu "
+ "to "LPU64"\n", inode->i_ino,
LTIME_S(inode->i_mtime), body->mtime);
LTIME_S(inode->i_mtime) = body->mtime;
}
+ lli->lli_lvb.lvb_mtime = body->mtime;
+ }
+ if (body->valid & OBD_MD_FLCTIME) {
+ if (body->ctime > LTIME_S(inode->i_ctime))
+ LTIME_S(inode->i_ctime) = body->ctime;
+ lli->lli_lvb.lvb_ctime = body->ctime;
}
if (body->valid & OBD_MD_FLMODE)
inode->i_mode = (inode->i_mode & S_IFMT)|(body->mode & ~S_IFMT);
&RMF_MDT_BODY);
LASSERT(body);
- /* mtime is always updated with ctime, but can be set in past.
- As write and utime(2) may happen within 1 second, and utime's
- mtime has a priority over write's one, so take mtime from mds
- for the same ctimes. */
+ if (body->valid & OBD_MD_FLMTIME &&
+ body->mtime > LTIME_S(inode->i_mtime)) {
+ CDEBUG(D_INODE, "setting ino %lu mtime from %lu to "LPU64"\n",
+ inode->i_ino, LTIME_S(inode->i_mtime), body->mtime);
+ LTIME_S(inode->i_mtime) = body->mtime;
+ }
if (body->valid & OBD_MD_FLCTIME &&
- body->ctime >= LTIME_S(inode->i_ctime)) {
+ body->ctime > LTIME_S(inode->i_ctime))
LTIME_S(inode->i_ctime) = body->ctime;
-
- if (body->valid & OBD_MD_FLMTIME) {
- CDEBUG(D_INODE, "setting ino %lu mtime from %lu "
- "to "LPU64"\n", inode->i_ino,
- LTIME_S(inode->i_mtime), body->mtime);
- LTIME_S(inode->i_mtime) = body->mtime;
- }
- }
}
static int ll_new_node(struct inode *dir, struct qstr *name,
return vvp_io_rw_lock(env, io, CLM_WRITE, start, end);
}
-static int vvp_io_trunc_iter_init(const struct lu_env *env,
- const struct cl_io_slice *ios)
+static int vvp_io_setattr_iter_init(const struct lu_env *env,
+ const struct cl_io_slice *ios)
{
- struct ccc_io *vio = cl2ccc_io(env, ios);
+ struct ccc_io *cio = ccc_env_io(env);
struct inode *inode = ccc_object_inode(ios->cis_obj);
/*
* This last one is especially bad for racing o_append users on other
* nodes.
*/
-
UNLOCK_INODE_MUTEX(inode);
- UP_WRITE_I_ALLOC_SEM(inode);
- vio->u.trunc.cui_locks_released = 1;
+ if (cl_io_is_trunc(ios->cis_io))
+ UP_WRITE_I_ALLOC_SEM(inode);
+ cio->u.setattr.cui_locks_released = 1;
return 0;
}
/**
- * Implementation of cl_io_operations::cio_lock() method for CIT_TRUNC io.
+ * Implementation of cl_io_operations::cio_lock() method for CIT_SETATTR io.
*
* Handles "lockless io" mode when extent locking is done by server.
*/
-static int vvp_io_trunc_lock(const struct lu_env *env,
- const struct cl_io_slice *ios)
+static int vvp_io_setattr_lock(const struct lu_env *env,
+ const struct cl_io_slice *ios)
{
- struct ccc_io *vio = cl2ccc_io(env, ios);
- struct cl_io *io = ios->cis_io;
- loff_t new_size = io->u.ci_truncate.tr_size;
- __u32 enqflags = new_size == 0 ? CEF_DISCARD_DATA : 0;
- int result;
-
- vio->u.trunc.cui_local_lock = TRUNC_EXTENT;
- result = ccc_io_one_lock(env, io, enqflags, CLM_WRITE,
- new_size, OBD_OBJECT_EOF);
- return result;
+ struct ccc_io *cio = ccc_env_io(env);
+ struct cl_io *io = ios->cis_io;
+ size_t new_size;
+ __u32 enqflags = 0;
+
+ if (cl_io_is_trunc(io)) {
+ new_size = io->u.ci_setattr.sa_attr.lvb_size;
+ if (new_size == 0)
+ enqflags = CEF_DISCARD_DATA;
+ } else {
+ LASSERT(io->u.ci_setattr.sa_attr.lvb_mtime <
+ io->u.ci_setattr.sa_attr.lvb_ctime);
+ new_size = 0;
+ }
+ cio->u.setattr.cui_local_lock = SETATTR_EXTENT_LOCK;
+ return ccc_io_one_lock(env, io, enqflags, CLM_WRITE,
+ new_size, OBD_OBJECT_EOF);
}
static int vvp_do_vmtruncate(struct inode *inode, size_t size)
return result;
}
-static int vvp_io_trunc_start(const struct lu_env *env,
- const struct cl_io_slice *ios)
+static int vvp_io_setattr_trunc(const struct lu_env *env,
+ const struct cl_io_slice *ios,
+ struct inode *inode, loff_t size)
{
- struct ccc_io *cio = cl2ccc_io(env, ios);
struct vvp_io *vio = cl2vvp_io(env, ios);
struct cl_io *io = ios->cis_io;
- struct inode *inode = ccc_object_inode(io->ci_obj);
struct cl_object *obj = ios->cis_obj;
- loff_t size = io->u.ci_truncate.tr_size;
pgoff_t start = cl_index(obj, size);
int result;
- LASSERT(cio->u.trunc.cui_locks_released);
-
- LOCK_INODE_MUTEX(inode);
DOWN_WRITE_I_ALLOC_SEM(inode);
- cio->u.trunc.cui_locks_released = 0;
result = vvp_do_vmtruncate(inode, size);
return result;
}
-static void vvp_io_trunc_end(const struct lu_env *env,
- const struct cl_io_slice *ios)
+static int vvp_io_setattr_mtime(const struct lu_env *env,
+ const struct cl_io_slice *ios)
{
- struct vvp_io *vio = cl2vvp_io(env, ios);
+ struct cl_io *io = ios->cis_io;
+ struct cl_object *obj = io->ci_obj;
+ struct cl_attr *attr = ccc_env_thread_attr(env);
+ int result;
+ unsigned valid = CAT_MTIME | CAT_CTIME;
+
+ cl_object_attr_lock(obj);
+ attr->cat_mtime = io->u.ci_setattr.sa_attr.lvb_mtime;
+ attr->cat_ctime = io->u.ci_setattr.sa_attr.lvb_ctime;
+ if (io->u.ci_setattr.sa_valid & ATTR_ATIME_SET) {
+ attr->cat_atime = io->u.ci_setattr.sa_attr.lvb_atime;
+ valid |= CAT_ATIME;
+ }
+ result = cl_object_attr_set(env, obj, attr, valid);
+ cl_object_attr_unlock(obj);
+
+ return result;
+}
+
+static int vvp_io_setattr_start(const struct lu_env *env,
+ const struct cl_io_slice *ios)
+{
+ struct ccc_io *cio = cl2ccc_io(env, ios);
struct cl_io *io = ios->cis_io;
struct inode *inode = ccc_object_inode(io->ci_obj);
- loff_t size = io->u.ci_truncate.tr_size;
+ LASSERT(cio->u.setattr.cui_locks_released);
+
+ LOCK_INODE_MUTEX(inode);
+ cio->u.setattr.cui_locks_released = 0;
+
+ if (cl_io_is_trunc(io))
+ return vvp_io_setattr_trunc(env, ios, inode,
+ io->u.ci_setattr.sa_attr.lvb_size);
+ else
+ return vvp_io_setattr_mtime(env, ios);
+}
+
+static void vvp_io_setattr_end(const struct lu_env *env,
+ const struct cl_io_slice *ios)
+{
+ struct vvp_io *vio = cl2vvp_io(env, ios);
+ struct cl_io *io = ios->cis_io;
+ struct inode *inode = ccc_object_inode(io->ci_obj);
+
+ if (!cl_io_is_trunc(io))
+ return;
if (vio->cui_partpage != NULL) {
cl_page_disown(env, ios->cis_io, vio->cui_partpage);
cl_page_put(env, vio->cui_partpage);
* Do vmtruncate again, to remove possible stale pages populated by
* competing read threads. bz20645.
*/
- vvp_do_vmtruncate(inode, size);
+ vvp_do_vmtruncate(inode, io->u.ci_setattr.sa_attr.lvb_size);
}
-static void vvp_io_trunc_fini(const struct lu_env *env,
- const struct cl_io_slice *ios)
+static void vvp_io_setattr_fini(const struct lu_env *env,
+ const struct cl_io_slice *ios)
{
struct ccc_io *cio = ccc_env_io(env);
+ struct cl_io *io = ios->cis_io;
struct inode *inode = ccc_object_inode(ios->cis_io->ci_obj);
- if (cio->u.trunc.cui_locks_released) {
+ if (cio->u.setattr.cui_locks_released) {
LOCK_INODE_MUTEX(inode);
- DOWN_WRITE_I_ALLOC_SEM(inode);
- cio->u.trunc.cui_locks_released = 0;
+ if (cl_io_is_trunc(io))
+ DOWN_WRITE_I_ALLOC_SEM(inode);
+ cio->u.setattr.cui_locks_released = 0;
}
vvp_io_fini(env, ios);
}
.cio_start = vvp_io_write_start,
.cio_advance = ccc_io_advance
},
- [CIT_TRUNC] = {
- .cio_fini = vvp_io_trunc_fini,
- .cio_iter_init = vvp_io_trunc_iter_init,
- .cio_lock = vvp_io_trunc_lock,
- .cio_start = vvp_io_trunc_start,
- .cio_end = vvp_io_trunc_end
+ [CIT_SETATTR] = {
+ .cio_fini = vvp_io_setattr_fini,
+ .cio_iter_init = vvp_io_setattr_iter_init,
+ .cio_lock = vvp_io_setattr_lock,
+ .cio_start = vvp_io_setattr_start,
+ .cio_end = vvp_io_setattr_end
},
[CIT_FAULT] = {
.cio_fini = vvp_io_fault_fini,
cio->cui_tot_nrsegs = 0;
ll_stats_ops_tally(sbi, op, count);
}
- } else if (io->ci_type == CIT_TRUNC) {
- /* lockless truncate? */
- ll_stats_ops_tally(sbi, LPROC_LL_TRUNC, 1);
+ } else if (io->ci_type == CIT_SETATTR) {
+ if (cl_io_is_trunc(io))
+ /* lockless truncate? */
+ ll_stats_ops_tally(sbi, LPROC_LL_TRUNC, 1);
+ else
+ io->ci_lockreq = CILR_MANDATORY;
}
RETURN(result);
}
inode->i_uid = attr->cat_uid;
if (valid & CAT_GID)
inode->i_gid = attr->cat_gid;
+ if (valid & CAT_ATIME)
+ LTIME_S(inode->i_atime) = attr->cat_atime;
+ if (valid & CAT_MTIME)
+ LTIME_S(inode->i_mtime) = attr->cat_mtime;
+ if (valid & CAT_CTIME)
+ LTIME_S(inode->i_ctime) = attr->cat_ctime;
if (0 && valid & CAT_SIZE)
cl_isize_write_nolock(inode, attr->cat_size);
/* not currently necessary */
struct cl_io *parent = lio->lis_cl.cis_io;
switch(io->ci_type) {
- case CIT_TRUNC: {
- loff_t new_size = parent->u.ci_truncate.tr_size;
-
- new_size = lov_size_to_stripe(lsm, new_size, stripe);
- io->u.ci_truncate.tr_capa = parent->u.ci_truncate.tr_capa;
- io->u.ci_truncate.tr_size = new_size;
+ case CIT_SETATTR: {
+ io->u.ci_setattr.sa_attr = parent->u.ci_setattr.sa_attr;
+ io->u.ci_setattr.sa_valid = parent->u.ci_setattr.sa_valid;
+ io->u.ci_setattr.sa_capa = parent->u.ci_setattr.sa_capa;
+ if (cl_io_is_trunc(io)) {
+ loff_t new_size = parent->u.ci_setattr.sa_attr.lvb_size;
+
+ new_size = lov_size_to_stripe(lsm, new_size, stripe);
+ io->u.ci_setattr.sa_attr.lvb_size = new_size;
+ }
break;
}
case CIT_FAULT: {
}
break;
- case CIT_TRUNC:
- lio->lis_pos = io->u.ci_truncate.tr_size;
+ case CIT_SETATTR:
+ if (cl_io_is_trunc(io))
+ lio->lis_pos = io->u.ci_setattr.sa_attr.lvb_size;
+ else
+ lio->lis_pos = 0;
lio->lis_endpos = OBD_OBJECT_EOF;
break;
.cio_start = lov_io_start,
.cio_end = lov_io_end
},
- [CIT_TRUNC] = {
+ [CIT_SETATTR] = {
.cio_fini = lov_io_fini,
.cio_iter_init = lov_io_iter_init,
.cio_iter_fini = lov_io_iter_fini,
.cio_start = LOV_EMPTY_IMPOSSIBLE,
.cio_end = LOV_EMPTY_IMPOSSIBLE
},
- [CIT_TRUNC] = {
+ [CIT_SETATTR] = {
.cio_fini = lov_empty_io_fini,
.cio_iter_init = LOV_EMPTY_IMPOSSIBLE,
.cio_lock = LOV_EMPTY_IMPOSSIBLE,
result = 0;
break;
case CIT_WRITE:
- case CIT_TRUNC:
+ case CIT_SETATTR:
result = -EBADF;
break;
case CIT_FAULT:
cl2lov(slice->cls_obj),
lov->lls_sub[0].sub_stripe,
got, need);
- } else if (io->ci_type != CIT_TRUNC && io->ci_type != CIT_MISC &&
+ } else if (io->ci_type != CIT_SETATTR && io->ci_type != CIT_MISC &&
!cl_io_is_append(io) && need->cld_mode != CLM_PHANTOM)
/*
* Multi-stripe locks are only suitable for `quick' IO and for
size = lov_size;
/* merge blocks, mtime, atime */
blocks += loi->loi_lvb.lvb_blocks;
+ if (loi->loi_lvb.lvb_mtime > current_mtime)
+ current_mtime = loi->loi_lvb.lvb_mtime;
if (loi->loi_lvb.lvb_atime > current_atime)
current_atime = loi->loi_lvb.lvb_atime;
-
- /* mtime is always updated with ctime, but can be set in past.
- As write and utime(2) may happen within 1 second, and utime's
- mtime has a priority over write's one, leave mtime from mds
- for the same ctimes. */
- if (loi->loi_lvb.lvb_ctime > current_ctime) {
+ if (loi->loi_lvb.lvb_ctime > current_ctime)
current_ctime = loi->loi_lvb.lvb_ctime;
- current_mtime = loi->loi_lvb.lvb_mtime;
- }
}
*kms_place = kms;
tgt->o_blksize += src->o_blksize;
if (valid & OBD_MD_FLCTIME && tgt->o_ctime < src->o_ctime)
tgt->o_ctime = src->o_ctime;
- /* Only mtime from OSTs are merged here, as they cannot be set
- in past (only MDS's mtime can) do not look at ctime. */
if (valid & OBD_MD_FLMTIME && tgt->o_mtime < src->o_mtime)
tgt->o_mtime = src->o_mtime;
} else {
if (valid & OBD_MD_FLATIME && src->o_atime > LTIME_S(dst->i_atime))
LTIME_S(dst->i_atime) = src->o_atime;
-
- /* mtime is always updated with ctime, but can be set in past.
- As write and utime(2) may happen within 1 second, and utime's
- mtime has a priority over write's one, leave mtime from mds
- for the same ctimes. */
- if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(dst->i_ctime)) {
+ if (valid & OBD_MD_FLMTIME && src->o_mtime > LTIME_S(dst->i_mtime))
+ LTIME_S(dst->i_mtime) = src->o_mtime;
+ if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(dst->i_ctime))
LTIME_S(dst->i_ctime) = src->o_ctime;
- if (valid & OBD_MD_FLMTIME)
- LTIME_S(dst->i_mtime) = src->o_mtime;
- }
if (valid & OBD_MD_FLSIZE)
i_size_write(dst, src->o_size);
/* optimum IO size */
int oi_lockless;
struct obdo oi_oa;
- struct osc_punch_cbargs {
+ struct osc_setattr_cbargs {
int opc_rc;
cfs_completion_t opc_sync;
- } oi_punch_cbarg;
+ } oi_setattr_cbarg;
};
/**
int *flags, void *data, struct lustre_handle *lockh,
int unref);
-int osc_punch_base(struct obd_export *exp, struct obdo *oa,
- struct obd_capa *capa,
+int osc_setattr_async_base(struct obd_export *exp, struct obd_info *oinfo,
+ struct obd_trans_info *oti,
+ obd_enqueue_update_f upcall, void *cookie,
+ struct ptlrpc_request_set *rqset);
+int osc_punch_base(struct obd_export *exp, struct obd_info *oinfo,
obd_enqueue_update_f upcall, void *cookie,
struct ptlrpc_request_set *rqset);
RETURN(0);
}
-static int osc_punch_upcall(void *a, int rc)
+static int osc_setattr_upcall(void *a, int rc)
{
- struct osc_punch_cbargs *args = a;
+ struct osc_setattr_cbargs *args = a;
args->opc_rc = rc;
cfs_complete(&args->opc_sync);
# define osc_trunc_check(env, io, oio, size) do {;} while (0)
#endif
-static int osc_io_trunc_start(const struct lu_env *env,
- const struct cl_io_slice *slice)
+static int osc_io_setattr_start(const struct lu_env *env,
+ const struct cl_io_slice *slice)
{
struct cl_io *io = slice->cis_io;
struct osc_io *oio = cl2osc_io(env, slice);
struct lov_oinfo *loi = cl2osc(obj)->oo_oinfo;
struct cl_attr *attr = &osc_env_info(env)->oti_attr;
struct obdo *oa = &oio->oi_oa;
- struct osc_punch_cbargs *cbargs = &oio->oi_punch_cbarg;
- struct obd_capa *capa;
- loff_t size = io->u.ci_truncate.tr_size;
+ struct osc_setattr_cbargs *cbargs = &oio->oi_setattr_cbarg;
+ loff_t size = io->u.ci_setattr.sa_attr.lvb_size;
+ unsigned int ia_valid = io->u.ci_setattr.sa_valid;
int result = 0;
+ struct obd_info oinfo = { { { 0 } } };
- osc_trunc_check(env, io, oio, size);
+ if (ia_valid & ATTR_SIZE)
+ osc_trunc_check(env, io, oio, size);
if (oio->oi_lockless == 0) {
cl_object_attr_lock(obj);
result = cl_object_attr_get(env, obj, attr);
if (result == 0) {
- attr->cat_size = attr->cat_kms = size;
- result = cl_object_attr_set(env, obj, attr,
- CAT_SIZE|CAT_KMS);
+ unsigned int cl_valid = 0;
+
+ if (ia_valid & ATTR_SIZE) {
+ attr->cat_size = attr->cat_kms = size;
+ cl_valid = (CAT_SIZE | CAT_KMS);
+ }
+ if (ia_valid & ATTR_MTIME_SET) {
+ attr->cat_mtime = io->u.ci_setattr.sa_attr.lvb_mtime;
+ cl_valid |= CAT_MTIME;
+ }
+ if (ia_valid & ATTR_ATIME_SET) {
+ attr->cat_atime = io->u.ci_setattr.sa_attr.lvb_atime;
+ cl_valid |= CAT_ATIME;
+ }
+ if (ia_valid & ATTR_CTIME_SET) {
+ attr->cat_ctime = io->u.ci_setattr.sa_attr.lvb_ctime;
+ cl_valid |= CAT_CTIME;
+ }
+ result = cl_object_attr_set(env, obj, attr, cl_valid);
}
cl_object_attr_unlock(obj);
}
-
memset(oa, 0, sizeof(*oa));
if (result == 0) {
oa->o_id = loi->loi_id;
oa->o_ctime = attr->cat_ctime;
oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLATIME |
OBD_MD_FLCTIME | OBD_MD_FLMTIME;
- if (oio->oi_lockless) {
- oa->o_flags = OBD_FL_SRVLOCK;
- oa->o_valid |= OBD_MD_FLFLAGS;
+ if (ia_valid & ATTR_SIZE) {
+ oa->o_size = size;
+ oa->o_blocks = OBD_OBJECT_EOF;
+ oa->o_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
+
+ if (oio->oi_lockless) {
+ oa->o_flags = OBD_FL_SRVLOCK;
+ oa->o_valid |= OBD_MD_FLFLAGS;
+ }
+ } else {
+ LASSERT(oio->oi_lockless == 0);
}
- oa->o_size = size;
- oa->o_blocks = OBD_OBJECT_EOF;
- oa->o_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
- capa = io->u.ci_truncate.tr_capa;
+ oinfo.oi_oa = oa;
+ oinfo.oi_capa = io->u.ci_setattr.sa_capa;
cfs_init_completion(&cbargs->opc_sync);
- result = osc_punch_base(osc_export(cl2osc(obj)), oa, capa,
- osc_punch_upcall, cbargs, PTLRPCD_SET);
+
+ if (ia_valid & ATTR_SIZE)
+ result = osc_punch_base(osc_export(cl2osc(obj)),
+ &oinfo, osc_setattr_upcall,
+ cbargs, PTLRPCD_SET);
+ else
+ result = osc_setattr_async_base(osc_export(cl2osc(obj)),
+ &oinfo, NULL,
+ osc_setattr_upcall,
+ cbargs, PTLRPCD_SET);
}
return result;
}
-static void osc_io_trunc_end(const struct lu_env *env,
- const struct cl_io_slice *slice)
+static void osc_io_setattr_end(const struct lu_env *env,
+ const struct cl_io_slice *slice)
{
struct cl_io *io = slice->cis_io;
struct osc_io *oio = cl2osc_io(env, slice);
- struct osc_punch_cbargs *cbargs = &oio->oi_punch_cbarg;
- struct obdo *oa = &oio->oi_oa;
+ struct osc_setattr_cbargs *cbargs = &oio->oi_setattr_cbarg;
int result;
cfs_wait_for_completion(&cbargs->opc_sync);
result = io->ci_result = cbargs->opc_rc;
if (result == 0) {
struct cl_object *obj = slice->cis_obj;
- if (oio->oi_lockless == 0) {
- struct cl_attr *attr = &osc_env_info(env)->oti_attr;
- int valid = 0;
-
- /* Update kms & size */
- if (oa->o_valid & OBD_MD_FLSIZE) {
- attr->cat_size = oa->o_size;
- attr->cat_kms = oa->o_size;
- valid |= CAT_KMS|CAT_SIZE;
- }
- if (oa->o_valid & OBD_MD_FLBLOCKS) {
- attr->cat_blocks = oa->o_blocks;
- valid |= CAT_BLOCKS;
- }
- if (oa->o_valid & OBD_MD_FLMTIME) {
- attr->cat_mtime = oa->o_mtime;
- valid |= CAT_MTIME;
- }
- if (oa->o_valid & OBD_MD_FLCTIME) {
- attr->cat_ctime = oa->o_ctime;
- valid |= CAT_CTIME;
- }
- if (oa->o_valid & OBD_MD_FLATIME) {
- attr->cat_atime = oa->o_atime;
- valid |= CAT_ATIME;
- }
- cl_object_attr_lock(obj);
- result = cl_object_attr_set(env, obj, attr, valid);
- cl_object_attr_unlock(obj);
- } else { /* lockless truncate */
+ if (oio->oi_lockless) {
+ /* lockless truncate */
struct osc_device *osd = lu2osc_dev(obj->co_lu.lo_dev);
+
+ LASSERT(cl_io_is_trunc(io));
/* XXX: Need a lock. */
osd->od_stats.os_lockless_truncates++;
}
}
+}
- /* return result; */
+static int osc_io_read_start(const struct lu_env *env,
+ const struct cl_io_slice *slice)
+{
+ struct osc_io *oio = cl2osc_io(env, slice);
+ struct cl_object *obj = slice->cis_obj;
+ struct cl_attr *attr = &osc_env_info(env)->oti_attr;
+ int result = 0;
+ ENTRY;
+
+ if (oio->oi_lockless == 0) {
+ cl_object_attr_lock(obj);
+ result = cl_object_attr_get(env, obj, attr);
+ if (result == 0) {
+ attr->cat_atime = LTIME_S(CFS_CURRENT_TIME);
+ result = cl_object_attr_set(env, obj, attr,
+ CAT_ATIME);
+ }
+ cl_object_attr_unlock(obj);
+ }
+ RETURN(result);
+}
+
+static int osc_io_write_start(const struct lu_env *env,
+ const struct cl_io_slice *slice)
+{
+ struct osc_io *oio = cl2osc_io(env, slice);
+ struct cl_object *obj = slice->cis_obj;
+ struct cl_attr *attr = &osc_env_info(env)->oti_attr;
+ int result = 0;
+ ENTRY;
+
+ if (oio->oi_lockless == 0) {
+ cl_object_attr_lock(obj);
+ result = cl_object_attr_get(env, obj, attr);
+ if (result == 0) {
+ attr->cat_mtime = attr->cat_ctime =
+ LTIME_S(CFS_CURRENT_TIME);
+ result = cl_object_attr_set(env, obj, attr,
+ CAT_MTIME | CAT_CTIME);
+ }
+ cl_object_attr_unlock(obj);
+ }
+ RETURN(result);
}
static const struct cl_io_operations osc_io_ops = {
.op = {
[CIT_READ] = {
+ .cio_start = osc_io_read_start,
.cio_fini = osc_io_fini
},
[CIT_WRITE] = {
+ .cio_start = osc_io_write_start,
.cio_fini = osc_io_fini
},
- [CIT_TRUNC] = {
- .cio_start = osc_io_trunc_start,
- .cio_end = osc_io_trunc_end
+ [CIT_SETATTR] = {
+ .cio_start = osc_io_setattr_start,
+ .cio_end = osc_io_setattr_end
},
[CIT_FAULT] = {
.cio_fini = osc_io_fini,
io->ci_lockreq == CILR_NEVER);
ocd = &class_exp2cliimp(osc_export(oob))->imp_connect_data;
- ols->ols_locklessable = (io->ci_type != CIT_TRUNC) &&
+ ols->ols_locklessable = (io->ci_type != CIT_SETATTR) &&
(io->ci_lockreq == CILR_MAYBE) &&
(ocd->ocd_connect_flags & OBD_CONNECT_SRVLOCK);
if (io->ci_lockreq == CILR_NEVER ||
/* lockless IO */
(ols->ols_locklessable && osc_object_is_contended(oob)) ||
/* lockless truncate */
- (io->ci_type == CIT_TRUNC &&
+ (cl_io_is_trunc(io) &&
(ocd->ocd_connect_flags & OBD_CONNECT_TRUNCLOCK) &&
osd->od_lockless_truncate)) {
ols->ols_locklessable = 1;
static int osc_setattr_interpret(const struct lu_env *env,
struct ptlrpc_request *req,
- struct osc_async_args *aa, int rc)
+ struct osc_setattr_args *sa, int rc)
{
struct ost_body *body;
ENTRY;
if (body == NULL)
GOTO(out, rc = -EPROTO);
- lustre_get_wire_obdo(aa->aa_oi->oi_oa, &body->oa);
+ lustre_get_wire_obdo(sa->sa_oa, &body->oa);
out:
- rc = aa->aa_oi->oi_cb_up(aa->aa_oi, rc);
+ rc = sa->sa_upcall(sa->sa_cookie, rc);
RETURN(rc);
}
-static int osc_setattr_async(struct obd_export *exp, struct obd_info *oinfo,
- struct obd_trans_info *oti,
- struct ptlrpc_request_set *rqset)
+int osc_setattr_async_base(struct obd_export *exp, struct obd_info *oinfo,
+ struct obd_trans_info *oti,
+ obd_enqueue_update_f upcall, void *cookie,
+ struct ptlrpc_request_set *rqset)
{
- struct ptlrpc_request *req;
- struct osc_async_args *aa;
- int rc;
+ struct ptlrpc_request *req;
+ struct osc_setattr_args *sa;
+ int rc;
ENTRY;
req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_OST_SETATTR);
RETURN(rc);
}
- if (oinfo->oi_oa->o_valid & OBD_MD_FLCOOKIE)
+ if (oti && oinfo->oi_oa->o_valid & OBD_MD_FLCOOKIE)
oinfo->oi_oa->o_lcookie = *oti->oti_logcookies;
osc_pack_req_body(req, oinfo);
req->rq_interpret_reply =
(ptlrpc_interpterer_t)osc_setattr_interpret;
- CLASSERT (sizeof(*aa) <= sizeof(req->rq_async_args));
- aa = ptlrpc_req_async_args(req);
- aa->aa_oi = oinfo;
+ CLASSERT (sizeof(*sa) <= sizeof(req->rq_async_args));
+ sa = ptlrpc_req_async_args(req);
+ sa->sa_oa = oinfo->oi_oa;
+ sa->sa_upcall = upcall;
+ sa->sa_cookie = cookie;
- ptlrpc_set_add_req(rqset, req);
+ if (rqset == PTLRPCD_SET)
+ ptlrpcd_add_req(req, PSCOPE_OTHER);
+ else
+ ptlrpc_set_add_req(rqset, req);
}
RETURN(0);
}
+static int osc_setattr_async(struct obd_export *exp, struct obd_info *oinfo,
+ struct obd_trans_info *oti,
+ struct ptlrpc_request_set *rqset)
+{
+ return osc_setattr_async_base(exp, oinfo, oti,
+ oinfo->oi_cb_up, oinfo, rqset);
+}
+
int osc_real_create(struct obd_export *exp, struct obdo *oa,
struct lov_stripe_md **ea, struct obd_trans_info *oti)
{
RETURN(rc);
}
-static int osc_punch_interpret(const struct lu_env *env,
- struct ptlrpc_request *req,
- struct osc_punch_args *aa, int rc)
-{
- struct ost_body *body;
- ENTRY;
-
- if (rc != 0)
- GOTO(out, rc);
-
- body = req_capsule_server_get(&req->rq_pill, &RMF_OST_BODY);
- if (body == NULL)
- GOTO(out, rc = -EPROTO);
-
- lustre_get_wire_obdo(aa->pa_oa, &body->oa);
-out:
- rc = aa->pa_upcall(aa->pa_cookie, rc);
- RETURN(rc);
-}
-
-int osc_punch_base(struct obd_export *exp, struct obdo *oa,
- struct obd_capa *capa,
+int osc_punch_base(struct obd_export *exp, struct obd_info *oinfo,
obd_enqueue_update_f upcall, void *cookie,
struct ptlrpc_request_set *rqset)
{
- struct ptlrpc_request *req;
- struct osc_punch_args *aa;
- struct ost_body *body;
- int rc;
+ struct ptlrpc_request *req;
+ struct osc_setattr_args *sa;
+ struct ost_body *body;
+ int rc;
ENTRY;
req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_OST_PUNCH);
if (req == NULL)
RETURN(-ENOMEM);
- osc_set_capa_size(req, &RMF_CAPA1, capa);
+ osc_set_capa_size(req, &RMF_CAPA1, oinfo->oi_capa);
rc = ptlrpc_request_pack(req, LUSTRE_OST_VERSION, OST_PUNCH);
if (rc) {
ptlrpc_request_free(req);
body = req_capsule_client_get(&req->rq_pill, &RMF_OST_BODY);
LASSERT(body);
- lustre_set_wire_obdo(&body->oa, oa);
- osc_pack_capa(req, body, capa);
+ lustre_set_wire_obdo(&body->oa, oinfo->oi_oa);
+ osc_pack_capa(req, body, oinfo->oi_capa);
ptlrpc_request_set_replen(req);
- req->rq_interpret_reply = (ptlrpc_interpterer_t)osc_punch_interpret;
- CLASSERT (sizeof(*aa) <= sizeof(req->rq_async_args));
- aa = ptlrpc_req_async_args(req);
- aa->pa_oa = oa;
- aa->pa_upcall = upcall;
- aa->pa_cookie = cookie;
+ req->rq_interpret_reply = (ptlrpc_interpterer_t)osc_setattr_interpret;
+ CLASSERT (sizeof(*sa) <= sizeof(req->rq_async_args));
+ sa = ptlrpc_req_async_args(req);
+ sa->sa_oa = oinfo->oi_oa;
+ sa->sa_upcall = upcall;
+ sa->sa_cookie = cookie;
if (rqset == PTLRPCD_SET)
ptlrpcd_add_req(req, PSCOPE_OTHER);
else
oinfo->oi_oa->o_size = oinfo->oi_policy.l_extent.start;
oinfo->oi_oa->o_blocks = oinfo->oi_policy.l_extent.end;
oinfo->oi_oa->o_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
- return osc_punch_base(exp, oinfo->oi_oa, oinfo->oi_capa,
+ return osc_punch_base(exp, oinfo,
oinfo->oi_cb_up, oinfo, rqset);
}