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

📄 mds_reint.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  linux/mds/mds_reint.c *  Lustre Metadata Server (mds) reintegration routines * *  Copyright (C) 2002-2005 Cluster File Systems, Inc. *   Author: Peter Braam <braam@clusterfs.com> *   Author: Andreas Dilger <adilger@clusterfs.com> *   Author: Phil Schwan <phil@clusterfs.com> * *   This file is part of the Lustre file system, http://www.lustre.org *   Lustre is a trademark of Cluster File Systems, Inc. * *   You may have signed or agreed to another license before downloading *   this software.  If so, you are bound by the terms and conditions *   of that agreement, and the following does not apply to you.  See the *   LICENSE file included with this distribution for more information. * *   If you did not agree to a different license, then this copy of Lustre *   is open source software; you can redistribute it and/or modify it *   under the terms of version 2 of the GNU General Public License as *   published by the Free Software Foundation. * *   In either case, Lustre is distributed in the hope that it will be *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   license text for more details. */#ifndef EXPORT_SYMTAB# define EXPORT_SYMTAB#endif#define DEBUG_SUBSYSTEM S_MDS#include <linux/fs.h>#include <obd_support.h>#include <obd_class.h>#include <obd.h>#include <lustre_lib.h>#include <lustre/lustre_idl.h>#include <lustre_mds.h>#include <lustre_dlm.h>#include <lustre_fsfilt.h>#include <lustre_ucache.h>#include "mds_internal.h"void mds_commit_cb(struct obd_device *obd, __u64 transno, void *data,                   int error){        obd_transno_commit_cb(obd, transno, error);}struct mds_logcancel_data {        struct lov_mds_md      *mlcd_lmm;        int                     mlcd_size;        int                     mlcd_cookielen;        int                     mlcd_eadatalen;        struct llog_cookie      mlcd_cookies[0];};static void mds_cancel_cookies_cb(struct obd_device *obd, __u64 transno,                                  void *cb_data, int error){        struct mds_logcancel_data *mlcd = cb_data;        struct lov_stripe_md *lsm = NULL;        struct llog_ctxt *ctxt;        int rc;        obd_transno_commit_cb(obd, transno, error);        CDEBUG(D_RPCTRACE, "cancelling %d cookies\n",               (int)(mlcd->mlcd_cookielen / sizeof(*mlcd->mlcd_cookies)));        rc = obd_unpackmd(obd->u.mds.mds_osc_exp, &lsm, mlcd->mlcd_lmm,                          mlcd->mlcd_eadatalen);        if (rc < 0) {                CERROR("bad LSM cancelling %d log cookies: rc %d\n",                       (int)(mlcd->mlcd_cookielen/sizeof(*mlcd->mlcd_cookies)),                       rc);        } else {                ///* XXX 0 normally, SENDNOW for debug */);                rc = obd_checkmd(obd->u.mds.mds_osc_exp, obd->obd_self_export,                                 lsm);                if (rc)                        CERROR("Can not revalidate lsm %p \n", lsm);                ctxt = llog_get_context(obd,mlcd->mlcd_cookies[0].lgc_subsys+1);                rc = llog_cancel(ctxt, lsm, mlcd->mlcd_cookielen /                                                sizeof(*mlcd->mlcd_cookies),                                 mlcd->mlcd_cookies, OBD_LLOG_FL_SENDNOW);                llog_ctxt_put(ctxt);                if (rc)                        CERROR("error cancelling %d log cookies: rc %d\n",                               (int)(mlcd->mlcd_cookielen /                                     sizeof(*mlcd->mlcd_cookies)), rc);        }        OBD_FREE(mlcd, mlcd->mlcd_size);}/* Assumes caller has already pushed us into the kernel context. */int mds_finish_transno(struct mds_obd *mds, struct inode *inode, void *handle,                       struct ptlrpc_request *req, int rc, __u32 op_data,                        int force_sync){        struct mds_export_data *med = &req->rq_export->exp_mds_data;        struct mds_client_data *mcd = med->med_mcd;        struct obd_device *obd = req->rq_export->exp_obd;        __u64 transno, prev_transno;        int err;        loff_t off;        int log_pri = D_RPCTRACE;        ENTRY;        if (IS_ERR(handle)) {                LASSERT(rc != 0);                RETURN(rc);        }        /* if the export has already been failed, we have no last_rcvd slot */        if (req->rq_export->exp_failed || obd->obd_fail) {                CWARN("commit transaction for disconnected client %s: rc %d\n",                      req->rq_export->exp_client_uuid.uuid, rc);                if (rc == 0)                        rc = -ENOTCONN;                if (handle)                        GOTO(commit, rc);                RETURN(rc);        }        if (handle == NULL) {                /* if we're starting our own xaction, use our own inode */                inode = mds->mds_rcvd_filp->f_dentry->d_inode;                handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL);                if (IS_ERR(handle)) {                        CERROR("fsfilt_start: %ld\n", PTR_ERR(handle));                        RETURN(PTR_ERR(handle));                }        }        off = med->med_lr_off;        transno = lustre_msg_get_transno(req->rq_reqmsg);        if (rc != 0) {                if (transno != 0) {                        CERROR("%s: replay %s transno "LPU64" failed: rc %d\n",                               obd->obd_name,                               libcfs_nid2str(req->rq_export->exp_connection->c_peer.nid),                               transno, rc);                        transno = 0;                }        } else if (transno == 0) {                spin_lock(&mds->mds_transno_lock);                transno = ++mds->mds_last_transno;                spin_unlock(&mds->mds_transno_lock);        } else {                spin_lock(&mds->mds_transno_lock);                if (transno > mds->mds_last_transno)                        mds->mds_last_transno = transno;                spin_unlock(&mds->mds_transno_lock);        }        req->rq_transno = transno;        lustre_msg_set_transno(req->rq_repmsg, transno);        if (lustre_msg_get_opc(req->rq_reqmsg) == MDS_CLOSE) {                prev_transno = le64_to_cpu(mcd->mcd_last_close_transno);                mcd->mcd_last_close_transno = cpu_to_le64(transno);                mcd->mcd_last_close_xid = cpu_to_le64(req->rq_xid);                mcd->mcd_last_close_result = cpu_to_le32(rc);                mcd->mcd_last_close_data = cpu_to_le32(op_data);        } else {                prev_transno = le64_to_cpu(mcd->mcd_last_transno);                if (((lustre_msg_get_flags(req->rq_reqmsg) &                      (MSG_RESENT | MSG_REPLAY)) == 0) ||                    (transno > prev_transno)) {                        mcd->mcd_last_transno = cpu_to_le64(transno);                        mcd->mcd_last_xid     = cpu_to_le64(req->rq_xid);                        mcd->mcd_last_result  = cpu_to_le32(rc);                        mcd->mcd_last_data    = cpu_to_le32(op_data);                }        }        /* update the server data to not lose the greatest transno. Bug 11125 */        if ((transno == 0) && (prev_transno == mds->mds_last_transno))                mds_update_server_data(obd, 0);        if (off <= 0) {                CERROR("client idx %d has offset %lld\n", med->med_lr_idx, off);                err = -EINVAL;        } else {                struct obd_export *exp = req->rq_export;                if (!force_sync)                        force_sync = fsfilt_add_journal_cb(exp->exp_obd,transno,                                                           handle, mds_commit_cb,                                                          NULL);                err = fsfilt_write_record(obd, mds->mds_rcvd_filp, mcd,                                          sizeof(*mcd), &off,                                           force_sync | exp->exp_need_sync);                if (force_sync)                        mds_commit_cb(obd, transno, NULL, err);        }        if (err) {                log_pri = D_ERROR;                if (rc == 0)                        rc = err;        }        DEBUG_REQ(log_pri, req,                  "wrote trans #"LPU64" rc %d client %s at idx %u: err = %d",                  transno, rc, mcd->mcd_uuid, med->med_lr_idx, err);        err = mds_lov_write_objids(obd);        if (err) {                log_pri = D_ERROR;                if (rc == 0)                        rc = err;        }        CDEBUG(log_pri, "wrote objids: err = %d\n", err);commit:        err = fsfilt_commit(obd, inode, handle, 0);        if (err) {                CERROR("error committing transaction: %d\n", err);                if (!rc)                        rc = err;        }        RETURN(rc);}/* this gives the same functionality as the code between * sys_chmod and inode_setattr * chown_common and inode_setattr * utimes and inode_setattr */int mds_fix_attr(struct inode *inode, struct mds_update_record *rec){        time_t now = CURRENT_SECONDS;        struct iattr *attr = &rec->ur_iattr;        unsigned int ia_valid = attr->ia_valid;        int error;        ENTRY;        if (ia_valid & ATTR_RAW)                attr->ia_valid &= ~ATTR_RAW;        if (!(ia_valid & ATTR_CTIME_SET))                LTIME_S(attr->ia_ctime) = now;        else                attr->ia_valid &= ~ATTR_CTIME_SET;        if (!(ia_valid & ATTR_ATIME_SET))                LTIME_S(attr->ia_atime) = now;        if (!(ia_valid & ATTR_MTIME_SET))                LTIME_S(attr->ia_mtime) = now;        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))                RETURN((attr->ia_valid & ~ATTR_ATTR_FLAG) ? -EPERM : 0);        /* times */        if ((ia_valid & (ATTR_MTIME|ATTR_ATIME)) == (ATTR_MTIME|ATTR_ATIME)) {                if (current->fsuid != inode->i_uid &&                    (error = ll_permission(inode, MAY_WRITE, NULL)) != 0)                        RETURN(error);        }        if (ia_valid & ATTR_SIZE &&            /* NFSD hack for open(O_CREAT|O_TRUNC)=mknod+truncate (bug 5781) */            !(rec->ur_uc.luc_fsuid == inode->i_uid &&              ia_valid & MDS_OPEN_OWNEROVERRIDE)) {                if ((error = ll_permission(inode, MAY_WRITE, NULL)) != 0)                        RETURN(error);        }        if (ia_valid & (ATTR_UID | ATTR_GID)) {                /* chown */                error = -EPERM;                if (IS_IMMUTABLE(inode) || IS_APPEND(inode))                        RETURN(-EPERM);                if (attr->ia_uid == (uid_t) -1)                        attr->ia_uid = inode->i_uid;                if (attr->ia_gid == (gid_t) -1)                        attr->ia_gid = inode->i_gid;                if (!(ia_valid & ATTR_MODE))                        attr->ia_mode = inode->i_mode;                /*                 * If the user or group of a non-directory has been                 * changed by a non-root user, remove the setuid bit.                 * 19981026 David C Niemi <niemi@tux.org>                 *                 * Changed this to apply to all users, including root,                 * to avoid some races. This is the behavior we had in                 * 2.0. The check for non-root was definitely wrong                 * for 2.2 anyway, as it should have been using                 * CAP_FSETID rather than fsuid -- 19990830 SD.                 */                if ((inode->i_mode & S_ISUID) == S_ISUID &&                    !S_ISDIR(inode->i_mode)) {                        attr->ia_mode &= ~S_ISUID;                        attr->ia_valid |= ATTR_MODE;                }                /*                 * Likewise, if the user or group of a non-directory                 * has been changed by a non-root user, remove the                 * setgid bit UNLESS there is no group execute bit                 * (this would be a file marked for mandatory                 * locking).  19981026 David C Niemi <niemi@tux.org>                 *                 * Removed the fsuid check (see the comment above) --                 * 19990830 SD.                 */                if (((inode->i_mode & (S_ISGID | S_IXGRP)) ==                     (S_ISGID | S_IXGRP)) && !S_ISDIR(inode->i_mode)) {                        attr->ia_mode &= ~S_ISGID;                        attr->ia_valid |= ATTR_MODE;                }

⌨️ 快捷键说明

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