この章では、主要なデータ構造体を列挙している。これらは、Linux で使用され、 本書においても述べられているものである。これらの構造体には、本書での体裁を 整えるために、若干の編集が加えられている。
[in net/ipv4/arp.c]
struct arp_table
{
struct arp_table *next; /* Linked entry list */
unsigned long last_used; /* For expiry */
unsigned long last_updated; /* For expiry */
unsigned int flags; /* Control status */
u32 ip; /* ip address of entry */
u32 mask; /* netmask - used for generalised
proxy arps (tridge)*/
unsigned char ha[MAX_ADDR_LEN]; /* Hardware address */
struct device *dev; /* Device the entry is tied to */
struct hh_cache *hh; /* Hardware headers chain */
/*
* The following entries are only used for unresolved hw addresses.
*/
struct timer_list timer; /* expire timer */
int retries; /* remaining retries */
struct sk_buff_head skb; /* list of queued packets */
};
blk_dev_struct データ構造体が使用されるのは、バッファキャッシュ経由
でブロックデバイスを利用できるように、ブロックデバイスを登録するためである。
それらは、blk_dev 配列内に保持される。
[in
include/linux/blkdev.h]
struct blk_dev_struct {
void (*request_fn)(void);
struct request * current_request;
struct request plug;
struct tq_struct plug_tq;
};
...
...
extern struct blk_dev_struct blk_dev[MAX_BLKDEV];
buffer_head データ構造体は、バッファキャッシュにあるブロック
バッファの情報を保持するためのものである。
[in
include/linux/fs.h]
/* bh state bits */
#define BH_Uptodate 0 /* 1 if the buffer contains valid data */
#define BH_Dirty 1 /* 1 if the buffer is dirty */
#define BH_Lock 2 /* 1 if the buffer is locked */
#define BH_Req 3 /* 0 if the buffer has been invalidated */
#define BH_Touched 4 /* 1 if the buffer has been touched (aging) */
#define BH_Has_aged 5 /* 1 if the buffer has been aged (aging) */
#define BH_Protected 6 /* 1 if the buffer is protected */
#define BH_FreeOnIO 7 /* 1 to discard the buffer_head after IO */
struct buffer_head {
/* First cache line: */
unsigned long b_blocknr; /* block number */
kdev_t b_dev; /* device (B_FREE = free) */
kdev_t b_rdev; /* Real device */
unsigned long b_rsector; /* Real buffer location on disk */
struct buffer_head *b_next; /* Hash queue list */
struct buffer_head *b_this_page; /* circular list of buffers in one
page */
/* Second cache line: */
unsigned long b_state; /* buffer state bitmap (above) */
struct buffer_head *b_next_free;
unsigned int b_count; /* users using this block */
unsigned long b_size; /* block size */
/* Non-performance-critical data follows. */
char *b_data; /* pointer to data block */
unsigned int b_list; /* List that this buffer appears */
unsigned long b_flushtime; /* Time when this (dirty) buffer
* should be written */
unsigned long b_lru_time; /* Time when this buffer was
* last used. */
struct wait_queue *b_wait;
struct buffer_head *b_prev; /* doubly linked hash list */
struct buffer_head *b_prev_free; /* doubly linked list of buffers */
struct buffer_head *b_reqnext; /* request queue */
};
システム上のすべてのネットワークデバイスは、device データ構造体
によって表現される。
[in
include/linux/netdevice.h]
struct device
{
/*
* This is the first field of the "visible" part of this structure
* (i.e. as seen by users in the "Space.c" file). It is the name
* the interface.
*/
char *name;
/* I/O specific fields */
unsigned long rmem_end; /* shmem "recv" end */
unsigned long rmem_start; /* shmem "recv" start */
unsigned long mem_end; /* shared mem end */
unsigned long mem_start; /* shared mem start */
unsigned long base_addr; /* device I/O address */
unsigned char irq; /* device IRQ number */
/* Low-level status flags. */
volatile unsigned char start, /* start an operation */
interrupt; /* interrupt arrived */
unsigned long tbusy; /* transmitter busy */
struct device *next;
/* The device initialization function. Called only once. */
int (*init)(struct device *dev);
/* Some hardware also needs these fields, but they are not part of
the usual set specified in Space.c. */
unsigned char if_port; /* Selectable AUI,TP, */
unsigned char dma; /* DMA channel */
struct enet_statistics* (*get_stats)(struct device *dev);
/*
* This marks the end of the "visible" part of the structure. All
* fields hereafter are internal to the system, and may change at
* will (read: may be cleaned up at will).
*/
/* These may be needed for future network-power-down code. */
unsigned long trans_start; /* Time (jiffies) of
last transmit */
unsigned long last_rx; /* Time of last Rx */
unsigned short flags; /* interface flags (BSD)*/
unsigned short family; /* address family ID */
unsigned short metric; /* routing metric */
unsigned short mtu; /* MTU value */
unsigned short type; /* hardware type */
unsigned short hard_header_len; /* hardware hdr len */
void *priv; /* private data */
/* Interface address info. */
unsigned char broadcast[MAX_ADDR_LEN];
unsigned char pad;
unsigned char dev_addr[MAX_ADDR_LEN];
unsigned char addr_len; /* hardware addr len */
unsigned long pa_addr; /* protocol address */
unsigned long pa_brdaddr; /* protocol broadcast addr*/
unsigned long pa_dstaddr; /* protocol P-P other addr*/
unsigned long pa_mask; /* protocol netmask */
unsigned short pa_alen; /* protocol address len */
struct dev_mc_list *mc_list; /* M'cast mac addrs */
int mc_count; /* No installed mcasts */
struct ip_mc_list *ip_mc_list; /* IP m'cast filter chain */
__u32 tx_queue_len; /* Max frames per queue */
/* For load balancing driver pair support */
unsigned long pkt_queue; /* Packets queued */
struct device *slave; /* Slave device */
struct net_alias_info *alias_info; /* main dev alias info */
struct net_alias *my_alias; /* alias devs */
/* Pointer to the interface buffers. */
struct sk_buff_head buffs[DEV_NUMBUFFS];
/* Pointers to interface service routines. */
int (*open)(struct device *dev);
int (*stop)(struct device *dev);
int (*hard_start_xmit) (struct sk_buff *skb,
struct device *dev);
int (*hard_header) (struct sk_buff *skb,
struct device *dev,
unsigned short type,
void *daddr,
void *saddr,
unsigned len);
int (*rebuild_header)(void *eth,
struct device *dev,
unsigned long raddr,
struct sk_buff *skb);
void (*set_multicast_list)(struct device *dev);
int (*set_mac_address)(struct device *dev,
void *addr);
int (*do_ioctl)(struct device *dev,
struct ifreq *ifr,
int cmd);
int (*set_config)(struct device *dev,
struct ifmap *map);
void (*header_cache_bind)(struct hh_cache **hhp,
struct device *dev,
unsigned short htype,
__u32 daddr);
void (*header_cache_update)(struct hh_cache *hh,
struct device *dev,
unsigned char * haddr);
int (*change_mtu)(struct device *dev,
int new_mtu);
struct iw_statistics* (*get_wireless_stats)(struct device *dev);
};
... ... extern struct device *dev_base;
device_struct データ構造体は、キャラクタデバイスとブロックデバイス
を登録するために使用される。(それらは、デバイス名と、そのデバイスに使用できる
ファイル操作ルーチンのセットとを保持する。) chrdevs と blkdevs 配列にある個々の有効な番号は、キャラクタデバイスとブロック
デバイスとをそれぞれに表したものである。
[in
fs/devices.c]
struct device_struct {
const char * name;
struct file_operations * fops;
};
(訳注)
static struct device_struct chrdevs[MAX_CHRDEV] = {
{ NULL, NULL },
};
static struct device_struct blkdevs[MAX_BLKDEV] = {
{ NULL, NULL },
};
[in kernel/dma.c]
struct dma_chan {
int lock;
const char *device_id;
};
struct ext2_inode {
__u16 i_mode; /* File mode */
__u16 i_uid; /* Owner Uid */
__u32 i_size; /* Size in bytes */
__u32 i_atime; /* Access time */
__u32 i_ctime; /* Creation time */
__u32 i_mtime; /* Modification time */
__u32 i_dtime; /* Deletion Time */
__u16 i_gid; /* Group Id */
__u16 i_links_count; /* Links count */
__u32 i_blocks; /* Blocks count */
__u32 i_flags; /* File flags */
union {
struct {
__u32 l_i_reserved1;
} linux1;
struct {
__u32 h_i_translator;
} hurd1;
struct {
__u32 m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
__u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
__u32 i_version; /* File version (for NFS) */
__u32 i_file_acl; /* File ACL */
__u32 i_dir_acl; /* Directory ACL */
__u32 i_faddr; /* Fragment address */
union {
struct {
__u8 l_i_frag; /* Fragment number */
__u8 l_i_fsize; /* Fragment size */
__u16 i_pad1;
__u32 l_i_reserved2[2];
} linux2;
struct {
__u8 h_i_frag; /* Fragment number */
__u8 h_i_fsize; /* Fragment size */
__u16 h_i_mode_high;
__u16 h_i_uid_high;
__u16 h_i_gid_high;
__u32 h_i_author;
} hurd2;
struct {
__u8 m_i_frag; /* Fragment number */
__u8 m_i_fsize; /* Fragment size */
__u16 m_pad1;
__u32 m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
};
[in include/linux/ext2_fs_i.h]
struct ext2_inode_info {
__u32 i_data[15];
__u32 i_flags;
__u32 i_faddr;
__u8 i_frag_no;
__u8 i_frag_size;
__u16 i_osync;
__u32 i_file_acl;
__u32 i_dir_acl;
__u32 i_dtime;
__u32 i_version;
__u32 i_block_group;
__u32 i_next_alloc_block;
__u32 i_next_alloc_goal;
__u32 i_prealloc_block;
__u32 i_prealloc_count;
int i_new_inode:1; /* Is a freshly allocated inode */
};
[in net/ipv4/route.c]
struct fib_info
{
struct fib_info *fib_next;
struct fib_info *fib_prev;
__u32 fib_gateway;
struct device *fib_dev;
int fib_refcnt;
unsigned long fib_window;
unsigned short fib_flags;
unsigned short fib_mtu;
unsigned short fib_irtt;
};
[in net/ipv4/route.c]
struct fib_node
{
struct fib_node *fib_next;
__u32 fib_dst;
unsigned long fib_use;
struct fib_info *fib_info;
short fib_metric;
unsigned char fib_tos;
};
[in net/ipv4/route.c]
struct fib_zone
{
struct fib_zone *fz_next;
struct fib_node **fz_hash_table;
struct fib_node *fz_list;
int fz_nent;
int fz_logmask;
__u32 fz_mask;
};
オープンされたファイル、ソケット等は、それぞれ file データ構造体
によって表される。
[in
include/linux/fs.h]
struct file {
mode_t f_mode;
loff_t f_pos;
unsigned short f_flags;
unsigned short f_count;
unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin;
struct file *f_next, *f_prev;
int f_owner; /* pid or -pgrp where SIGIO should be sent */
struct inode * f_inode;
struct file_operations * f_op;
unsigned long f_version;
void *private_data; /* needed for tty driver, and maybe others */
};
file_struct データ構造体は、プロセスがオープンしたファイルについて
記述するものである。
[in
include/linux/sched.h]
struct files_struct {
int count;
fd_set close_on_exec;
fd_set open_fds;
struct file * fd[NR_OPEN];
};
[in
include/linux/fs.h]
#define NR_OPEN 256
[in include/linux/fs.h]
struct file_system_type {
struct super_block *(*read_super) (struct super_block *, void *, int);
const char *name;
int requires_dev;
struct file_system_type * next;
};
[in
fs/super.c]
static struct file_system_type *file_systems = (struct file_system_type *) NULL;
[in mm/page_alloc.c]
/*
* Free area management
*
* The free_area_list arrays point to the queue heads
* of the free areas of different sizes
*/
#define NR_MEM_LISTS 6
/* The start of this MUST match the start of "struct page" */
struct free_area_struct {
struct page *next;
struct page *prev;
unsigned int * map;
};
#define memory_head(x) ((struct page *)(x))
static struct free_area_struct free_area[NR_MEM_LISTS];
(訳注: 参考 linux-2.0.11)
struct free_area_struct {
struct page list;
unsigned int * map;
};
struct fs_struct {
int count;
unsigned short umask;
struct inode * root, * pwd;
};
gendisk データ構造体は、ハードディスクに関する情報を保持している。
これらは、初期化の過程で、ディスクが見いだされ、パーティションが検出される
際に使用される。
[in
include/linux/genhd.h]
struct hd_struct {
long start_sect;
long nr_sects;
};
struct gendisk {
int major; /* major number of driver */
const char *major_name; /* name of major driver */
int minor_shift; /* number of times minor is shifted to
get real minor */
int max_p; /* maximum partitions per device */
int max_nr; /* maximum number of real devices */
void (*init)(struct gendisk *);
/* Initialization called before we
do our thing */
struct hd_struct *part; /* partition table */
int *sizes; /* device size in blocks, copied to
blk_size[] */
int nr_real; /* number of real devices */
void *real_devices; /* internal use */
struct gendisk *next;
};
(訳注)
extern struct gendisk *gendisk_head; /* linked list of disks */
[in include/linux/netdevice.h]
struct hh_cache
{
struct hh_cache *hh_next;
void *hh_arp; /* Opaque pointer, used by
* any address resolution module,
* not only ARP.
*/
int hh_refcnt; /* number of users */
unsigned short hh_type; /* protocol identifier, f.e ETH_P_IP */
char hh_uptodate; /* hh_data is valid */
char hh_data[16]; /* cached hardware header */
};
[in drivers/block/ide.h]
typedef struct ide_drive_s {
special_t special; /* special action flags */
unsigned present : 1; /* drive is physically present */
unsigned noprobe : 1; /* from: hdx=noprobe */
unsigned keep_settings : 1; /* restore settings after drive reset */
unsigned busy : 1; /* currently doing revalidate_disk() */
unsigned removable : 1; /* 1 if need to do check_media_change */
unsigned using_dma : 1; /* disk is using dma for read/write */
unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */
unsigned unmask : 1; /* flag: okay to unmask other irqs */
unsigned no_unmask : 1; /* disallow setting unmask bit */
unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */
unsigned nobios : 1; /* flag: do not probe bios for drive */
unsigned slow : 1; /* flag: slow data port */
unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */
#if FAKE_FDISK_FOR_EZDRIVE
unsigned remap_0_to_1 : 1; /* flag: partitioned with ezdrive */
#endif /* FAKE_FDISK_FOR_EZDRIVE */
unsigned no_geom : 1; /* flag: do not set geometry */
ide_media_t media; /* disk, cdrom, tape, floppy */
select_t select; /* basic drive/head select reg value */
byte ctl; /* "normal" value for IDE_CONTROL_REG */
byte ready_stat; /* min status value for drive ready */
byte mult_count; /* current multiple sector setting */
byte mult_req; /* requested multiple sector setting */
byte tune_req; /* requested drive tuning setting */
byte io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
byte bad_wstat; /* used for ignoring WRERR_STAT */
byte sect0; /* offset of first sector for DM6:DDO */
byte usage; /* current "open()" count for drive */
byte head; /* "real" number of heads */
byte sect; /* "real" sectors per track */
byte bios_head; /* BIOS/fdisk/LILO number of heads */
byte bios_sect; /* BIOS/fdisk/LILO sectors per track */
unsigned short bios_cyl; /* BIOS/fdisk/LILO number of cyls */
unsigned short cyl; /* "real" number of cyls */
void *hwif; /* actually (ide_hwif_t *) */
struct wait_queue *wqueue; /* used to wait for drive in open() */
struct hd_driveid *id; /* drive model identification info */
struct hd_struct *part; /* drive partition table */
char name[4]; /* drive name, such as "hda" */
#ifdef CONFIG_BLK_DEV_IDECD
struct cdrom_info cdrom_info; /* for ide-cd.c */
#endif /* CONFIG_BLK_DEV_IDECD */
#ifdef CONFIG_BLK_DEV_IDETAPE
idetape_tape_t tape; /* for ide-tape.c */
#endif /* CONFIG_BLK_DEV_IDETAPE */
#ifdef CONFIG_BLK_DEV_IDEFLOPPY
void *floppy; /* for ide-floppy.c */
#endif /* CONFIG_BLK_DEV_IDEFLOPPY */
#ifdef CONFIG_BLK_DEV_IDESCSI
void *scsi; /* for ide-scsi.c */
#endif /* CONFIG_BLK_DEV_IDESCSI */
} ide_drive_t;
[in drivers/block/ide.h]
typedef struct hwif_s {
struct hwif_s *next; /* for linked-list in ide_hwgroup_t */
void *hwgroup; /* actually (ide_hwgroup_t *) */
unsigned short io_base; /* base io port addr */
unsigned short ctl_port; /* usually io_base+0x206 */
ide_drive_t drives[MAX_DRIVES]; /* drive info */
struct gendisk *gd; /* gendisk structure */
ide_tuneproc_t *tuneproc; /* routine to tune PIO mode for drives */
#if defined(CONFIG_BLK_DEV_HT6560B) || defined(CONFIG_BLK_DEV_PROMISE)
ide_selectproc_t *selectproc; /* tweaks hardware to select drive */
#endif
ide_dmaproc_t *dmaproc; /* dma read/write/abort routine */
unsigned long *dmatable; /* dma physical region descriptor table */
unsigned short dma_base; /* base addr for dma ports (triton) */
byte irq; /* our irq number */
byte major; /* our major number */
char name[5]; /* name of interface, eg. "ide0" */
byte index; /* 0 for ide0; 1 for ide1; ... */
hwif_chipset_t chipset; /* sub-module for tuning.. */
unsigned noprobe : 1; /* don't probe for this interface */
unsigned present : 1; /* this interface exists */
unsigned serialized : 1; /* serialized operation with mate hwif */
unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */
#ifdef CONFIG_BLK_DEV_PROMISE
unsigned is_promise2: 1; /* 2nd i/f on promise DC4030 */
#endif /* CONFIG_BLK_DEV_PROMISE */
#if (DISK_RECOVERY_TIME > 0)
unsigned long last_time; /* time when previous rq was done */
#endif
#ifdef CONFIG_BLK_DEV_IDECD
struct request request_sense_request; /* from ide-cd.c */
struct packet_command request_sense_pc; /* from ide-cd.c */
#endif /* CONFIG_BLK_DEV_IDECD */
#ifdef CONFIG_BLK_DEV_IDETAPE
ide_drive_t *tape_drive; /* Pointer to the tape on this interface */
#endif /* CONFIG_BLK_DEV_IDETAPE */
} ide_hwif_t;
... ... #ifndef _IDE_C extern ide_hwif_t ide_hwifs[]; /* master data repository */ #endif
VFS inode データ構造体は、ディスク上のファイルやディレクトリの
情報を保持するものである。
[in
include/linux/fs.h]
struct inode {
kdev_t i_dev;
unsigned long i_ino;
umode_t i_mode;
nlink_t i_nlink;
uid_t i_uid;
gid_t i_gid;
kdev_t i_rdev;
off_t i_size;
time_t i_atime;
time_t i_mtime;
time_t i_ctime;
unsigned long i_blksize;
unsigned long i_blocks;
unsigned long i_version;
unsigned long i_nrpages;
struct semaphore i_sem;
struct inode_operations *i_op;
struct super_block *i_sb;
struct wait_queue *i_wait;
struct file_lock *i_flock;
struct vm_area_struct *i_mmap;
struct page *i_pages;
struct dquot *i_dquot[MAXQUOTAS];
struct inode *i_next, *i_prev;
struct inode *i_hash_next, *i_hash_prev;
struct inode *i_bound_to, *i_bound_by;
struct inode *i_mount;
unsigned short i_count;
unsigned short i_flags;
unsigned char i_lock;
unsigned char i_dirt;
unsigned char i_pipe;
unsigned char i_sock;
unsigned char i_seek;
unsigned char i_update;
unsigned short i_writecount;
union {
struct pipe_inode_info pipe_i;
struct minix_inode_info minix_i;
struct ext_inode_info ext_i;
struct ext2_inode_info ext2_i;
struct hpfs_inode_info hpfs_i;
struct msdos_inode_info msdos_i;
struct umsdos_inode_info umsdos_i;
struct iso_inode_info isofs_i;
struct nfs_inode_info nfs_i;
struct xiafs_inode_info xiafs_i;
struct sysv_inode_info sysv_i;
struct affs_inode_info affs_i;
struct ufs_inode_info ufs_i;
struct socket socket_i;
void *generic_ip;
} u;
};
(訳注) [in fs/inode.c]
static struct inode * first_inode;
ipc_perm データ構造体は、System V IPC オブジェクトのアクセス
許可情報を記述するものである。
[in
include/linux/ipc.h]
struct ipc_perm
{
key_t key;
ushort uid; /* owner euid and egid */
ushort gid;
ushort cuid; /* creator euid and egid */
ushort cgid;
ushort mode; /* access modes see mode flags below */
ushort seq; /* sequence number */
};
[in include/net/ip.h]
struct ipfrag
{
int offset; /* offset of fragment in IP datagram */
int end; /* last byte of data in datagram */
int len; /* length of this fragment */
struct sk_buff *skb; /* complete received fragment */
unsigned char *ptr; /* pointer into real fragment data */
struct ipfrag *next; /* linked list pointers */
struct ipfrag *prev;
};
[in include/net/ip.h]
struct ipq
{
unsigned char *mac; /* pointer to MAC header */
struct iphdr *iph; /* pointer to IP header */
int len; /* total length of original datagram */
short ihlen; /* length of the IP header */
short maclen; /* length of the MAC header */
struct timer_list timer; /* when will this queue expire? */
struct ipfrag *fragments; /* linked list of received fragments */
struct ipq *next; /* linked list pointers */
struct ipq *prev;
struct device *dev; /* Device - for icmp replies */
};
static struct ipq *ipqueue = NULL;
[in include/linux/interrupt.h]
irqaction データ構造体は、システムの割り込みハンドラーを記述
するために使用されるものである。
struct irqaction {
void (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
unsigned long mask;
const char *name;
void *dev_id;
struct irqaction *next;
};
[in arch/*/kernel/irq.c]( i386, alpha)
static struct irqaction *irq_action[16] = {
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL
};
typedef unsigned short kdev_t;
Linux が理解するバイナリファイルのフォーマットは、それぞれ linux_binfmt データ構造体によって表現される。
[in
include/linux/binfmts.h]
struct linux_binfmt {
struct linux_binfmt * next;
long *use_count;
int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
int (*load_shlib)(int fd);
int (*core_dump)(long signr, struct pt_regs * regs);
};
mem_map_t データ構造体(ページとも呼ばれる)は、物理メモリにある
個々のページに関する情報を保持するために使用される。
[in
include/linux/mm.h]
typedef struct page {
/* these must be first (free area handling) */
struct page *next;
struct page *prev;
struct inode *inode;
unsigned long offset;
struct page *next_hash;
atomic_t count;
unsigned flags; /* atomic flags, some possibly
updated asynchronously */
unsigned dirty:16,
age:8;
struct wait_queue *wait;
struct page *prev_hash;
struct buffer_head *buffers;
unsigned long swap_unlock_entry;
unsigned long map_nr; /* page->map_nr == page - mem_map */
} mem_map_t;
.....
.....
extern mem_map_t * mem_map;
extern struct page * page_hash_table[PAGE_HASH_SIZE];
mm_struct データ構造体は、タスクもしくはプロセスの仮想メモリを
記述するために使用される。
[in
include/linux/sched.h]
struct mm_struct {
int count;
pgd_t * pgd;
unsigned long context;
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack, start_mmap;
unsigned long arg_start, arg_end, env_start, env_end;
unsigned long rss, total_vm, locked_vm;
unsigned long def_flags;
struct vm_area_struct * mmap;
struct vm_area_struct * mmap_avl;
struct semaphore mmap_sem;
};
struct module {
struct module *next;
struct module_ref *ref; /* the list of modules that refer to me */
struct symbol_table *symtab;
const char *name;
int size; /* size of module in pages */
void* addr; /* address of module */
int state;
void (*cleanup)(void); /* cleanup routine */
};
[in kernel/module.c]
static struct module kernel_module; static struct module *module_list = &kernel_module;
[in include/linux/msg.h]
struct msg {
struct msg *msg_next; /* next message on queue */
long msg_type;
char *msg_spot; /* message text address */
time_t msg_stime; /* msgsnd time */
short msg_ts; /* message text size */
};
[in include/linux/msg.h]
struct msqid_ds {
struct ipc_perm msg_perm;
struct msg *msg_first; /* first message on queue */
struct msg *msg_last; /* last message in queue */
time_t msg_stime; /* last msgsnd time */
time_t msg_rtime; /* last msgrcv time */
time_t msg_ctime; /* last change time */
struct wait_queue *wwait;
struct wait_queue *rwait;
ushort msg_cbytes; /* current number of bytes on queue */
ushort msg_qnum; /* number of messages in queue */
ushort msg_qbytes; /* max number of bytes on queue */
ushort msg_lspid; /* pid of last msgsnd */
ushort msg_lrpid; /* last receive pid */
};
...
...
#define MSGMNI 128 /* <= 1K */ /* max # of msg queue identifiers */
[in ipc/msg.c]
static struct msqid_ds *msgque[MSGMNI];
[in include/linux/netdevice.h]
struct packet_type {
unsigned short type; /* This is really htons(ether_type). */
struct device * dev;
int (*func) (struct sk_buff *, struct device *,
struct packet_type *);
void *data;
struct packet_type *next;
};
[in net/core/dev.c]
struct packet_type *ptype_base[16]; struct packet_type *ptype_all = NULL; /* Taps */
システム上のすべての PCI バスは、pci_bus データ構造体によって
表現されている。
[in
include/linux/pci.h]
struct pci_bus {
struct pci_bus *parent; /* parent bus this bridge is on */
struct pci_bus *children; /* chain of P2P bridges on this bus */
struct pci_bus *next; /* chain of all PCI buses */
struct pci_dev *self; /* bridge device as seen by parent */
struct pci_dev *devices; /* devices behind this bridge */
void *sysdata; /* hook for sys-specific extension */
unsigned char number; /* bus number */
unsigned char primary; /* number of primary bridge */
unsigned char secondary; /* number of secondary bridge */
unsigned char subordinate; /* max number of subordinate buses */
};
...
...
extern struct pci_bus pci_root; /* root bus */
PCI-PCI ブリッジと PCI-ISA ブリッジを含む、システム上のすべての PCI デバイス
は、pci_dev データ構造体によって表現される。
[in
include/linux/pci.h]
/*
* There is one pci_dev structure for each slot-number/function-number
* combination:
*/
struct pci_dev {
struct pci_bus *bus; /* bus this device is on */
struct pci_dev *sibling; /* next device on this bus */
struct pci_dev *next; /* chain of all devices */
void *sysdata; /* hook for sys-specific extension */
unsigned int devfn; /* encoded device & function index */
unsigned short vendor;
unsigned short device;
unsigned int class; /* 3 bytes: (base,sub,prog-if) */
unsigned int master : 1; /* set if device is master capable */
/*
* In theory, the irq level can be read from configuration
* space and all would be fine. However, old PCI chips don't
* support these registers and return 0 instead. For example,
* the Vision864-P rev 0 chip can uses INTA, but returns 0 in
* the interrupt line and pin registers. pci_init()
* initializes this field with the value at PCI_INTERRUPT_LINE
* and it is the job of pcibios_fixup() to change it if
* necessary. The field must not be 0 unless the device
* cannot generate interrupts at all.
*/
unsigned char irq; /* irq generated by this device */
};
...
...
extern struct pci_dev *pci_devices; /* list of all devices */
[in include/linux/pipe_fs_i.h]
struct pipe_inode_info {
struct wait_queue * wait;
char * base;
unsigned int start;
unsigned int len;
unsigned int lock;
unsigned int rd_openers;
unsigned int wr_openers;
unsigned int readers;
unsigned int writers;
};
#define PIPE_WAIT(inode) ((inode).u.pipe_i.wait)
#define PIPE_BASE(inode) ((inode).u.pipe_i.base)
#define PIPE_START(inode) ((inode).u.pipe_i.start)
#define PIPE_LEN(inode) ((inode).u.pipe_i.len)
#define PIPE_RD_OPENERS(inode) ((inode).u.pipe_i.rd_openers)
#define PIPE_WR_OPENERS(inode) ((inode).u.pipe_i.wr_openers)
#define PIPE_READERS(inode) ((inode).u.pipe_i.readers)
#define PIPE_WRITERS(inode) ((inode).u.pipe_i.writers)
#define PIPE_LOCK(inode) ((inode).u.pipe_i.lock)
#define PIPE_SIZE(inode) PIPE_LEN(inode)
...
...
[in include/linux/net.h]
struct proto_ops {
int family;
int (*create) (struct socket *sock, int protocol);
int (*dup) (struct socket *newsock, struct socket *oldsock);
int (*release) (struct socket *sock, struct socket *peer);
int (*bind) (struct socket *sock, struct sockaddr *umyaddr,
int sockaddr_len);
int (*connect) (struct socket *sock, struct sockaddr *uservaddr,
int sockaddr_len, int flags);
int (*socketpair) (struct socket *sock1, struct socket *sock2);
int (*accept) (struct socket *sock, struct socket *newsock,
int flags);
int (*getname) (struct socket *sock, struct sockaddr *uaddr,
int *usockaddr_len, int peer);
int (*select) (struct socket *sock, int sel_type,
select_table *wait);
int (*ioctl) (struct socket *sock, unsigned int cmd,
unsigned long arg);
int (*listen) (struct socket *sock, int len);
int (*shutdown) (struct socket *sock, int flags);
int (*setsockopt) (struct socket *sock, int level, int optname,
char *optval, int optlen);
int (*getsockopt) (struct socket *sock, int level, int optname,
char *optval, int *optlen);
int (*fcntl) (struct socket *sock, unsigned int cmd,
unsigned long arg);
int (*sendmsg) (struct socket *sock, struct msghdr *m,
int total_len, int nonblock, int flags);
int (*recvmsg) (struct socket *sock, struct msghdr *m,
int total_len, int nonblock, int flags, int *addr_len);
};
[in net/socket.c]
static struct proto_ops *pops[NPROTO];
request データ構造体は、システム上のブロックデバイスに対して
リクエストを送るために使用される。そのリクエストは、常に、バッファキャッシュに
対するデータブロックの読み書きでなければならない。
[in
include/linux/blkdev.h]
struct request {
volatile int rq_status;
#define RQ_INACTIVE (-1)
#define RQ_ACTIVE 1
#define RQ_SCSI_BUSY 0xffff
#define RQ_SCSI_DONE 0xfffe
#define RQ_SCSI_DISCONNECTING 0xffe0
kdev_t rq_dev;
int cmd; /* READ or WRITE */
int errors;
unsigned long sector;
unsigned long nr_sectors;
unsigned long current_nr_sectors;
char * buffer;
struct semaphore * sem;
struct buffer_head * bh;
struct buffer_head * bhtail;
struct request * next;
};
(訳注) [in drivers/block/ll_rw_blk.c]
static struct request all_requests[NR_REQUEST];
rtable データ構造体は、ある IP ホストにパケットを送信する際に
取るべきルートに関する情報を保持するもので、IP ルートキャッシュの内部で
使用される。
[in
include/net/route.h]
struct rtable
{
struct rtable *rt_next;
__u32 rt_dst;
__u32 rt_src;
__u32 rt_gateway;
atomic_t rt_refcnt;
atomic_t rt_use;
unsigned long rt_window;
atomic_t rt_lastuse;
struct hh_cache *rt_hh;
struct device *rt_dev;
unsigned short rt_flags;
unsigned short rt_mtu;
unsigned short rt_irtt;
unsigned char rt_tos;
};
[in net/ipv4/route.c]
struct rtable *ip_rt_hash_table[RT_HASH_DIVISOR];
(簡略化しています)
[in
drivers/scsi/scsi.h]
typedef struct scsi_cmnd {
struct Scsi_Host * host;
Scsi_Device * device;
unsigned char target, lun, channel;
unsigned char cmd_len;
unsigned char old_cmd_len;
struct scsi_cmnd *next, *prev, *device_next, *reset_chain;
/* These elements define the operation we are about to perform */
unsigned char cmnd[12];
unsigned request_bufflen; /* Actual request size */
void * request_buffer; /* Actual requested buffer */
/* These elements define the operation we ultimately want to perform */
unsigned char data_cmnd[12];
unsigned short old_use_sg; /* We save use_sg here when requesting
* sense info */
unsigned short use_sg; /* Number of pieces of scatter-gather */
unsigned short sglist_len; /* size of malloc'd scatter-gather list */
unsigned short abort_reason;/* If the mid-level code requests an
* abort, this is the reason. */
unsigned bufflen; /* Size of data buffer */
void *buffer; /* Data buffer */
unsigned underflow; /* Return error if less than this amount is
* transfered */
unsigned transfersize; /* How much we are guaranteed to transfer with
* each SCSI transfer (ie, between disconnect /
* reconnects. Probably == sector size */
struct request request; /* A copy of the command we are working on */
unsigned char sense_buffer[16]; /* Sense for this command, if needed */
unsigned long serial_number;
unsigned long serial_number_at_timeout;
int retries;
int allowed;
int timeout_per_command, timeout_total, timeout;
unsigned volatile char internal_timeout;
unsigned flags;
int this_count;
void (*scsi_done)(struct scsi_cmnd *);
void (*done)(struct scsi_cmnd *); /* Mid-level done function */
Scsi_Pointer SCp; /* Scratchpad used by some host adapters */
unsigned char * host_scribble;
int result; /* Status code from lower level driver */
unsigned char tag; /* SCSI-II queued command tag */
unsigned long pid; /* Process ID, starts at 0 */
} Scsi_Cmnd;
[in drivers/scsi/scsi.h]
typedef struct scsi_device {
struct scsi_device * next; /* Used for linked list */
unsigned char id, lun, channel;
unsigned int manufacturer; /* Manufacturer of device, for using
* vendor-specific cmd's */
int attached; /* # of high level drivers attached to
* this */
int access_count; /* Count of open channels/mounts */
struct wait_queue * device_wait;/* Used to wait if device is busy */
struct Scsi_Host * host;
void (*scsi_request_fn)(void); /* Used to jumpstart things after an
* ioctl */
struct scsi_cmnd *device_queue; /* queue of SCSI Command structures */
void *hostdata; /* available to low-level driver */
char type;
char scsi_level;
char vendor[8], model[16], rev[4];
unsigned char current_tag; /* current tag */
unsigned char sync_min_period; /* Not less than this period */
unsigned char sync_max_offset; /* Not greater than this offset */
unsigned char queue_depth; /* How deep a queue to use */
unsigned writeable:1;
unsigned removable:1;
unsigned random:1;
unsigned has_cmdblocks:1;
unsigned changed:1; /* Data invalid due to media change */
unsigned busy:1; /* Used to prevent races */
unsigned lockable:1; /* Able to prevent media removal */
unsigned borken:1; /* Tell the Seagate driver to be
* painfully slow on this device */
unsigned tagged_supported:1; /* Supports SCSI-II tagged queuing */
unsigned tagged_queue:1; /* SCSI-II tagged queuing enabled */
unsigned disconnect:1; /* can disconnect */
unsigned soft_reset:1; /* Uses soft reset option */
unsigned sync:1; /* Negotiate for sync transfers */
unsigned single_lun:1; /* Indicates we should only allow I/O to
* one of the luns for the device at a
* time. */
unsigned was_reset:1; /* There was a bus reset on the bus for
* this device */
unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN
* because we did a bus reset. */
} Scsi_Device;
...
...
extern Scsi_Device * scsi_devices;
[in drivers/scsi/hosts.h]
struct Scsi_Device_Template
{
struct Scsi_Device_Template * next;
const char * name;
const char * tag;
long * usage_count; /* Used for loadable modules */
unsigned char scsi_type;
unsigned char major;
unsigned char nr_dev; /* Number currently attached */
unsigned char dev_noticed; /* Number of devices detected. */
unsigned char dev_max; /* Current size of arrays */
unsigned blk:1; /* 0 if character device */
int (*detect)(Scsi_Device *); /* Returns 1 if we can attach this device */
int (*init)(void); /* Sizes arrays based
upon number of devices
* detected */
void (*finish)(void); /* Perform initialization after attachment */
int (*attach)(Scsi_Device *); /* Attach devices to arrays */
void (*detach)(Scsi_Device *);
};
...
...
extern struct Scsi_Device_Template * scsi_devicelist;
ypedef struct scsi_disk {
unsigned capacity; /* size in blocks */
unsigned sector_size; /* size in bytes */
Scsi_Device *device;
unsigned char ready; /* flag ready for FLOPTICAL */
unsigned char write_prot; /* flag write_protect for rmvable dev */
unsigned char sector_bit_size; /* sector_size = 2
to the bit size power */
unsigned char sector_bit_shift; /* power of 2 sectors per FS block */
unsigned ten:1; /* support ten byte read / write */
unsigned remap:1; /* support remapping */
unsigned has_part_table:1; /* has partition table */
} Scsi_Disk;
extern Scsi_Disk * rscsi_disks;
(簡略化しています)
[in
drivers/scsi/hosts.h]
struct Scsi_Host
{
struct Scsi_Host * next;
unsigned short extra_bytes;
volatile unsigned char host_busy;
char host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
unsigned long last_reset;
struct wait_queue *host_wait;
Scsi_Cmnd *host_queue;
Scsi_Host_Template * hostt;
unsigned int max_id;
unsigned int max_lun;
unsigned int max_channel;
struct Scsi_Host * block;
unsigned wish_block:1;
/* These parameters should be set by the detect routine */
unsigned char *base;
unsigned int io_port;
unsigned char n_io_port;
unsigned char irq;
unsigned char dma_channel;
unsigned int unique_id;
int this_id;
int can_queue;
short cmd_per_lun;
short unsigned int sg_tablesize;
unsigned unchecked_isa_dma:1;
unsigned use_clustering:1;
unsigned loaded_as_module:1;
void (*select_queue_depths)(struct Scsi_Host *, Scsi_Device *);
unsigned long hostdata[0]; /* Used for storage of host specific stuff */
};
(簡略化しています。)
[in
drivers/scsi/hosts.h]
typedef struct SHT
{
/* Used with loadable modules so we can construct a linked list. */
struct SHT * next;
/* Used with loadable modules so that
we know when it is safe to unload */
long * usage_count;
struct proc_dir_entry *proc_dir;
int (*proc_info)(char *, char **, off_t, int, int, int);
const char *name;
int (* detect)(struct SHT *);
int (*release)(struct Scsi_Host *);
const char *(* info)(struct Scsi_Host *);
int (* command)(Scsi_Cmnd *);
int (* queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int (* abort)(Scsi_Cmnd *);
int (* reset)(Scsi_Cmnd *, unsigned int);
int (* slave_attach)(int, int);
int (* bios_param)(Disk *, kdev_t, int []);
int can_queue;
int this_id;
short unsigned int sg_tablesize;
short cmd_per_lun;
unsigned char present;
unsigned unchecked_isa_dma:1;
unsigned use_clustering:1;
} Scsi_Host_Template;
extern struct Scsi_Host * scsi_hostlist;
[in
drivers/scsi/hosts.c]
static Scsi_Host_Template builtin_scsi_hosts[] = ... ...
[in include/linux/sem.h]
struct sem {
short semval; /* current value */
short sempid; /* pid of last operation */
};
セマフォは、重要なデータ構造やコード領域を保護するために利用される仕組み
である。
[in include/asm/semaphore.h](
i386,
alpha]
struct semaphore {
int count;
int waking;
int lock ; /* to make waking testing atomic */
struct wait_queue *wait;
};
[in include/linux/sem.h]
struct semid_ds {
struct ipc_perm sem_perm; /* permissions .. see ipc.h */
time_t sem_otime; /* last semop time */
time_t sem_ctime; /* last change time */
struct sem *sem_base; /* ptr to first semaphore in array */
struct sem_queue *sem_pending; /* pending operations to be processed */
struct sem_queue **sem_pending_last; /* last pending operation */
struct sem_undo *undo; /* undo requests on this array */
ushort sem_nsems; /* no. of semaphores in array */
};
[in ipc/sem.c]
static struct semid_ds *semary[SEMMNI];
[in include/linux/sem.h]
struct sem_queue {
struct sem_queue * next; /* next entry in the queue */
struct sem_queue ** prev; /* previous entry in the queue,
*(q->prev) == q */
struct wait_queue * sleeper; /* sleeping process */
struct sem_undo * undo; /* undo structure */
int pid; /* process id of requesting process */
int status; /* completion status of operation */
struct semid_ds * sma; /* semaphore array for operations */
struct sembuf * sops; /* array of pending operations */
int nsops; /* number of operations */
};
[in include/linux/sem.h]
struct sem_undo {
struct sem_undo * proc_next; /* next entry on this process */
struct sem_undo * id_next; /* next entry on this semaphore set */
int semid; /* semaphore set identifier */
short * semadj; /* array of adjustments,
one per semaphore */
};
[in include/linux/shm.h]
struct shmid_ds {
struct ipc_perm shm_perm; /* operation perms */
int shm_segsz; /* size of segment (bytes) */
time_t shm_atime; /* last attach time */
time_t shm_dtime; /* last detach time */
time_t shm_ctime; /* last change time */
unsigned short shm_cpid; /* pid of creator */
unsigned short shm_lpid; /* pid of last operator */
short shm_nattch; /* no. of current attaches */
/* the following are private */
unsigned short shm_npages; /* size of segment (pages) */
unsigned long *shm_pages; /* array of ptrs to frames -> SHMMAX */
struct vm_area_struct *attaches; /* descriptors for attaches */
};
[in ipc/shm.c]
static struct shmid_ds *shm_segs[SHMMNI];
[in include/asm/signal.h]( i386, alpha)
struct sigaction {
__sighandler_t sa_handler;
sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};
struct signal_struct {
int count;
struct sigaction action[32];
};
sk_buff データ構造体は、ネットワークデータがプロトコル階層を移動
する際に、そのデータを記述するために使用されるものである。
[in
include/linux/skbuff.h]
struct sk_buff
{
struct sk_buff *next; /* Next buffer in list */
struct sk_buff *prev; /* Previous buffer in list */
struct sk_buff_head *list; /* List we are on */
int magic_debug_cookie;
struct sk_buff *link3; /* Link for IP protocol level buffer chains*/
struct sock *sk; /* Socket we are owned by */
unsigned long when; /* used to compute rtt's */
struct timeval stamp; /* Time we arrived */
struct device *dev; /* Device we arrived on/are leaving by */
union
{
struct tcphdr *th;
struct ethhdr *eth;
struct iphdr *iph;
struct udphdr *uh;
unsigned char *raw;
/* for passing file handles in a unix domain socket */
void *filp;
} h;
union
{
/* As yet incomplete physical layer views */
unsigned char *raw;
struct ethhdr *ethernet;
} mac;
struct iphdr *ip_hdr; /* For IPPROTO_RAW */
unsigned long len; /* Length of actual data */
unsigned long csum; /* Checksum */
__u32 saddr; /* IP source address */
__u32 daddr; /* IP target address */
__u32 raddr; /* IP next hop address */
__u32 seq; /* TCP sequence number */
__u32 end_seq; /* seq [+ fin] [+ syn] + datalen */
__u32 ack_seq; /* TCP ack sequence number */
unsigned char proto_priv[16];
volatile char acked, /* Are we acked ? */
used, /* Are we in use ? */
free, /* How to free this buffer */
arp; /* Has IP/ARP resolution finished */
unsigned char tries, /* Times tried */
lock, /* Are we locked ? */
localroute, /* Local routing asserted for this frame */
pkt_type, /* Packet class */
pkt_bridged, /* Tracker for bridging */
ip_summed; /* Driver fed us an IP checksum */
#define PACKET_HOST 0 /* To us */
#define PACKET_BROADCAST 1 /* To all */
#define PACKET_MULTICAST 2 /* To group */
#define PACKET_OTHERHOST 3 /* To someone else */
unsigned short users; /* User count - see datagram.c,tcp.c */
unsigned short protocol; /* Packet protocol from driver. */
unsigned int truesize; /* Buffer size */
atomic_t count; /* reference count */
struct sk_buff *data_skb; /* Link to the actual data skb */
unsigned char *head; /* Head of buffer */
unsigned char *data; /* Data head pointer */
unsigned char *tail; /* Tail pointer */
unsigned char *end; /* End pointer */
void (*destructor)(struct sk_buff *); /* Destruct function */
__u16 redirport; /* Redirect port */
};
struct sk_buff_head
{
struct sk_buff * next;
struct sk_buff * prev;
__u32 qlen; /* Must be same length as a pointer
for using debugging */
#if CONFIG_SKB_CHECK
int magic_debug_cookie;
#endif
};
[in net/core/dev.c]
static struct sk_buff_head backlog;
個々の sock データ構造体は、BSD ソケットに関するプロトコル固有の
情報を保持するためのものである。例えば、INET(Internet Address Domain)ソケット
の場合、このデータ構造体には、TCP/IP と UDP/IP 固有の情報のすべてが保持される
ことになる。
[in
include/net/sock.h]
struct sock
{
/* This must be first. */
struct sock *sklist_next;
struct sock *sklist_prev;
struct options *opt;
atomic_t wmem_alloc;
atomic_t rmem_alloc;
unsigned long allocation; /* Allocation mode */
__u32 write_seq;
__u32 sent_seq;
__u32 acked_seq;
__u32 copied_seq;
__u32 rcv_ack_seq;
unsigned short rcv_ack_cnt; /* count of same ack */
__u32 window_seq;
__u32 fin_seq;
__u32 urg_seq;
__u32 urg_data;
__u32 syn_seq;
int users; /* user count */
/*
* Not all are volatile, but some are, so we
* might as well say they all are.
*/
volatile char dead,
urginline,
intr,
blog,
done,
reuse,
keepopen,
linger,
delay_acks,
destroy,
ack_timed,
no_check,
zapped,
broadcast,
nonagle,
bsdism;
unsigned long lingertime;
int proc;
struct sock *next;
struct sock **pprev;
struct sock *bind_next;
struct sock **bind_pprev;
struct sock *pair;
int hashent;
struct sock *prev;
struct sk_buff *volatile send_head;
struct sk_buff *volatile send_next;
struct sk_buff *volatile send_tail;
struct sk_buff_head back_log;
struct sk_buff *partial;
struct timer_list partial_timer;
long retransmits;
struct sk_buff_head write_queue,
receive_queue;
struct proto *prot;
struct wait_queue **sleep;
__u32 daddr;
__u32 saddr; /* Sending source */
__u32 rcv_saddr; /* Bound address */
unsigned short max_unacked;
unsigned short window;
__u32 lastwin_seq; /* sequence number when we last
updated the window we offer */
__u32 high_seq; /* sequence number when we did
current fast retransmit */
volatile unsigned long ato; /* ack timeout */
volatile unsigned long lrcvtime; /* jiffies at last data rcv */
volatile unsigned long idletime; /* jiffies at last rcv */
unsigned int bytes_rcv;
/*
* mss is min(mtu, max_window)
*/
unsigned short mtu; /* mss negotiated in the syn's */
volatile unsigned short mss; /* current eff. mss - can change */
volatile unsigned short user_mss; /* mss requested by user in ioctl */
volatile unsigned short max_window;
unsigned long window_clamp;
unsigned int ssthresh;
unsigned short num;
volatile unsigned short cong_window;
volatile unsigned short cong_count;
volatile unsigned short packets_out;
volatile unsigned short shutdown;
volatile unsigned long rtt;
volatile unsigned long mdev;
volatile unsigned long rto;
volatile unsigned short backoff;
int err, err_soft;/* Soft holds errors that don't
cause failure but are the cause
of a persistent failure not
just 'timed out' */
unsigned char protocol;
volatile unsigned char state;
unsigned char ack_backlog;
unsigned char max_ack_backlog;
unsigned char priority;
unsigned char debug;
int rcvbuf;
int sndbuf;
unsigned short type;
unsigned char localroute; /* Route locally only */
/*
* This is where all the private (optional) areas that don't
* overlap will eventually live.
*/
union
{
struct unix_opt af_unix;
#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
struct atalk_sock af_at;
#endif
#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
struct ipx_opt af_ipx;
#endif
#ifdef CONFIG_INET
struct inet_packet_opt af_packet;
#ifdef CONFIG_NUTCP
struct tcp_opt af_tcp;
#endif
#endif
} protinfo;
/*
* IP 'private area'
*/
int ip_ttl; /* TTL setting */
int ip_tos; /* TOS */
struct tcphdr dummy_th;
struct timer_list keepalive_timer; /* TCP keepalive hack */
struct timer_list retransmit_timer; /* TCP retransmit timer */
struct timer_list delack_timer; /* TCP delayed ack timer */
int ip_xmit_timeout; /* Why the timeout is running */
struct rtable *ip_route_cache; /* Cached output route */
unsigned char ip_hdrincl; /* Include headers ? */
#ifdef CONFIG_IP_MULTICAST
int ip_mc_ttl; /* Multicasting TTL */
int ip_mc_loop; /* Loopback */
char ip_mc_name[MAX_ADDR_LEN]; /* Multicast device name */
struct ip_mc_socklist *ip_mc_list; /* Group array */
#endif
/*
* This part is used for the timeout functions (timer.c).
*/
int timeout; /* What are we waiting for? */
struct timer_list timer; /* This is the TIME_WAIT/receive
* timer when we are doing IP
*/
struct timeval stamp;
/*
* Identd
*/
struct socket *socket;
/*
* Callbacks
*/
void (*state_change)(struct sock *sk);
void (*data_ready)(struct sock *sk,int bytes);
void (*write_space)(struct sock *sk);
void (*error_report)(struct sock *sk);
};
(訳注)[in net/ipv4/udp.c]
struct sock *udp_hash[UDP_HTABLE_SIZE];
(訳注)[in net/ipv4/tcp.c]
struct sock *tcp_established_hash[TCP_HTABLE_SIZE]; ... struct sock *tcp_listening_hash[TCP_LHTABLE_SIZE]; ... struct sock *tcp_bound_hash[TCP_BHTABLE_SIZE];
struct sockaddr
{
unsigned short sa_family; /* address family, AF_xxx */
char sa_data[14]; /* 14 bytes of protocol address */
};
個々の socket データ構造体は、BSD ソケットに関する情報を保持する
ものである。しかし、これは単独で存在するのではなく、VFS inode
データ構造体の一部として存在するものである。
[in
include/linux/net.h]
struct socket {
short type; /* SOCK_STREAM, ... */
socket_state state;
long flags;
struct proto_ops *ops; /* protocols do most everything */
void *data; /* protocol data */
struct socket *conn; /* server socket connected to */
struct socket *iconn; /* incomplete client conn.s */
struct socket *next;
struct wait_queue **wait; /* ptr to place to wait on */
struct inode *inode;
struct fasync_struct *fasync_list; /* Asynchronous wake up list */
struct file *file; /* File back pointer for gc */
};
[in include/linux/fs.h]
struct super_block {
kdev_t s_dev;
unsigned long s_blocksize;
unsigned char s_blocksize_bits;
unsigned char s_lock;
unsigned char s_rd_only;
unsigned char s_dirt;
struct file_system_type *s_type;
struct super_operations *s_op;
struct dquot_operations *dq_op;
unsigned long s_flags;
unsigned long s_magic;
unsigned long s_time;
struct inode * s_covered;
struct inode * s_mounted;
struct wait_queue * s_wait;
union {
struct minix_sb_info minix_sb;
struct ext_sb_info ext_sb;
struct ext2_sb_info ext2_sb;
struct hpfs_sb_info hpfs_sb;
struct msdos_sb_info msdos_sb;
struct isofs_sb_info isofs_sb;
struct nfs_sb_info nfs_sb;
struct xiafs_sb_info xiafs_sb;
struct sysv_sb_info sysv_sb;
struct affs_sb_info affs_sb;
struct ufs_sb_info ufs_sb;
void *generic_sbp;
} u;
};
...
...
extern struct super_block super_blocks[NR_SUPER];
typedef struct swap_control_v5
{
int sc_max_page_age;
int sc_page_advance;
int sc_page_decline;
int sc_page_initial_age;
int sc_max_buff_age;
int sc_buff_advance;
int sc_buff_decline;
int sc_buff_initial_age;
int sc_age_cluster_fract;
int sc_age_cluster_min;
int sc_pageout_weight;
int sc_bufferout_weight;
int sc_buffer_grace;
int sc_nr_buffs_to_free;
int sc_nr_pages_to_free;
enum RCL_POLICY sc_policy;
} swap_control_v5;
typedef struct swap_control_v5 swap_control_t;
extern swap_control_t swap_control;
[in mm/swap.c]
/*
* Constants for the page aging mechanism: the maximum age (actually,
* the maximum "youthfulness"); the quanta by which pages rejuvenate
* and age; and the initial age for new pages.
*/
swap_control_t swap_control = {
20, 3, 1, 3, /* Page aging */
10, 2, 2, 4, /* Buffer aging */
32, 4, /* Aging cluster */
8192, 8192, /* Pageout and bufferout weights */
-200, /* Buffer grace */
1, 1, /* Buffs/pages to free */
RCL_ROUND_ROBIN /* Balancing policy */
};
[in include/linux/swap.h]
struct swap_info_struct {
unsigned int flags;
kdev_t swap_device;
struct inode * swap_file;
unsigned char * swap_map;
unsigned char * swap_lockmap;
int lowest_bit;
int highest_bit;
int cluster_next;
int cluster_nr;
int prio; /* swap priority */
int pages;
unsigned long max;
int next; /* next entry on swap list */
};
extern int nr_swap_pages;
extern int nr_free_pages;
extern atomic_t nr_async_pages;
extern int min_free_pages;
extern int free_pages_low;
extern int free_pages_high;
[in mm/swap.c]
/* * We identify three levels of free memory. We never let free mem * fall below the min_free_pages except for atomic allocations. We * start background swapping if we fall below free_pages_high free * pages, and we begin intensive swapping below free_pages_low. * * Keep these three variables contiguous for sysctl(2). */ int min_free_pages = 20; int free_pages_low = 30; int free_pages_high = 40; /* We track the number of pages currently being asynchronously swapped out, so that we don't try to swap TOO many pages out at once */ atomic_t nr_async_pages = 0;
個々の task_struct データ構造体は、システム上の、ひとつのプロセス
もしくはタスクについて記述するものである。
[in
include/linux/sched.h]
struct task_struct {
/* these are hardcoded - don't touch */
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
long counter;
long priority;
unsigned long signal;
unsigned long blocked; /* bitmap of masked signals */
unsigned long flags; /* per process flags, defined below */
int errno;
long debugreg[8]; /* Hardware debugging registers */
struct exec_domain *exec_domain;
/* various fields */
struct linux_binfmt *binfmt;
struct task_struct *next_task, *prev_task;
struct task_struct *next_run, *prev_run;
unsigned long saved_kernel_stack;
unsigned long kernel_stack_page;
int exit_code, exit_signal;
/* ??? */
unsigned long personality;
int dumpable:1;
int did_exec:1;
int pid;
int pgrp;
int tty_old_pgrp;
int session;
/* boolean value for session group leader */
int leader;
int groups[NGROUPS];
/*
* pointers to (original) parent process, youngest child, younger sibling,
* older sibling, respectively. (p->father can be replaced with
* p->p_pptr->pid)
*/
struct task_struct *p_opptr, *p_pptr, *p_cptr,
*p_ysptr, *p_osptr;
struct wait_queue *wait_chldexit;
unsigned short uid,euid,suid,fsuid;
unsigned short gid,egid,sgid,fsgid;
unsigned long timeout, policy, rt_priority;
unsigned long it_real_value, it_prof_value, it_virt_value;
unsigned long it_real_incr, it_prof_incr, it_virt_incr;
struct timer_list real_timer;
long utime, stime, cutime, cstime, start_time;
/* mm fault and swap info: this can arguably be seen as either
mm-specific or thread-specific */
unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
int swappable:1;
unsigned long swap_address;
unsigned long old_maj_flt; /* old value of maj_flt */
unsigned long dec_flt; /* page fault count of the last time */
unsigned long swap_cnt; /* number of pages to swap on next pass */
/* limits */
struct rlimit rlim[RLIM_NLIMITS];
unsigned short used_math;
char comm[16];
/* file system info */
int link_count;
struct tty_struct *tty; /* NULL if no tty */
/* ipc stuff */
struct sem_undo *semundo;
struct sem_queue *semsleeping;
/* ldt for this task - used by Wine. If NULL, default_ldt is used */
struct desc_struct *ldt;
/* tss for this task */
struct thread_struct tss;
/* filesystem information */
struct fs_struct *fs;
/* open file information */
struct files_struct *files;
/* memory management info */
struct mm_struct *mm;
/* signal handlers */
struct signal_struct *sig;
#ifdef __SMP__
int processor;
int last_processor;
int lock_depth; /* Lock depth.
We can context switch in and out
of holding a syscall kernel lock... */
#endif
};
... ... extern struct task_struct *task[NR_TASKS]; ... extern struct task_struct *current_set[NR_CPUS]; /* * On a single processor system this comes out as current_set[0] when cpp * has finished with it, which gcc will optimise away. */ #define current (0+current_set[smp_processor_id()]) /* Current on this processor */ extern unsigned long volatile jiffies;
#define NR_TASKS 512
(訳注: 以下のコードは、patch-1.3.99 で入りましたが、おそらく利用されることの
ないまま、v2.2.0 以降で消滅しています。)
[in
kernel/sched.c]
#ifdef PAST_2_0
/* This process is locked to a processor group */
if (p->processor_mask && !(p->processor_mask & (1<<this_cpu))
return -1000;
timer_list というデータ構造によって、プロセスのリアルタイム
タイマーが実装されている。
[in
include/linux/timer.h]
struct timer_list {
struct timer_list *next;
struct timer_list *prev;
unsigned long expires;
unsigned long data;
void (*function)(unsigned long);
};
struct timer_struct {
unsigned long expires;
void (*fn)(void);
};
extern unsigned long timer_active;
extern struct timer_struct timer_table[32];
個々のタスクキュー(tq_struct)データ構造体は、キュー上に登録された
仕事に関する情報を保持している。通常これらのタスクは、デバイスドライバに
とって必要なのだが、すぐに実行する必要のないタスクである。
[in
include/linux/tqueue.h]
struct tq_struct {
struct tq_struct *next; /* linked list of active bh's */
int sync; /* must be initialized to zero */
void (*routine)(void *); /* function to call */
void *data; /* argument to function */
};
struct vfsmount
{
kdev_t mnt_dev; /* Device this applies to */
char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
char *mnt_dirname; /* Name of directory mounted on */
unsigned int mnt_flags; /* Flags of this device */
struct semaphore mnt_sem; /* lock device while I/O in progress */
struct super_block *mnt_sb; /* pointer to superblock */
struct file *mnt_quotas[MAXQUOTAS]; /* fp's to quotafiles */
time_t mnt_iexp[MAXQUOTAS]; /* expiretime for inodes */
time_t mnt_bexp[MAXQUOTAS]; /* expiretime for blocks */
struct vfsmount *mnt_next; /* pointer to next in linkedlist */
};
[in fs/super.c]
static struct vfsmount *vfsmntlist = (struct vfsmount *) NULL,
*vfsmnttail = (struct vfsmount *) NULL,
*mru_vfsmnt = (struct vfsmount *) NULL;
個々の vm_area データ構造体は、あるプロセスの仮想メモリエリアを
記述するものである。
[in
include/linux/mm.h]
struct vm_area_struct {
struct mm_struct * vm_mm; /* VM area parameters */
unsigned long vm_start;
unsigned long vm_end;
pgprot_t vm_page_prot;
unsigned short vm_flags;
/* AVL tree of VM areas per task, sorted by address */
short vm_avl_height;
struct vm_area_struct * vm_avl_left;
struct vm_area_struct * vm_avl_right;
/* linked list of VM areas per task, sorted by address */
struct vm_area_struct * vm_next;
/* for areas with inode, the circular list inode->i_mmap */
/* for shm areas, the circular list of attaches */
/* otherwise unused */
struct vm_area_struct * vm_next_share;
struct vm_area_struct * vm_prev_share;
/* more */
struct vm_operations_struct * vm_ops;
unsigned long vm_offset;
struct inode * vm_inode;
unsigned long vm_pte; /* shared mem */
};
[in include/linux/mm.h]
struct vm_operations_struct {
void (*open)(struct vm_area_struct * area);
void (*close)(struct vm_area_struct * area);
void (*unmap)(struct vm_area_struct *area, unsigned long, size_t);
void (*protect)(struct vm_area_struct *area, unsigned long, size_t,
unsigned int newprot);
int (*sync)(struct vm_area_struct *area, unsigned long, size_t,
unsigned int flags);
void (*advise)(struct vm_area_struct *area, unsigned long, size_t,
unsigned int advise);
unsigned long (*nopage)(struct vm_area_struct * area,
unsigned long address, int write_access);
unsigned long (*wppage)(struct vm_area_struct * area,
unsigned long address, unsigned long page);
int (*swapout)(struct vm_area_struct *, unsigned long, pte_t *);
pte_t (*swapin)(struct vm_area_struct *, unsigned long, unsigned long);
};
[in include/linux/wait.h]
struct wait_queue {
struct task_struct * task;
struct wait_queue * next;
};