Beispiel #1
0
static int pnode_revalidate_finish(struct ptlrpc_request *req,
                                   struct lookup_intent *it,
                                   struct pnode *pnode)
{
        struct inode *inode = pnode->p_base->pb_ino;
        struct lustre_md md;
        int rc = 0;
        ENTRY;

        LASSERT(inode);

        if (!req)
                RETURN(0);

        if (it_disposition(it, DISP_LOOKUP_NEG))
                RETURN(-ENOENT);

        rc = md_get_lustre_md(llu_i2sbi(inode)->ll_md_exp, req,
                              llu_i2sbi(inode)->ll_dt_exp, 
                              llu_i2sbi(inode)->ll_md_exp, &md);
        if (rc)
                RETURN(rc);

        llu_update_inode(inode, &md);

        RETURN(rc);
}
Beispiel #2
0
static void
llu_lookup_finish_locks(struct lookup_intent *it, struct pnode *pnode)
{
        struct inode *inode;
        LASSERT(it);
        LASSERT(pnode);

        inode = pnode->p_base->pb_ino;
        if (it->d.lustre.it_lock_mode && inode != NULL) {
                struct llu_sb_info *sbi;

                CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%llu/%lu)\n",
                       inode, (long long)llu_i2stat(inode)->st_ino,
                       llu_i2info(inode)->lli_st_generation);

                sbi = llu_i2sbi(inode);
                md_set_lock_data(sbi->ll_md_exp,
                                 &it->d.lustre.it_lock_handle, inode, NULL);
        }

        /* drop lookup/getattr locks */
        if (it->it_op & (IT_LOOKUP | IT_GETATTR))
                ll_intent_release(it);

}
Beispiel #3
0
int llu_file_release(struct inode *inode)
{
        struct ll_file_data *fd;
        struct llu_sb_info *sbi = llu_i2sbi(inode);
        struct llu_inode_info *lli = llu_i2info(inode);
        int rc = 0, rc2;

        ENTRY;
        CDEBUG(D_VFSTRACE, "VFS Op:inode=%llu/%lu\n",
               (long long)llu_i2stat(inode)->st_ino, lli->lli_st_generation);

        if (llu_is_root_inode(inode))
                RETURN(0);

        /* still opened by others? */
        if (--lli->lli_open_count)
                RETURN(0);

        fd = lli->lli_file_data;
        if (!fd) /* no process opened the file after an mcreate */
                RETURN(0);

        rc2 = llu_md_close(sbi->ll_md_exp, inode);
        if (rc2 && !rc)
                rc = rc2;

        RETURN(rc);
}
Beispiel #4
0
static void llu_prepare_close(struct inode *inode, struct md_op_data *op_data,
                              struct ll_file_data *fd)
{
        struct obd_client_handle *och = &fd->fd_mds_och;

        op_data->op_attr.ia_valid = ATTR_MODE      | ATTR_ATIME_SET |
                                    ATTR_MTIME_SET | ATTR_CTIME_SET;

