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

📄 iscsi_main.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
    return NULL;}#if 0/* 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;}#endif#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_task(collection_ptr) ((collection_ptr)->head)#define next_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;    }    /* try to get one from the HBA's free task collection */    spin_lock(&hba->free_task_lock);    if ((task = pop_task(&hba->free_tasks))) {        atomic_dec(&hba->num_free_tasks);        atomic_inc(&hba->num_used_tasks);        hba->min_free_tasks = MIN(hba->min_free_tasks, atomic_read(&hba->num_free_tasks));    }    else {        hba->min_free_tasks = 0;    }    spin_unlock(&hba->free_task_lock);    /* otherwise, try to dynamically allocate a task */    if (!task) {        if ((task = kmalloc(sizeof(iscsi_task_t), GFP_ATOMIC))) {            atomic_inc(&hba->num_used_tasks);            DEBUG_ALLOC6("iSCSI: kmalloc task %p (active %u, used %u, free %u) for session %p to %s\n",                         task, atomic_read(&session->num_active_tasks),                          atomic_read(&hba->num_used_tasks), atomic_read(&hba->num_free_tasks),                         session, session->log_name);        }    }    if (task) {        memset(task, 0, sizeof(iscsi_task_t) );        task->itt = RSVD_TASK_TAG;        task->ttt = RSVD_TASK_TAG;        task->mgmt_itt = RSVD_TASK_TAG;        task->next = task->prev = NULL;        task->order_next = task->order_prev = NULL;        task->session = session;        wmb();    }    else {        set_bit(SESSION_TASK_ALLOC_FAILED, &session->control_bits);    }    return task;}static void free_task( iscsi_task_t *task ){    iscsi_session_t *session = task->session;    iscsi_hba_t *hba;        if (! task) {        DEBUG_ERR0("iSCSI: free_task couldn't free NULL task\n");        return;    }    if (! session) {        DEBUG_ERR1("iSCSI: free_task couldn't find session for task %p\n", task);        return;    }    hba = session->hba;    if (!hba) {        DEBUG_ERR1("iSCSI: free_task couldn't find HBA for task %p\n", task);        return;    }    if (task->next || task->prev || task->order_next || task->order_prev) {        /* this is a memory leak, which is better than memory corruption */        printk("iSCSI: bug - tried to free task %p with prev %p, next %p, order_prev %p, order_next %p\n",               task, task->prev, task->next, task->order_prev, task->order_next);        return;    }    DEBUG_QUEUE4("iSCSI: free_task %p, itt %u, session %p, %u currently free\n",                  task, task->itt, task->session, atomic_read(&hba->num_free_tasks));    /* zero out the task settings */    task->scsi_cmnd = NULL;    task->session = NULL;    task->itt = RSVD_TASK_TAG;    task->mgmt_itt = RSVD_TASK_TAG;    task->next = task->prev = NULL;    task->order_next = task->order_prev = NULL;    atomic_set(&task->refcount, 0);        /* put the task on the session's free list */    spin_lock(&hba->free_task_lock);    atomic_inc(&hba->num_free_tasks);    atomic_dec(&hba->num_used_tasks);    add_task(&hba->free_tasks, task);    spin_unlock(&hba->free_task_lock);    /* If an alloc call has failed, we need to wake up the TX thread     * now that a task is available, since there are no guarantees     * that anything else will wake it up.     */    if (test_and_clear_bit(SESSION_TASK_ALLOC_FAILED, &session->control_bits))        wake_tx_thread(TX_SCSI_COMMAND, session);}/* As long as the tx thread is the only caller, no locking * is required.  If any other thread also needs to call this, * then all callers must be changed to agree on some locking * protocol.  Currently, some but not all caller's are holding * the session->task_lock. */static inline uint32_t allocate_itt(iscsi_session_t *session){    uint32_t itt = 0;    if (session) {        itt = session->itt++;        /* iSCSI reserves 0xFFFFFFFF, this driver reserves 0 */        if (session->itt == RSVD_TASK_TAG)            session->itt = 1;    }    return itt;}/* Caller must hold the session's task_lock.  Associating a task with * a session causes it to be completed on a session drop or target * reset, along with all other session tasks, in the order they were * added to the session.  Preserving the ordering is required by the * Linux SCSI architecture.  Tasks that should not be completed to the * Linux SCSI layer (because the eh_abort_handler has or will return * SUCCESS for it) get removed from the session, though they may still * be in various task collections so that PDUs relating to them can be * sent or received. */static void add_session_task(iscsi_session_t *session, iscsi_task_t *task){    if (atomic_read(&session->num_active_tasks) == 0) {        /* session going from idle to active, pretend we just         * received something, so that the idle period before this doesn't         * cause an immediate timeout.         */        session->last_rx = jiffies;    }    atomic_inc(&session->num_active_tasks);    /* set task info */    task->session = session;    task->itt = allocate_itt(session);    DEBUG_QUEUE5("iSCSI: task %p allocated itt %u for command %p, session %p to %s\n",                  task, task->itt, task->scsi_cmnd, session, session->log_name);    /* add it to the session task ordering list */    if (session->arrival_order.head) {        task->order_prev = session->arrival_order.tail;        task->order_next = NULL;        session->arrival_order.tail->order_next = task;        session->arrival_order.tail = task;    }    else {        task->order_prev = NULL;        task->order_next = NULL;        session->arrival_order.head = session->arrival_order.tail = task;    }    DEBUG_FLOW4("iSCSI: task %p, itt %u, added to session %p to %s\n", task, task->itt, session, session->log_name);}static int remove_session_task(iscsi_session_t *session, iscsi_task_t *task){    /* remove the task from the session's arrival_order collection */    if (task == session->arrival_order.head) {        if ((session->arrival_order.head = task->order_next))            session->arrival_order.head->order_prev = NULL;        else            session->arrival_order.tail = NULL;    }    else if (task == session->arrival_order.tail) {        session->arrival_order.tail = task->order_prev;        session->arrival_order.tail->order_next = NULL;    }    else {        /* we should always be in the middle, 

⌨️ 快捷键说明

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