Unknown symbol问题!!急!
我在修改iscsi—target代码的时候遇到了这个问题,自己定义的函数可以编译通过,但是当加载模块的时候就提示我定义的函数和全局变量是Unknown symbol!!
我没有添加代码的时候结果是正确的~~iscsi.h是整个工程的头文件,其他的.c文件的函数都是在这里面定义的。
请高手一定帮忙阿!!我搞了好久了~~
通过dmesg查看结果:
iSCSI Enterprise Target Software - version 0.4.15
iotype_init(92) register fileio
iotype_init(92) register blockio
iotype_init(92) register nullio
iscsi_trgt: Unknown symbol get_ppos
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol init_ppos_table
iscsi_trgt: Unknown symbol set_ppos
iscsi_trgt: Unknown symbol get_ppos
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol set_ppos
iscsi_trgt: Unknown symbol get_ppos
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol set_ppos
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol ppos_table
iscsi_trgt: Unknown symbol ppos_table
iscsi_trgt: Unknown symbol ppos_table
我认为有关的源代码如下:
iscsi.h是原有的代码,table.c注释下的代码是我添加的。
- /*
- * Copyright (C) 2002-2003 Ardis Technolgies <[email]roman@ardistech.com[/email]>
- *
- * Released under the terms of the GNU GPL v2.0.
- */
- #ifndef __ISCSI_H__
- #define __ISCSI_H__
- #include <linux/pagemap.h>
- #include <linux/seq_file.h>
- #include <linux/mm.h>
- #include <linux/crypto.h>
- #include <net/sock.h>
- #include <asm/scatterlist.h>
- #include "iscsi_hdr.h"
- #include "iet_u.h"
- struct iscsi_sess_param {
- int initial_r2t;
- int immediate_data;
- int max_connections;
- int max_recv_data_length;
- int max_xmit_data_length;
- int max_burst_length;
- int first_burst_length;
- int default_wait_time;
- int default_retain_time;
- int max_outstanding_r2t;
- int data_pdu_inorder;
- int data_sequence_inorder;
- int error_recovery_level;
- int header_digest;
- int data_digest;
- int ofmarker;
- int ifmarker;
- int ofmarkint;
- int ifmarkint;
- };
- struct iscsi_trgt_param {
- int wthreads;
- int target_type;
- int queued_cmnds;
- };
- struct tio {
- u32 pg_cnt;
- pgoff_t idx;
- u32 offset;
- u32 size;
- struct page **pvec;
- atomic_t count;
- };
- struct network_thread_info {
- struct task_struct *task;
- unsigned long flags;
- struct list_head active_conns;
- spinlock_t nthread_lock;
- void (*old_state_change)(struct sock *);
- void (*old_data_ready)(struct sock *, int);
- };
- struct worker_thread_info;
- struct worker_thread {
- struct task_struct *w_task;
- struct list_head w_list;
- struct worker_thread_info *w_info;
- };
- struct worker_thread_info {
- spinlock_t wthread_lock;
- u32 nr_running_wthreads;
- struct list_head wthread_list;
- struct list_head work_queue;
- wait_queue_head_t wthread_sleep;
- };
- struct iscsi_cmnd;
- struct target_type {
- int id;
- int (*execute_cmnd) (struct iscsi_cmnd *);
- };
- enum iscsi_device_state {
- IDEV_RUNNING,
- IDEV_DEL,
- };
- struct iscsi_target {
- struct list_head t_list;
- u32 tid;
- char name[ISCSI_NAME_LEN];
- struct iscsi_sess_param sess_param;
- struct iscsi_trgt_param trgt_param;
- atomic_t nr_volumes;
- struct list_head volumes;
- struct list_head session_list;
- struct network_thread_info nthread_info;
- struct worker_thread_info wthread_info;
- struct semaphore target_sem;
- struct list_head initiator_list;
- u32 initiator_iid_count;
- };
- struct iscsi_queue {
- spinlock_t queue_lock;
- struct iscsi_cmnd *ordered_cmnd;
- struct list_head wait_list;
- int active_cnt;
- };
- struct iet_volume {
- u32 lun;
- enum iscsi_device_state l_state;
- atomic_t l_count;
- struct iscsi_target *target;
- struct list_head list;
- struct iscsi_queue queue;
- u8 scsi_id[SCSI_ID_LEN];
- u8 scsi_sn[SCSI_SN_LEN];
- u32 blk_shift;
- u64 blk_cnt;
- u64 reserve_sid;
- spinlock_t reserve_lock;
- unsigned long flags;
- struct iotype *iotype;
- void *private;
- };
- enum lu_flags {
- LU_READONLY,
- LU_ASYNC,
- };
- #define LUReadonly(lu) test_bit(LU_READONLY, &(lu)->flags)
- #define SetLUReadonly(lu) set_bit(LU_READONLY, &(lu)->flags)
- #define LUAsync(lu) test_bit(LU_ASYNC, &(lu)->flags)
- #define SetLUAsync(lu) set_bit(LU_ASYNC, &(lu)->flags)
- #define IET_HASH_ORDER 8
- #define cmnd_hashfn(itt) hash_long((itt), IET_HASH_ORDER)
- struct iscsi_session {
- struct list_head list;
- struct iscsi_target *target;
- char *initiator;
- u64 sid;
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
- struct iscsi_sess_param param;
- u32 max_queued_cmnds;
- struct list_head conn_list;
- struct list_head pending_list;
- spinlock_t cmnd_hash_lock;
- struct list_head cmnd_hash[1 << IET_HASH_ORDER];
- u32 next_ttt;
- struct iscsi_initiator *rinitiator;
- };
- enum connection_state_bit {
- CONN_ACTIVE,
- CONN_CLOSING,
- };
- #define ISCSI_CONN_IOV_MAX (((256 << 10) >> PAGE_SHIFT) + 1)
- struct iscsi_conn {
- struct list_head list; /* list entry in session list */
- struct iscsi_session *session; /* owning session */
- u16 cid;
- unsigned long state;
- u32 stat_sn;
- u32 exp_stat_sn;
- int hdigest_type;
- int ddigest_type;
- struct list_head poll_list;
- struct file *file;
- struct socket *sock;
- spinlock_t list_lock;
- atomic_t nr_cmnds;
- atomic_t nr_busy_cmnds;
- struct list_head pdu_list; /* in/outcoming pdus */
- struct list_head write_list; /* list of data pdus to be sent */
- struct iscsi_cmnd *read_cmnd;
- struct msghdr read_msg;
- struct iovec read_iov[ISCSI_CONN_IOV_MAX];
- u32 read_size;
- u32 read_overflow;
- int read_state;
- struct iscsi_cmnd *write_cmnd;
- struct iovec write_iov[ISCSI_CONN_IOV_MAX];
- struct iovec *write_iop;
- struct tio *write_tcmnd;
- u32 write_size;
- u32 write_offset;
- int write_state;
- struct hash_desc rx_hash;
- struct hash_desc tx_hash;
- struct scatterlist hash_sg[ISCSI_CONN_IOV_MAX];
- };
- struct iscsi_pdu {
- struct iscsi_hdr bhs;
- void *ahs;
- unsigned int ahssize;
- unsigned int datasize;
- };
- typedef void (iet_show_info_t)(struct seq_file *seq, struct iscsi_target *target);
- struct iscsi_cmnd {
- struct list_head list;
- struct list_head conn_list;
- unsigned long flags;
- struct iscsi_conn *conn;
- struct iet_volume *lun;
- struct iscsi_pdu pdu;
- struct list_head pdu_list;
- struct list_head hash_list;
- struct tio *tio;
- u32 r2t_sn;
- u32 r2t_length;
- u32 is_unsolicited_data;
- u32 target_task_tag;
- u32 outstanding_r2t;
- u32 hdigest;
- u32 ddigest;
- struct iscsi_cmnd *req;
- };
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //映射表数据结构
- struct ppos_list_node
- {
- loff_t ppos;
- u32 offset;
- struct ppos_list_node *next;
- };
- struct ppos
- {
- struct ppos_list_node *newppos;
- int node_num;
- };
- struct ppos_table
- {
- struct ppos ppos_item[1024];
- loff_t ppos_now;
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- #define ISCSI_OP_SCSI_REJECT ISCSI_OP_VENDOR1_CMD
- #define ISCSI_OP_PDU_REJECT ISCSI_OP_VENDOR2_CMD
- #define ISCSI_OP_DATA_REJECT ISCSI_OP_VENDOR3_CMD
- #define ISCSI_OP_SCSI_ABORT ISCSI_OP_VENDOR4_CMD
- /* iscsi.c */
- extern struct iscsi_cmnd *cmnd_alloc(struct iscsi_conn *, int);
- extern void cmnd_rx_start(struct iscsi_cmnd *);
- extern void cmnd_rx_end(struct iscsi_cmnd *);
- extern void cmnd_tx_start(struct iscsi_cmnd *);
- extern void cmnd_tx_end(struct iscsi_cmnd *);
- extern void cmnd_release(struct iscsi_cmnd *, int);
- extern void send_data_rsp(struct iscsi_cmnd *, int (*)(struct iscsi_cmnd *));
- extern void send_scsi_rsp(struct iscsi_cmnd *, int (*)(struct iscsi_cmnd *));
- /* tio.c */
- extern int tio_init(void);
- extern void tio_exit(void);
- extern struct tio *tio_alloc(int);
- extern void tio_get(struct tio *);
- extern void tio_put(struct tio *);
- extern void tio_set(struct tio *, u32, loff_t);
- extern int tio_read(struct iet_volume *, struct tio *);
- extern int tio_write(struct iet_volume *, struct tio *);
- extern int tio_sync(struct iet_volume *, struct tio *);
- /* iotype.c */
- extern struct iotype *get_iotype(const char *name);
- extern void put_iotype(struct iotype *iot);
- /* params.c */
- extern int iscsi_param_set(struct iscsi_target *, struct iscsi_param_info *, int);
- /* target_disk.c */
- extern struct target_type disk_ops;
- /* event.c */
- extern int event_send(u32, u64, u32, u32, int);
- extern int event_init(void);
- extern void event_exit(void);
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /*table.c*/
- extern int table_init(void);
- extern void table_exit(void);
- extern void insert_list(struct ppos_list_node *, struct ppos_list_node *);
- extern int init_ppos_table(struct ppos_table *);
- extern loff_t set_ppos(loff_t, struct ppos_table *);
- extern loff_t get_ppos(loff_t, struct ppos_table *);
- extern struct ppos_table *ppos_table;
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- #define get_pgcnt(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
- static inline void iscsi_cmnd_get_length(struct iscsi_pdu *pdu)
- {
- #if defined(__BIG_ENDIAN)
- pdu->ahssize = pdu->bhs.length.ahslength * 4;
- pdu->datasize = pdu->bhs.length.datalength;
- #elif defined(__LITTLE_ENDIAN)
- pdu->ahssize = (pdu->bhs.length & 0xff) * 4;
- pdu->datasize = be32_to_cpu(pdu->bhs.length & ~0xff);
- #else
- #error
- #endif
- }
- static inline void iscsi_cmnd_set_length(struct iscsi_pdu *pdu)
- {
- #if defined(__BIG_ENDIAN)
- pdu->bhs.length.ahslength = pdu->ahssize / 4;
- pdu->bhs.length.datalength = pdu->datasize;
- #elif defined(__LITTLE_ENDIAN)
- pdu->bhs.length = cpu_to_be32(pdu->datasize) | (pdu->ahssize / 4);
- #else
- #error
- #endif
- }
- #define cmnd_hdr(cmnd) ((struct iscsi_scsi_cmd_hdr *) (&((cmnd)->pdu.bhs)))
- #define cmnd_ttt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.ttt)
- #define cmnd_itt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.itt)
- #define cmnd_opcode(cmnd) ((cmnd)->pdu.bhs.opcode & ISCSI_OPCODE_MASK)
- #define cmnd_scsicode(cmnd) cmnd_hdr(cmnd)->scb[0]
- #define SECTOR_SIZE_BITS 9
- enum cmnd_flags {
- CMND_hashed,
- CMND_queued,
- CMND_final,
- CMND_waitio,
- CMND_close,
- CMND_lunit,
- CMND_pending,
- CMND_tmfabort,
- CMND_rxstart,
- };
- #define set_cmnd_hashed(cmnd) set_bit(CMND_hashed, &(cmnd)->flags)
- #define cmnd_hashed(cmnd) test_bit(CMND_hashed, &(cmnd)->flags)
- #define set_cmnd_queued(cmnd) set_bit(CMND_queued, &(cmnd)->flags)
- #define cmnd_queued(cmnd) test_bit(CMND_queued, &(cmnd)->flags)
- #define set_cmnd_final(cmnd) set_bit(CMND_final, &(cmnd)->flags)
- #define cmnd_final(cmnd) test_bit(CMND_final, &(cmnd)->flags)
- #define set_cmnd_waitio(cmnd) set_bit(CMND_waitio, &(cmnd)->flags)
- #define cmnd_waitio(cmnd) test_bit(CMND_waitio, &(cmnd)->flags)
- #define set_cmnd_close(cmnd) set_bit(CMND_close, &(cmnd)->flags)
- #define cmnd_close(cmnd) test_bit(CMND_close, &(cmnd)->flags)
- #define set_cmnd_lunit(cmnd) set_bit(CMND_lunit, &(cmnd)->flags)
- #define cmnd_lunit(cmnd) test_bit(CMND_lunit, &(cmnd)->flags)
- #define set_cmnd_pending(cmnd) set_bit(CMND_pending, &(cmnd)->flags)
- #define clear_cmnd_pending(cmnd) clear_bit(CMND_pending, &(cmnd)->flags)
- #define cmnd_pending(cmnd) test_bit(CMND_pending, &(cmnd)->flags)
- #define set_cmnd_tmfabort(cmnd) set_bit(CMND_tmfabort, &(cmnd)->flags)
- #define cmnd_tmfabort(cmnd) test_bit(CMND_tmfabort, &(cmnd)->flags)
- #define set_cmnd_rxstart(cmnd) set_bit(CMND_rxstart, &(cmnd)->flags)
- #define cmnd_rxstart(cmnd) test_bit(CMND_rxstart, &(cmnd)->flags)
- #define VENDOR_ID "IET"
- #define PRODUCT_ID "VIRTUAL-DISK"
- #define PRODUCT_REV "0"
- #endif /* __ISCSI_H__ */
复制代码
table.c是我自己实现的文件
- #include "iscsi.h"
- #include "iscsi_dbg.h"
- #include "iotype.h"
- void insert_list(struct ppos_list_node *ppos_list, struct ppos_list_node *list_node)
- {
- list_node->next = ppos_list;
- ppos_list = list_node;
- }
- int init_ppos_table(struct ppos_table *mytable)
- {
- int i;
- mytable = (struct ppos_table *)kzalloc(sizeof(*mytable), GFP_KERNEL);
- if(!mytable)
- return -ENOMEM;
- for(i = 0; i < 1024; i++)
- {
- mytable->ppos_item[i].newppos = NULL;
- mytable->ppos_item[i].node_num = 0;
- }
- mytable->ppos_now = -1;
- return 0;
- }
- loff_t get_ppos(loff_t ppos, struct ppos_table *mytable)//参数是页面偏移加页内偏移量
- {
- u32 myoffset;
- loff_t myppos;
- int i;
- i = (int) ppos >> PAGE_CACHE_SHIFT;
- myoffset = ppos & ~PAGE_CACHE_MASK;
- myppos = mytable->ppos_item[i].newppos->ppos << PAGE_CACHE_SHIFT;
- myppos += myoffset;
- return myppos;
- }
- loff_t set_ppos(loff_t ppos, struct ppos_table *mytable) //参数是页面偏移加页内偏移量
- {
- u32 myoffset;
- loff_t myppos;
- struct ppos_list_node *newnode;
- newnode = kzalloc(sizeof(*newnode), GFP_KERNEL);
- newnode->next = NULL;
- myoffset = ppos & ~PAGE_CACHE_MASK;
- myppos = (int) ppos >> PAGE_CACHE_SHIFT;
- newnode->ppos = ++(mytable->ppos_now);
- newnode->offset = myoffset;
- insert_list(mytable->ppos_item[myppos].newppos, newnode);
- return ((mytable->ppos_now << PAGE_CACHE_SHIFT) + myoffset);
- }
- int table_init(void)
- {
- int i = init_ppos_table(ppos_table);
- return i;
- }
- void table_exit(void)
- {
- }
复制代码
file-io.c是调用这些函数的文件,调用代码都在fileio_make_request函数中~~
- /*
- * Target device file I/O.
- * (C) 2004 - 2005 FUJITA Tomonori <[email]tomof@acm.org[/email]>
- * This code is licenced under the GPL.
- */
- #include <linux/blkdev.h>
- #include <linux/writeback.h>
- #include <linux/parser.h>
- #include "iscsi.h"
- #include "iscsi_dbg.h"
- #include "iotype.h"
- struct fileio_data {
- char *path;
- struct file *filp;
- };
- static int fileio_make_request(struct iet_volume *lu, struct tio *tio, int rw)
- {
- struct fileio_data *p = lu->private;
- struct file *filp;
- mm_segment_t oldfs;
- struct page *page;
- u32 offset, size;
- loff_t ppos, count,newppos;
- char *buf;
- int i, err = 0;
- ssize_t ret;
- assert(p);
- filp = p->filp;
- size = tio->size;
- offset= tio->offset;
- ppos = (loff_t) tio->idx << (PAGE_CACHE_SHIFT + 2);
- ppos += offset;
- for (i = 0; i < tio->pg_cnt; i++) {
- page = tio->pvec[i];
- assert(page);
- buf = page_address(page);
- buf += offset;
- if (offset + size > PAGE_CACHE_SIZE)
- count = PAGE_CACHE_SIZE - offset;
- else
- count = size;
- oldfs = get_fs();
- set_fs(get_ds());
- [color=Red] if (rw == READ)
- {
- newppos = get_ppos(ppos, ppos_table);
- ret = do_sync_read(filp, buf, count, &newppos);
- }
- else
- {
- newppos = set_ppos(ppos, ppos_table);
- ret = do_sync_write(filp, buf, count, &newppos);
- }[/color]
- set_fs(oldfs);
- if (ret != count) {
- eprintk("I/O error %lld, %ld\n", count, (long) ret);
- err = -EIO;
- }
- size -= count;
- offset = 0;
- }
- assert(!size);
- return err;
- }
- static int fileio_sync(struct iet_volume *lu, struct tio *tio)
- {
- struct fileio_data *p = lu->private;
- struct inode *inode = p->filp->f_dentry->d_inode;
- struct address_space *mapping = inode->i_mapping;
- loff_t ppos, count;
- int res;
- if (tio) {
- ppos = (loff_t) tio->idx << PAGE_CACHE_SHIFT;
- count = tio->size;
- } else {
- ppos = 0;
- count = lu->blk_cnt << lu->blk_shift;
- }
- res = sync_page_range(inode, mapping, ppos, count);
- if (res) {
- eprintk("I/O error: syncing pages failed: %d\n", res);
- return -EIO;
- } else
- return 0;
- }
- static int open_path(struct iet_volume *volume, const char *path)
- {
- int err = 0;
- struct fileio_data *info = volume->private;
- struct file *filp;
- mm_segment_t oldfs;
- int flags;
- info->path = kstrdup(path, GFP_KERNEL);
- if (!info->path)
- return -ENOMEM;
- oldfs = get_fs();
- set_fs(get_ds());
- flags = (LUReadonly(volume) ? O_RDONLY : O_RDWR) | O_LARGEFILE;
- filp = filp_open(path, flags, 0);
- set_fs(oldfs);
- if (IS_ERR(filp)) {
- err = PTR_ERR(filp);
- eprintk("Can't open %s %d\n", path, err);
- info->filp = NULL;
- } else
- info->filp = filp;
- return err;
- }
- static int set_scsiid(struct iet_volume *volume, const char *id)
- {
- size_t len;
- if ((len = strlen(id)) > SCSI_ID_LEN - VENDOR_ID_LEN) {
- eprintk("SCSI ID too long, %zd provided, %u max\n", len,
- SCSI_ID_LEN - VENDOR_ID_LEN);
- return -EINVAL;
- }
- memcpy(volume->scsi_id + VENDOR_ID_LEN, id, len);
- return 0;
- }
- static void gen_scsiid(struct iet_volume *volume, struct inode *inode)
- {
- int i;
- u32 *p;
- strlcpy(volume->scsi_id, VENDOR_ID, VENDOR_ID_LEN);
- for (i = VENDOR_ID_LEN; i < SCSI_ID_LEN; i++)
- if (volume->scsi_id[i])
- return;
- p = (u32 *) (volume->scsi_id + VENDOR_ID_LEN);
- *(p + 0) = volume->target->trgt_param.target_type;
- *(p + 1) = volume->target->tid;
- *(p + 2) = (unsigned int) inode->i_ino;
- *(p + 3) = (unsigned int) inode->i_sb->s_dev;
- }
- static int set_scsisn(struct iet_volume *volume, const char *sn)
- {
- size_t len;
- if ((len = strlen(sn)) > SCSI_SN_LEN) {
- eprintk("SCSI SN too long, %zd provided, %u max\n", len,
- SCSI_SN_LEN);
- return -EINVAL;
- }
- memcpy(volume->scsi_sn, sn, len);
- return 0;
- }
- enum {
- Opt_scsiid, Opt_scsisn, Opt_path, Opt_ignore, Opt_err,
- };
- static match_table_t tokens = {
- {Opt_scsiid, "ScsiId=%s"},
- {Opt_scsisn, "ScsiSN=%s"},
- {Opt_path, "Path=%s"},
- {Opt_ignore, "Type=%s"},
- {Opt_ignore, "IOMode=%s"},
- {Opt_err, NULL},
- };
- static int parse_fileio_params(struct iet_volume *volume, char *params)
- {
- int err = 0;
- char *p, *q;
- while ((p = strsep(¶ms, ",")) != NULL) {
- substring_t args[MAX_OPT_ARGS];
- int token;
- if (!*p)
- continue;
- token = match_token(p, tokens, args);
- switch (token) {
- case Opt_scsiid:
- if (!(q = match_strdup(&args[0]))) {
- err = -ENOMEM;
- goto out;
- }
- err = set_scsiid(volume, q);
- kfree(q);
- if (err < 0)
- goto out;
- break;
- case Opt_scsisn:
- if (!(q = match_strdup(&args[0]))) {
- err = -ENOMEM;
- goto out;
- }
- err = set_scsisn(volume, q);
- kfree(q);
- if (err < 0)
- goto out;
- break;
- case Opt_path:
- if (!(q = match_strdup(&args[0]))) {
- err = -ENOMEM;
- goto out;
- }
- err = open_path(volume, q);
- kfree(q);
- if (err < 0)
- goto out;
- break;
- case Opt_ignore:
- break;
- default:
- eprintk("Unknown %s\n", p);
- return -EINVAL;
- }
- }
- out:
- return err;
- }
- static void fileio_detach(struct iet_volume *lu)
- {
- struct fileio_data *p = lu->private;
- kfree(p->path);
- if (p->filp)
- filp_close(p->filp, NULL);
- kfree(p);
- lu->private = NULL;
- }
- static int fileio_attach(struct iet_volume *lu, char *args)
- {
- int err = 0;
- struct fileio_data *p;
- struct inode *inode;
- if (lu->private) {
- printk("already attached ? %d\n", lu->lun);
- return -EBUSY;
- }
- p = kzalloc(sizeof(*p), GFP_KERNEL);
- if (!p)
- return -ENOMEM;
- lu->private = p;
- if ((err = parse_fileio_params(lu, args)) < 0) {
- eprintk("%d\n", err);
- goto out;
- }
- inode = p->filp->f_dentry->d_inode;
- gen_scsiid(lu, inode);
- if (S_ISREG(inode->i_mode))
- ;
- else if (S_ISBLK(inode->i_mode))
- inode = inode->i_bdev->bd_inode;
- else {
- err = -EINVAL;
- goto out;
- }
- lu->blk_shift = SECTOR_SIZE_BITS;
- lu->blk_cnt = inode->i_size >> (lu->blk_shift + 2);
- out:
- if (err < 0)
- fileio_detach(lu);
- return err;
- }
- void fileio_show(struct iet_volume *lu, struct seq_file *seq)
- {
- struct fileio_data *p = lu->private;
- seq_printf(seq, " path:%s\n", p->path);
- }
- struct iotype fileio =
- {
- .name = "fileio",
- .attach = fileio_attach,
- .make_request = fileio_make_request,
- .sync = fileio_sync,
- .detach = fileio_detach,
- .show = fileio_show,
- };
复制代码
[ 本帖最后由 lianxi1999 于 2008-12-5 11:29 编辑 ]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这一系列的:
iscsi_trgt: Unknown symbol get_ppos
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol init_ppos_table
iscsi_trgt: Unknown symbol set_ppos
iscsi_trgt: Unknown symbol get_ppos
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol set_ppos
iscsi_trgt: Unknown symbol get_ppos
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol set_ppos
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol mytable
iscsi_trgt: Unknown symbol ppos_table
iscsi_trgt: Unknown symbol ppos_table
iscsi_trgt: Unknown symbol ppos_table
有两个可行的解决方案:
1. 你可以把定义这些symbol的源文件包进来,一起编译;
2. 这些symbol,他们的头文件可能你确实包进来了;但是,对于Linux内核模块,如果相应模块并没有调用EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL()——模块导出符号表可供其它模块引用。那么其他模块去引用它,当然就不行了。
我这里只有一个模块啊~
并且这些函数都是定义在table.c中的,编译也是一起编译的,并没有多个模块~~
你得makefile怎么写的,贴出来看看
肯定是没有把table.c这个文件编译进去
你的iscsi的target 连接模块问题
这是整个工程的makefile
复制代码
这是kernel的makefile
复制代码
在kernel的makefile中,我已经将table.o添加了。~~
[ 本帖最后由 lianxi1999 于 2008-12-5 12:36 编辑 ]