diff options
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/drivers/harddog_kern.c | 1 | ||||
-rw-r--r-- | arch/um/include/sysdep-x86_64/kernel-offsets.h | 1 | ||||
-rw-r--r-- | arch/um/kernel/skas/uaccess.c | 15 | ||||
-rw-r--r-- | arch/um/kernel/vmlinux.lds.S | 1 | ||||
-rw-r--r-- | arch/um/os-Linux/umid.c | 97 | ||||
-rw-r--r-- | arch/um/sys-i386/checksum.S | 1 | ||||
-rw-r--r-- | arch/um/sys-i386/ptrace.c | 1 | ||||
-rw-r--r-- | arch/um/sys-ppc/misc.S | 1 | ||||
-rw-r--r-- | arch/um/sys-x86_64/syscall_table.c | 1 |
9 files changed, 73 insertions, 46 deletions
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c index d18a974..64ff22a 100644 --- a/arch/um/drivers/harddog_kern.c +++ b/arch/um/drivers/harddog_kern.c @@ -35,7 +35,6 @@ */ #include <linux/module.h> -#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/fs.h> diff --git a/arch/um/include/sysdep-x86_64/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h index 939cc47..91d129f 100644 --- a/arch/um/include/sysdep-x86_64/kernel-offsets.h +++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/sched.h> #include <linux/time.h> diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 5992c32..8912cec 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -8,6 +8,7 @@ #include "linux/kernel.h" #include "linux/string.h" #include "linux/fs.h" +#include "linux/hardirq.h" #include "linux/highmem.h" #include "asm/page.h" #include "asm/pgtable.h" @@ -38,7 +39,7 @@ static unsigned long maybe_map(unsigned long virt, int is_write) return((unsigned long) phys); } -static int do_op(unsigned long addr, int len, int is_write, +static int do_op_one_page(unsigned long addr, int len, int is_write, int (*op)(unsigned long addr, int len, void *arg), void *arg) { struct page *page; @@ -49,9 +50,11 @@ static int do_op(unsigned long addr, int len, int is_write, return(-1); page = phys_to_page(addr); - addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK); + addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + (addr & ~PAGE_MASK); + n = (*op)(addr, len, arg); - kunmap(page); + + kunmap_atomic(page, KM_UML_USERCOPY); return(n); } @@ -77,7 +80,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) remain = len; current->thread.fault_catcher = jmpbuf; - n = do_op(addr, size, is_write, op, arg); + n = do_op_one_page(addr, size, is_write, op, arg); if(n != 0){ *res = (n < 0 ? remain : 0); goto out; @@ -91,7 +94,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) } while(addr < ((addr + remain) & PAGE_MASK)){ - n = do_op(addr, PAGE_SIZE, is_write, op, arg); + n = do_op_one_page(addr, PAGE_SIZE, is_write, op, arg); if(n != 0){ *res = (n < 0 ? remain : 0); goto out; @@ -105,7 +108,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) goto out; } - n = do_op(addr, remain, is_write, op, arg); + n = do_op_one_page(addr, remain, is_write, op, arg); if(n != 0) *res = (n < 0 ? remain : 0); else *res = 0; diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S index 0a7d50f..72acdce 100644 --- a/arch/um/kernel/vmlinux.lds.S +++ b/arch/um/kernel/vmlinux.lds.S @@ -1,4 +1,3 @@ -#include <linux/config.h> /* in case the preprocessor is a 32bit one */ #undef i386 #ifdef CONFIG_LD_SCRIPT_STATIC diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index 362db05..48092b9 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -67,32 +67,53 @@ err: return err; } -static int actually_do_remove(char *dir) +/* + * Unlinks the files contained in @dir and then removes @dir. + * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We + * ignore ENOENT errors for anything (they happen, strangely enough - possibly due + * to races between multiple dying UML threads). + */ +static int remove_files_and_dir(char *dir) { DIR *directory; struct dirent *ent; int len; char file[256]; + int ret; directory = opendir(dir); - if(directory == NULL) - return -errno; + if (directory == NULL) { + if (errno != ENOENT) + return -errno; + else + return 0; + } - while((ent = readdir(directory)) != NULL){ - if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) + while ((ent = readdir(directory)) != NULL) { + if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue; len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1; - if(len > sizeof(file)) - return -E2BIG; + if (len > sizeof(file)) { + ret = -E2BIG; + goto out; + } sprintf(file, "%s/%s", dir, ent->d_name); - if(unlink(file) < 0) - return -errno; + if (unlink(file) < 0 && errno != ENOENT) { + ret = -errno; + goto out; + } } - if(rmdir(dir) < 0) - return -errno; - return 0; + if (rmdir(dir) < 0 && errno != ENOENT) { + ret = -errno; + goto out; + } + + ret = 0; +out: + closedir(directory); + return ret; } /* This says that there isn't already a user of the specified directory even if @@ -103,9 +124,10 @@ static int actually_do_remove(char *dir) * something other than UML sticking stuff in the directory * this boot racing with a shutdown of the other UML * In any of these cases, the directory isn't useful for anything else. + * + * Boolean return: 1 if in use, 0 otherwise. */ - -static int not_dead_yet(char *dir) +static inline int is_umdir_used(char *dir) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; char pid[sizeof("nnnnn\0")], *end; @@ -113,7 +135,7 @@ static int not_dead_yet(char *dir) n = snprintf(file, sizeof(file), "%s/pid", dir); if(n >= sizeof(file)){ - printk("not_dead_yet - pid filename too long\n"); + printk("is_umdir_used - pid filename too long\n"); err = -E2BIG; goto out; } @@ -123,7 +145,7 @@ static int not_dead_yet(char *dir) if(fd < 0) { fd = -errno; if(fd != -ENOENT){ - printk("not_dead_yet : couldn't open pid file '%s', " + printk("is_umdir_used : couldn't open pid file '%s', " "err = %d\n", file, -fd); } goto out; @@ -132,18 +154,18 @@ static int not_dead_yet(char *dir) err = 0; n = read(fd, pid, sizeof(pid)); if(n < 0){ - printk("not_dead_yet : couldn't read pid file '%s', " + printk("is_umdir_used : couldn't read pid file '%s', " "err = %d\n", file, errno); goto out_close; } else if(n == 0){ - printk("not_dead_yet : couldn't read pid file '%s', " + printk("is_umdir_used : couldn't read pid file '%s', " "0-byte read\n", file); goto out_close; } p = strtoul(pid, &end, 0); if(end == pid){ - printk("not_dead_yet : couldn't parse pid file '%s', " + printk("is_umdir_used : couldn't parse pid file '%s', " "errno = %d\n", file, errno); goto out_close; } @@ -153,19 +175,32 @@ static int not_dead_yet(char *dir) return 1; } - err = actually_do_remove(dir); - if(err) - printk("not_dead_yet - actually_do_remove failed with " - "err = %d\n", err); - - return err; - out_close: close(fd); out: return 0; } +/* + * Try to remove the directory @dir unless it's in use. + * Precondition: @dir exists. + * Returns 0 for success, < 0 for failure in removal or if the directory is in + * use. + */ +static int umdir_take_if_dead(char *dir) +{ + int ret; + if (is_umdir_used(dir)) + return -EEXIST; + + ret = remove_files_and_dir(dir); + if (ret) { + printk("is_umdir_used - remove_files_and_dir failed with " + "err = %d\n", ret); + } + return ret; +} + static void __init create_pid_file(void) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; @@ -244,11 +279,7 @@ int __init make_umid(void) if(err != -EEXIST) goto err; - /* 1 -> this umid is already in use - * < 0 -> we couldn't remove the umid directory - * In either case, we can't use this umid, so return -EEXIST. - */ - if(not_dead_yet(tmp) != 0) + if (umdir_take_if_dead(tmp) < 0) goto err; err = mkdir(tmp, 0777); @@ -344,9 +375,9 @@ static void remove_umid_dir(void) char dir[strlen(uml_dir) + UMID_LEN + 1], err; sprintf(dir, "%s%s", uml_dir, umid); - err = actually_do_remove(dir); + err = remove_files_and_dir(dir); if(err) - printf("remove_umid_dir - actually_do_remove failed with " + printf("remove_umid_dir - remove_files_and_dir failed with " "err = %d\n", err); } diff --git a/arch/um/sys-i386/checksum.S b/arch/um/sys-i386/checksum.S index d98b2ff..62c7e56 100644 --- a/arch/um/sys-i386/checksum.S +++ b/arch/um/sys-i386/checksum.S @@ -25,7 +25,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/errno.h> /* diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index 6028bc7..28bf011 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -3,7 +3,6 @@ * Licensed under the GPL */ -#include <linux/config.h> #include <linux/compiler.h> #include "linux/sched.h" #include "linux/mm.h" diff --git a/arch/um/sys-ppc/misc.S b/arch/um/sys-ppc/misc.S index f0c971db..1364b7d 100644 --- a/arch/um/sys-ppc/misc.S +++ b/arch/um/sys-ppc/misc.S @@ -15,7 +15,6 @@ * */ -#include <linux/config.h> #include <asm/processor.h> #include "ppc_asm.h" diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c index 3c43181..9e9ad72 100644 --- a/arch/um/sys-x86_64/syscall_table.c +++ b/arch/um/sys-x86_64/syscall_table.c @@ -4,7 +4,6 @@ #include <linux/linkage.h> #include <linux/sys.h> #include <linux/cache.h> -#include <linux/config.h> #define __NO_STUBS |