/* * linux/fs/proc/root.c * * Copyright (C) 1991, 1992 Linus Torvalds * * proc root directory handling functions */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "internal.h" enum { Opt_gid, Opt_hidepid, Opt_err, }; static const match_table_t tokens = { {Opt_hidepid, "hidepid=%u"}, {Opt_gid, "gid=%u"}, {Opt_err, NULL}, }; int proc_parse_options(char *options, struct pid_namespace *pid) { char *p; substring_t args[MAX_OPT_ARGS]; int option; if (!options) return 1; while ((p = strsep(&options, ",")) != NULL) { int token; if (!*p) continue; args[0].to = args[0].from = NULL; token = match_token(p, tokens, args); switch (token) { case Opt_gid: if (match_int(&args[0], &option)) return 0; pid->pid_gid = make_kgid(current_user_ns(), option); break; case Opt_hidepid: if (match_int(&args[0], &option)) return 0; if (option < 0 || option > 2) { pr_err("proc: hidepid value must be between 0 and 2.\n"); return 0; } pid->hide_pid = option; break; default: pr_err("proc: unrecognized mount option \"%s\" " "or missing value\n", p); return 0; } } return 1; } int proc_remount(struct super_block *sb, int *flags, char *data) { struct pid_namespace *pid = sb->s_fs_info; sync_filesystem(sb); return !proc_parse_options(data, pid); } static struct dentry *proc_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { struct pid_namespace *ns; if (flags & MS_KERNMOUNT) { ns = data; data = NULL; } else { ns = task_active_pid_ns(current); } return mount_ns(fs_type, flags, data, ns, ns->user_ns, proc_fill_super); } static void proc_kill_sb(struct super_block *sb) { struct pid_namespace *ns; ns = (struct pid_namespace *)sb->s_fs_info; if (ns->proc_self) dput(ns->proc_self); if (ns->proc_thread_self) dput(ns->proc_thread_self); kill_anon_super(sb); put_pid_ns(ns); } static struct file_system_type proc_fs_type = { .name = "proc", .mount = proc_mount, .kill_sb = proc_kill_sb, .fs_flags = FS_USERNS_MOUNT, }; void __init proc_root_init(void) { int err; proc_init_inodecache(); set_proc_pid_nlink(); err = register_filesystem(&proc_fs_type); if (err) return; proc_self_init(); proc_thread_self_init(); proc_symlink("mounts", NULL, "self/mounts"); proc_net_init(); #ifdef CONFIG_SYSVIPC proc_mkdir("sysvipc", NULL); #endif proc_mkdir("fs", NULL); proc_mkdir("driver", NULL); proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */ #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) /* just give it a mountpoint */ proc_create_mount_point("openprom"); #endif proc_tty_init(); proc_mkdir("bus", NULL); proc_sys_init(); } static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat ) { generic_fillattr(d_inode(dentry), stat); stat->nlink = proc_root.nlink + nr_processes(); return 0; } static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, unsigned int flags) { if (!proc_pid_lookup(dir, dentry, flags)) return NULL; return proc_lookup(dir, dentry, flags); } static int proc_root_readdir(struct file *file, struct dir_context *ctx) { if (ctx->pos < FIRST_PROCESS_ENTRY) { int error = proc_readdir(file, ctx); if (unlikely(error <= 0)) return error; ctx->pos = FIRST_PROCESS_ENTRY; } return proc_pid_readdir(file, ctx); } /* * The root /proc directory is special, as it has the * directories. Thus we don't use the generic * directory handling functions for that.. */ static const struct file_operations proc_root_operations = { .read = generic_read_dir, .iterate_shared = proc_root_readdir, .llseek = generic_file_llseek, }; /* * proc root can do almost nothing.. */ static const struct inode_operations proc_root_inode_operations = { .lookup = proc_root_lookup, .getattr = proc_root_getattr, }; /* * This is the root "inode" in the /proc tree.. */ struct proc_dir_entry proc_root = { .low_ino = PROC_ROOT_INO, .namelen = 5, .mode = S_IFDIR | S_IRUGO | S_IXUGO, .nlink = 2, .count = ATOMIC_INIT(1), .proc_iops = &proc_root_inode_operations, .proc_fops = &proc_root_operations, .parent = &proc_root, .subdir = RB_ROOT, .name = "/proc", }; int pid_ns_prepare_proc(struct pid_namespace *ns) { struct vfsmount *mnt; mnt = kern_mount_data(&proc_fs_type, ns); if (IS_ERR(mnt)) return PTR_ERR(mnt); ns->proc_mnt = mnt; return 0; } void pid_ns_release_proc(struct pid_namespace *ns) { kern_unmount(ns->proc_mnt); } iv>
authorChristoph Hellwig <hch@lst.de>2017-01-30 13:15:41 +0100
committerBjorn Helgaas <bhelgaas@google.com>2017-02-02 10:35:46 -0600
commitdfef358bd1beb4e7b5c94eca944be9cd23dfc752 (patch)
treeb9a2afb38a4c2ac8ad31f49ec0d71fe9e5b1994c /include/dt-bindings/iio
parent030305d69fc6963c16003f50d7e8d74b02d0a143 (diff)
PCI/MSI: Don't apply affinity if there aren't enough vectors left
Bart reported a problem wіth an out of bounds access in the low-level IRQ affinity code, which we root caused to the qla2xxx driver assigning all its MSI-X vectors to the pre and post vectors, and not having any left for the actually spread IRQs. Fix this issue by not asking for affinity assignment when there are no vectors to assign left. Fixes: 402723ad5c62 ("PCI/MSI: Provide pci_alloc_irq_vectors_affinity()") Link: https://lkml.kernel.org/r/1485359225.3093.3.camel@sandisk.com Reported-by: Bart Van Assche <bart.vanassche@sandisk.com> Tested-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'include/dt-bindings/iio')