echo_client.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 1,511 行 · 第 1/4 页

C
1,511
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  Copyright (c) 2001-2003 Cluster File Systems, Inc. * *   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. */#define DEBUG_SUBSYSTEM S_ECHO#ifdef __KERNEL__#include <libcfs/libcfs.h>#else#include <liblustre.h>#endif#include <obd.h>#include <obd_support.h>#include <obd_class.h>#include <obd_echo.h>#include <lustre_debug.h>#include <lprocfs_status.h>static obd_id last_object_id;#if 0static voidecho_printk_object (char *msg, struct ec_object *eco){        struct lov_stripe_md *lsm = eco->eco_lsm;        int                   i;        printk (KERN_INFO "Lustre: %s: object %p: "LPX64", refs %d%s: "LPX64                "=%u!%u\n", msg, eco, eco->eco_id, eco->eco_refcount,                eco->eco_deleted ? "(deleted) " : "",                lsm->lsm_object_id, lsm->lsm_stripe_size,                lsm->lsm_stripe_count);        for (i = 0; i < lsm->lsm_stripe_count; i++)                printk (KERN_INFO "Lustre:   @%2u:"LPX64"\n",                        lsm->lsm_oinfo[i].loi_ost_idx,                        lsm->lsm_oinfo[i].loi_id);}#endifstatic struct ec_object *echo_find_object_locked (struct obd_device *obd, obd_id id){        struct echo_client_obd *ec = &obd->u.echo_client;        struct ec_object       *eco = NULL;        struct list_head       *el;        list_for_each (el, &ec->ec_objects) {                eco = list_entry (el, struct ec_object, eco_obj_chain);                if (eco->eco_id == id)                        return (eco);        }        return (NULL);}static intecho_copyout_lsm (struct lov_stripe_md *lsm, void *_ulsm, int ulsm_nob){        struct lov_stripe_md *ulsm = _ulsm;        int nob, i;        nob = offsetof (struct lov_stripe_md, lsm_oinfo[lsm->lsm_stripe_count]);        if (nob > ulsm_nob)                return (-EINVAL);        if (copy_to_user (ulsm, lsm, sizeof(ulsm)))                return (-EFAULT);        for (i = 0; i < lsm->lsm_stripe_count; i++) {                if (copy_to_user (ulsm->lsm_oinfo[i], lsm->lsm_oinfo[i],                                  sizeof(lsm->lsm_oinfo[0])))                        return (-EFAULT);        }        return (0);}static intecho_copyin_lsm (struct obd_device *obd, struct lov_stripe_md *lsm,                 void *ulsm, int ulsm_nob){        struct echo_client_obd *ec = &obd->u.echo_client;        int                     i;        if (ulsm_nob < sizeof (*lsm))                return (-EINVAL);        if (copy_from_user (lsm, ulsm, sizeof (*lsm)))                return (-EFAULT);        if (lsm->lsm_stripe_count > ec->ec_nstripes ||            lsm->lsm_magic != LOV_MAGIC ||            (lsm->lsm_stripe_size & (~CFS_PAGE_MASK)) != 0 ||            ((__u64)lsm->lsm_stripe_size * lsm->lsm_stripe_count > ~0UL))                return (-EINVAL);        for (i = 0; i < lsm->lsm_stripe_count; i++) {                if (copy_from_user(lsm->lsm_oinfo[i],                                   ((struct lov_stripe_md *)ulsm)->lsm_oinfo[i],                                   sizeof(lsm->lsm_oinfo[0])))                        return (-EFAULT);        }        return (0);}static struct ec_object *echo_allocate_object (struct obd_device *obd){        struct echo_client_obd *ec = &obd->u.echo_client;        struct ec_object       *eco;        int rc;        OBD_ALLOC(eco, sizeof (*eco));        if (eco == NULL)                return NULL;        rc = obd_alloc_memmd(ec->ec_exp, &eco->eco_lsm);        if (rc < 0) {                OBD_FREE(eco, sizeof (*eco));                return NULL;        }        eco->eco_device = obd;        eco->eco_deleted = 0;        eco->eco_refcount = 0;        eco->eco_lsm->lsm_magic = LOV_MAGIC;        /* leave stripe count 0 by default */        return (eco);}static voidecho_free_object (struct ec_object *eco){        struct obd_device      *obd = eco->eco_device;        struct echo_client_obd *ec = &obd->u.echo_client;        LASSERT (eco->eco_refcount == 0);        if (!eco->eco_lsm)                 CERROR("No object %s\n", obd->obd_name);        else                 obd_free_memmd(ec->ec_exp, &eco->eco_lsm);        OBD_FREE (eco, sizeof (*eco));}static int echo_create_object(struct obd_device *obd, int on_target,                              struct obdo *oa, void *ulsm, int ulsm_nob,                              struct obd_trans_info *oti){        struct echo_client_obd *ec = &obd->u.echo_client;        struct ec_object       *eco2;        struct ec_object       *eco;        struct lov_stripe_md   *lsm;        int                     rc;        int                     i, idx;        if ((oa->o_valid & OBD_MD_FLID) == 0 && /* no obj id */            (on_target ||                       /* set_stripe */             ec->ec_nstripes != 0)) {           /* LOV */                CERROR ("No valid oid\n");                return (-EINVAL);        }        if (ulsm != NULL) {                eco = echo_allocate_object (obd);                if (eco == NULL)                         return (-ENOMEM);                lsm = eco->eco_lsm;                rc = echo_copyin_lsm (obd, lsm, ulsm, ulsm_nob);                if (rc != 0)                        goto failed;                /* setup object ID here for !on_target and LOV hint */                if ((oa->o_valid & OBD_MD_FLID) != 0)                        eco->eco_id = lsm->lsm_object_id = oa->o_id;                if (lsm->lsm_stripe_count == 0)                        lsm->lsm_stripe_count = ec->ec_nstripes;                if (lsm->lsm_stripe_size == 0)                        lsm->lsm_stripe_size = CFS_PAGE_SIZE;                idx = ll_rand();                /* setup stripes: indices + default ids if required */                for (i = 0; i < lsm->lsm_stripe_count; i++) {                        if (lsm->lsm_oinfo[i]->loi_id == 0)                                lsm->lsm_oinfo[i]->loi_id = lsm->lsm_object_id;                        lsm->lsm_oinfo[i]->loi_ost_idx =                                (idx + i) % ec->ec_nstripes;                }        } else {                OBD_ALLOC(eco, sizeof(*eco));                if (!eco)                         return (-ENOMEM);                eco->eco_device = obd;                lsm = NULL;        }        if (oa->o_id == 0)                oa->o_id = ++last_object_id;        if (on_target) {                oa->o_gr = FILTER_GROUP_ECHO;                oa->o_valid |= OBD_MD_FLGROUP;                rc = obd_create(ec->ec_exp, oa, &lsm, oti);                if (rc != 0)                        goto failed;                /* See what object ID we were given */                eco->eco_id = oa->o_id = lsm->lsm_object_id;                oa->o_valid |= OBD_MD_FLID;                LASSERT(eco->eco_lsm == NULL || eco->eco_lsm == lsm);                eco->eco_lsm = lsm;        }        spin_lock (&ec->ec_lock);        eco2 = echo_find_object_locked (obd, oa->o_id);        if (eco2 != NULL) {                     /* conflict */                spin_unlock (&ec->ec_lock);                CERROR ("Can't create object id "LPX64": id already exists%s\n",                        oa->o_id, on_target ? " (undoing create)" : "");                if (on_target)                        obd_destroy(ec->ec_exp, oa, lsm, oti, NULL);                rc = -EEXIST;                goto failed;        }        list_add (&eco->eco_obj_chain, &ec->ec_objects);        spin_unlock (&ec->ec_lock);        CDEBUG (D_INFO,                "created %p: "LPX64"=%u#%u@%u refs %d del %d\n",                eco, eco->eco_id,                eco->eco_lsm->lsm_stripe_size,                eco->eco_lsm->lsm_stripe_count,                eco->eco_lsm->lsm_oinfo[0]->loi_ost_idx,                eco->eco_refcount, eco->eco_deleted);        return (0); failed:        echo_free_object (eco);        if (rc)                 CERROR("%s: err %d on create\n", obd->obd_name, rc);        return (rc);}static intecho_get_object (struct ec_object **ecop, struct obd_device *obd,                 struct obdo *oa){        struct echo_client_obd *ec = &obd->u.echo_client;        struct ec_object       *eco;        struct ec_object       *eco2;        int                     rc;        if ((oa->o_valid & OBD_MD_FLID) == 0 ||            oa->o_id == 0)                      /* disallow use of object id 0 */        {                CERROR ("No valid oid\n");                return (-EINVAL);        }        spin_lock (&ec->ec_lock);        eco = echo_find_object_locked (obd, oa->o_id);        if (eco != NULL) {                if (eco->eco_deleted) {           /* being deleted */                        spin_unlock(&ec->ec_lock);/* (see comment in cleanup) */                        return (-EAGAIN);                }                eco->eco_refcount++;                spin_unlock (&ec->ec_lock);                *ecop = eco;                CDEBUG (D_INFO,                        "found %p: "LPX64"=%u#%u@%u refs %d del %d\n",                        eco, eco->eco_id,                        eco->eco_lsm->lsm_stripe_size,                        eco->eco_lsm->lsm_stripe_count,                        eco->eco_lsm->lsm_oinfo[0]->loi_ost_idx,                        eco->eco_refcount, eco->eco_deleted);                return (0);        }        spin_unlock (&ec->ec_lock);        if (ec->ec_nstripes != 0)               /* striping required */                return (-ENOENT);        eco = echo_allocate_object (obd);        if (eco == NULL)                return (-ENOMEM);        eco->eco_id = eco->eco_lsm->lsm_object_id = oa->o_id;        spin_lock (&ec->ec_lock);        eco2 = echo_find_object_locked (obd, oa->o_id);        if (eco2 == NULL) {                     /* didn't race */                list_add (&eco->eco_obj_chain, &ec->ec_objects);                spin_unlock (&ec->ec_lock);                eco->eco_refcount = 1;                *ecop = eco;                CDEBUG (D_INFO,                        "created %p: "LPX64"=%u#%u@%d refs %d del %d\n",                        eco, eco->eco_id,                        eco->eco_lsm->lsm_stripe_size,                        eco->eco_lsm->lsm_stripe_count,                        eco->eco_lsm->lsm_oinfo[0]->loi_ost_idx,                        eco->eco_refcount, eco->eco_deleted);                return (0);        }        if (eco2->eco_deleted)                rc = -EAGAIN;                   /* lose race */        else {                eco2->eco_refcount++;           /* take existing */                *ecop = eco2;                rc = 0;                LASSERT (eco2->eco_id == eco2->eco_lsm->lsm_object_id);                CDEBUG (D_INFO,                        "found(2) %p: "LPX64"=%u#%u@%d refs %d del %d\n",                        eco2, eco2->eco_id,                        eco2->eco_lsm->lsm_stripe_size,                        eco2->eco_lsm->lsm_stripe_count,                        eco2->eco_lsm->lsm_oinfo[0]->loi_ost_idx,                        eco2->eco_refcount, eco2->eco_deleted);        }        spin_unlock (&ec->ec_lock);        echo_free_object (eco);        return (rc);}static voidecho_put_object (struct ec_object *eco){        struct obd_device      *obd = eco->eco_device;        struct echo_client_obd *ec = &obd->u.echo_client;        /* Release caller's ref on the object.         * delete => mark for deletion when last ref goes         */        spin_lock (&ec->ec_lock);        eco->eco_refcount--;        LASSERT (eco->eco_refcount >= 0);

⌨️ 快捷键说明

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