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

📄 iscsi.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
            hba->session_list_tail = NULL;    }    else if (session == hba->session_list_tail) {        hba->session_list_tail = session->prev;        hba->session_list_tail->next = NULL;    }    else {        /* we should always be in the middle,          * but check pointers to make sure we don't crash the kernel          * if the function is called for a session not on the hba.         */        if (session->next && session->prev) {            session->next->prev = session->prev;            session->prev->next = session->next;        }        else {            DEBUG_ERR2("iSCSI: failed to remove session %p from hba %p\n",                       session, hba);            return 0;        }    }    session->prev = NULL;    session->next = NULL;        return 1;}static iscsi_session_t *find_session_for_cmnd(Scsi_Cmnd *sc) {    iscsi_session_t *session = NULL;    iscsi_hba_t *hba;    DECLARE_NOQUEUE_FLAGS;    if (!sc->host)        return NULL;    if (!sc->host->hostdata)        return NULL;    hba = (iscsi_hba_t *)sc->host->hostdata;    /* find the session for this command */    SPIN_LOCK_NOQUEUE(&hba->session_lock);    session = hba->session_list_head;    while (session && (session->channel != sc->channel || session->target_id != sc->target))        session = session->next;    if (session)        atomic_inc(&session->refcount); /* caller must use drop_reference when it's done with the session */    SPIN_UNLOCK_NOQUEUE(&hba->session_lock);    return session;}static iscsi_session_t *find_session_by_channel(unsigned int host_no, unsigned int channel, unsigned int target_id){    iscsi_session_t *session = NULL;    iscsi_hba_t *hba;    DECLARE_NOQUEUE_FLAGS;    spin_lock(&iscsi_hba_list_lock);    hba = iscsi_hba_list;    while (hba && (hba->host_no != host_no)) {        hba = hba->next;    }    /* find the session for this command */    if (hba) {        SPIN_LOCK_NOQUEUE(&hba->session_lock);        session = hba->session_list_head;        while (session && (session->channel != channel || session->target_id != target_id))            session = session->next;        if (session)            atomic_inc(&session->refcount); /* caller must use drop_reference when it's done with the session */        SPIN_UNLOCK_NOQUEUE(&hba->session_lock);    }    spin_unlock(&iscsi_hba_list_lock);            return session;}static iscsi_session_t *find_session_by_bus(int iscsi_bus, int target_id){    iscsi_session_t *session = NULL;    iscsi_hba_t *hba;    unsigned int hba_index;    unsigned int channel;    DECLARE_NOQUEUE_FLAGS;    /* compute the appropriate HBA and channel numbers */    hba_index = iscsi_bus / ISCSI_MAX_CHANNELS_PER_HBA;    channel = iscsi_bus % ISCSI_MAX_CHANNELS_PER_HBA;    spin_lock(&iscsi_hba_list_lock);    hba = iscsi_hba_list;    while (hba && (hba_index-- > 0)) {        hba = hba->next;    }    /* find the session for this command */    if (hba) {        SPIN_LOCK_NOQUEUE(&hba->session_lock);        session = hba->session_list_head;        while (session && (session->channel != channel || session->target_id != target_id))            session = session->next;        if (session)            atomic_inc(&session->refcount); /* caller must use drop_reference when it's done with the session */        SPIN_UNLOCK_NOQUEUE(&hba->session_lock);    }    spin_unlock(&iscsi_hba_list_lock);    return session;}static void delete_session(iscsi_session_t *session){    DEBUG_INIT1("iSCSI: terminated and deleted session %p\n", session);    if (session->auth_client) {        memset(session->auth_client, 0, sizeof(*session->auth_client));        kfree(session->auth_client);        session->auth_client = NULL;    }    if (session->portals) {        kfree(session->portals);        session->portals = NULL;    }    memset(session, 0, sizeof(*session));    kfree(session);}/* decrement the session refcount, and remove it and free it if the refcount hit zero */static void drop_reference(iscsi_session_t *session){    iscsi_hba_t *hba;    DECLARE_NOQUEUE_FLAGS;    if (!session) {        printk("iSCSI: bug - drop_reference(NULL)\n");        return;    }    if ((hba = session->hba)) {        /* may need to remove it from the HBA's session list */        SPIN_LOCK_NOQUEUE(&hba->session_lock);        if (atomic_dec_and_test(&session->refcount)) {            if (remove_session(hba, session)) {                delete_session(session);            }            else {                printk("iSCSI: bug - failed to remove unreferenced session %p\n", session);            }        }        SPIN_UNLOCK_NOQUEUE(&hba->session_lock);    }    else {        /* session isn't in an HBA's list at the moment, so just check         * the refcount, and possibly free it.           */        if (atomic_dec_and_test(&session->refcount)) {            delete_session(session);        }    }}/* must hold the task_lock to call this */static iscsi_task_t *find_task(iscsi_task_collection_t *collection, uint32_t itt){    iscsi_task_t *task = collection->head;        while (task) {        if (task->itt == itt) {            DEBUG_FLOW3("iSCSI: found itt %u, task %p, refcount %d\n", itt, task, atomic_read(&task->refcount));            return task;        }        task = task->next;    }    return NULL;}/* don't actually use this at the moment *//* must hold the task_lock to call this */static iscsi_task_t *find_mgmt_task(iscsi_task_collection_t *collection, uint32_t mgmt_itt){    iscsi_task_t *task = collection->head;        while (task) {        if (task->mgmt_itt == mgmt_itt) {            DEBUG_FLOW2("iSCSI: found mgmt_itt %u, task %p\n", mgmt_itt, task);            return task;        }        task = task->next;    }    return NULL;}#if 0/* don't actually need this at the moment *//* must hold the task_lock to call this */static iscsi_task_t *find_task_for_cmnd(iscsi_task_collection_t *collection, Scsi_Cmnd *sc){    iscsi_task_t *task = collection->head;        while (task) {        if (task->scsi_cmnd == sc) {            DEBUG_FLOW3("iSCSI: found itt %u, task %p for cmnd %p\n", task->itt, task, sc);            return task;        }        task = task->next;    }    return NULL;}#endif/* add a task to the collection.  Must hold the task_lock to do this. */static void add_task(iscsi_task_collection_t *collection, iscsi_task_t *task){    if (task->prev || task->next)        printk("iSCSI: bug - adding task %p, prev %p, next %p, to collection %p\n",               task, task->prev, task->next, collection);    if (collection->head) {        task->next = NULL;        task->prev = collection->tail;        collection->tail->next = task;        collection->tail = task;    }    else {        task->prev = task->next = NULL;        collection->head = collection->tail = task;    }}#define first_iscsi_task(collection_ptr) ((collection_ptr)->head)#define next_iscsi_task(collection_ptr, task_ptr) ((task_ptr)->next)#define order_next_task(collection_ptr, task_ptr) ((task_ptr)->order_next)/* must hold the task_lock when calling this */static iscsi_task_t *pop_task(iscsi_task_collection_t *collection){    iscsi_task_t *task = NULL;    if ((task = collection->head)) {        /* pop the head */        if ((collection->head = task->next))            collection->head->prev = NULL;        else            collection->tail = NULL;        /* and return it */        task->prev = NULL;        task->next = NULL;                return task;    }    return NULL;}/* must hold the task_lock when calling this */static void push_task(iscsi_task_collection_t *collection, iscsi_task_t *task){    if (task) {        task->prev = NULL;        task->next = collection->head;        if (collection->head) {            collection->head->prev = task;            collection->head = task;        }        else {            collection->head = collection->tail = task;        }    }}static void unlink_task(iscsi_task_collection_t *collection, iscsi_task_t *task){    /* unlink the task from the collection */    if (task == collection->head) {        if ((collection->head = task->next))            collection->head->prev = NULL;        else            collection->tail = NULL;    }    else if (task == collection->tail) {        collection->tail = task->prev;        collection->tail->next = NULL;    }    else {        task->next->prev = task->prev;        task->prev->next = task->next;    }    task->next = NULL;    task->prev = NULL;}/* if the task for the itt is found in the collection, remove it, and return it. * otherwise, return NULL.  Must hold the task_lock to call this. */static iscsi_task_t *remove_task(iscsi_task_collection_t *collection, uint32_t itt){    iscsi_task_t *task = NULL;    iscsi_task_t *search = collection->head;    while (search) {        if (search->itt == itt) {            task = search;            unlink_task(collection, task);            return task;        }        search = search->next;    }    return NULL;}/* if the task for the mgmt_itt is found in the collection, remove it, and return it. * otherwise, return NULL.  Must hold the task_lock to call this. */static iscsi_task_t *remove_mgmt_task(iscsi_task_collection_t *collection, uint32_t mgmt_itt){    iscsi_task_t *task = NULL;    iscsi_task_t *search = collection->head;    while (search) {        if (search->mgmt_itt == mgmt_itt) {            task = search;            unlink_task(collection, task);            return task;        }        search = search->next;    }    return NULL;}/* if the task for the itt is found in the collection, remove it, and return it. * otherwise, return NULL.  Must hold the task_lock to call this. */static iscsi_task_t *remove_task_for_cmnd(iscsi_task_collection_t *collection, Scsi_Cmnd *sc){    iscsi_task_t *task = NULL;    iscsi_task_t *search = collection->head;    while (search) {        if (search->scsi_cmnd == sc) {            task = search;            unlink_task(collection, task);            return task;        }        search = search->next;    }    return NULL;}/*  * remove all tasks with the specified LUN.  Must hold the task_lock to call this. */static void remove_tasks_for_lun(iscsi_task_collection_t *collection, int lun){    iscsi_task_t *search = collection->head;    iscsi_task_t *next = NULL;    while (search) {        next = search->next;        if (search->scsi_cmnd && search->scsi_cmnd->lun == lun)            unlink_task(collection, search);                search = next;    }}/* must be called with no locks held, since it may sleep, and acquires * locks on it's own. */static iscsi_task_t *alloc_task(iscsi_session_t *session){    iscsi_task_t *task = NULL;    iscsi_hba_t *hba = session->hba;    if (!hba) {        printk("iSCSI: alloc_task - session %p has NULL HBA\n", session);        return NULL;

⌨️ 快捷键说明

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