この章では、主要なデータ構造体を列挙している。これらは、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; };