static int llu_queue_pio(const struct lu_env *env, struct cl_io *io, struct llu_io_group *group, char *buf, size_t count, loff_t pos) { struct cl_object *obj = io->ci_obj; struct inode *inode = ccc_object_inode(obj); struct intnl_stat *st = llu_i2stat(inode); struct obd_export *exp = llu_i2obdexp(inode); struct page *page; int rc = 0, ret_bytes = 0; struct cl_page *clp; struct cl_2queue *queue; ENTRY; if (!exp) RETURN(-EINVAL); queue = &io->ci_queue; cl_2queue_init(queue); /* prepare the pages array */ do { unsigned long index, offset, bytes; offset = (pos & ~CFS_PAGE_MASK); index = pos >> PAGE_CACHE_SHIFT; bytes = PAGE_CACHE_SIZE - offset; if (bytes > count) bytes = count; /* prevent read beyond file range */ if (/* local_lock && */ io->ci_type == CIT_READ && pos + bytes >= st->st_size) { if (pos >= st->st_size) break; bytes = st->st_size - pos; } /* prepare page for this index */ page = llu_get_user_page(index, buf - offset, offset, bytes); if (!page) { rc = -ENOMEM; break; } clp = cl_page_find(env, obj, cl_index(obj, pos), page, CPT_TRANSIENT); if (IS_ERR(clp)) { rc = PTR_ERR(clp); break; } rc = cl_page_own(env, io, clp); if (rc) { LASSERT(clp->cp_state == CPS_FREEING); cl_page_put(env, clp); break; } cl_2queue_add(queue, clp); /* drop the reference count for cl_page_find, so that the page * will be freed in cl_2queue_fini. */ cl_page_put(env, clp); cl_page_clip(env, clp, offset, offset+bytes); count -= bytes; pos += bytes; buf += bytes; group->lig_rwcount += bytes; ret_bytes += bytes; page++; } while (count); if (rc == 0) { enum cl_req_type iot; iot = io->ci_type == CIT_READ ? CRT_READ : CRT_WRITE; rc = cl_io_submit_sync(env, io, iot, queue, 0); } group->lig_rc = rc; cl_2queue_discard(env, io, queue); cl_2queue_disown(env, io, queue); cl_2queue_fini(env, queue); RETURN(ret_bytes); }
int llu_objects_destroy(struct ptlrpc_request *req, struct inode *dir) { struct mdt_body *body; struct lov_mds_md *eadata; struct lov_stripe_md *lsm = NULL; struct obd_trans_info oti = { 0 }; struct obdo *oa; int rc; ENTRY; body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); if (!(body->valid & OBD_MD_FLEASIZE)) RETURN(0); if (body->eadatasize == 0) { CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n"); GOTO(out, rc = -EPROTO); } /* The MDS sent back the EA because we unlinked the last reference * to this file. Use this EA to unlink the objects on the OST. * It's opaque so we don't swab here; we leave it to obd_unpackmd() to * check it is complete and sensible. */ eadata = req_capsule_server_sized_get(&req->rq_pill, &RMF_MDT_MD, body->eadatasize); LASSERT(eadata != NULL); rc = obd_unpackmd(llu_i2obdexp(dir), &lsm, eadata,body->eadatasize); if (rc < 0) { CERROR("obd_unpackmd: %d\n", rc); GOTO(out, rc); } LASSERT(rc >= sizeof(*lsm)); OBDO_ALLOC(oa); if (oa == NULL) GOTO(out_free_memmd, rc = -ENOMEM); oa->o_id = lsm->lsm_object_id; oa->o_seq = lsm->lsm_object_seq; oa->o_mode = body->mode & S_IFMT; oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLGROUP; obdo_from_inode(oa, NULL, &llu_i2info(dir)->lli_fid, 0); if (body->valid & OBD_MD_FLCOOKIE) { oa->o_valid |= OBD_MD_FLCOOKIE; oti.oti_logcookies = req_capsule_server_sized_get(&req->rq_pill, &RMF_LOGCOOKIES, sizeof(struct llog_cookie) * lsm->lsm_stripe_count); if (oti.oti_logcookies == NULL) { oa->o_valid &= ~OBD_MD_FLCOOKIE; body->valid &= ~OBD_MD_FLCOOKIE; } } rc = obd_destroy(llu_i2obdexp(dir), oa, lsm, &oti, NULL, NULL); OBDO_FREE(oa); if (rc) CERROR("obd destroy objid 0x"LPX64" error %d\n", lsm->lsm_object_id, rc); out_free_memmd: obd_free_memmd(llu_i2obdexp(dir), &lsm); out: return rc; }