} ci_wr;
struct cl_io_rw_common ci_rw;
struct cl_setattr_io {
- struct ost_lvb sa_attr;
- unsigned int sa_valid;
- int sa_stripe_index;
- struct lu_fid *sa_parent_fid;
- struct obd_capa *sa_capa;
+ struct ost_lvb sa_attr;
+ unsigned int sa_attr_flags;
+ unsigned int sa_valid;
+ int sa_stripe_index;
+ const struct lu_fid *sa_parent_fid;
+ struct obd_capa *sa_capa;
} ci_setattr;
struct cl_fault_io {
/** page index within file. */
struct obdo *oa, struct obd_trans_info *oti);
int (*o_setattr)(const struct lu_env *, struct obd_export *exp,
struct obd_info *oinfo, struct obd_trans_info *oti);
- int (*o_setattr_async)(struct obd_export *exp, struct obd_info *oinfo,
- struct obd_trans_info *oti,
- struct ptlrpc_request_set *rqset);
int (*o_getattr)(const struct lu_env *env, struct obd_export *exp,
struct obd_info *oinfo);
int (*o_preprw)(const struct lu_env *env, int cmd,
RETURN(rc);
}
-/* This performs all the requests set init/wait/destroy actions. */
-static inline int obd_setattr_rqset(struct obd_export *exp,
- struct obd_info *oinfo,
- struct obd_trans_info *oti)
-{
- struct ptlrpc_request_set *set = NULL;
- int rc;
- ENTRY;
-
- EXP_CHECK_DT_OP(exp, setattr_async);
- EXP_COUNTER_INCREMENT(exp, setattr_async);
-
- set = ptlrpc_prep_set();
- if (set == NULL)
- RETURN(-ENOMEM);
-
- rc = OBP(exp->exp_obd, setattr_async)(exp, oinfo, oti, set);
- if (rc == 0)
- rc = ptlrpc_set_wait(set);
- ptlrpc_set_destroy(set);
- RETURN(rc);
-}
-
-/* This adds all the requests into @set if @set != NULL, otherwise
- all requests are sent asynchronously without waiting for response. */
-static inline int obd_setattr_async(struct obd_export *exp,
- struct obd_info *oinfo,
- struct obd_trans_info *oti,
- struct ptlrpc_request_set *set)
-{
- int rc;
- ENTRY;
-
- EXP_CHECK_DT_OP(exp, setattr_async);
- EXP_COUNTER_INCREMENT(exp, setattr_async);
-
- rc = OBP(exp->exp_obd, setattr_async)(exp, oinfo, oti, set);
- RETURN(rc);
-}
-
static inline int obd_add_conn(struct obd_import *imp, struct obd_uuid *uuid,
int priority)
{
*/
static DEFINE_MUTEX(cl_inode_fini_guard);
-int cl_setattr_ost(struct inode *inode, const struct iattr *attr,
- struct obd_capa *capa)
+int cl_setattr_ost(struct cl_object *obj, const struct iattr *attr,
+ unsigned int attr_flags, struct obd_capa *capa)
{
struct lu_env *env;
struct cl_io *io;
RETURN(PTR_ERR(env));
io = vvp_env_thread_io(env);
- io->ci_obj = ll_i2info(inode)->lli_clob;
+ io->ci_obj = obj;
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_attr_flags = attr_flags;
io->u.ci_setattr.sa_valid = attr->ia_valid;
- io->u.ci_setattr.sa_parent_fid = ll_inode2fid(inode);
+ io->u.ci_setattr.sa_parent_fid = lu_object_fid(&obj->co_lu);
io->u.ci_setattr.sa_capa = capa;
again:
int ll_getparent(struct file *file, struct getparent __user *arg);
/* lcommon_cl.c */
-int cl_setattr_ost(struct inode *inode, const struct iattr *attr,
- struct obd_capa *capa);
+int cl_setattr_ost(struct cl_object *obj, const struct iattr *attr,
+ unsigned int attr_flags, struct obd_capa *capa);
extern struct lu_env *cl_inode_fini_env;
extern int cl_inode_fini_refcheck;
else
capa = ll_mdscapa_get(inode);
- rc = cl_setattr_ost(inode, attr, capa);
+ rc = cl_setattr_ost(ll_i2info(inode)->lli_clob, attr, 0, capa);
if (attr->ia_valid & ATTR_SIZE)
ll_truncate_free_capa(capa);
RETURN(put_user(flags, (int __user *)arg));
}
case FSFILT_IOC_SETFLAGS: {
- struct lov_stripe_md *lsm;
- struct obd_info oinfo = { { { 0 } } };
- struct md_op_data *op_data;
+ struct iattr *attr;
+ struct md_op_data *op_data;
+ struct cl_object *obj;
+ struct obd_capa *capa;
if (get_user(flags, (int __user *)arg))
RETURN(-EFAULT);
inode->i_flags = ll_ext_to_inode_flags(flags);
- lsm = ccc_inode_lsm_get(inode);
- if (!lsm_has_objects(lsm)) {
- ccc_inode_lsm_put(inode, lsm);
+ obj = ll_i2info(inode)->lli_clob;
+ if (obj == NULL)
RETURN(0);
- }
- OBDO_ALLOC(oinfo.oi_oa);
- if (!oinfo.oi_oa) {
- ccc_inode_lsm_put(inode, lsm);
+ OBD_ALLOC_PTR(attr);
+ if (attr == NULL)
RETURN(-ENOMEM);
- }
- oinfo.oi_md = lsm;
- oinfo.oi_oa->o_oi = lsm->lsm_oi;
- oinfo.oi_oa->o_flags = flags;
- oinfo.oi_oa->o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS |
- OBD_MD_FLGROUP;
- oinfo.oi_capa = ll_mdscapa_get(inode);
- obdo_set_parent_fid(oinfo.oi_oa, &ll_i2info(inode)->lli_fid);
- rc = obd_setattr_rqset(sbi->ll_dt_exp, &oinfo, NULL);
- capa_put(oinfo.oi_capa);
- OBDO_FREE(oinfo.oi_oa);
- ccc_inode_lsm_put(inode, lsm);
- if (rc && rc != -EPERM && rc != -EACCES)
- CERROR("osc_setattr_async fails: rc = %d\n", rc);
+ attr->ia_valid = ATTR_ATTR_FLAG;
+
+ capa = ll_mdscapa_get(inode);
+ rc = cl_setattr_ost(obj, attr, flags, capa);
+ capa_put(capa);
+ OBD_FREE_PTR(attr);
RETURN(rc);
}
default:
if (new_size == 0)
enqflags = CEF_DISCARD_DATA;
} else {
- if ((io->u.ci_setattr.sa_attr.lvb_mtime >=
- io->u.ci_setattr.sa_attr.lvb_ctime) ||
- (io->u.ci_setattr.sa_attr.lvb_atime >=
- io->u.ci_setattr.sa_attr.lvb_ctime))
- return 0;
- new_size = 0;
- }
+ unsigned int valid = io->u.ci_setattr.sa_valid;
+
+ if (!(valid & TIMES_SET_FLAGS))
+ return 0;
+
+ if ((!(valid & ATTR_MTIME) ||
+ io->u.ci_setattr.sa_attr.lvb_mtime >=
+ io->u.ci_setattr.sa_attr.lvb_ctime) &&
+ (!(valid & ATTR_ATIME) ||
+ io->u.ci_setattr.sa_attr.lvb_atime >=
+ io->u.ci_setattr.sa_attr.lvb_ctime))
+ return 0;
+
+ new_size = 0;
+ }
return vvp_io_one_lock(env, io, enqflags, CLM_WRITE,
new_size, OBD_OBJECT_EOF);
if (cl_io_is_trunc(io))
result = vvp_io_setattr_trunc(env, ios, inode,
io->u.ci_setattr.sa_attr.lvb_size);
- if (result == 0)
+ if (result == 0 && io->u.ci_setattr.sa_valid & TIMES_SET_FLAGS)
result = vvp_io_setattr_time(env, ios);
return result;
}
int lov_prep_getattr_set(struct obd_export *exp, struct obd_info *oinfo,
struct lov_request_set **reqset);
int lov_fini_getattr_set(struct lov_request_set *set);
-int lov_prep_setattr_set(struct obd_export *exp, struct obd_info *oinfo,
- struct obd_trans_info *oti,
- struct lov_request_set **reqset);
-int lov_update_setattr_set(struct lov_request_set *set,
- struct lov_request *req, int rc);
-int lov_fini_setattr_set(struct lov_request_set *set);
int lov_prep_statfs_set(struct obd_device *obd, struct obd_info *oinfo,
struct lov_request_set **reqset);
void lov_update_statfs(struct obd_statfs *osfs, struct obd_statfs *lov_sfs,
switch (io->ci_type) {
case CIT_SETATTR: {
io->u.ci_setattr.sa_attr = parent->u.ci_setattr.sa_attr;
+ io->u.ci_setattr.sa_attr_flags =
+ parent->u.ci_setattr.sa_attr_flags;
io->u.ci_setattr.sa_valid = parent->u.ci_setattr.sa_valid;
io->u.ci_setattr.sa_stripe_index = stripe;
io->u.ci_setattr.sa_parent_fid =
RETURN(rc ? rc : err);
}
-static int lov_setattr_interpret(struct ptlrpc_request_set *rqset,
- void *data, int rc)
-{
- struct lov_request_set *lovset = (struct lov_request_set *)data;
- int err;
- ENTRY;
-
- if (rc)
- atomic_set(&lovset->set_completes, 0);
- err = lov_fini_setattr_set(lovset);
- RETURN(rc ? rc : err);
-}
-
-/* If @oti is given, the request goes from MDS and responses from OSTs are not
- needed. Otherwise, a client is waiting for responses. */
-static int lov_setattr_async(struct obd_export *exp, struct obd_info *oinfo,
- struct obd_trans_info *oti,
- struct ptlrpc_request_set *rqset)
-{
- struct lov_request_set *set;
- struct lov_request *req;
- struct list_head *pos;
- struct lov_obd *lov;
- int rc = 0;
- ENTRY;
-
- LASSERT(oinfo);
- ASSERT_LSM_MAGIC(oinfo->oi_md);
- if (oinfo->oi_oa->o_valid & OBD_MD_FLCOOKIE) {
- LASSERT(oti);
- LASSERT(oti->oti_logcookies);
- }
-
- if (!exp || !exp->exp_obd)
- RETURN(-ENODEV);
-
- lov = &exp->exp_obd->u.lov;
- rc = lov_prep_setattr_set(exp, oinfo, oti, &set);
- if (rc)
- RETURN(rc);
-
- CDEBUG(D_INFO, "objid "DOSTID": %ux%u byte stripes\n",
- POSTID(&oinfo->oi_md->lsm_oi),
- oinfo->oi_md->lsm_stripe_count,
- oinfo->oi_md->lsm_stripe_size);
-
- list_for_each(pos, &set->set_list) {
- req = list_entry(pos, struct lov_request, rq_link);
-
- if (oinfo->oi_oa->o_valid & OBD_MD_FLCOOKIE)
- oti->oti_logcookies = set->set_cookies + req->rq_stripe;
-
- CDEBUG(D_INFO, "objid "DOSTID"[%d] has subobj "DOSTID" at idx"
- "%u\n", POSTID(&oinfo->oi_oa->o_oi), req->rq_stripe,
- POSTID(&req->rq_oi.oi_oa->o_oi), req->rq_idx);
-
- rc = obd_setattr_async(lov->lov_tgts[req->rq_idx]->ltd_exp,
- &req->rq_oi, oti, rqset);
- if (rc) {
- CERROR("error: setattr objid "DOSTID" subobj"
- DOSTID" on OST idx %d: rc = %d\n",
- POSTID(&set->set_oi->oi_oa->o_oi),
- POSTID(&req->rq_oi.oi_oa->o_oi),
- req->rq_idx, rc);
- break;
- }
- }
-
- /* If we are not waiting for responses on async requests, return. */
- if (rc || !rqset || list_empty(&rqset->set_requests)) {
- int err;
- if (rc)
- atomic_set(&set->set_completes, 0);
- err = lov_fini_setattr_set(set);
- RETURN(rc ? rc : err);
- }
-
- LASSERT(rqset->set_interpret == NULL);
- rqset->set_interpret = lov_setattr_interpret;
- rqset->set_arg = (void *)set;
-
- RETURN(0);
-}
-
int lov_statfs_interpret(struct ptlrpc_request_set *rqset, void *data, int rc)
{
struct lov_request_set *lovset = (struct lov_request_set *)data;
.o_statfs_async = lov_statfs_async,
.o_packmd = lov_packmd,
.o_unpackmd = lov_unpackmd,
- .o_setattr_async = lov_setattr_async,
.o_iocontrol = lov_iocontrol,
.o_get_info = lov_get_info,
.o_set_info_async = lov_set_info_async,
RETURN(rc);
}
-int lov_fini_setattr_set(struct lov_request_set *set)
-{
- int rc = 0;
- ENTRY;
-
- if (set == NULL)
- RETURN(0);
- LASSERT(set->set_exp);
- if (atomic_read(&set->set_completes)) {
- rc = common_attr_done(set);
- /* FIXME update qos data here */
- }
-
- lov_put_reqset(set);
- RETURN(rc);
-}
-
-int lov_update_setattr_set(struct lov_request_set *set,
- struct lov_request *req, int rc)
-{
- struct lov_obd *lov = &req->rq_rqset->set_exp->exp_obd->u.lov;
- struct lov_stripe_md *lsm = req->rq_rqset->set_oi->oi_md;
- ENTRY;
-
- lov_update_set(set, req, rc);
-
- /* grace error on inactive ost */
- if (rc && !(lov->lov_tgts[req->rq_idx] &&
- lov->lov_tgts[req->rq_idx]->ltd_active))
- rc = 0;
-
- if (rc == 0) {
- if (req->rq_oi.oi_oa->o_valid & OBD_MD_FLCTIME)
- lsm->lsm_oinfo[req->rq_stripe]->loi_lvb.lvb_ctime =
- req->rq_oi.oi_oa->o_ctime;
- if (req->rq_oi.oi_oa->o_valid & OBD_MD_FLMTIME)
- lsm->lsm_oinfo[req->rq_stripe]->loi_lvb.lvb_mtime =
- req->rq_oi.oi_oa->o_mtime;
- if (req->rq_oi.oi_oa->o_valid & OBD_MD_FLATIME)
- lsm->lsm_oinfo[req->rq_stripe]->loi_lvb.lvb_atime =
- req->rq_oi.oi_oa->o_atime;
- }
-
- RETURN(rc);
-}
-
-/* The callback for osc_setattr_async that finilizes a request info when a
- * response is received. */
-static int cb_setattr_update(void *cookie, int rc)
-{
- struct obd_info *oinfo = cookie;
- struct lov_request *lovreq;
- lovreq = container_of(oinfo, struct lov_request, rq_oi);
- return lov_update_setattr_set(lovreq->rq_rqset, lovreq, rc);
-}
-
-int lov_prep_setattr_set(struct obd_export *exp, struct obd_info *oinfo,
- struct obd_trans_info *oti,
- struct lov_request_set **reqset)
-{
- struct lov_request_set *set;
- struct lov_obd *lov = &exp->exp_obd->u.lov;
- int rc = 0, i;
- ENTRY;
-
- OBD_ALLOC(set, sizeof(*set));
- if (set == NULL)
- RETURN(-ENOMEM);
- lov_init_set(set);
-
- set->set_exp = exp;
- set->set_oi = oinfo;
- if (oti != NULL && oinfo->oi_oa->o_valid & OBD_MD_FLCOOKIE)
- set->set_cookies = oti->oti_logcookies;
-
- for (i = 0; i < oinfo->oi_md->lsm_stripe_count; i++) {
- struct lov_oinfo *loi = oinfo->oi_md->lsm_oinfo[i];
- struct lov_request *req;
-
- if (lov_oinfo_is_dummy(loi))
- continue;
-
- if (!lov_check_and_wait_active(lov, loi->loi_ost_idx)) {
- CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
- continue;
- }
-
- OBD_ALLOC(req, sizeof(*req));
- if (req == NULL)
- GOTO(out_set, rc = -ENOMEM);
- req->rq_stripe = i;
- req->rq_idx = loi->loi_ost_idx;
-
- OBDO_ALLOC(req->rq_oi.oi_oa);
- if (req->rq_oi.oi_oa == NULL) {
- OBD_FREE(req, sizeof(*req));
- GOTO(out_set, rc = -ENOMEM);
- }
- memcpy(req->rq_oi.oi_oa, oinfo->oi_oa,
- sizeof(*req->rq_oi.oi_oa));
- req->rq_oi.oi_oa->o_oi = loi->loi_oi;
- req->rq_oi.oi_oa->o_stripe_idx = i;
- req->rq_oi.oi_cb_up = cb_setattr_update;
- req->rq_oi.oi_capa = oinfo->oi_capa;
-
- if (oinfo->oi_oa->o_valid & OBD_MD_FLSIZE) {
- int off = lov_stripe_offset(oinfo->oi_md,
- oinfo->oi_oa->o_size, i,
- &req->rq_oi.oi_oa->o_size);
-
- if (off < 0 && req->rq_oi.oi_oa->o_size)
- req->rq_oi.oi_oa->o_size--;
-
- CDEBUG(D_INODE, "stripe %d has size "LPU64"/"LPU64"\n",
- i, req->rq_oi.oi_oa->o_size,
- oinfo->oi_oa->o_size);
- }
- lov_set_add_req(req, set);
- }
- if (!set->set_count)
- GOTO(out_set, rc = -EIO);
- *reqset = set;
- RETURN(rc);
-out_set:
- lov_fini_setattr_set(set);
- RETURN(rc);
-}
-
#define LOV_U64_MAX ((__u64)~0ULL)
#define LOV_SUM_MAX(tot, add) \
do { \
LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
- LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
__u64 *flags, void *data, struct lustre_handle *lockh,
int unref);
-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_setattr_async(struct obd_export *exp, struct obd_info *oinfo,
+ 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);
oa->o_oi = loi->loi_oi;
obdo_set_parent_fid(oa, io->u.ci_setattr.sa_parent_fid);
oa->o_stripe_idx = io->u.ci_setattr.sa_stripe_index;
- oa->o_mtime = attr->cat_mtime;
- oa->o_atime = attr->cat_atime;
- oa->o_ctime = attr->cat_ctime;
- oa->o_valid |= OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLATIME |
- OBD_MD_FLCTIME | OBD_MD_FLMTIME;
+ oa->o_valid |= OBD_MD_FLID | OBD_MD_FLGROUP;
+ if (ia_valid & ATTR_CTIME) {
+ oa->o_valid |= OBD_MD_FLCTIME;
+ oa->o_ctime = attr->cat_ctime;
+ }
+ if (ia_valid & ATTR_ATIME) {
+ oa->o_valid |= OBD_MD_FLATIME;
+ oa->o_atime = attr->cat_atime;
+ }
+ if (ia_valid & ATTR_MTIME) {
+ oa->o_valid |= OBD_MD_FLMTIME;
+ oa->o_mtime = attr->cat_mtime;
+ }
if (ia_valid & ATTR_SIZE) {
oa->o_size = size;
oa->o_blocks = OBD_OBJECT_EOF;
LASSERT(oio->oi_lockless == 0);
}
+ if (ia_valid & ATTR_ATTR_FLAG) {
+ oa->o_flags = io->u.ci_setattr.sa_attr_flags;
+ oa->o_valid |= OBD_MD_FLFLAGS;
+ }
+
oinfo.oi_oa = oa;
oinfo.oi_capa = io->u.ci_setattr.sa_capa;
init_completion(&cbargs->opc_sync);
&oinfo, osc_async_upcall,
cbargs, PTLRPCD_SET);
else
- result = osc_setattr_async_base(osc_export(cl2osc(obj)),
- &oinfo, NULL,
- osc_async_upcall,
- cbargs, PTLRPCD_SET);
+ result = osc_setattr_async(osc_export(cl2osc(obj)),
+ &oinfo,
+ osc_async_upcall,
+ cbargs, PTLRPCD_SET);
cbargs->opc_rpc_sent = result == 0;
}
return result;
RETURN(rc);
}
-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_setattr_async(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_setattr_args *sa;
RETURN(rc);
}
- if (oti && oinfo->oi_oa->o_valid & OBD_MD_FLCOOKIE)
- oinfo->oi_oa->o_lcookie = *oti->oti_logcookies;
-
osc_pack_req_body(req, oinfo);
ptlrpc_request_set_replen(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);
-}
-
static int osc_create(const struct lu_env *env, struct obd_export *exp,
struct obdo *oa, struct obd_trans_info *oti)
{
.o_destroy = osc_destroy,
.o_getattr = osc_getattr,
.o_setattr = osc_setattr,
- .o_setattr_async = osc_setattr_async,
.o_iocontrol = osc_iocontrol,
.o_set_info_async = osc_set_info_async,
.o_import_event = osc_import_event,