Messages in this thread Patch in this message | | | Date | Wed, 05 Mar 2008 20:32:44 +0300 | From | Pavel Emelyanov <> | Subject | [PATCH 3/9] Add a mode on the struct probe |
| |
The idea of the set is to make the dev_t to struct kobj map be per-cgroup, and provide a permissions for this mapping. This mode mask will operate with FMODE_xxx modes.
To achieve this, I add the mode_t mode on the struct probe, which sets this mapping, and move the locked part of the kobj_map() into a separate function, which also accepts the mode to be set on the probe.
By default all the modes are provided for a map.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
--- drivers/base/map.c | 31 ++++++++++++++++++++++++++----- 1 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/drivers/base/map.c b/drivers/base/map.c index 7de565f..c7e28a1 100644 --- a/drivers/base/map.c +++ b/drivers/base/map.c @@ -15,6 +15,7 @@ #include <linux/kdev_t.h> #include <linux/kobject.h> #include <linux/kobj_map.h> +#include <linux/fs.h> #define KOBJ_MAP_PROBES 255 @@ -22,6 +23,7 @@ struct kobj_map { struct probe { struct probe *next; dev_t dev; + mode_t mode; unsigned long range; struct module *owner; kobj_probe_t *get; @@ -31,9 +33,9 @@ struct kobj_map { struct mutex *lock; }; -int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, - struct module *module, kobj_probe_t *probe, - int (*lock)(dev_t, void *), void *data) +static int __kobj_map(struct kobj_map *domain, dev_t dev, mode_t mode, + unsigned long range, struct module *module, + kobj_probe_t *probe, int (*lock)(dev_t, void *), void *data) { unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; unsigned index = MAJOR(dev); @@ -55,8 +57,15 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, p->dev = dev; p->range = range; p->data = data; + /* + * When opening a device we want to (dis)allow only + * read or write. But sys_open() can provide more + * modes like lseek or pread. So, these FMODE-s are + * always 'on'. + */ + p->mode = mode | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; } - mutex_lock(domain->lock); + for (i = 0, p -= n; i < n; i++, p++, index++) { struct probe **s = &domain->probes[index % KOBJ_MAP_PROBES]; while (*s && (*s)->range < range) @@ -64,10 +73,22 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, p->next = *s; *s = p; } - mutex_unlock(domain->lock); return 0; } +int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, + struct module *module, kobj_probe_t *probe, + int (*lock)(dev_t, void *), void *data) +{ + int err; + + mutex_lock(domain->lock); + err = __kobj_map(domain, dev, FMODE_READ | FMODE_WRITE, range, + module, probe, lock, data); + mutex_unlock(domain->lock); + return err; +} + void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range) { unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; -- 1.5.3.4
| |