示例#1
0
文件: file.c 项目: DCteam/lustre
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);
}
示例#2
0
文件: dir.c 项目: Lezval/lustre
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;
}
示例#3
0
static int llu_lookup_it(struct inode *parent, struct pnode *pnode,
                         struct lookup_intent *it, int flags)
{
        struct md_op_data op_data = {{ 0 }};
        struct ptlrpc_request *req = NULL;
        struct lookup_intent lookup_it = { .it_op = IT_LOOKUP };
        __u32 opc;
        int rc;
        ENTRY;

        if (pnode->p_base->pb_name.len > EXT2_NAME_LEN)
                RETURN(-ENAMETOOLONG);

        if (!it) {
                it = &lookup_it;
                it->it_op_release = ll_intent_release;
        }

	if (it->it_op & IT_CREAT)
		opc = LUSTRE_OPC_CREATE;
	else
		opc = LUSTRE_OPC_ANY;

        llu_prep_md_op_data(&op_data, parent, NULL,
                            pnode->p_base->pb_name.name,
                            pnode->p_base->pb_name.len, flags, opc);

        rc = md_intent_lock(llu_i2mdexp(parent), &op_data, NULL, 0, it,
                            flags, &req, llu_md_blocking_ast,
                            LDLM_FL_CANCEL_ON_BLOCK);
        if (rc < 0)
                GOTO(out, rc);

	rc = lookup_it_finish(req, DLM_REPLY_REC_OFF, it, parent, pnode);
        if (rc != 0) {
                ll_intent_release(it);
                GOTO(out, rc);
        }

        llu_lookup_finish_locks(it, pnode);

 out:
        if (req)
                ptlrpc_req_finished(req);
        return rc;
}
示例#4
0
static int llu_pb_revalidate(struct pnode *pnode, int flags,
                             struct lookup_intent *it)
{
        struct pnode_base *pb = pnode->p_base;
        struct md_op_data op_data = {{ 0 }};
        struct ptlrpc_request *req = NULL;
        struct lookup_intent lookup_it = { .it_op = IT_LOOKUP };
        struct obd_export *exp;
        int rc;
        ENTRY;

        CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,intent=%x\n",
               (int)pb->pb_name.len, pb->pb_name.name, it ? it->it_op : 0);

        /* We don't want to cache negative dentries, so return 0 immediately.
         * We believe that this is safe, that negative dentries cannot be
         * pinned by someone else */
        if (pb->pb_ino == NULL) {
                CDEBUG(D_INODE, "negative pb\n");
                RETURN(0);
        }

        /* This is due to bad interaction with libsysio. remove this when we
         * switched to libbsdio XXX
         */
        {
                struct llu_inode_info *lli = llu_i2info(pb->pb_ino);
                struct intnl_stat *st = llu_i2stat(pb->pb_ino);
                if (lli->lli_it) {
                        CDEBUG(D_INODE, "inode %llu still have intent "
                                        "%p(opc 0x%x), release it\n",
                                        (long long) st->st_ino, lli->lli_it,
                                        lli->lli_it->it_op);
                        ll_intent_release(lli->lli_it);
                        OBD_FREE(lli->lli_it, sizeof(*lli->lli_it));
                        lli->lli_it = NULL;
                }
        }

        exp = llu_i2mdexp(pb->pb_ino);

        if (!it) {
                it = &lookup_it;
                it->it_op_release = ll_intent_release;
        }

        llu_prep_md_op_data(&op_data, pnode->p_parent->p_base->pb_ino,
                            pb->pb_ino, pb->pb_name.name, pb->pb_name.len,
                            0, LUSTRE_OPC_ANY);

        rc = md_intent_lock(exp, &op_data, NULL, 0, it, flags,
                            &req, llu_md_blocking_ast,
                            LDLM_FL_CANCEL_ON_BLOCK);
        /* If req is NULL, then md_intent_lock only tried to do a lock match;
         * if all was well, it will return 1 if it found locks, 0 otherwise. */
        if (req == NULL && rc >= 0)
                GOTO(out, rc);

        if (rc < 0)
                GOTO(out, rc = 0);

        rc = pnode_revalidate_finish(req, it, pnode);
        if (rc != 0) {
                ll_intent_release(it);
                GOTO(out, rc = 0);
        }
        rc = 1;

        /* Note: ll_intent_lock may cause a callback, check this! */

        if (it->it_op & IT_OPEN)
                LL_SAVE_INTENT(pb->pb_ino, it);

 out:
        if (req && rc == 1)
                ptlrpc_req_finished(req);
        if (rc == 0) {
                LASSERT(pb->pb_ino);
                I_RELE(pb->pb_ino);
                pb->pb_ino = NULL;
        } else {
                llu_lookup_finish_locks(it, pnode);
        }
        RETURN(rc);
}