        if (fd->fd_flags & FMODE_WRITE) {
                struct llu_sb_info *sbi = llu_i2sbi(inode);
                if (!(sbi->ll_lco.lco_flags & OBD_CONNECT_SOM) ||
                    !S_ISREG(llu_i2stat(inode)->st_mode)) {
                        op_data->op_attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS;
                } else {
                        /* Inode cannot be dirty. Close the epoch. */
                        op_data->op_flags |= MF_EPOCH_CLOSE;
                        /* XXX: Send SOM attributes only if they are really
                         * changed.  */
                        llu_done_writing_attr(inode, op_data);
                }
        }
        llu_pack_inode2opdata(inode, op_data, &och->och_fh);
        llu_prep_md_op_data(op_data, inode, NULL, NULL,
                            0, 0, LUSTRE_OPC_ANY);
}
Beispiel #5
0
static int llu_dir_do_readpage(struct inode *inode, struct page *page)
{
        struct llu_inode_info *lli = llu_i2info(inode);
        struct intnl_stat     *st = llu_i2stat(inode);
        struct llu_sb_info    *sbi = llu_i2sbi(inode);
        struct ptlrpc_request *request;
        struct lustre_handle   lockh;
        struct mdt_body       *body;
        struct lookup_intent   it = { .it_op = IT_READDIR };
        struct md_op_data      op_data = {{ 0 }};
        ldlm_policy_data_t policy = { .l_inodebits = { MDS_INODELOCK_UPDATE } };
        int rc = 0;
        ENTRY;

        llu_prep_md_op_data(&op_data, inode, NULL, NULL, 0, 0, LUSTRE_OPC_ANY);
        rc = md_lock_match(sbi->ll_md_exp, LDLM_FL_BLOCK_GRANTED,
                           &lli->lli_fid, LDLM_IBITS, &policy, LCK_CR, &lockh);
        if (!rc) {
		struct ldlm_enqueue_info einfo = {
			.ei_type	= LDLM_IBITS,
			.ei_mode	= LCK_CR,
			.ei_cb_bl	= llu_md_blocking_ast,
			.ei_cb_cp	= ldlm_completion_ast,
			.ei_cbdata	= inode,
		};

                rc = md_enqueue(sbi->ll_md_exp, &einfo, &it,
                                &op_data, &lockh, NULL, 0, NULL,
                                LDLM_FL_CANCEL_ON_BLOCK);
                request = (struct ptlrpc_request *)it.d.lustre.it_data;
                if (request)
                        ptlrpc_req_finished(request);
                if (rc < 0) {
                        CERROR("lock enqueue: err: %d\n", rc);
                        RETURN(rc);
                }
        }
        ldlm_lock_dump_handle(D_OTHER, &lockh);

        op_data.op_offset = (__u64)hash_x_index(page->index, 0);
        op_data.op_npages = 1;
        rc = md_readpage(sbi->ll_md_exp, &op_data, &page, &request);
        if (!rc) {
                body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
                LASSERT(body != NULL);         /* checked by md_readpage() */

                if (body->valid & OBD_MD_FLSIZE)
                        st->st_size = body->size;
        } else {
                CERROR("read_dir_page(%ld) error %d\n", page->index, rc);
        }
        ptlrpc_req_finished(request);
        EXIT;

        ldlm_lock_decref(&lockh, LCK_CR);
        return rc;
}
Beispiel #6
0
/** Cliens updates SOM attributes on MDS: obd_getattr and md_setattr. */
int llu_som_update(struct inode *inode, struct md_op_data *op_data)
{
        struct llu_inode_info *lli = llu_i2info(inode);
        struct llu_sb_info *sbi = llu_i2sbi(inode);
        struct obdo oa = { 0 };
        __u32 old_flags;
        int rc;
        ENTRY;

        LASSERT(!(lli->lli_flags & LLIF_MDS_SIZE_LOCK));
        LASSERT(sbi->ll_lco.lco_flags & OBD_CONNECT_SOM);

        old_flags = op_data->op_flags;
        op_data->op_flags = MF_SOM_CHANGE;

        /* If inode is already in another epoch, skip getattr from OSTs. */
        if (lli->lli_ioepoch == op_data->op_ioepoch) {
                rc = llu_inode_getattr(inode, &oa, op_data->op_ioepoch,
                                       old_flags & MF_GETATTR_LOCK);
                if (rc) {
                        oa.o_valid = 0;
                        if (rc == -ENOENT)
                                CDEBUG(D_INODE, "objid "LPX64" is destroyed\n",
                                       lli->lli_smd->lsm_object_id);
                        else
                                CERROR("inode_getattr failed (%d): unable to "
                                       "send a Size-on-MDS attribute update "
                                       "for inode %llu/%lu\n", rc,
                                       (long long)llu_i2stat(inode)->st_ino,
                                       lli->lli_st_generation);
                }  else {
                        CDEBUG(D_INODE, "Size-on-MDS update on "DFID"\n",
                               PFID(&lli->lli_fid));
                }

                /* Install attributes into op_data. */
                md_from_obdo(op_data, &oa, oa.o_valid);
        }

        rc = llu_md_setattr(inode, op_data, NULL);
        RETURN(rc);
}
Beispiel #7
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);
}