diff -urN S22-pre2/drivers/s390/block/dasd.c S22-pre2-current/drivers/s390/block/dasd.c --- S22-pre2/drivers/s390/block/dasd.c Mon Jun 16 11:34:27 2003 +++ S22-pre2-current/drivers/s390/block/dasd.c Sat Jun 28 10:30:34 2003 @@ -3901,9 +3901,6 @@ release:dasd_devices_close, /* close */ }; -static struct inode_operations dasd_devices_inode_ops = { -}; - static int dasd_statistics_open (struct inode *inode, struct file *file) { @@ -4084,9 +4081,6 @@ release:dasd_devices_close, /* close */ }; -static struct inode_operations dasd_statistics_inode_ops = { -}; - int dasd_proc_init (void) { @@ -4096,12 +4090,10 @@ S_IFREG | S_IRUGO | S_IWUSR, dasd_proc_root_entry); dasd_devices_entry->proc_fops = &dasd_devices_file_ops; - dasd_devices_entry->proc_iops = &dasd_devices_inode_ops; dasd_statistics_entry = create_proc_entry ("statistics", S_IFREG | S_IRUGO | S_IWUSR, dasd_proc_root_entry); dasd_statistics_entry->proc_fops = &dasd_statistics_file_ops; - dasd_statistics_entry->proc_iops = &dasd_statistics_inode_ops; return rc; } diff -urN S22-pre2/drivers/s390/char/tape.c S22-pre2-current/drivers/s390/char/tape.c --- S22-pre2/drivers/s390/char/tape.c Thu Nov 29 02:56:42 2001 +++ S22-pre2-current/drivers/s390/char/tape.c Sat Jun 28 10:30:11 2003 @@ -210,12 +210,12 @@ release:tape_devices_release, /* close */ }; +#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) static struct inode_operations tape_devices_inode_ops = { -#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) default_file_ops:&tape_devices_file_ops /* file ops */ -#endif /* LINUX_IS_24 */ }; +#endif /* LINUX_IS_24 */ #endif /* CONFIG_PROC_FS */ /* SECTION: Parameters for tape */ @@ -914,7 +914,6 @@ S_IFREG | S_IRUGO | S_IWUSR, &proc_root); tape_devices_entry->proc_fops = &tape_devices_file_ops; - tape_devices_entry->proc_iops = &tape_devices_inode_ops; #else tape_devices_entry = (struct proc_dir_entry *) kmalloc (sizeof (struct proc_dir_entry), GFP_ATOMIC); diff -urN S22-pre2/drivers/s390/net/ctcmain.c S22-pre2-current/drivers/s390/net/ctcmain.c --- S22-pre2/drivers/s390/net/ctcmain.c Thu Jan 24 09:22:45 2002 +++ S22-pre2-current/drivers/s390/net/ctcmain.c Sat Jun 28 10:54:48 2003 @@ -2713,22 +2713,26 @@ * procfs related structures and routines *****************************************************************************/ -static net_device *find_netdev_by_ino(unsigned long ino) +static net_device *find_netdev_by_stat(struct proc_dir_entry *stat) { - channel *ch = channels; - net_device *dev = NULL; - ctc_priv *privptr; + channel *ch; + for (ch = channels; ch; ch = ch->next) { + net_device *dev = ch->netdev; + ctc_priv *privptr = (ctc_priv *)dev->priv; + if (privptr->proc_stat_entry == stat) + return dev; + } + return NULL; +} - while (ch) { - if (ch->netdev != dev) { - dev = ch->netdev; - privptr = (ctc_priv *)dev->priv; - - if ((privptr->proc_ctrl_entry->low_ino == ino) || - (privptr->proc_stat_entry->low_ino == ino)) - return dev; - } - ch = ch->next; +static net_device *find_netdev_by_ctrl(struct proc_dir_entry *ctrl) +{ + channel *ch; + for (ch = channels; ch; ch = ch->next) { + net_device *dev = ch->netdev; + ctc_priv *privptr = (ctc_priv *)dev->priv; + if (privptr->proc_ctrl_entry == ctrl) + return dev; } return NULL; } @@ -2768,14 +2772,13 @@ static ssize_t ctc_ctrl_write(struct file *file, const char *buf, size_t count, loff_t *off) { - unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; net_device *dev; ctc_priv *privptr; char *e; int bs1; char tmp[40]; - if (!(dev = find_netdev_by_ino(ino))) + if (!(dev = find_netdev_by_ctrl(file->f_dentry->d_inode->u.generic_ip))) return -ENODEV; if (off != &file->f_pos) return -ESPIPE; @@ -2813,7 +2816,6 @@ static ssize_t ctc_ctrl_read(struct file *file, char *buf, size_t count, loff_t *off) { - unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; char *sbuf = (char *)file->private_data; net_device *dev; ctc_priv *privptr; @@ -2821,7 +2823,7 @@ char *p = sbuf; int l; - if (!(dev = find_netdev_by_ino(ino))) + if (!(dev = find_netdev_by_ctrl(file->f_dentry->d_inode->u.generic_ip))) return -ENODEV; if (off != &file->f_pos) return -ESPIPE; @@ -2865,11 +2867,10 @@ static ssize_t ctc_stat_write(struct file *file, const char *buf, size_t count, loff_t *off) { - unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; net_device *dev; ctc_priv *privptr; - if (!(dev = find_netdev_by_ino(ino))) + if (!(dev = find_netdev_by_stat(file->f_dentry->d_inode->u.generic_ip))) return -ENODEV; privptr = (ctc_priv *)dev->priv; privptr->channel[WRITE]->prof.maxmulti = 0; @@ -2884,7 +2885,6 @@ static ssize_t ctc_stat_read(struct file *file, char *buf, size_t count, loff_t *off) { - unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; char *sbuf = (char *)file->private_data; net_device *dev; ctc_priv *privptr; @@ -2892,7 +2892,7 @@ char *p = sbuf; int l; - if (!(dev = find_netdev_by_ino(ino))) + if (!(dev = find_netdev_by_stat(file->f_dentry->d_inode->u.generic_ip))) return -ENODEV; if (off != &file->f_pos) return -ESPIPE; @@ -2946,15 +2946,12 @@ release: ctc_ctrl_close, }; -static struct inode_operations ctc_stat_iops = { #if LINUX_VERSION_CODE < 0x020363 +static struct inode_operations ctc_stat_iops = { default_file_ops: &ctc_stat_fops -#endif }; static struct inode_operations ctc_ctrl_iops = { -#if LINUX_VERSION_CODE < 0x020363 default_file_ops: &ctc_ctrl_fops -#endif }; static struct proc_dir_entry stat_entry = { @@ -2981,7 +2978,6 @@ &ctc_ctrl_iops /* ops */ }; -#if LINUX_VERSION_CODE < 0x020363 static struct proc_dir_entry ctc_dir = { 0, /* low_ino */ 3, /* namelen */ @@ -3012,7 +3008,6 @@ }; #else static struct proc_dir_entry *ctc_dir = NULL; -static struct proc_dir_entry *ctc_template = NULL; #endif /** @@ -3062,13 +3057,11 @@ S_IFREG | S_IRUSR | S_IWUSR, privptr->proc_dentry); privptr->proc_stat_entry->proc_fops = &ctc_stat_fops; - privptr->proc_stat_entry->proc_iops = &ctc_stat_iops; privptr->proc_ctrl_entry = create_proc_entry("buffersize", S_IFREG | S_IRUSR | S_IWUSR, privptr->proc_dentry); privptr->proc_ctrl_entry->proc_fops = &ctc_ctrl_fops; - privptr->proc_ctrl_entry->proc_iops = &ctc_ctrl_iops; #else privptr->proc_dentry->name = dev->name; privptr->proc_dentry->namelen = strlen(dev->name); @@ -3470,8 +3463,12 @@ return NULL; memset(dev, 0, sizeof(net_device)); } +#if LINUX_VERSION_CODE < 0x020363 priv_size = sizeof(ctc_priv) + sizeof(ctc_template) + sizeof(stat_entry) + sizeof(ctrl_entry); +#else + priv_size = sizeof(ctc_priv); +#endif dev->priv = kmalloc(priv_size, GFP_KERNEL); if (dev->priv == NULL) { if (alloc_device) @@ -3480,6 +3477,7 @@ } memset(dev->priv, 0, priv_size); privptr = (ctc_priv *)dev->priv; +#if LINUX_VERSION_CODE < 0x020363 privptr->proc_dentry = (struct proc_dir_entry *) (((char *)privptr) + sizeof(ctc_priv)); privptr->proc_stat_entry = (struct proc_dir_entry *) @@ -3491,6 +3489,7 @@ memcpy(privptr->proc_dentry, &ctc_template, sizeof(ctc_template)); memcpy(privptr->proc_stat_entry, &stat_entry, sizeof(stat_entry)); memcpy(privptr->proc_ctrl_entry, &ctrl_entry, sizeof(ctrl_entry)); +#endif privptr->fsm = init_fsm("ctcdev", dev_state_names, dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS, dev_fsm, DEV_FSM_LEN, GFP_KERNEL); diff -urN S22-pre2/drivers/s390/net/netiucv.c S22-pre2-current/drivers/s390/net/netiucv.c --- S22-pre2/drivers/s390/net/netiucv.c Tue Dec 10 14:24:56 2002 +++ S22-pre2-current/drivers/s390/net/netiucv.c Sat Jun 28 11:10:21 2003 @@ -1287,24 +1287,38 @@ * procfs related structures and routines *****************************************************************************/ -static net_device * -find_netdev_by_ino(unsigned long ino) +static net_device *find_netdev_by_stat(struct proc_dir_entry *p) { - iucv_connection *conn = connections; - net_device *dev = NULL; - netiucv_priv *privptr; + iucv_connection *conn; + for (conn = connections; conn; conn = conn->next) { + net_device *dev = conn->netdev; + netiucv_priv *privptr = (netiucv_priv *)dev->priv; + if (privptr->proc_stat_entry == p) + return dev; + } + return NULL; +} - while (conn) { - if (conn->netdev != dev) { - dev = conn->netdev; - privptr = (netiucv_priv *)dev->priv; - - if ((privptr->proc_buffer_entry->low_ino == ino) || - (privptr->proc_user_entry->low_ino == ino) || - (privptr->proc_stat_entry->low_ino == ino) ) - return dev; - } - conn = conn->next; +static net_device *find_netdev_by_user(struct proc_dir_entry *p) +{ + iucv_connection *conn; + for (conn = connections; conn; conn = conn->next) { + net_device *dev = conn->netdev; + netiucv_priv *privptr = (netiucv_priv *)dev->priv; + if (privptr->proc_user_entry == p) + return dev; + } + return NULL; +} + +static net_device *find_netdev_by_buf(struct proc_dir_entry *p) +{ + iucv_connection *conn; + for (conn = connections; conn; conn = conn->next) { + net_device *dev = conn->netdev; + netiucv_priv *privptr = (netiucv_priv *)dev->priv; + if (privptr->proc_buffer_entry == p) + return dev; } return NULL; } @@ -1348,14 +1362,13 @@ netiucv_buffer_write(struct file *file, const char *buf, size_t count, loff_t *off) { - unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; net_device *dev; netiucv_priv *privptr; char *e; int bs1; char tmp[CTRL_BUFSIZE]; - if (!(dev = find_netdev_by_ino(ino))) + if (!(dev = find_netdev_by_buf(file->f_dentry->d_inode->u.generic_ip))) return -ENODEV; if (off != &file->f_pos) return -ESPIPE; @@ -1391,7 +1404,6 @@ static ssize_t netiucv_buffer_read(struct file *file, char *buf, size_t count, loff_t *off) { - unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; char *sbuf = (char *)file->private_data; net_device *dev; netiucv_priv *privptr; @@ -1399,7 +1411,7 @@ char *p = sbuf; int l; - if (!(dev = find_netdev_by_ino(ino))) + if (!(dev = find_netdev_by_buf(file->f_dentry->d_inode->u.generic_ip))) return -ENODEV; if (off != &file->f_pos) return -ESPIPE; @@ -1444,7 +1456,6 @@ netiucv_user_write(struct file *file, const char *buf, size_t count, loff_t *off) { - unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; net_device *dev; netiucv_priv *privptr; int i; @@ -1452,7 +1463,7 @@ char tmp[CTRL_BUFSIZE]; char user[9]; - if (!(dev = find_netdev_by_ino(ino))) + if (!(dev = find_netdev_by_user(file->f_dentry->d_inode->u.generic_ip))) return -ENODEV; if (off != &file->f_pos) return -ESPIPE; @@ -1486,7 +1497,6 @@ static ssize_t netiucv_user_read(struct file *file, char *buf, size_t count, loff_t *off) { - unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; char *sbuf = (char *)file->private_data; net_device *dev; netiucv_priv *privptr; @@ -1494,7 +1504,7 @@ char *p = sbuf; int l; - if (!(dev = find_netdev_by_ino(ino))) + if (!(dev = find_netdev_by_user(file->f_dentry->d_inode->u.generic_ip))) return -ENODEV; if (off != &file->f_pos) return -ESPIPE; @@ -1542,11 +1552,10 @@ static ssize_t netiucv_stat_write(struct file *file, const char *buf, size_t count, loff_t *off) { - unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; net_device *dev; netiucv_priv *privptr; - if (!(dev = find_netdev_by_ino(ino))) + if (!(dev = find_netdev_by_stat(file->f_dentry->d_inode->u.generic_ip))) return -ENODEV; privptr = (netiucv_priv *)dev->priv; privptr->conn->prof.maxmulti = 0; @@ -1561,7 +1570,6 @@ static ssize_t netiucv_stat_read(struct file *file, char *buf, size_t count, loff_t *off) { - unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; char *sbuf = (char *)file->private_data; net_device *dev; netiucv_priv *privptr; @@ -1569,7 +1577,7 @@ char *p = sbuf; int l; - if (!(dev = find_netdev_by_ino(ino))) + if (!(dev = find_netdev_by_stat(file->f_dentry->d_inode->u.generic_ip))) return -ENODEV; if (off != &file->f_pos) return -ESPIPE; @@ -1628,21 +1636,17 @@ release: netiucv_user_close, }; -static struct inode_operations netiucv_stat_iops = { #if LINUX_VERSION_CODE < 0x020363 +static struct inode_operations netiucv_stat_iops = { default_file_ops: &netiucv_stat_fops -#endif }; + static struct inode_operations netiucv_buffer_iops = { -#if LINUX_VERSION_CODE < 0x020363 default_file_ops: &netiucv_buffer_fops -#endif }; static struct inode_operations netiucv_user_iops = { -#if LINUX_VERSION_CODE < 0x020363 default_file_ops: &netiucv_user_fops -#endif }; static struct proc_dir_entry stat_entry = { @@ -1681,7 +1685,6 @@ &netiucv_user_iops /* ops */ }; -#if LINUX_VERSION_CODE < 0x020363 static struct proc_dir_entry netiucv_dir = { 0, /* low_ino */ 4, /* namelen */ @@ -1767,19 +1770,16 @@ S_IFREG | S_IRUSR | S_IWUSR, privptr->proc_dentry); privptr->proc_stat_entry->proc_fops = &netiucv_stat_fops; - privptr->proc_stat_entry->proc_iops = &netiucv_stat_iops; privptr->proc_buffer_entry = create_proc_entry("buffersize", S_IFREG | S_IRUSR | S_IWUSR, privptr->proc_dentry); privptr->proc_buffer_entry->proc_fops = &netiucv_buffer_fops; - privptr->proc_buffer_entry->proc_iops = &netiucv_buffer_iops; privptr->proc_user_entry = create_proc_entry("username", S_IFREG | S_IRUSR | S_IWUSR, privptr->proc_dentry); privptr->proc_user_entry->proc_fops = &netiucv_user_fops; - privptr->proc_user_entry->proc_iops = &netiucv_user_iops; #else privptr->proc_dentry->name = dev->name; privptr->proc_dentry->namelen = strlen(dev->name); @@ -1921,8 +1921,12 @@ #endif sprintf(dev->name, "iucv%d", ifno); +#if LINUX_VERSION_CODE < 0x020363 priv_size = sizeof(netiucv_priv) + sizeof(netiucv_template) + sizeof(stat_entry) + sizeof(buffer_entry) + sizeof(user_entry); +#else + priv_size = sizeof(netiucv_priv); +#endif dev->priv = kmalloc(priv_size, GFP_KERNEL); if (dev->priv == NULL) { kfree(dev); @@ -1930,6 +1934,7 @@ } memset(dev->priv, 0, priv_size); privptr = (netiucv_priv *)dev->priv; +#if LINUX_VERSION_CODE < 0x020363 privptr->proc_dentry = (struct proc_dir_entry *) (((char *)privptr) + sizeof(netiucv_priv)); privptr->proc_stat_entry = (struct proc_dir_entry *) @@ -1947,6 +1952,7 @@ memcpy(privptr->proc_stat_entry, &stat_entry, sizeof(stat_entry)); memcpy(privptr->proc_buffer_entry, &buffer_entry, sizeof(buffer_entry)); memcpy(privptr->proc_user_entry, &user_entry, sizeof(user_entry)); +#endif privptr->fsm = init_fsm("netiucvdev", dev_state_names, dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS, dev_fsm, DEV_FSM_LEN, GFP_KERNEL); diff -urN S22-pre2/fs/proc/Makefile S22-pre2-current/fs/proc/Makefile --- S22-pre2/fs/proc/Makefile Thu Nov 29 02:57:33 2001 +++ S22-pre2-current/fs/proc/Makefile Sat Jun 28 12:12:04 2003 @@ -11,7 +11,7 @@ export-objs := root.o -obj-y := inode.o root.o base.o generic.o array.o \ +obj-y := root.o base.o generic.o array.o \ kmsg.o proc_tty.o proc_misc.o kcore.o ifeq ($(CONFIG_PROC_DEVICETREE),y) diff -urN S22-pre2/fs/proc/generic.c S22-pre2-current/fs/proc/generic.c --- S22-pre2/fs/proc/generic.c Mon Jun 16 11:34:30 2003 +++ S22-pre2-current/fs/proc/generic.c Sat Jun 28 12:28:15 2003 @@ -8,14 +8,20 @@ * Copyright (C) 1997 Theodore Ts'o */ -#include - -#include #include #include +#include +#include #include +#include +#include +#include #define __NO_VERSION__ #include +#include + +#include +#include #include static ssize_t proc_file_read(struct file * file, char * buf, @@ -23,6 +29,8 @@ static ssize_t proc_file_write(struct file * file, const char * buffer, size_t count, loff_t *ppos); static loff_t proc_file_lseek(struct file *, loff_t, int); +static struct inode *proc_get_inode(struct super_block * sb, int ino, + struct proc_dir_entry * de); int proc_match(int len, const char *name,struct proc_dir_entry * de) { @@ -194,7 +202,7 @@ static unsigned long proc_alloc_map[(PROC_NDYNAMIC + BITS_PER_LONG - 1) / BITS_PER_LONG]; -spinlock_t proc_alloc_map_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t proc_alloc_map_lock = SPIN_LOCK_UNLOCKED; static int make_inode_number(void) { @@ -249,7 +257,7 @@ * Don't create negative dentries here, return -ENOENT by hand * instead. */ -struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry) +static struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry) { struct inode *inode; struct proc_dir_entry * de; @@ -290,7 +298,7 @@ * value of the readdir() call, as long as it's non-negative * for success.. */ -int proc_readdir(struct file * filp, +static int proc_readdir(struct file * filp, void * dirent, filldir_t filldir) { struct proc_dir_entry * de; @@ -360,9 +368,7 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp) { - int i; - - i = make_inode_number(); + int i = make_inode_number(); if (i < 0) return -EAGAIN; dp->low_ino = i; @@ -370,17 +376,10 @@ dp->parent = dir; dir->subdir = dp; if (S_ISDIR(dp->mode)) { - if (dp->proc_iops == NULL) { - dp->proc_fops = &proc_dir_operations; - dp->proc_iops = &proc_dir_inode_operations; - } + dp->proc_fops = &proc_dir_operations; dir->nlink++; - } else if (S_ISLNK(dp->mode)) { - if (dp->proc_iops == NULL) - dp->proc_iops = &proc_link_inode_operations; } else if (S_ISREG(dp->mode)) { - if (dp->proc_fops == NULL) - dp->proc_fops = &proc_file_operations; + dp->proc_fops = &proc_file_operations; } return 0; } @@ -492,9 +491,6 @@ ent = proc_create(&parent,name, (S_IFDIR | S_IRUGO | S_IXUGO),2); if (ent) { - ent->proc_fops = &proc_dir_operations; - ent->proc_iops = &proc_dir_inode_operations; - if (proc_register(parent, ent) < 0) { kfree(ent); ent = NULL; @@ -523,10 +519,6 @@ ent = proc_create(&parent,name,mode,nlink); if (ent) { - if (S_ISDIR(mode)) { - ent->proc_fops = &proc_dir_operations; - ent->proc_iops = &proc_dir_inode_operations; - } if (proc_register(parent, ent) < 0) { kfree(ent); ent = NULL; @@ -535,7 +527,7 @@ return ent; } -void free_proc_entry(struct proc_dir_entry *de) +static void free_proc_entry(struct proc_dir_entry *de) { int ino = de->low_ino; @@ -585,3 +577,250 @@ out: return; } + +static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de) +{ + atomic_inc(&de->count); + return de; +} + +/* + * Decrements the use count and checks for deferred deletion. + */ +static void de_put(struct proc_dir_entry *de) +{ + lock_kernel(); + if (!atomic_read(&de->count)) { + printk("de_put: entry %s already free!\n", de->name); + unlock_kernel(); + return; + } + + if (atomic_dec_and_test(&de->count)) { + if (de->deleted) { + printk("de_put: deferred delete of %s\n", + de->name); + free_proc_entry(de); + } + } + unlock_kernel(); +} + +/* + * Decrement the use count of the proc_dir_entry. + */ +static void proc_delete_inode(struct inode *inode) +{ + struct proc_dir_entry *de = inode->u.generic_ip; + + inode->i_state = I_CLEAR; + + if (PROC_INODE_PROPER(inode)) { + proc_pid_delete_inode(inode); + return; + } + if (de) { + if (de->owner) + __MOD_DEC_USE_COUNT(de->owner); + de_put(de); + } +} + +struct vfsmount *proc_mnt; + +static void proc_read_inode(struct inode * inode) +{ + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; +} + +static int proc_statfs(struct super_block *sb, struct statfs *buf) +{ + buf->f_type = PROC_SUPER_MAGIC; + buf->f_bsize = PAGE_SIZE/sizeof(long); + buf->f_bfree = 0; + buf->f_bavail = 0; + buf->f_ffree = 0; + buf->f_namelen = NAME_MAX; + return 0; +} + +static struct super_operations proc_sops = { + read_inode: proc_read_inode, + put_inode: force_delete, + delete_inode: proc_delete_inode, + statfs: proc_statfs, +}; + + +static int parse_options(char *options,uid_t *uid,gid_t *gid) +{ + char *this_char,*value; + + *uid = current->uid; + *gid = current->gid; + if (!options) return 1; + for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) { + if ((value = strchr(this_char,'=')) != NULL) + *value++ = 0; + if (!strcmp(this_char,"uid")) { + if (!value || !*value) + return 0; + *uid = simple_strtoul(value,&value,0); + if (*value) + return 0; + } + else if (!strcmp(this_char,"gid")) { + if (!value || !*value) + return 0; + *gid = simple_strtoul(value,&value,0); + if (*value) + return 0; + } + else return 1; + } + return 1; +} + +static struct inode *proc_get_inode(struct super_block * sb, int ino, + struct proc_dir_entry * de) +{ + struct inode * inode; + + /* + * Increment the use count so the dir entry can't disappear. + */ + de_get(de); +#if 1 +/* shouldn't ever happen */ +if (de->deleted) +printk("proc_iget: using deleted entry %s, count=%d\n", de->name, atomic_read(&de->count)); +#endif + + inode = iget(sb, ino); + if (!inode) + goto out_fail; + + inode->u.generic_ip = (void *) de; + if (de->mode) { + inode->i_mode = de->mode; + inode->i_uid = de->uid; + inode->i_gid = de->gid; + } + if (de->size) + inode->i_size = de->size; + if (de->nlink) + inode->i_nlink = de->nlink; + if (de->owner) + __MOD_INC_USE_COUNT(de->owner); + if (S_ISDIR(de->mode)) + inode->i_op = &proc_dir_inode_operations; + else if (S_ISLNK(de->mode)) + inode->i_op = &proc_link_inode_operations; + if (de->proc_fops) + inode->i_fop = de->proc_fops; + else if (S_ISBLK(de->mode)||S_ISCHR(de->mode)||S_ISFIFO(de->mode)) + init_special_inode(inode,de->mode,kdev_t_to_nr(de->rdev)); + +out: + return inode; + +out_fail: + de_put(de); + goto out; +} + +static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry) +{ + if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */ + int nlink = proc_root.nlink; + + nlink += nr_threads; + + dir->i_nlink = nlink; + } + + if (!proc_lookup(dir, dentry)) + return NULL; + + return proc_pid_lookup(dir, dentry); +} + +static int proc_root_readdir(struct file * filp, + void * dirent, filldir_t filldir) +{ + unsigned int nr = filp->f_pos; + + if (nr < FIRST_PROCESS_ENTRY) { + int error = proc_readdir(filp, dirent, filldir); + if (error <= 0) + return error; + filp->f_pos = FIRST_PROCESS_ENTRY; + } + + return proc_pid_readdir(filp, dirent, filldir); +} + +/* + * The root /proc directory is special, as it has the + * directories. Thus we don't use the generic + * directory handling functions for that.. + */ +static struct file_operations proc_root_operations = { + read: generic_read_dir, + readdir: proc_root_readdir, +}; + +/* + * proc root can do almost nothing.. + */ +static struct inode_operations proc_root_inode_operations = { + lookup: proc_root_lookup, +}; + +/* + * This is the root "inode" in the /proc tree.. + */ +struct proc_dir_entry proc_root = { + low_ino: PROC_ROOT_INO, + namelen: 5, + name: "/proc", + mode: S_IFDIR | S_IRUGO | S_IXUGO, + nlink: 2, + parent: &proc_root, +}; + +struct super_block *proc_read_super(struct super_block *s,void *data, + int silent) +{ + struct inode * root_inode; + struct task_struct *p; + + s->s_blocksize = 1024; + s->s_blocksize_bits = 10; + s->s_magic = PROC_SUPER_MAGIC; + s->s_op = &proc_sops; + + root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root); + if (!root_inode) + goto out_no_root; + root_inode->i_op = &proc_root_inode_operations; + root_inode->i_fop = &proc_root_operations; + /* + * Fixup the root inode's nlink value + */ + read_lock(&tasklist_lock); + for_each_task(p) if (p->pid) root_inode->i_nlink++; + read_unlock(&tasklist_lock); + s->s_root = d_alloc_root(root_inode); + if (!s->s_root) + goto out_no_root; + parse_options(data, &root_inode->i_uid, &root_inode->i_gid); + return s; + +out_no_root: + printk("proc_read_super: get root inode failed\n"); + iput(root_inode); + return NULL; +} + +MODULE_LICENSE("GPL"); diff -urN S22-pre2/fs/proc/inode.c S22-pre2-current/fs/proc/inode.c --- S22-pre2/fs/proc/inode.c Mon Jun 16 11:34:30 2003 +++ S22-pre2-current/fs/proc/inode.c Wed Dec 31 19:00:00 1969 @@ -1,210 +0,0 @@ -/* - * linux/fs/proc/inode.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define __NO_VERSION__ -#include -#include - -#include -#include - -extern void free_proc_entry(struct proc_dir_entry *); - -static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de) -{ - if (de) - atomic_inc(&de->count); - return de; -} - -/* - * Decrements the use count and checks for deferred deletion. - */ -static void de_put(struct proc_dir_entry *de) -{ - if (de) { - lock_kernel(); - if (!atomic_read(&de->count)) { - printk("de_put: entry %s already free!\n", de->name); - unlock_kernel(); - return; - } - - if (atomic_dec_and_test(&de->count)) { - if (de->deleted) { - printk("de_put: deferred delete of %s\n", - de->name); - free_proc_entry(de); - } - } - unlock_kernel(); - } -} - -/* - * Decrement the use count of the proc_dir_entry. - */ -static void proc_delete_inode(struct inode *inode) -{ - struct proc_dir_entry *de = inode->u.generic_ip; - - inode->i_state = I_CLEAR; - - if (PROC_INODE_PROPER(inode)) { - proc_pid_delete_inode(inode); - return; - } - if (de) { - if (de->owner) - __MOD_DEC_USE_COUNT(de->owner); - de_put(de); - } -} - -struct vfsmount *proc_mnt; - -static void proc_read_inode(struct inode * inode) -{ - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; -} - -static int proc_statfs(struct super_block *sb, struct statfs *buf) -{ - buf->f_type = PROC_SUPER_MAGIC; - buf->f_bsize = PAGE_SIZE/sizeof(long); - buf->f_bfree = 0; - buf->f_bavail = 0; - buf->f_ffree = 0; - buf->f_namelen = NAME_MAX; - return 0; -} - -static struct super_operations proc_sops = { - read_inode: proc_read_inode, - put_inode: force_delete, - delete_inode: proc_delete_inode, - statfs: proc_statfs, -}; - - -static int parse_options(char *options,uid_t *uid,gid_t *gid) -{ - char *this_char,*value; - - *uid = current->uid; - *gid = current->gid; - if (!options) return 1; - for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) { - if ((value = strchr(this_char,'=')) != NULL) - *value++ = 0; - if (!strcmp(this_char,"uid")) { - if (!value || !*value) - return 0; - *uid = simple_strtoul(value,&value,0); - if (*value) - return 0; - } - else if (!strcmp(this_char,"gid")) { - if (!value || !*value) - return 0; - *gid = simple_strtoul(value,&value,0); - if (*value) - return 0; - } - else return 1; - } - return 1; -} - -struct inode * proc_get_inode(struct super_block * sb, int ino, - struct proc_dir_entry * de) -{ - struct inode * inode; - - /* - * Increment the use count so the dir entry can't disappear. - */ - de_get(de); -#if 1 -/* shouldn't ever happen */ -if (de && de->deleted) -printk("proc_iget: using deleted entry %s, count=%d\n", de->name, atomic_read(&de->count)); -#endif - - inode = iget(sb, ino); - if (!inode) - goto out_fail; - - inode->u.generic_ip = (void *) de; - if (de) { - if (de->mode) { - inode->i_mode = de->mode; - inode->i_uid = de->uid; - inode->i_gid = de->gid; - } - if (de->size) - inode->i_size = de->size; - if (de->nlink) - inode->i_nlink = de->nlink; - if (de->owner) - __MOD_INC_USE_COUNT(de->owner); - if (de->proc_iops) - inode->i_op = de->proc_iops; - if (de->proc_fops) - inode->i_fop = de->proc_fops; - else if (S_ISBLK(de->mode)||S_ISCHR(de->mode)||S_ISFIFO(de->mode)) - init_special_inode(inode,de->mode,kdev_t_to_nr(de->rdev)); - } - -out: - return inode; - -out_fail: - de_put(de); - goto out; -} - -struct super_block *proc_read_super(struct super_block *s,void *data, - int silent) -{ - struct inode * root_inode; - struct task_struct *p; - - s->s_blocksize = 1024; - s->s_blocksize_bits = 10; - s->s_magic = PROC_SUPER_MAGIC; - s->s_op = &proc_sops; - - root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root); - if (!root_inode) - goto out_no_root; - /* - * Fixup the root inode's nlink value - */ - read_lock(&tasklist_lock); - for_each_task(p) if (p->pid) root_inode->i_nlink++; - read_unlock(&tasklist_lock); - s->s_root = d_alloc_root(root_inode); - if (!s->s_root) - goto out_no_root; - parse_options(data, &root_inode->i_uid, &root_inode->i_gid); - return s; - -out_no_root: - printk("proc_read_super: get root inode failed\n"); - iput(root_inode); - return NULL; -} -MODULE_LICENSE("GPL"); diff -urN S22-pre2/fs/proc/root.c S22-pre2-current/fs/proc/root.c --- S22-pre2/fs/proc/root.c Fri Apr 19 02:35:42 2002 +++ S22-pre2-current/fs/proc/root.c Sat Jun 28 12:07:20 2003 @@ -70,68 +70,6 @@ proc_bus = proc_mkdir("bus", 0); } -static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry) -{ - if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */ - int nlink = proc_root.nlink; - - nlink += nr_threads; - - dir->i_nlink = nlink; - } - - if (!proc_lookup(dir, dentry)) - return NULL; - - return proc_pid_lookup(dir, dentry); -} - -static int proc_root_readdir(struct file * filp, - void * dirent, filldir_t filldir) -{ - unsigned int nr = filp->f_pos; - - if (nr < FIRST_PROCESS_ENTRY) { - int error = proc_readdir(filp, dirent, filldir); - if (error <= 0) - return error; - filp->f_pos = FIRST_PROCESS_ENTRY; - } - - return proc_pid_readdir(filp, dirent, filldir); -} - -/* - * The root /proc directory is special, as it has the - * directories. Thus we don't use the generic - * directory handling functions for that.. - */ -static struct file_operations proc_root_operations = { - read: generic_read_dir, - readdir: proc_root_readdir, -}; - -/* - * proc root can do almost nothing.. - */ -static struct inode_operations proc_root_inode_operations = { - lookup: proc_root_lookup, -}; - -/* - * This is the root "inode" in the /proc tree.. - */ -struct proc_dir_entry proc_root = { - low_ino: PROC_ROOT_INO, - namelen: 5, - name: "/proc", - mode: S_IFDIR | S_IRUGO | S_IXUGO, - nlink: 2, - proc_iops: &proc_root_inode_operations, - proc_fops: &proc_root_operations, - parent: &proc_root, -}; - #ifdef CONFIG_SYSCTL EXPORT_SYMBOL(proc_sys_root); #endif diff -urN S22-pre2/include/linux/proc_fs.h S22-pre2-current/include/linux/proc_fs.h --- S22-pre2/include/linux/proc_fs.h Fri Apr 19 02:36:16 2002 +++ S22-pre2-current/include/linux/proc_fs.h Sat Jun 28 12:17:43 2003 @@ -59,7 +59,6 @@ uid_t uid; gid_t gid; unsigned long size; - struct inode_operations * proc_iops; struct file_operations * proc_fops; get_info_t *get_info; struct module *owner; @@ -96,7 +95,6 @@ extern struct vfsmount *proc_mnt; extern struct super_block *proc_read_super(struct super_block *,void *,int); -extern struct inode * proc_get_inode(struct super_block *, int, struct proc_dir_entry *); extern int proc_match(int, const char *,struct proc_dir_entry *); @@ -107,9 +105,6 @@ * The /proc root directory has extended versions to take care * of the /proc/ subdirectories. */ -extern int proc_readdir(struct file *, void *, filldir_t); -extern struct dentry *proc_lookup(struct inode *, struct dentry *); - extern struct file_operations proc_kcore_operations; extern struct file_operations proc_kmsg_operations; extern struct file_operations ppc_htab_operations; diff -urN S22-pre2/kernel/sysctl.c S22-pre2-current/kernel/sysctl.c --- S22-pre2/kernel/sysctl.c Sat Jun 28 10:20:27 2003 +++ S22-pre2-current/kernel/sysctl.c Sat Jun 28 11:24:58 2003 @@ -127,17 +127,14 @@ static ssize_t proc_readsys(struct file *, char *, size_t, loff_t *); static ssize_t proc_writesys(struct file *, const char *, size_t, loff_t *); -static int proc_sys_permission(struct inode *, int); +static int proc_opensys(struct inode *, struct file *); struct file_operations proc_sys_file_operations = { + open: proc_opensys, read: proc_readsys, write: proc_writesys, }; -static struct inode_operations proc_sys_inode_operations = { - permission: proc_sys_permission, -}; - extern struct proc_dir_entry *proc_sys_root; static void register_proc_table(ctl_table *, struct proc_dir_entry *); @@ -639,10 +636,8 @@ if (!de) continue; de->data = (void *) table; - if (table->proc_handler) { + if (table->proc_handler) de->proc_fops = &proc_sys_file_operations; - de->proc_iops = &proc_sys_inode_operations; - } } table->de = de; if (de->mode & S_IFDIR) @@ -711,6 +706,19 @@ return res; } +static int proc_opensys(struct inode *inode, struct file *file) +{ + if (file->f_mode & FMODE_WRITE) { + /* + * sysctl entries that are not writable, + * are _NOT_ writable, capabilities or not. + */ + if (!(inode->i_mode & S_IWUSR)) + return -EPERM; + } + return 0; +} + static ssize_t proc_readsys(struct file * file, char * buf, size_t count, loff_t *ppos) { @@ -721,11 +729,6 @@ size_t count, loff_t *ppos) { return do_rw_proc(1, file, (char *) buf, count, ppos); -} - -static int proc_sys_permission(struct inode *inode, int op) -{ - return test_perm(inode->i_mode, op); } /** diff -urN S22-pre2/net/wanrouter/wanproc.c S22-pre2-current/net/wanrouter/wanproc.c --- S22-pre2/net/wanrouter/wanproc.c Thu Nov 29 02:58:04 2001 +++ S22-pre2-current/net/wanrouter/wanproc.c Sat Jun 28 11:13:37 2003 @@ -102,11 +102,6 @@ read: router_proc_read, }; - static struct inode_operations router_inode = - { - permission: router_proc_perms, - }; - /* * /proc/net/router/ file operations */ @@ -148,17 +143,15 @@ if (!proc_router) goto fail; - p = create_proc_entry("config",0,proc_router); + p = create_proc_entry("config",0666,proc_router); if (!p) goto fail_config; p->proc_fops = &router_fops; - p->proc_iops = &router_inode; p->get_info = config_get_info; - p = create_proc_entry("status",0,proc_router); + p = create_proc_entry("status",0666,proc_router); if (!p) goto fail_stat; p->proc_fops = &router_fops; - p->proc_iops = &router_inode; p->get_info = status_get_info; return 0; fail_stat: @@ -189,11 +182,10 @@ if (wandev->magic != ROUTER_MAGIC) return -EINVAL; - wandev->dent = create_proc_entry(wandev->name, 0, proc_router); + wandev->dent = create_proc_entry(wandev->name, 0666, proc_router); if (!wandev->dent) return -ENOMEM; wandev->dent->proc_fops = &wandev_fops; - wandev->dent->proc_iops = &router_inode; wandev->dent->get_info = wandev_get_info; wandev->dent->data = wandev; return 0; @@ -216,11 +208,6 @@ /* * Verify access rights. */ - - static int router_proc_perms (struct inode* inode, int op) - { - return 0; - } /* * Read router proc directory entry.