summaryrefslogtreecommitdiff
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/mqueue.c8
-rw-r--r--ipc/shm.c4
-rw-r--r--ipc/util.c62
3 files changed, 53 insertions, 21 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 02717f71d8d0..7a8ce610fda2 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -84,8 +84,8 @@ struct mqueue_inode_info {
unsigned long qsize; /* size of queue in memory (sum of all msgs) */
};
-static struct inode_operations mqueue_dir_inode_operations;
-static struct file_operations mqueue_file_operations;
+static const struct inode_operations mqueue_dir_inode_operations;
+static const struct file_operations mqueue_file_operations;
static struct super_operations mqueue_super_ops;
static void remove_notification(struct mqueue_inode_info *info);
@@ -1160,13 +1160,13 @@ out:
return ret;
}
-static struct inode_operations mqueue_dir_inode_operations = {
+static const struct inode_operations mqueue_dir_inode_operations = {
.lookup = simple_lookup,
.create = mqueue_create,
.unlink = mqueue_unlink,
};
-static struct file_operations mqueue_file_operations = {
+static const struct file_operations mqueue_file_operations = {
.flush = mqueue_flush_file,
.poll = mqueue_poll_file,
.read = mqueue_read_file,
diff --git a/ipc/shm.c b/ipc/shm.c
index f8e10a25ad7d..5bb617f6306e 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -42,7 +42,7 @@
#include "util.h"
-static struct file_operations shm_file_operations;
+static const struct file_operations shm_file_operations;
static struct vm_operations_struct shm_vm_ops;
static struct ipc_ids init_shm_ids;
@@ -249,7 +249,7 @@ static int shm_release(struct inode *ino, struct file *file)
return 0;
}
-static struct file_operations shm_file_operations = {
+static const struct file_operations shm_file_operations = {
.mmap = shm_mmap,
.release = shm_release,
#ifndef CONFIG_MMU
diff --git a/ipc/util.c b/ipc/util.c
index 0c97cb746160..08a647965b9e 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -205,7 +205,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 +738,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 +778,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 +813,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 +844,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 */