📄 mds_reint.c
字号:
/* -*- 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 + -