Esempio n. 1
0
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);
}
Esempio n. 2
0
File: file.c Progetto: DCteam/lustre
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;
}