⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 handler.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
        if ((S_ISREG(inode->i_mode) && (reqbody->valid & OBD_MD_FLEASIZE)) ||            (S_ISDIR(inode->i_mode) && (reqbody->valid & OBD_MD_FLDIREA))) {                if (lustre_msg_get_opc(req->rq_reqmsg) == MDS_GETATTR &&                   ((S_ISDIR(inode->i_mode) && (reqbody->valid & OBD_MD_FLDIREA))))                        flags = MDS_GETATTR;                rc = mds_pack_md(obd, req->rq_repmsg, reply_off, body,                                 inode, 1, flags);                /* If we have LOV EA data, the OST holds size, atime, mtime */                if (!(body->valid & OBD_MD_FLEASIZE) &&                    !(body->valid & OBD_MD_FLDIREA))                        body->valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |                                        OBD_MD_FLATIME | OBD_MD_FLMTIME);                lustre_shrink_reply(req, reply_off, body->eadatasize, 0);                if (body->eadatasize)                        reply_off++;        } else if (S_ISLNK(inode->i_mode) &&                   (reqbody->valid & OBD_MD_LINKNAME) != 0) {                char *symname = lustre_msg_buf(req->rq_repmsg, reply_off, 0);                int len;                LASSERT (symname != NULL);       /* caller prepped reply */                len = lustre_msg_buflen(req->rq_repmsg, reply_off);                rc = inode->i_op->readlink(dentry, symname, len);                if (rc < 0) {                        CERROR("readlink failed: %d\n", rc);                } else if (rc != len - 1) {                        CERROR ("Unexpected readlink rc %d: expecting %d\n",                                rc, len - 1);                        rc = -EINVAL;                } else {                        CDEBUG(D_INODE, "read symlink dest %s\n", symname);                        body->valid |= OBD_MD_LINKNAME;                        body->eadatasize = rc + 1;                        symname[rc] = 0;        /* NULL terminate */                        rc = 0;                }                reply_off++;        } else if (reqbody->valid == OBD_MD_FLFLAGS &&                   reqbody->flags & MDS_BFLAG_EXT_FLAGS) {                int flags;                /* We only return the full set of flags on ioctl, otherwise we                 * get enough flags from the inode in mds_pack_inode2body(). */                rc = fsfilt_iocontrol(obd, inode, NULL, EXT3_IOC_GETFLAGS,                                      (long)&flags);                if (rc == 0)                        body->flags = flags | MDS_BFLAG_EXT_FLAGS;        }        if (reqbody->valid & OBD_MD_FLMODEASIZE) {                struct mds_obd *mds = mds_req2mds(req);                body->max_cookiesize = mds->mds_max_cookiesize;                body->max_mdsize = mds->mds_max_mdsize;                body->valid |= OBD_MD_FLMODEASIZE;        }        if (rc)                RETURN(rc);#ifdef CONFIG_FS_POSIX_ACL        if ((req->rq_export->exp_connect_flags & OBD_CONNECT_ACL) &&            (reqbody->valid & OBD_MD_FLACL)) {                rc = mds_pack_acl(&req->rq_export->exp_mds_data,                                  inode, req->rq_repmsg,                                  body, reply_off);                lustre_shrink_reply(req, reply_off, body->aclsize, 0);                if (body->aclsize)                        reply_off++;        }#endif        RETURN(rc);}static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct inode *inode,                                int offset){        struct mds_obd *mds = mds_req2mds(req);        struct mds_body *body;        int rc, bufcount = 2;        int size[4] = { sizeof(struct ptlrpc_body), sizeof(*body) };        ENTRY;        LASSERT(offset == REQ_REC_OFF); /* non-intent */        body = lustre_msg_buf(req->rq_reqmsg, offset, sizeof(*body));        LASSERT(body != NULL);                    /* checked by caller */        LASSERT(lustre_req_swabbed(req, offset)); /* swabbed by caller */        if ((S_ISREG(inode->i_mode) && (body->valid & OBD_MD_FLEASIZE)) ||            (S_ISDIR(inode->i_mode) && (body->valid & OBD_MD_FLDIREA))) {                LOCK_INODE_MUTEX(inode);                rc = fsfilt_get_md(req->rq_export->exp_obd, inode, NULL, 0,                                   "lov");                UNLOCK_INODE_MUTEX(inode);                CDEBUG(D_INODE, "got %d bytes MD data for inode %lu\n",                       rc, inode->i_ino);                if ((rc == 0) && (lustre_msg_get_opc(req->rq_reqmsg) == MDS_GETATTR) &&                     ((S_ISDIR(inode->i_mode) && (body->valid & OBD_MD_FLDIREA))))                        rc = sizeof(struct lov_mds_md);                if (rc < 0) {                        if (rc != -ENODATA) {                                CERROR("error getting inode %lu MD: rc = %d\n",                                       inode->i_ino, rc);                                RETURN(rc);                        }                        size[bufcount] = 0;                } else if (rc > mds->mds_max_mdsize) {                        size[bufcount] = 0;                        CERROR("MD size %d larger than maximum possible %u\n",                               rc, mds->mds_max_mdsize);                } else {                        size[bufcount] = rc;                }                bufcount++;        } else if (S_ISLNK(inode->i_mode) && (body->valid & OBD_MD_LINKNAME)) {                if (i_size_read(inode) + 1 != body->eadatasize)                        CERROR("symlink size: %Lu, reply space: %d\n",                               i_size_read(inode) + 1, body->eadatasize);                size[bufcount] = min_t(int, i_size_read(inode) + 1,                                       body->eadatasize);                bufcount++;                CDEBUG(D_INODE, "symlink size: %Lu, reply space: %d\n",                       i_size_read(inode) + 1, body->eadatasize);        }#ifdef CONFIG_FS_POSIX_ACL        if ((req->rq_export->exp_connect_flags & OBD_CONNECT_ACL) &&            (body->valid & OBD_MD_FLACL)) {                struct dentry de = { .d_inode = inode };                size[bufcount] = 0;                if (inode->i_op && inode->i_op->getxattr) {                        lock_24kernel();                        rc = inode->i_op->getxattr(&de, MDS_XATTR_NAME_ACL_ACCESS,                                                   NULL, 0);                        unlock_24kernel();                        if (rc < 0) {                                if (rc != -ENODATA) {                                        CERROR("got acl size: %d\n", rc);                                        RETURN(rc);                                }                        } else                                size[bufcount] = rc;                }                bufcount++;        }#endif        if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETATTR_PACK)) {                CERROR("failed MDS_GETATTR_PACK test\n");                req->rq_status = -ENOMEM;                RETURN(-ENOMEM);        }        rc = lustre_pack_reply(req, bufcount, size, NULL);        if (rc) {                req->rq_status = rc;                RETURN(rc);        }        RETURN(0);}static int mds_getattr_lock(struct ptlrpc_request *req, int offset,                            int child_part, struct lustre_handle *child_lockh){        struct obd_device *obd = req->rq_export->exp_obd;        struct mds_obd *mds = &obd->u.mds;        struct ldlm_reply *rep = NULL;        struct lvfs_run_ctxt saved;        struct mds_body *body;        struct dentry *dparent = NULL, *dchild = NULL;        struct lvfs_ucred uc = {NULL,};        struct lustre_handle parent_lockh;        int namesize;        int rc = 0, cleanup_phase = 0, resent_req = 0;        char *name;        ENTRY;        LASSERT(!strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME));        /* Swab now, before anyone looks inside the request */        body = lustre_swab_reqbuf(req, offset, sizeof(*body),                                  lustre_swab_mds_body);        if (body == NULL) {                CERROR("Can't swab mds_body\n");                RETURN(-EFAULT);        }        lustre_set_req_swabbed(req, offset + 1);        name = lustre_msg_string(req->rq_reqmsg, offset + 1, 0);        if (name == NULL) {                CERROR("Can't unpack name\n");                RETURN(-EFAULT);        }        namesize = lustre_msg_buflen(req->rq_reqmsg, offset + 1);        /* namesize less than 2 means we have empty name, probably came from           revalidate by cfid, so no point in having name to be set */        if (namesize <= 1)                name = NULL;        rc = mds_init_ucred(&uc, req, offset);        if (rc)                GOTO(cleanup, rc);        LASSERT(offset == REQ_REC_OFF || offset == DLM_INTENT_REC_OFF);        /* if requests were at offset 2, the getattr reply goes back at 1 */        if (offset == DLM_INTENT_REC_OFF) {                rep = lustre_msg_buf(req->rq_repmsg, DLM_LOCKREPLY_OFF,                                     sizeof(*rep));                offset = DLM_REPLY_REC_OFF;        }        push_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);        cleanup_phase = 1; /* kernel context */        intent_set_disposition(rep, DISP_LOOKUP_EXECD);        /* FIXME: handle raw lookup */#if 0        if (body->valid == OBD_MD_FLID) {                struct mds_body *mds_reply;                int size = sizeof(*mds_reply);                ino_t inum;                // The user requested ONLY the inode number, so do a raw lookup                rc = lustre_pack_reply(req, 1, &size, NULL);                if (rc) {                        CERROR("out of memory\n");                        GOTO(cleanup, rc);                }                rc = dir->i_op->lookup_raw(dir, name, namesize - 1, &inum);                mds_reply = lustre_msg_buf(req->rq_repmsg, offset,                                           sizeof(*mds_reply));                mds_reply->fid1.id = inum;                mds_reply->valid = OBD_MD_FLID;                GOTO(cleanup, rc);        }#endif        if (lustre_handle_is_used(child_lockh)) {                LASSERT(lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT);                resent_req = 1;        }        if (resent_req == 0) {                if (name) {                        OBD_FAIL_TIMEOUT(OBD_FAIL_MDS_RESEND, obd_timeout*2);                        rc = mds_get_parent_child_locked(obd, &obd->u.mds,                                                          &body->fid1,                                                         &parent_lockh,                                                          &dparent, LCK_CR,                                                         MDS_INODELOCK_UPDATE,                                                         name, namesize,                                                         child_lockh, &dchild,                                                         LCK_CR, child_part);                } else {                        /* For revalidate by fid we always take UPDATE lock */                        dchild = mds_fid2locked_dentry(obd, &body->fid2, NULL,                                                       LCK_CR, child_lockh,                                                       NULL, 0, child_part);                        LASSERT(dchild);                        if (IS_ERR(dchild))                                rc = PTR_ERR(dchild);                }                 if (rc)                        GOTO(cleanup, rc);        } else {                struct ldlm_lock *granted_lock;                struct ll_fid child_fid;                struct ldlm_resource *res;                DEBUG_REQ(D_DLMTRACE, req, "resent, not enqueuing new locks");                granted_lock = ldlm_handle2lock(child_lockh);                LASSERTF(granted_lock != NULL, LPU64"/%u lockh "LPX64"\n",                         body->fid1.id, body->fid1.generation,                         child_lockh->cookie);                res = granted_lock->l_resource;                child_fid.id = res->lr_name.name[0];                child_fid.generation = res->lr_name.name[1];                dchild = mds_fid2dentry(&obd->u.mds, &child_fid, NULL);                LASSERT(!IS_ERR(dchild));                LDLM_LOCK_PUT(granted_lock);        }        cleanup_phase = 2; /* dchild, dparent, locks */        if (dchild->d_inode == NULL) {                intent_set_disposition(rep, DISP_LOOKUP_NEG);                /* in the intent case, the policy clears this error:                   the disposition is enough */                GOTO(cleanup, rc = -ENOENT);        } else {                intent_set_disposition(rep, DISP_LOOKUP_POS);        }        if (req->rq_repmsg == NULL) {                rc = mds_getattr_pack_msg(req, dchild->d_inode, offset);                if (rc != 0) {                        CERROR ("mds_getattr_pack_msg: %d\n", rc);                        GOTO (cleanup, rc);                }        }        rc = mds_getattr_internal(obd, dchild, req, body, offset);        GOTO(cleanup, rc); /* returns the lock to the client */ cleanup:        switch (cleanup_phase) {        case 2:                if (resent_req == 0) {                        if (rc && dchild->d_inode)                                ldlm_lock_decref(child_lockh, LCK_CR);                        if (name) {                                ldlm_lock_decref(&parent_lockh, LCK_CR);                                l_dput(dparent);                        }                }                l_dput(dchild);        case 1:                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);        default:                mds_exit_ucred(&uc, mds);                if (!req->rq_packed_final) {                        int rc2 = lustre_pack_reply(req, 1, NULL, NULL);                        if (rc == 0)                                rc = rc2;                        req->rq_status = rc;                }        }        return rc;}static int mds_getattr(struct ptlrpc_request *req, int offset){        struct mds_obd *mds = mds_req2mds(req);        struct obd_device *obd = req->rq_export->exp_obd;        struct lvfs_run_ctxt saved;        struct dentry *de;        struct mds_body *body;        struct lvfs_ucred uc = { NULL, };        int rc = 0;        ENTRY;        OBD_COUNTER_INCREMENT(obd, getattr);        body = lustre_swab_reqbuf(req, offset, sizeof(*body),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -