📄 ost_handler.c
字号:
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Copyright (C) 2001-2003 Cluster File Systems, Inc. * Author: Peter J. Braam <braam@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. * * Storage Target Handling functions * Lustre Object Server Module (OST) * * This server is single threaded at present (but can easily be multi * threaded). For testing and management it is treated as an * obd_device, although it does not export a full OBD method table * (the requests are coming in over the wire, so object target * modules do not have a full method table.) */#ifndef EXPORT_SYMTAB# define EXPORT_SYMTAB#endif#define DEBUG_SUBSYSTEM S_OST#include <linux/module.h>#include <obd_ost.h>#include <lustre_net.h>#include <lustre_dlm.h>#include <lustre_export.h>#include <lustre_debug.h>#include <linux/init.h>#include <lprocfs_status.h>#include <lustre_commit_confd.h>#include <libcfs/list.h>#include <lustre_quota.h>#include "ost_internal.h"static int oss_num_threads;CFS_MODULE_PARM(oss_num_threads, "i", int, 0444, "number of OSS service threads to start");static int ost_num_threads;CFS_MODULE_PARM(ost_num_threads, "i", int, 0444, "number of OST service threads to start (deprecated)");static int oss_num_create_threads;CFS_MODULE_PARM(oss_num_create_threads, "i", int, 0444, "number of OSS create threads to start");void oti_to_request(struct obd_trans_info *oti, struct ptlrpc_request *req){ struct oti_req_ack_lock *ack_lock; int i; if (oti == NULL) return; if (req->rq_repmsg) lustre_msg_set_transno(req->rq_repmsg, oti->oti_transno); req->rq_transno = oti->oti_transno; /* XXX 4 == entries in oti_ack_locks??? */ for (ack_lock = oti->oti_ack_locks, i = 0; i < 4; i++, ack_lock++) { if (!ack_lock->mode) break; /* XXX not even calling target_send_reply in some cases... */ ptlrpc_save_lock (req, &ack_lock->lock, ack_lock->mode); }}static int ost_destroy(struct obd_export *exp, struct ptlrpc_request *req, struct obd_trans_info *oti){ struct ost_body *body, *repbody; int rc, size[2] = { sizeof(struct ptlrpc_body), sizeof(*body) }; ENTRY; body = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*body), lustre_swab_ost_body); if (body == NULL) RETURN(-EFAULT); if (body->oa.o_id == 0) RETURN(-EPROTO); if (lustre_msg_buflen(req->rq_reqmsg, REQ_REC_OFF + 1)) { struct ldlm_request *dlm; dlm = lustre_swab_reqbuf(req, REQ_REC_OFF + 1, sizeof(*dlm), lustre_swab_ldlm_request); if (dlm == NULL) RETURN (-EFAULT); ldlm_request_cancel(req, dlm, 0); } rc = lustre_pack_reply(req, 2, size, NULL); if (rc) RETURN(rc); if (body->oa.o_valid & OBD_MD_FLCOOKIE) oti->oti_logcookies = &body->oa.o_lcookie; repbody = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*repbody)); memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); req->rq_status = obd_destroy(exp, &body->oa, NULL, oti, NULL); RETURN(0);}static int ost_getattr(struct obd_export *exp, struct ptlrpc_request *req){ struct ost_body *body, *repbody; struct obd_info oinfo = { { { 0 } } }; int rc, size[2] = { sizeof(struct ptlrpc_body), sizeof(*body) }; ENTRY; body = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*body), lustre_swab_ost_body); if (body == NULL) RETURN(-EFAULT); rc = lustre_pack_reply(req, 2, size, NULL); if (rc) RETURN(rc); repbody = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*repbody)); memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); oinfo.oi_oa = &repbody->oa; req->rq_status = obd_getattr(exp, &oinfo); RETURN(0);}static int ost_statfs(struct ptlrpc_request *req){ struct obd_statfs *osfs; int rc, size[2] = { sizeof(struct ptlrpc_body), sizeof(*osfs) }; ENTRY; rc = lustre_pack_reply(req, 2, size, NULL); if (rc) RETURN(rc); osfs = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*osfs)); req->rq_status = obd_statfs(req->rq_export->exp_obd, osfs, cfs_time_current_64() - HZ, 0); if (OBD_FAIL_CHECK_ONCE(OBD_FAIL_OST_ENOSPC)) osfs->os_bfree = osfs->os_bavail = 64; if (req->rq_status != 0) CERROR("ost: statfs failed: rc %d\n", req->rq_status); RETURN(0);}static int ost_create(struct obd_export *exp, struct ptlrpc_request *req, struct obd_trans_info *oti){ struct ost_body *body, *repbody; int rc, size[2] = { sizeof(struct ptlrpc_body), sizeof(*repbody) }; ENTRY; body = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*body), lustre_swab_ost_body); if (body == NULL) RETURN(-EFAULT); rc = lustre_pack_reply(req, 2, size, NULL); if (rc) RETURN(rc); repbody = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*repbody)); memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); oti->oti_logcookies = &repbody->oa.o_lcookie; req->rq_status = obd_create(exp, &repbody->oa, NULL, oti); //obd_log_cancel(conn, NULL, 1, oti->oti_logcookies, 0); RETURN(0);}/* * Helper function for ost_punch(): if asked by client, acquire [size, EOF] * lock on the file being truncated. */static int ost_punch_lock_get(struct obd_export *exp, struct obdo *oa, struct lustre_handle *lh){ int flags; struct ldlm_res_id res_id = { .name = { oa->o_id } }; ldlm_policy_data_t policy; __u64 start; __u64 finis; ENTRY; LASSERT(!lustre_handle_is_used(lh)); if (!(oa->o_valid & OBD_MD_FLFLAGS) || !(oa->o_flags & OBD_FL_TRUNCLOCK)) RETURN(0); CDEBUG(D_INODE, "OST-side truncate lock.\n"); start = oa->o_size; finis = start + oa->o_blocks; /* * standard truncate optimization: if file body is completely * destroyed, don't send data back to the server. */ flags = (start == 0) ? LDLM_AST_DISCARD_DATA : 0; policy.l_extent.start = start & CFS_PAGE_MASK; /* * If ->o_blocks is EOF it means "lock till the end of the * file". Otherwise, it's size of a hole being punched (in bytes) */ if (oa->o_blocks == OBD_OBJECT_EOF || finis < start) policy.l_extent.end = OBD_OBJECT_EOF; else policy.l_extent.end = finis | ~CFS_PAGE_MASK; RETURN(ldlm_cli_enqueue_local(exp->exp_obd->obd_namespace, &res_id, LDLM_EXTENT, &policy, LCK_PW, &flags, ldlm_blocking_ast, ldlm_completion_ast, ldlm_glimpse_ast, NULL, 0, NULL, lh));}/* * Helper function for ost_punch(): release lock acquired by * ost_punch_lock_get(), if any. */static void ost_punch_lock_put(struct obd_export *exp, struct obdo *oa, struct lustre_handle *lh){ ENTRY; if (lustre_handle_is_used(lh)) ldlm_lock_decref(lh, LCK_PW); EXIT;}static int ost_punch(struct obd_export *exp, struct ptlrpc_request *req, struct obd_trans_info *oti){ struct obd_info oinfo = { { { 0 } } }; struct ost_body *body, *repbody; int rc, size[2] = { sizeof(struct ptlrpc_body), sizeof(*repbody) }; struct lustre_handle lh = {0,}; ENTRY; /* check that we do support OBD_CONNECT_TRUNCLOCK. */ CLASSERT(OST_CONNECT_SUPPORTED & OBD_CONNECT_TRUNCLOCK); body = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*body), lustre_swab_ost_body); if (body == NULL) RETURN(-EFAULT); oinfo.oi_oa = &body->oa; oinfo.oi_policy.l_extent.start = oinfo.oi_oa->o_size; oinfo.oi_policy.l_extent.end = oinfo.oi_oa->o_blocks; if ((oinfo.oi_oa->o_valid & (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) != (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) RETURN(-EINVAL); rc = lustre_pack_reply(req, 2, size, NULL); if (rc) RETURN(rc); repbody = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*repbody)); rc = ost_punch_lock_get(exp, oinfo.oi_oa, &lh); if (rc == 0) { if (oinfo.oi_oa->o_valid & OBD_MD_FLFLAGS && oinfo.oi_oa->o_flags == OBD_FL_TRUNCLOCK) /* * If OBD_FL_TRUNCLOCK is the only bit set in * ->o_flags, clear OBD_MD_FLFLAGS to avoid falling * through filter_setattr() to filter_iocontrol(). */ oinfo.oi_oa->o_valid &= ~OBD_MD_FLFLAGS; req->rq_status = obd_punch(exp, &oinfo, oti, NULL); ost_punch_lock_put(exp, oinfo.oi_oa, &lh); } repbody->oa = *oinfo.oi_oa; RETURN(rc);}static int ost_sync(struct obd_export *exp, struct ptlrpc_request *req){ struct ost_body *body, *repbody; int rc, size[2] = { sizeof(struct ptlrpc_body), sizeof(*repbody) }; ENTRY; body = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*body), lustre_swab_ost_body); if (body == NULL) RETURN(-EFAULT); rc = lustre_pack_reply(req, 2, size, NULL); if (rc) RETURN(rc); repbody = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*repbody)); memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); req->rq_status = obd_sync(exp, &repbody->oa, NULL, repbody->oa.o_size, repbody->oa.o_blocks); RETURN(0);}static int ost_setattr(struct obd_export *exp, struct ptlrpc_request *req, struct obd_trans_info *oti){ struct ost_body *body, *repbody; int rc, size[2] = { sizeof(struct ptlrpc_body), sizeof(*repbody) }; struct obd_info oinfo = { { { 0 } } }; ENTRY; body = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*body),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -