The patch titled cgroups: introduce cft->read_seq() has been added to the -mm tree. Its filename is cgroups-introduce-cft-read_seq-v2.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/ ------------------------------------------------------ Subject: cgroups: introduce cft->read_seq() From: Serge E. Hallyn <serue@xxxxxxxxxx> Introduce a read_seq() helper in cftype, which uses seq_file to print out lists. Use it in the devices cgroup. Also split devices.allow into two files, so now devices.deny and devices.allow are the ones to use to manipulate the whitelist, while devices.list outputs the cgroup's current whitelist. Signed-off-by: Serge E. Hallyn <serue@xxxxxxxxxx> Acked-by: Paul Menage <menage@xxxxxxxxxx> Cc: Balbir Singh <balbir@xxxxxxxxxx> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/cgroup.h | 6 +++ kernel/cgroup.c | 15 ++++--- security/device_cgroup.c | 74 +++++++++++-------------------------- 3 files changed, 38 insertions(+), 57 deletions(-) diff -puN include/linux/cgroup.h~cgroups-introduce-cft-read_seq-v2 include/linux/cgroup.h --- a/include/linux/cgroup.h~cgroups-introduce-cft-read_seq-v2 +++ a/include/linux/cgroup.h @@ -226,6 +226,12 @@ struct cftype { */ int (*read_map) (struct cgroup *cont, struct cftype *cft, struct cgroup_map_cb *cb); + /* + * read_seq_string() is used for outputting a simple sequence + * using seqfile. + */ + int (*read_seq_string) (struct cgroup *cont, struct cftype *cft, + struct seq_file *m); ssize_t (*write) (struct cgroup *cgrp, struct cftype *cft, struct file *file, diff -puN kernel/cgroup.c~cgroups-introduce-cft-read_seq-v2 kernel/cgroup.c --- a/kernel/cgroup.c~cgroups-introduce-cft-read_seq-v2 +++ a/kernel/cgroup.c @@ -1549,11 +1549,14 @@ static int cgroup_seqfile_show(struct se { struct cgroup_seqfile_state *state = m->private; struct cftype *cft = state->cft; - struct cgroup_map_cb cb = { - .fill = cgroup_map_add, - .state = m, - }; - return cft->read_map(state->cgroup, cft, &cb); + if (cft->read_map) { + struct cgroup_map_cb cb = { + .fill = cgroup_map_add, + .state = m, + }; + return cft->read_map(state->cgroup, cft, &cb); + } + return cft->read_seq_string(state->cgroup, cft, m); } int cgroup_seqfile_release(struct inode *inode, struct file *file) @@ -1581,7 +1584,7 @@ static int cgroup_file_open(struct inode cft = __d_cft(file->f_dentry); if (!cft) return -ENODEV; - if (cft->read_map) { + if (cft->read_map || cft->read_seq_string) { struct cgroup_seqfile_state *state = kzalloc(sizeof(*state), GFP_USER); if (!state) diff -puN security/device_cgroup.c~cgroups-introduce-cft-read_seq-v2 security/device_cgroup.c --- a/security/device_cgroup.c~cgroups-introduce-cft-read_seq-v2 +++ a/security/device_cgroup.c @@ -9,6 +9,7 @@ #include <linux/ctype.h> #include <linux/list.h> #include <linux/uaccess.h> +#include <linux/seq_file.h> #define ACC_MKNOD 1 #define ACC_READ 2 @@ -201,11 +202,15 @@ static void devcgroup_destroy(struct cgr #define DEVCG_ALLOW 1 #define DEVCG_DENY 2 +#define DEVCG_LIST 3 + +#define MAJMINLEN 10 +#define ACCLEN 4 static void set_access(char *acc, short access) { int idx = 0; - memset(acc, 0, 4); + memset(acc, 0, ACCLEN); if (access & ACC_READ) acc[idx++] = 'r'; if (access & ACC_WRITE) @@ -225,70 +230,33 @@ static char type_to_char(short type) return 'X'; } -static void set_majmin(char *str, int len, unsigned m) +static void set_majmin(char *str, unsigned m) { - memset(str, 0, len); + memset(str, 0, MAJMINLEN); if (m == ~0) sprintf(str, "*"); else - snprintf(str, len, "%d", m); + snprintf(str, MAJMINLEN, "%d", m); } -static char *print_whitelist(struct dev_cgroup *devcgroup, int *len) +static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft, + struct seq_file *m) { - char *buf, *s, acc[4]; + struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup); struct dev_whitelist_item *wh; - int ret; - int count = 0; - char maj[10], min[10]; - - buf = kmalloc(4096, GFP_KERNEL); - if (!buf) - return ERR_PTR(-ENOMEM); - s = buf; - *s = '\0'; - *len = 0; + char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN]; spin_lock(&devcgroup->lock); list_for_each_entry(wh, &devcgroup->whitelist, list) { set_access(acc, wh->access); - set_majmin(maj, 10, wh->major); - set_majmin(min, 10, wh->minor); - ret = snprintf(s, 4095-(s-buf), "%c %s:%s %s\n", - type_to_char(wh->type), maj, min, acc); - if (s+ret >= buf+4095) { - kfree(buf); - buf = ERR_PTR(-ENOMEM); - break; - } - s += ret; - *len += ret; - count++; + set_majmin(maj, wh->major); + set_majmin(min, wh->minor); + seq_printf(m, "%c %s:%s %s\n", type_to_char(wh->type), + maj, min, acc); } spin_unlock(&devcgroup->lock); - return buf; -} - -static ssize_t devcgroup_access_read(struct cgroup *cgroup, - struct cftype *cft, struct file *file, - char __user *userbuf, size_t nbytes, loff_t *ppos) -{ - struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup); - int filetype = cft->private; - char *buffer; - int uninitialized_var(len); - int retval; - - if (filetype != DEVCG_ALLOW) - return -EINVAL; - buffer = print_whitelist(devcgroup, &len); - if (IS_ERR(buffer)) - return PTR_ERR(buffer); - - retval = simple_read_from_buffer(userbuf, nbytes, ppos, buffer, len); - kfree(buffer); - return retval; + return 0; } /* @@ -501,7 +469,6 @@ out1: static struct cftype dev_cgroup_files[] = { { .name = "allow", - .read = devcgroup_access_read, .write = devcgroup_access_write, .private = DEVCG_ALLOW, }, @@ -510,6 +477,11 @@ static struct cftype dev_cgroup_files[] .write = devcgroup_access_write, .private = DEVCG_DENY, }, + { + .name = "list", + .read_seq_string = devcgroup_seq_read, + .private = DEVCG_LIST, + }, }; static int devcgroup_populate(struct cgroup_subsys *ss, _ Patches currently in -mm which might be from serue@xxxxxxxxxx are git-unionfs.patch git-vfs.patch capabilities-implement-per-process-securebits.patch capabilities-implement-per-process-securebits-warning-fix.patch capabilities-implement-per-process-securebits-fix.patch root_plug-use-cap_task_prctl.patch smack-use-cap_task_prctl.patch cgroups-kernel-ns_cgroupc-should-include-linux-nsproxyh.patch cgroups-implement-device-whitelist-v6.patch cgroups-implement-device-whitelist-v6-checkpatch-fixes.patch cgroups-implement-device-whitelist-v6-cleanups.patch cgroups-implement-device-whitelist-doc.patch cgroups-implement-device-whitelist-v6-fix.patch cgroups-introduce-cft-read_seq-v2.patch signals-cleanup-security_task_kill-usage-implementation.patch signals-check_kill_permission-check-session-under-tasklist_lock.patch ipc-semaphores-code-factorisation.patch ipc-shared-memory-introduce-shmctl_down.patch ipc-message-queues-introduce-msgctl_down.patch ipc-semaphores-move-the-rwmutex-handling-inside-semctl_down.patch ipc-semaphores-remove-one-unused-parameter-from-semctl_down.patch ipc-get-rid-of-the-use-_setbuf-structure.patch ipc-introduce-ipc_update_perm.patch ipc-consolidate-all-xxxctl_down-functions.patch reiser4-replace-uid==0-check-with-capability.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html