/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * lustre/mdt/mdt_lib.c * Lustre Metadata Target (mdt) request unpacking helper. * * Copyright (c) 2006 Cluster File Systems, Inc. * Author: Peter Braam * Author: Andreas Dilger * Author: Phil Schwan * Author: Mike Shaver * Author: Nikita Danilov * Author: Huang Hua * * * 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 "mdt_internal.h" /* if object is dying, pack the lov/llog data, * parameter info->mti_attr should be valid at this point! */ int mdt_handle_last_unlink(struct mdt_thread_info *info, struct mdt_object *mo, const struct req_format *fmt) { struct mdt_body *body; struct lu_attr *la = &info->mti_attr.ma_attr; int rc = 0; ENTRY; body = req_capsule_server_get(&info->mti_pill, &RMF_MDT_BODY); mdt_pack_attr2body(body, la, mdt_object_fid(mo)); /* if last unlinked object reference so client should destroy ost * objects*/ if (S_ISREG(la->la_mode) && la->la_nlink == 0 && mo->mot_header.loh_ref == 1) { struct lov_mds_md *lmm; /* reply should contains more data, * * so we need to extend it */ req_capsule_extend(&info->mti_pill, fmt); lmm = req_capsule_server_get(&info->mti_pill, &RMF_MDT_MD); /*TODO: lmm data & llog cookie * rc = mo_xattr_get(info->mti_ctxt, mdt_object_child(o), * lmm, info->mti_mdt->mdt_max_mdsize, * MDS_LOV_MD_NAME); * if (rc >= 0) { * if (S_ISDIR(info->mti_attr.la_mode)) * body->valid |= OBD_MD_FLDIREA; * else * body->valid |= OBD_MD_FLEASIZE; * body->eadatasize = rc; * rc = 0; * } */ } RETURN(rc); } /* unpacking */ static int mdt_setattr_unpack(struct mdt_thread_info *info) { struct mdt_rec_setattr *rec; struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_reint_record *rr = &info->mti_rr; struct req_capsule *pill = &info->mti_pill; ENTRY; rec = req_capsule_client_get(pill, &RMF_REC_SETATTR); if (rec == NULL) RETURN(-EFAULT); rr->rr_fid1 = &rec->sa_fid; attr->la_valid = rec->sa_valid; attr->la_mode = rec->sa_mode; attr->la_uid = rec->sa_uid; attr->la_gid = rec->sa_gid; attr->la_size = rec->sa_size; attr->la_flags = rec->sa_attr_flags; attr->la_ctime = rec->sa_ctime; attr->la_atime = rec->sa_atime; attr->la_mtime = rec->sa_mtime; if (req_capsule_field_present(pill, &RMF_EADATA)) { rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA); rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA, RCL_CLIENT); } if (req_capsule_field_present(pill, &RMF_LOGCOOKIES)) { rr->rr_logcookies = req_capsule_client_get(pill, &RMF_LOGCOOKIES); rr->rr_logcookielen = req_capsule_get_size(pill, &RMF_LOGCOOKIES, RCL_CLIENT); } RETURN(0); } static int mdt_create_unpack(struct mdt_thread_info *info) { struct mdt_rec_create *rec; struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_reint_record *rr = &info->mti_rr; struct req_capsule *pill = &info->mti_pill; int result = 0; ENTRY; rec = req_capsule_client_get(pill, &RMF_REC_CREATE); if (rec != NULL) { rr->rr_fid1 = &rec->cr_fid1; rr->rr_fid2 = &rec->cr_fid2; attr->la_mode = rec->cr_mode; attr->la_rdev = rec->cr_rdev; attr->la_uid = rec->cr_fsuid; attr->la_gid = rec->cr_fsgid; attr->la_flags = rec->cr_flags; attr->la_ctime = rec->cr_time; attr->la_mtime = rec->cr_time; rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); if (rr->rr_name) { if (req_capsule_field_present(pill, &RMF_SYMTGT)) { rr->rr_tgt = req_capsule_client_get(pill, &RMF_SYMTGT); if (rr->rr_tgt == NULL) result = -EFAULT; } } else result = -EFAULT; } else result = -EFAULT; RETURN(result); } static int mdt_link_unpack(struct mdt_thread_info *info) { struct mdt_rec_link *rec; struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_reint_record *rr = &info->mti_rr; struct req_capsule *pill = &info->mti_pill; int result = 0; ENTRY; rec = req_capsule_client_get(pill, &RMF_REC_LINK); if (rec != NULL) { attr->la_uid = rec->lk_fsuid; attr->la_gid = rec->lk_fsgid; rr->rr_fid1 = &rec->lk_fid1; rr->rr_fid2 = &rec->lk_fid2; attr->la_ctime = rec->lk_time; attr->la_mtime = rec->lk_time; rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); if (rr->rr_name == NULL) result = -EFAULT; } else result = -EFAULT; RETURN(result); } static int mdt_unlink_unpack(struct mdt_thread_info *info) { struct mdt_rec_unlink *rec; struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_reint_record *rr = &info->mti_rr; struct req_capsule *pill = &info->mti_pill; int result = 0; ENTRY; rec = req_capsule_client_get(pill, &RMF_REC_UNLINK); if (rec != NULL) { attr->la_uid = rec->ul_fsuid; attr->la_gid = rec->ul_fsgid; rr->rr_fid1 = &rec->ul_fid1; rr->rr_fid2 = &rec->ul_fid2; attr->la_ctime = rec->ul_time; attr->la_mtime = rec->ul_time; attr->la_mode = rec->ul_mode; rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); if (rr->rr_name == NULL) result = -EFAULT; } else result = -EFAULT; RETURN(result); } static int mdt_rename_unpack(struct mdt_thread_info *info) { struct mdt_rec_rename *rec; struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_reint_record *rr = &info->mti_rr; struct req_capsule *pill = &info->mti_pill; int result = 0; ENTRY; rec = req_capsule_client_get(pill, &RMF_REC_RENAME); if (rec != NULL) { attr->la_uid = rec->rn_fsuid; attr->la_gid = rec->rn_fsgid; rr->rr_fid1 = &rec->rn_fid1; rr->rr_fid2 = &rec->rn_fid2; attr->la_ctime = rec->rn_time; attr->la_mtime = rec->rn_time; rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); rr->rr_tgt = req_capsule_client_get(pill, &RMF_SYMTGT); if (rr->rr_name == NULL || rr->rr_tgt == NULL) result = -EFAULT; } else result = -EFAULT; RETURN(result); } static int mdt_open_unpack(struct mdt_thread_info *info) { struct mdt_rec_create *rec; struct lu_attr *attr = &info->mti_attr.ma_attr; struct req_capsule *pill = &info->mti_pill; struct mdt_reint_record *rr = &info->mti_rr; int result; ENTRY; rec = req_capsule_client_get(pill, &RMF_REC_CREATE); if (rec != NULL) { rr->rr_fid1 = &rec->cr_fid1; rr->rr_fid2 = &rec->cr_fid2; attr->la_mode = rec->cr_mode; attr->la_flags = rec->cr_flags; rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); if (rr->rr_name == NULL) result = -EFAULT; else result = 0; } else result = -EFAULT; RETURN(result); } typedef int (*reint_unpacker)(struct mdt_thread_info *info); static reint_unpacker mdt_reint_unpackers[REINT_MAX] = { [REINT_SETATTR] = mdt_setattr_unpack, [REINT_CREATE] = mdt_create_unpack, [REINT_LINK] = mdt_link_unpack, [REINT_UNLINK] = mdt_unlink_unpack, [REINT_RENAME] = mdt_rename_unpack, [REINT_OPEN] = mdt_open_unpack }; int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op) { int rc; ENTRY; if (op < REINT_MAX && mdt_reint_unpackers[op] != NULL) { info->mti_rr.rr_opcode = op; rc = mdt_reint_unpackers[op](info); } else { CERROR("Unexpected opcode %d\n", op); rc = -EFAULT; } RETURN(rc); }