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

📄 super.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
        obddev = sbi->ll_mdc_exp->exp_obd;        res_id.name[0] = llu_i2stat(inode)->st_ino;        res_id.name[1] = lli->lli_st_generation;        CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id.name[0]);        flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_CBPENDING | LDLM_FL_TEST_LOCK;        if (ldlm_lock_match(obddev->obd_namespace, flags, &res_id, LDLM_IBITS,                            &policy, LCK_CR|LCK_CW|LCK_PR|LCK_PW, &lockh)) {                RETURN(1);        }        RETURN(0);}static int llu_inode_revalidate(struct inode *inode){        struct lov_stripe_md *lsm = NULL;        ENTRY;        if (!inode) {                CERROR("REPORT THIS LINE TO PETER\n");                RETURN(0);        }        if (!llu_have_md_lock(inode, MDS_INODELOCK_UPDATE)) {                struct lustre_md md;                struct ptlrpc_request *req = NULL;                struct llu_sb_info *sbi = llu_i2sbi(inode);                struct ll_fid fid;                unsigned long valid = OBD_MD_FLGETATTR;                int rc, ealen = 0;                /* Why don't we update all valid MDS fields here, if we're                 * doing an RPC anyways?  -phil */                if (S_ISREG(llu_i2stat(inode)->st_mode)) {                        ealen = obd_size_diskmd(sbi->ll_osc_exp, NULL);                        valid |= OBD_MD_FLEASIZE;                }                ll_inode2fid(&fid, inode);                rc = mdc_getattr(sbi->ll_mdc_exp, &fid, valid, ealen, &req);                if (rc) {                        CERROR("failure %d inode %llu\n", rc,                               (long long)llu_i2stat(inode)->st_ino);                        RETURN(-abs(rc));                }                rc = mdc_req2lustre_md(req, REPLY_REC_OFF, sbi->ll_osc_exp,&md);                /* XXX Too paranoid? */                if (((md.body->valid ^ valid) & OBD_MD_FLEASIZE) &&                    !((md.body->valid & OBD_MD_FLNLINK) &&                      (md.body->nlink == 0))) {                        CERROR("Asked for %s eadata but got %s (%d)\n",                               (valid & OBD_MD_FLEASIZE) ? "some" : "no",                               (md.body->valid & OBD_MD_FLEASIZE) ? "some":"none",                                md.body->eadatasize);                }                if (rc) {                        ptlrpc_req_finished(req);                        RETURN(rc);                }                llu_update_inode(inode, md.body, md.lsm);                if (md.lsm != NULL && llu_i2info(inode)->lli_smd != md.lsm)                        obd_free_memmd(sbi->ll_osc_exp, &md.lsm);                if (md.body->valid & OBD_MD_FLSIZE)                        set_bit(LLI_F_HAVE_MDS_SIZE_LOCK,                                &llu_i2info(inode)->lli_flags);                ptlrpc_req_finished(req);        }        lsm = llu_i2info(inode)->lli_smd;        if (!lsm)       /* object not yet allocated, don't validate size */                RETURN(0);        /* ll_glimpse_size will prefer locally cached writes if they extend         * the file */        RETURN(llu_glimpse_size(inode));}static void copy_stat_buf(struct inode *ino, struct intnl_stat *b){        *b = *llu_i2stat(ino);}static int llu_iop_getattr(struct pnode *pno,                           struct inode *ino,                           struct intnl_stat *b){        int rc;        ENTRY;        liblustre_wait_event(0);        if (!ino) {                LASSERT(pno);                LASSERT(pno->p_base->pb_ino);                ino = pno->p_base->pb_ino;        } else {                LASSERT(!pno || pno->p_base->pb_ino == ino);        }        /* libsysio might call us directly without intent lock,         * we must re-fetch the attrs here         */        rc = llu_inode_revalidate(ino);        if (!rc) {                copy_stat_buf(ino, b);                LASSERT(!llu_i2info(ino)->lli_it);        }        liblustre_wait_event(0);        RETURN(rc);}static int null_if_equal(struct ldlm_lock *lock, void *data){        if (data == lock->l_ast_data) {                lock->l_ast_data = NULL;                if (lock->l_req_mode != lock->l_granted_mode)                        LDLM_ERROR(lock,"clearing inode with ungranted lock\n");        }        return LDLM_ITER_CONTINUE;}void llu_clear_inode(struct inode *inode){        struct ll_fid fid;        struct llu_inode_info *lli = llu_i2info(inode);        struct llu_sb_info *sbi = llu_i2sbi(inode);        ENTRY;        CDEBUG(D_VFSTRACE, "VFS Op:inode=%llu/%lu(%p)\n",               (long long)llu_i2stat(inode)->st_ino, lli->lli_st_generation,               inode);        ll_inode2fid(&fid, inode);        clear_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &(lli->lli_flags));        mdc_change_cbdata(sbi->ll_mdc_exp, &fid, null_if_equal, inode);        if (lli->lli_smd)                obd_change_cbdata(sbi->ll_osc_exp, lli->lli_smd,                                  null_if_equal, inode);        if (lli->lli_smd) {                obd_free_memmd(sbi->ll_osc_exp, &lli->lli_smd);                lli->lli_smd = NULL;        }        if (lli->lli_symlink_name) {                OBD_FREE(lli->lli_symlink_name,                         strlen(lli->lli_symlink_name) + 1);                lli->lli_symlink_name = NULL;        }        EXIT;}void llu_iop_gone(struct inode *inode){        struct llu_inode_info *lli = llu_i2info(inode);        ENTRY;        liblustre_wait_event(0);        llu_clear_inode(inode);        OBD_FREE(lli, sizeof(*lli));        EXIT;}static int inode_setattr(struct inode * inode, struct iattr * attr){        unsigned int ia_valid = attr->ia_valid;        struct intnl_stat *st = llu_i2stat(inode);        int error = 0;        /*         * inode_setattr() is only ever invoked with ATTR_SIZE (by         * llu_setattr_raw()) when file has no bodies. Check this.         */        LASSERT(ergo(ia_valid & ATTR_SIZE, llu_i2info(inode)->lli_smd == NULL));        if (ia_valid & ATTR_SIZE)                st->st_size = attr->ia_size;        if (ia_valid & ATTR_UID)                st->st_uid = attr->ia_uid;        if (ia_valid & ATTR_GID)                st->st_gid = attr->ia_gid;        if (ia_valid & ATTR_ATIME)                st->st_atime = attr->ia_atime;        if (ia_valid & ATTR_MTIME)                st->st_mtime = attr->ia_mtime;        if (ia_valid & ATTR_CTIME)                st->st_ctime = attr->ia_ctime;        if (ia_valid & ATTR_MODE) {                st->st_mode = attr->ia_mode;                if (!in_group_p(st->st_gid) && !capable(CAP_FSETID))                        st->st_mode &= ~S_ISGID;        }        /* mark_inode_dirty(inode); */        return error;}/* If this inode has objects allocated to it (lsm != NULL), then the OST * object(s) determine the file size and mtime.  Otherwise, the MDS will * keep these values until such a time that objects are allocated for it. * We do the MDS operations first, as it is checking permissions for us. * We don't to the MDS RPC if there is nothing that we want to store there, * otherwise there is no harm in updating mtime/atime on the MDS if we are * going to do an RPC anyways. * * If we are doing a truncate, we will send the mtime and ctime updates * to the OST with the punch RPC, otherwise we do an explicit setattr RPC. * I don't believe it is possible to get e.g. ATTR_MTIME_SET and ATTR_SIZE * at the same time. */int llu_setattr_raw(struct inode *inode, struct iattr *attr){        struct lov_stripe_md *lsm = llu_i2info(inode)->lli_smd;        struct llu_sb_info *sbi = llu_i2sbi(inode);        struct intnl_stat *st = llu_i2stat(inode);        struct ptlrpc_request *request = NULL;        struct mdc_op_data op_data;        int ia_valid = attr->ia_valid;        int rc = 0;        ENTRY;        CDEBUG(D_VFSTRACE, "VFS Op:inode=%llu\n", (long long)st->st_ino);        if (ia_valid & ATTR_SIZE) {                if (attr->ia_size > ll_file_maxbytes(inode)) {                        CDEBUG(D_INODE, "file too large %llu > "LPU64"\n",                               (long long)attr->ia_size,                               ll_file_maxbytes(inode));                        RETURN(-EFBIG);                }                attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;        }        /* We mark all of the fields "set" so MDS/OST does not re-set them */        if (attr->ia_valid & ATTR_CTIME) {                attr->ia_ctime = CURRENT_TIME;                attr->ia_valid |= ATTR_CTIME_SET;        }        if (!(ia_valid & ATTR_ATIME_SET) && (attr->ia_valid & ATTR_ATIME)) {                attr->ia_atime = CURRENT_TIME;                attr->ia_valid |= ATTR_ATIME_SET;        }        if (!(ia_valid & ATTR_MTIME_SET) && (attr->ia_valid & ATTR_MTIME)) {                attr->ia_mtime = CURRENT_TIME;                attr->ia_valid |= ATTR_MTIME_SET;        }        if ((attr->ia_valid & ATTR_CTIME) && !(attr->ia_valid & ATTR_MTIME)) {                /* To avoid stale mtime on mds, obtain it from ost and send                    to mds. */                rc = llu_glimpse_size(inode);                if (rc)                         RETURN(rc);                                attr->ia_valid |= ATTR_MTIME_SET | ATTR_MTIME;                attr->ia_mtime = inode->i_stbuf.st_mtime;        }        if (attr->ia_valid & (ATTR_MTIME | ATTR_CTIME))                CDEBUG(D_INODE, "setting mtime %lu, ctime %lu, now = %lu\n",                       LTIME_S(attr->ia_mtime), LTIME_S(attr->ia_ctime),                       LTIME_S(CURRENT_TIME));        if (lsm)                attr->ia_valid &= ~ATTR_SIZE;        /* If only OST attributes being set on objects, don't do MDS RPC.         * In that case, we need to check permissions and update the local         * inode ourselves so we can call obdo_from_inode() always. */        if (ia_valid & (lsm ? ~(ATTR_SIZE | ATTR_FROM_OPEN | ATTR_RAW) : ~0)) {                struct lustre_md md;                llu_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);                rc = mdc_setattr(sbi->ll_mdc_exp, &op_data,                                  attr, NULL, 0, NULL, 0, &request);                if (rc) {                        ptlrpc_req_finished(request);                        if (rc != -EPERM && rc != -EACCES)                                CERROR("mdc_setattr fails: rc = %d\n", rc);                        RETURN(rc);                }                rc = mdc_req2lustre_md(request, REPLY_REC_OFF, sbi->ll_osc_exp,                                       &md);                if (rc) {                        ptlrpc_req_finished(request);                        RETURN(rc);                }                /* We call inode_setattr to adjust timestamps.                 * If there is at least some data in file, we cleared ATTR_SIZE                 * above to avoid invoking vmtruncate, otherwise it is important                 * to call vmtruncate in inode_setattr to update inode->i_size                 * (bug 6196) */                inode_setattr(inode, attr);                llu_update_inode(inode, md.body, md.lsm);                ptlrpc_req_finished(request);                if (!lsm || !S_ISREG(st->st_mode)) {                        CDEBUG(D_INODE, "no lsm: not setting attrs on OST\n");                        RETURN(0);                }        } else {                /* The OST doesn't check permissions, but the alternative is                 * a gratuitous RPC to the MDS.  We already rely on the client                 * to do read/write/truncate permission checks, so is mtime OK?                 */                if (ia_valid & (ATTR_MTIME | ATTR_ATIME)) {                        /* from sys_utime() */                        if (!(ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET))) {                                if (current->fsuid != st->st_uid &&                                    (rc = ll_permission(inode, MAY_WRITE)) != 0)                                        RETURN(rc);                        } else {                                /* from inode_change_ok() */                                if (current->fsuid != st->st_uid &&                                    !capable(CAP_FOWNER))                                        RETURN(-EPERM);                        }                }                /* Won't invoke llu_vmtruncate(), as we already cleared                 * ATTR_SIZE */                inode_setattr(inode, attr);        }        if (ia_valid & ATTR_SIZE) {                ldlm_policy_data_t policy = { .l_extent = {attr->ia_size,                                                           OBD_OBJECT_EOF} };                struct lustre_handle lockh = { 0, };                struct lustre_handle match_lockh = { 0, };                int err;                int flags = LDLM_FL_TEST_LOCK; /* for assertion check below */                int lock_mode;                obd_flag obd_flags;                /* check that there are no matching locks */                LASSERT(obd_match(sbi->ll_osc_exp, lsm, LDLM_EXTENT, &policy,                                  LCK_PW, &flags, inode, &match_lockh) <= 0);                /* XXX when we fix the AST intents to pass the discard-range                 * XXX extent, make ast_flags always LDLM_AST_DISCARD_DATA                 * XXX here. */                flags = (attr->ia_size == 0) ? LDLM_AST_DISCARD_DATA : 0;                if (sbi->ll_lco.lco_flags & OBD_CONNECT_TRUNCLOCK) {                        lock_mode = LCK_NL;                        obd_flags = OBD_FL_TRUNCLOCK;                        CDEBUG(D_INODE, "delegating locking to the OST");                } else {                        lock_mode = LCK_PW;                        obd_flags = 0;                }                /* with lock_mode == LK_NL no lock is taken. */                rc = llu_extent_lock(NULL, inode, lsm, lock_mode, &policy,                                     &lockh, flags);                if (rc != ELDLM_OK) {                        if (rc > 0)                                RETURN(-ENOLCK);                        RETURN(rc);                }                rc = llu_vmtruncate(inode, attr->ia_size, obd_flags);                /* unlock now as we don't mind others file lockers racing with                 * the mds updates below? */                err = llu_extent_unlock(NULL, inode, lsm, lock_mode, &lockh);                if (err) {                        CERROR("llu_extent_unlock failed: %d\n", err);                        if (!rc)                                rc = err;                }        } else if (ia_valid & (ATTR_MTIME | ATTR_MTIME_SET)) {                struct obd_info oinfo = { { { 0 } } };                struct obdo oa;                CDEBUG(D_INODE, "set mtime on OST inode %llu to %lu\n",                       (long long)st->st_ino, LTIME_S(attr->ia_mtime));                oa.o_id = lsm->lsm_object_id;                oa.o_valid = OBD_MD_FLID;                obdo_from_inode(&oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |

⌨️ 快捷键说明

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