📄 proc.c
字号:
infault: kfree(kbuf);nomem: _leave(" = %d", ret); return ret;}/* * initialise /proc/fs/afs/<cell>/ */int afs_proc_cell_setup(struct afs_cell *cell){ struct proc_dir_entry *p; _enter("%p{%s}", cell, cell->name); cell->proc_dir = proc_mkdir(cell->name, proc_afs); if (!cell->proc_dir) goto error_dir; p = create_proc_entry("servers", 0, cell->proc_dir); if (!p) goto error_servers; p->proc_fops = &afs_proc_cell_servers_fops; p->owner = THIS_MODULE; p->data = cell; p = create_proc_entry("vlservers", 0, cell->proc_dir); if (!p) goto error_vlservers; p->proc_fops = &afs_proc_cell_vlservers_fops; p->owner = THIS_MODULE; p->data = cell; p = create_proc_entry("volumes", 0, cell->proc_dir); if (!p) goto error_volumes; p->proc_fops = &afs_proc_cell_volumes_fops; p->owner = THIS_MODULE; p->data = cell; _leave(" = 0"); return 0;error_volumes: remove_proc_entry("vlservers", cell->proc_dir);error_vlservers: remove_proc_entry("servers", cell->proc_dir);error_servers: remove_proc_entry(cell->name, proc_afs);error_dir: _leave(" = -ENOMEM"); return -ENOMEM;}/* * remove /proc/fs/afs/<cell>/ */void afs_proc_cell_remove(struct afs_cell *cell){ _enter(""); remove_proc_entry("volumes", cell->proc_dir); remove_proc_entry("vlservers", cell->proc_dir); remove_proc_entry("servers", cell->proc_dir); remove_proc_entry(cell->name, proc_afs); _leave("");}/* * open "/proc/fs/afs/<cell>/volumes" which provides a summary of extant cells */static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file){ struct afs_cell *cell; struct seq_file *m; int ret; cell = PDE(inode)->data; if (!cell) return -ENOENT; ret = seq_open(file, &afs_proc_cell_volumes_ops); if (ret < 0) return ret; m = file->private_data; m->private = cell; return 0;}/* * close the file and release the ref to the cell */static int afs_proc_cell_volumes_release(struct inode *inode, struct file *file){ return seq_release(inode, file);}/* * set up the iterator to start reading from the cells list and return the * first item */static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos){ struct afs_cell *cell = m->private; _enter("cell=%p pos=%Ld", cell, *_pos); /* lock the list against modification */ down_read(&cell->vl_sem); return seq_list_start_head(&cell->vl_list, *_pos);}/* * move to next cell in cells list */static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v, loff_t *_pos){ struct afs_cell *cell = p->private; _enter("cell=%p pos=%Ld", cell, *_pos); return seq_list_next(v, &cell->vl_list, _pos);}/* * clean up after reading from the cells list */static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v){ struct afs_cell *cell = p->private; up_read(&cell->vl_sem);}static const char afs_vlocation_states[][4] = { [AFS_VL_NEW] = "New", [AFS_VL_CREATING] = "Crt", [AFS_VL_VALID] = "Val", [AFS_VL_NO_VOLUME] = "NoV", [AFS_VL_UPDATING] = "Upd", [AFS_VL_VOLUME_DELETED] = "Del", [AFS_VL_UNCERTAIN] = "Unc",};/* * display a header line followed by a load of volume lines */static int afs_proc_cell_volumes_show(struct seq_file *m, void *v){ struct afs_cell *cell = m->private; struct afs_vlocation *vlocation = list_entry(v, struct afs_vlocation, link); /* display header on line 1 */ if (v == &cell->vl_list) { seq_puts(m, "USE STT VLID[0] VLID[1] VLID[2] NAME\n"); return 0; } /* display one cell per line on subsequent lines */ seq_printf(m, "%3d %s %08x %08x %08x %s\n", atomic_read(&vlocation->usage), afs_vlocation_states[vlocation->state], vlocation->vldb.vid[0], vlocation->vldb.vid[1], vlocation->vldb.vid[2], vlocation->vldb.name); return 0;}/* * open "/proc/fs/afs/<cell>/vlservers" which provides a list of volume * location server */static int afs_proc_cell_vlservers_open(struct inode *inode, struct file *file){ struct afs_cell *cell; struct seq_file *m; int ret; cell = PDE(inode)->data; if (!cell) return -ENOENT; ret = seq_open(file, &afs_proc_cell_vlservers_ops); if (ret<0) return ret; m = file->private_data; m->private = cell; return 0;}/* * close the file and release the ref to the cell */static int afs_proc_cell_vlservers_release(struct inode *inode, struct file *file){ return seq_release(inode, file);}/* * set up the iterator to start reading from the cells list and return the * first item */static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos){ struct afs_cell *cell = m->private; loff_t pos = *_pos; _enter("cell=%p pos=%Ld", cell, *_pos); /* lock the list against modification */ down_read(&cell->vl_sem); /* allow for the header line */ if (!pos) return (void *) 1; pos--; if (pos >= cell->vl_naddrs) return NULL; return &cell->vl_addrs[pos];}/* * move to next cell in cells list */static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v, loff_t *_pos){ struct afs_cell *cell = p->private; loff_t pos; _enter("cell=%p{nad=%u} pos=%Ld", cell, cell->vl_naddrs, *_pos); pos = *_pos; (*_pos)++; if (pos >= cell->vl_naddrs) return NULL; return &cell->vl_addrs[pos];}/* * clean up after reading from the cells list */static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v){ struct afs_cell *cell = p->private; up_read(&cell->vl_sem);}/* * display a header line followed by a load of volume lines */static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v){ struct in_addr *addr = v; /* display header on line 1 */ if (v == (struct in_addr *) 1) { seq_puts(m, "ADDRESS\n"); return 0; } /* display one cell per line on subsequent lines */ seq_printf(m, "%u.%u.%u.%u\n", NIPQUAD(addr->s_addr)); return 0;}/* * open "/proc/fs/afs/<cell>/servers" which provides a summary of active * servers */static int afs_proc_cell_servers_open(struct inode *inode, struct file *file){ struct afs_cell *cell; struct seq_file *m; int ret; cell = PDE(inode)->data; if (!cell) return -ENOENT; ret = seq_open(file, &afs_proc_cell_servers_ops); if (ret < 0) return ret; m = file->private_data; m->private = cell; return 0;}/* * close the file and release the ref to the cell */static int afs_proc_cell_servers_release(struct inode *inode, struct file *file){ return seq_release(inode, file);}/* * set up the iterator to start reading from the cells list and return the * first item */static void *afs_proc_cell_servers_start(struct seq_file *m, loff_t *_pos) __acquires(m->private->servers_lock){ struct afs_cell *cell = m->private; _enter("cell=%p pos=%Ld", cell, *_pos); /* lock the list against modification */ read_lock(&cell->servers_lock); return seq_list_start_head(&cell->servers, *_pos);}/* * move to next cell in cells list */static void *afs_proc_cell_servers_next(struct seq_file *p, void *v, loff_t *_pos){ struct afs_cell *cell = p->private; _enter("cell=%p pos=%Ld", cell, *_pos); return seq_list_next(v, &cell->servers, _pos);}/* * clean up after reading from the cells list */static void afs_proc_cell_servers_stop(struct seq_file *p, void *v) __releases(p->private->servers_lock){ struct afs_cell *cell = p->private; read_unlock(&cell->servers_lock);}/* * display a header line followed by a load of volume lines */static int afs_proc_cell_servers_show(struct seq_file *m, void *v){ struct afs_cell *cell = m->private; struct afs_server *server = list_entry(v, struct afs_server, link); char ipaddr[20]; /* display header on line 1 */ if (v == &cell->servers) { seq_puts(m, "USE ADDR STATE\n"); return 0; } /* display one cell per line on subsequent lines */ sprintf(ipaddr, "%u.%u.%u.%u", NIPQUAD(server->addr)); seq_printf(m, "%3d %-15.15s %5d\n", atomic_read(&server->usage), ipaddr, server->fs_state); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -