Exemplo n.º 1
0
static int lookup_it_finish(struct ptlrpc_request *request, int offset,
			    struct lookup_intent *it,
			    struct inode *parent, struct pnode *child)
{
        struct llu_sb_info *sbi = llu_i2sbi(parent);
        struct inode *inode = NULL;
        int rc;

        /* libsysio require us generate inode right away if success.
         * so if mds created new inode for us we need make sure it
         * succeeded. thus for any error we can't delay to the
         * llu_file_open() time. */
        if (it_disposition(it, DISP_OPEN_CREATE) &&
            it_open_error(DISP_OPEN_CREATE, it)) {
                CDEBUG(D_INODE, "detect mds create error\n");
                return it_open_error(DISP_OPEN_CREATE, it);
        }
        if (it_disposition(it, DISP_OPEN_OPEN) &&
            it_open_error(DISP_OPEN_OPEN, it)) {
                CDEBUG(D_INODE, "detect mds open error\n");
                /* undo which did by md_intent_lock */
                if (it_disposition(it, DISP_OPEN_CREATE) &&
                    !it_open_error(DISP_OPEN_CREATE, it)) {
			LASSERT(request);
			LASSERT(atomic_read(&request->rq_refcount) > 1);
			CDEBUG(D_INODE, "dec a ref of req %p\n", request);
			ptlrpc_req_finished(request);
                }
                return it_open_error(DISP_OPEN_OPEN, it);
        }

        /* NB 1 request reference will be taken away by ll_intent_lock()
         * when I return
         */
        if (!it_disposition(it, DISP_LOOKUP_NEG) || (it->it_op & IT_CREAT)) {
                struct lustre_md md;
                struct llu_inode_info *lli;
                struct intnl_stat *st;
                ENTRY;

                if (it_disposition(it, DISP_OPEN_CREATE))
                        ptlrpc_req_finished(request);

                rc = md_get_lustre_md(sbi->ll_md_exp, request,
                                      sbi->ll_dt_exp, sbi->ll_md_exp, &md);
                if (rc)
                        RETURN(rc);

                inode = llu_iget(parent->i_fs, &md);
                if (!inode || IS_ERR(inode)) {
                        /* free the lsm if we allocated one above */
                        if (md.lsm != NULL)
                                obd_free_memmd(sbi->ll_dt_exp, &md.lsm);
                        RETURN(inode ? PTR_ERR(inode) : -ENOMEM);
		} else if (md.lsm != NULL) {
                        obd_free_memmd(sbi->ll_dt_exp, &md.lsm);
                }

                lli = llu_i2info(inode);
                st = llu_i2stat(inode);

                /* If this is a stat, get the authoritative file size */
                if (it->it_op == IT_GETATTR && S_ISREG(st->st_mode) &&
		    lli->lli_has_smd) {
                        ldlm_error_t rc;

                        /* bug 2334: drop MDS lock before acquiring OST lock */
                        ll_intent_drop_lock(it);

                        rc = cl_glimpse_size(inode);
                        if (rc) {
                                I_RELE(inode);
                                RETURN(rc);
                        }
                }
        } else {
                ENTRY;
        }

        /* intent will be further used in cases of open()/getattr() */
        if (inode && (it->it_op & IT_OPEN))
                LL_SAVE_INTENT(inode, it);

        child->p_base->pb_ino = inode;

        RETURN(0);
}
Exemplo n.º 2
0
Arquivo: file.c Projeto: DCteam/lustre
int llu_iop_open(struct pnode *pnode, int flags, mode_t mode)
{
        struct inode *inode = pnode->p_base->pb_ino;
        struct llu_inode_info *lli = llu_i2info(inode);
        struct intnl_stat *st = llu_i2stat(inode);
        struct ll_file_data *fd;
        struct ptlrpc_request *request;
        struct lookup_intent *it;
        struct lov_stripe_md *lsm;
        int rc = 0;
        ENTRY;

        liblustre_wait_event(0);

        /* don't do anything for '/' */
        if (llu_is_root_inode(inode))
                RETURN(0);

        CDEBUG(D_VFSTRACE, "VFS Op:inode=%llu\n", (long long)st->st_ino);
        LL_GET_INTENT(inode, it);

        if (!it->d.lustre.it_disposition) {
                LBUG();
        }

        rc = it_open_error(DISP_OPEN_OPEN, it);
        if (rc)
                GOTO(out_release, rc);

        rc = llu_local_open(lli, it);
        if (rc)
                LBUG();

        if (!S_ISREG(st->st_mode))
                GOTO(out_release, rc = 0);

        fd = lli->lli_file_data;

        lsm = lli->lli_smd;
        if (lsm)
                flags &= ~O_LOV_DELAY_CREATE;
        /*XXX: open_flags are overwritten and the previous ones are lost */
        lli->lli_open_flags = flags & ~(O_CREAT | O_EXCL | O_TRUNC);

 out_release:
        request = it->d.lustre.it_data;
        ptlrpc_req_finished(request);

        it->it_op_release(it);
        OBD_FREE(it, sizeof(*it));

        /* libsysio hasn't done anything for O_TRUNC. here we
         * simply simulate it as open(...); truncate(...); */
        if (rc == 0 && (flags & O_TRUNC) && S_ISREG(st->st_mode)) {
                struct iattr attr;

                memset(&attr, 0, sizeof(attr));
                attr.ia_size = 0;
                attr.ia_valid |= ATTR_SIZE | ATTR_RAW;
                rc = llu_setattr_raw(inode, &attr);
                if (rc)
                        CERROR("error %d truncate in open()\n", rc);
        }

        liblustre_wait_event(0);
        RETURN(rc);
}