X-Git-Url: http://git.samba.org/samba.git/?p=sfrench%2Fcifs-2.6.git;a=blobdiff_plain;f=ipc%2Futil.c;h=0b652387d169a6b6af1609071bfb3aa2e8a6b954;hp=0c97cb746160980733569830b1944451f9d33a22;hb=f88d205501e35195444bdd41983e26546af3f56a;hpb=a727fea99bf4b2addcd64c596735148117a7b37f diff --git a/ipc/util.c b/ipc/util.c index 0c97cb746160..0b652387d169 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -144,6 +144,13 @@ void free_ipc_ns(struct kref *kref) shm_exit_ns(ns); kfree(ns); } +#else +int copy_ipcs(unsigned long flags, struct task_struct *tsk) +{ + if (flags & CLONE_NEWIPC) + return -EINVAL; + return 0; +} #endif /** @@ -205,7 +212,7 @@ void __ipc_init ipc_init_ids(struct ipc_ids* ids, int size) } #ifdef CONFIG_PROC_FS -static struct file_operations sysvipc_proc_fops; +static const struct file_operations sysvipc_proc_fops; /** * ipc_init_proc_interface - Create a proc interface for sysipc types using a seq_file interface. * @path: Path in procfs @@ -738,14 +745,20 @@ int ipc_parse_version (int *cmd) #endif /* __ARCH_WANT_IPC_PARSE_VERSION */ #ifdef CONFIG_PROC_FS +struct ipc_proc_iter { + struct ipc_namespace *ns; + struct ipc_proc_iface *iface; +}; + static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos) { - struct ipc_proc_iface *iface = s->private; + struct ipc_proc_iter *iter = s->private; + struct ipc_proc_iface *iface = iter->iface; struct kern_ipc_perm *ipc = it; loff_t p; struct ipc_ids *ids; - ids = current->nsproxy->ipc_ns->ids[iface->ids]; + ids = iter->ns->ids[iface->ids]; /* If we had an ipc id locked before, unlock it */ if (ipc && ipc != SEQ_START_TOKEN) @@ -772,12 +785,13 @@ static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos) */ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) { - struct ipc_proc_iface *iface = s->private; + struct ipc_proc_iter *iter = s->private; + struct ipc_proc_iface *iface = iter->iface; struct kern_ipc_perm *ipc; loff_t p; struct ipc_ids *ids; - ids = current->nsproxy->ipc_ns->ids[iface->ids]; + ids = iter->ns->ids[iface->ids]; /* * Take the lock - this will be released by the corresponding @@ -806,21 +820,23 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) static void sysvipc_proc_stop(struct seq_file *s, void *it) { struct kern_ipc_perm *ipc = it; - struct ipc_proc_iface *iface = s->private; + struct ipc_proc_iter *iter = s->private; + struct ipc_proc_iface *iface = iter->iface; struct ipc_ids *ids; /* If we had a locked segment, release it */ if (ipc && ipc != SEQ_START_TOKEN) ipc_unlock(ipc); - ids = current->nsproxy->ipc_ns->ids[iface->ids]; + ids = iter->ns->ids[iface->ids]; /* Release the lock we took in start() */ mutex_unlock(&ids->mutex); } static int sysvipc_proc_show(struct seq_file *s, void *it) { - struct ipc_proc_iface *iface = s->private; + struct ipc_proc_iter *iter = s->private; + struct ipc_proc_iface *iface = iter->iface; if (it == SEQ_START_TOKEN) return seq_puts(s, iface->header); @@ -835,22 +851,45 @@ static struct seq_operations sysvipc_proc_seqops = { .show = sysvipc_proc_show, }; -static int sysvipc_proc_open(struct inode *inode, struct file *file) { +static int sysvipc_proc_open(struct inode *inode, struct file *file) +{ int ret; struct seq_file *seq; + struct ipc_proc_iter *iter; + + ret = -ENOMEM; + iter = kmalloc(sizeof(*iter), GFP_KERNEL); + if (!iter) + goto out; ret = seq_open(file, &sysvipc_proc_seqops); - if (!ret) { - seq = file->private_data; - seq->private = PDE(inode)->data; - } + if (ret) + goto out_kfree; + + seq = file->private_data; + seq->private = iter; + + iter->iface = PDE(inode)->data; + iter->ns = get_ipc_ns(current->nsproxy->ipc_ns); +out: return ret; +out_kfree: + kfree(iter); + goto out; +} + +static int sysvipc_proc_release(struct inode *inode, struct file *file) +{ + struct seq_file *seq = file->private_data; + struct ipc_proc_iter *iter = seq->private; + put_ipc_ns(iter->ns); + return seq_release_private(inode, file); } -static struct file_operations sysvipc_proc_fops = { +static const struct file_operations sysvipc_proc_fops = { .open = sysvipc_proc_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = sysvipc_proc_release, }; #endif /* CONFIG_PROC_FS */