From: Mark Huang Date: Fri, 4 Mar 2005 02:10:38 +0000 (+0000) Subject: remove most uml vendor branch changes, stock fedora uml works X-Git-Tag: before-fedora-2_6_18-1_2239_FC5-vs2_0_2_2-rc6-merge~240 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=ca631a4bee813691c3a9f4dfc0ee0e6c1c2009d0;p=linux-2.6.git remove most uml vendor branch changes, stock fedora uml works --- diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 6b10e6ca8..48618a93e 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -83,9 +83,6 @@ config NET source "fs/Kconfig.binfmt" -config EXTERNFS - tristate "Support for host-based filesystems" - config HOSTFS tristate "Host filesystem" help @@ -107,15 +104,11 @@ config HOSTFS If you'd like to be able to work with files stored on the host, say Y or M here; otherwise say N. -config HUMFS - tristate 'Usable host filesystem' - depends on EXTERNFS - config HPPFS tristate "HoneyPot ProcFS (EXPERIMENTAL)" depends on BROKEN help - hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc + hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc entries to be overridden, removed, or fabricated from the host. Its purpose is to allow a UML to appear to be a physical machine by removing or changing anything in /proc which gives away the @@ -218,9 +211,6 @@ config HIGHMEM bool "Highmem support" depends on BROKEN -config PROC_MM - bool "/proc/mm support" - config KERNEL_STACK_ORDER int "Kernel stack size order" default 2 diff --git a/arch/um/Makefile b/arch/um/Makefile index 69fbd65fc..b8371a958 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -202,6 +202,4 @@ $(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h FORCE $(ARCH_DIR)/kernel/skas/util: scripts_basic FORCE $(Q)$(MAKE) $(build)=$@ -define archhelp - echo '* linux - Binary kernel image (./linux)' -endef +export SUBARCH USER_CFLAGS OS diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index d87c9e7a1..7c7d00847 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 @@ -10,12 +10,6 @@ ifeq ($(CONFIG_MODE_SKAS),y) endif endif -ifeq ($(CONFIG_MODE_SKAS),y) - ifneq ($(CONFIG_MODE_TT),y) - START = 0x8048000 - endif -endif - CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) ARCH_USER_CFLAGS := @@ -32,12 +26,8 @@ SYS_UTIL_DIR := $(ARCH_DIR)/sys-i386/util SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h -sys_prepare: $(SYS_DIR)/sc.h - prepare: $(SYS_HEADERS) -filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc - $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc $(call filechk,gen_header) diff --git a/arch/um/defconfig b/arch/um/defconfig index fe6ab55d7..0524a22fa 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -17,11 +17,8 @@ CONFIG_MODE_TT=y CONFIG_MODE_SKAS=y CONFIG_NET=y CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -CONFIG_EXTERNFS=y +CONFIG_BINFMT_MISC=m CONFIG_HOSTFS=y -CONFIG_HUMFS=y -CONFIG_HPPFS=y CONFIG_MCONSOLE=y # CONFIG_HOST_2G_2G is not set # CONFIG_SMP is not set @@ -214,7 +211,6 @@ CONFIG_TUN=m # Ethernet (10 or 100Mbit) # # CONFIG_NET_ETHERNET is not set -# CONFIG_NE2000 is not set # # Ethernet (1000 Mbit) @@ -321,11 +317,6 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -CONFIG_JFFS_FS=y -CONFIG_JFFS_FS_VERBOSE=0 -# CONFIG_JFFS_PROC_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -395,18 +386,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set -# -# Linux VServer -# -CONFIG_VSERVER_LEGACY=y -CONFIG_PROC_SECURE=y -# CONFIG_VSERVER_HARDCPU is not set -# CONFIG_INOXID_NONE is not set -# CONFIG_INOXID_GID16 is not set -CONFIG_INOXID_GID24=y -# CONFIG_INOXID_GID32 is not set -# CONFIG_INOXID_MAGIC is not set - # # Security options # diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index c3e3b9408..7a8d75086 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -138,54 +138,6 @@ void generic_free(void *data) kfree(data); } -void generic_close(int fd, void *unused) -{ - os_close_file(fd); -} - -int generic_read(int fd, char *c_out, void *unused) -{ - int n; - - n = os_read_file(fd, c_out, sizeof(*c_out)); - - if(n == -EAGAIN) - return(0); - else if(n == 0) - return(-EIO); - return(n); -} - -/* XXX Trivial wrapper around os_write_file */ - -int generic_write(int fd, const char *buf, int n, void *unused) -{ - return(os_write_file(fd, buf, n)); -} - -int generic_window_size(int fd, void *unused, unsigned short *rows_out, - unsigned short *cols_out) -{ - int rows, cols; - int ret; - - ret = os_window_size(fd, &rows, &cols); - if(ret < 0) - return(ret); - - ret = ((*rows_out != rows) || (*cols_out != cols)); - - *rows_out = rows; - *cols_out = cols; - - return(ret); -} - -void generic_free(void *data) -{ - kfree(data); -} - static void tty_receive_char(struct tty_struct *tty, char ch) { if(tty == NULL) return; diff --git a/arch/um/drivers/cow_kern.c b/arch/um/drivers/cow_kern.c deleted file mode 100644 index ad843f3b6..000000000 --- a/arch/um/drivers/cow_kern.c +++ /dev/null @@ -1,630 +0,0 @@ -#define COW_MAJOR 60 -#define MAJOR_NR COW_MAJOR - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "2_5compat.h" -#include "cow.h" -#include "ubd_user.h" - -#define COW_SHIFT 4 - -struct cow { - int count; - char *cow_path; - dev_t cow_dev; - struct block_device *cow_bdev; - char *backing_path; - dev_t backing_dev; - struct block_device *backing_bdev; - int sectorsize; - unsigned long *bitmap; - unsigned long bitmap_len; - int bitmap_offset; - int data_offset; - devfs_handle_t devfs; - struct semaphore sem; - struct semaphore io_sem; - atomic_t working; - spinlock_t io_lock; - struct buffer_head *bh; - struct buffer_head *bhtail; - void *end_io; -}; - -#define DEFAULT_COW { \ - .count = 0, \ - .cow_path = NULL, \ - .cow_dev = 0, \ - .backing_path = NULL, \ - .backing_dev = 0, \ - .bitmap = NULL, \ - .bitmap_len = 0, \ - .bitmap_offset = 0, \ - .data_offset = 0, \ - .devfs = NULL, \ - .working = ATOMIC_INIT(0), \ - .io_lock = SPIN_LOCK_UNLOCKED, \ -} - -#define MAX_DEV (8) -#define MAX_MINOR (MAX_DEV << COW_SHIFT) - -struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW }; - -/* Not modified by this driver */ -static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE }; -static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 }; - -/* Protected by cow_lock */ -static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 }; - -static struct hd_struct cow_part[MAX_MINOR] = - { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } }; - -/* Protected by io_request_lock */ -static request_queue_t *cow_queue; - -static int cow_open(struct inode *inode, struct file *filp); -static int cow_release(struct inode * inode, struct file * file); -static int cow_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg); -static int cow_revalidate(kdev_t rdev); - -static struct block_device_operations cow_blops = { - .open = cow_open, - .release = cow_release, - .ioctl = cow_ioctl, - .revalidate = cow_revalidate, -}; - -/* Initialized in an initcall, and unchanged thereafter */ -devfs_handle_t cow_dir_handle; - -#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \ -{ \ - .major = maj, \ - .major_name = name, \ - .minor_shift = shift, \ - .max_p = 1 << shift, \ - .part = parts, \ - .sizes = bsizes, \ - .nr_real = max, \ - .real_devices = NULL, \ - .next = NULL, \ - .fops = blops, \ - .de_arr = NULL, \ - .flags = 0 \ -} - -static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED; - -static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part, - COW_SHIFT, sizes, MAX_DEV, - &cow_blops); - -static int cow_add(int n) -{ - struct cow *dev = &cow_dev[n]; - char name[sizeof("nnnnnn\0")]; - int err = -ENODEV; - - if(dev->cow_path == NULL) - goto out; - - sprintf(name, "%d", n); - dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE, - MAJOR_NR, n << COW_SHIFT, S_IFBLK | - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, - &cow_blops, NULL); - - init_MUTEX_LOCKED(&dev->sem); - init_MUTEX(&dev->io_sem); - - return(0); - - out: - return(err); -} - -/* - * Add buffer_head to back of pending list - */ -static void cow_add_bh(struct cow *cow, struct buffer_head *bh) -{ - unsigned long flags; - - spin_lock_irqsave(&cow->io_lock, flags); - if(cow->bhtail != NULL){ - cow->bhtail->b_reqnext = bh; - cow->bhtail = bh; - } - else { - cow->bh = bh; - cow->bhtail = bh; - } - spin_unlock_irqrestore(&cow->io_lock, flags); -} - -/* -* Grab first pending buffer -*/ -static struct buffer_head *cow_get_bh(struct cow *cow) -{ - struct buffer_head *bh; - - spin_lock_irq(&cow->io_lock); - bh = cow->bh; - if(bh != NULL){ - if(bh == cow->bhtail) - cow->bhtail = NULL; - cow->bh = bh->b_reqnext; - bh->b_reqnext = NULL; - } - spin_unlock_irq(&cow->io_lock); - - return(bh); -} - -static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, - struct buffer_head **cow_bh, int ncow_bh) -{ - int i; - - if(ncow_bh > 0) - ll_rw_block(WRITE, ncow_bh, cow_bh); - - for(i = 0; i < ncow_bh ; i++){ - wait_on_buffer(cow_bh[i]); - brelse(cow_bh[i]); - } - - ll_rw_block(WRITE, 1, &bh); - brelse(bh); -} - -static struct buffer_head *cow_new_bh(struct cow *dev, int sector) -{ - struct buffer_head *bh; - - sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize; - bh = getblk(dev->cow_dev, sector, dev->sectorsize); - memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])), - dev->sectorsize); - return(bh); -} - -/* Copied from loop.c, needed to avoid deadlocking in make_request. */ - -static int cow_thread(void *data) -{ - struct cow *dev = data; - struct buffer_head *bh; - - daemonize(); - exit_files(current); - - sprintf(current->comm, "cow%d", dev - cow_dev); - - spin_lock_irq(¤t->sigmask_lock); - sigfillset(¤t->blocked); - flush_signals(current); - spin_unlock_irq(¤t->sigmask_lock); - - atomic_inc(&dev->working); - - current->policy = SCHED_OTHER; - current->nice = -20; - - current->flags |= PF_NOIO; - - /* - * up sem, we are running - */ - up(&dev->sem); - - for(;;){ - int start, len, nbh, i, update_bitmap = 0; - struct buffer_head *cow_bh[2]; - - down_interruptible(&dev->io_sem); - /* - * could be upped because of tear-down, not because of - * pending work - */ - if(!atomic_read(&dev->working)) - break; - - bh = cow_get_bh(dev); - if(bh == NULL){ - printk(KERN_ERR "cow: missing bh\n"); - continue; - } - - start = bh->b_blocknr * bh->b_size / dev->sectorsize; - len = bh->b_size / dev->sectorsize; - for(i = 0; i < len ; i++){ - if(ubd_test_bit(start + i, - (unsigned char *) dev->bitmap)) - continue; - - update_bitmap = 1; - ubd_set_bit(start + i, (unsigned char *) dev->bitmap); - } - - cow_bh[0] = NULL; - cow_bh[1] = NULL; - nbh = 0; - if(update_bitmap){ - cow_bh[0] = cow_new_bh(dev, start); - nbh++; - if(start / dev->sectorsize != - (start + len) / dev->sectorsize){ - cow_bh[1] = cow_new_bh(dev, start + len); - nbh++; - } - } - - bh->b_dev = dev->cow_dev; - bh->b_blocknr += dev->data_offset / dev->sectorsize; - - cow_handle_bh(dev, bh, cow_bh, nbh); - - /* - * upped both for pending work and tear-down, lo_pending - * will hit zero then - */ - if(atomic_dec_and_test(&dev->working)) - break; - } - - up(&dev->sem); - return(0); -} - -static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh) -{ - struct cow *dev; - int n, minor; - - minor = MINOR(bh->b_rdev); - n = minor >> COW_SHIFT; - dev = &cow_dev[n]; - - dev->end_io = NULL; - if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){ - bh->b_rdev = dev->cow_dev; - bh->b_rsector += dev->data_offset / dev->sectorsize; - } - else if(rw == WRITE){ - bh->b_dev = dev->cow_dev; - bh->b_blocknr += dev->data_offset / dev->sectorsize; - - cow_add_bh(dev, bh); - up(&dev->io_sem); - return(0); - } - else { - bh->b_rdev = dev->backing_dev; - } - - return(1); -} - -int cow_init(void) -{ - int i; - - cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL); - if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) { - printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR); - return -1; - } - read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */ - blksize_size[MAJOR_NR] = blk_sizes; - blk_size[MAJOR_NR] = sizes; - INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes); - - cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR); - blk_init_queue(cow_queue, NULL); - INIT_ELV(cow_queue, &cow_queue->elevator); - blk_queue_make_request(cow_queue, cow_make_request); - - add_gendisk(&cow_gendisk); - - for(i=0;i 0){ - n = (left > blocksize) ? blocksize : left; - - bh = bread(dev, block, (n < 512) ? 512 : n); - if(bh == NULL) - return(-EIO); - - n -= offset; - memcpy(&buf[cur], bh->b_data + offset, n); - block++; - left -= n; - cur += n; - offset = 0; - brelse(bh); - } - - return(count); -} - -static int cow_open(struct inode *inode, struct file *filp) -{ - int (*dev_ioctl)(struct inode *, struct file *, unsigned int, - unsigned long); - mm_segment_t fs; - struct cow *dev; - __u64 size; - __u32 version, align; - time_t mtime; - char *backing_file; - int n, offset, err = 0; - - n = DEVICE_NR(inode->i_rdev); - if(n >= MAX_DEV) - return(-ENODEV); - dev = &cow_dev[n]; - offset = n << COW_SHIFT; - - spin_lock(&cow_lock); - - if(dev->count == 0){ - dev->cow_dev = name_to_kdev_t(dev->cow_path); - if(dev->cow_dev == 0){ - printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") " - "failed\n", dev->cow_path); - err = -ENODEV; - } - - dev->backing_dev = name_to_kdev_t(dev->backing_path); - if(dev->backing_dev == 0){ - printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") " - "failed\n", dev->backing_path); - err = -ENODEV; - } - - if(err) - goto out; - - dev->cow_bdev = bdget(dev->cow_dev); - if(dev->cow_bdev == NULL){ - printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", - dev->cow_path); - err = -ENOMEM; - } - dev->backing_bdev = bdget(dev->backing_dev); - if(dev->backing_bdev == NULL){ - printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", - dev->backing_path); - err = -ENOMEM; - } - - if(err) - goto out; - - err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, - BDEV_RAW); - if(err){ - printk("cow_open - blkdev_get of COW device failed, " - "error = %d\n", err); - goto out; - } - - err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW); - if(err){ - printk("cow_open - blkdev_get of backing device " - "failed, error = %d\n", err); - goto out; - } - - err = read_cow_header(reader, &dev->cow_dev, &version, - &backing_file, &mtime, &size, - &dev->sectorsize, &align, - &dev->bitmap_offset); - if(err){ - printk(KERN_ERR "cow_open - read_cow_header failed, " - "err = %d\n", err); - goto out; - } - - cow_sizes(version, size, dev->sectorsize, align, - dev->bitmap_offset, &dev->bitmap_len, - &dev->data_offset); - dev->bitmap = (void *) vmalloc(dev->bitmap_len); - if(dev->bitmap == NULL){ - err = -ENOMEM; - printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); - goto out; - } - flush_tlb_kernel_vm(); - - err = reader(dev->bitmap_offset, (char *) dev->bitmap, - dev->bitmap_len, &dev->cow_dev); - if(err < 0){ - printk(KERN_ERR "Failed to read COW bitmap\n"); - vfree(dev->bitmap); - goto out; - } - - dev_ioctl = dev->backing_bdev->bd_op->ioctl; - fs = get_fs(); - set_fs(KERNEL_DS); - err = (*dev_ioctl)(inode, filp, BLKGETSIZE, - (unsigned long) &sizes[offset]); - set_fs(fs); - if(err){ - printk(KERN_ERR "cow_open - BLKGETSIZE failed, " - "error = %d\n", err); - goto out; - } - - kernel_thread(cow_thread, dev, - CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - down(&dev->sem); - } - dev->count++; - out: - spin_unlock(&cow_lock); - return(err); -} - -static int cow_release(struct inode * inode, struct file * file) -{ - struct cow *dev; - int n, err; - - n = DEVICE_NR(inode->i_rdev); - if(n >= MAX_DEV) - return(-ENODEV); - dev = &cow_dev[n]; - - spin_lock(&cow_lock); - - if(--dev->count > 0) - goto out; - - err = blkdev_put(dev->cow_bdev, BDEV_RAW); - if(err) - printk("cow_release - blkdev_put of cow device failed, " - "error = %d\n", err); - bdput(dev->cow_bdev); - dev->cow_bdev = 0; - - err = blkdev_put(dev->backing_bdev, BDEV_RAW); - if(err) - printk("cow_release - blkdev_put of backing device failed, " - "error = %d\n", err); - bdput(dev->backing_bdev); - dev->backing_bdev = 0; - - out: - spin_unlock(&cow_lock); - return(0); -} - -static int cow_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) -{ - struct cow *dev; - int (*dev_ioctl)(struct inode *, struct file *, unsigned int, - unsigned long); - int n; - - n = DEVICE_NR(inode->i_rdev); - if(n >= MAX_DEV) - return(-ENODEV); - dev = &cow_dev[n]; - - dev_ioctl = dev->backing_bdev->bd_op->ioctl; - return((*dev_ioctl)(inode, file, cmd, arg)); -} - -static int cow_revalidate(kdev_t rdev) -{ - printk(KERN_ERR "Need to implement cow_revalidate\n"); - return(0); -} - -static int parse_unit(char **ptr) -{ - char *str = *ptr, *end; - int n = -1; - - if(isdigit(*str)) { - n = simple_strtoul(str, &end, 0); - if(end == str) - return(-1); - *ptr = end; - } - else if (('a' <= *str) && (*str <= 'h')) { - n = *str - 'a'; - str++; - *ptr = str; - } - return(n); -} - -static int cow_setup(char *str) -{ - struct cow *dev; - char *cow_name, *backing_name; - int unit; - - unit = parse_unit(&str); - if(unit < 0){ - printk(KERN_ERR "cow_setup - Couldn't parse unit number\n"); - return(1); - } - - if(*str != '='){ - printk(KERN_ERR "cow_setup - Missing '=' after unit " - "number\n"); - return(1); - } - str++; - - cow_name = str; - backing_name = strchr(str, ','); - if(backing_name == NULL){ - printk(KERN_ERR "cow_setup - missing backing device name\n"); - return(0); - } - *backing_name = '\0'; - backing_name++; - - spin_lock(&cow_lock); - - dev = &cow_dev[unit]; - dev->cow_path = cow_name; - dev->backing_path = backing_name; - - spin_unlock(&cow_lock); - return(0); -} - -__setup("cow", cow_setup); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index e3a40f385..122664b6b 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c @@ -35,12 +35,12 @@ struct cow_header_v2 { int sectorsize; }; -/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in +/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in * case other systems have different values for MAXPATHLEN */ #define PATH_LEN_V3 4096 -/* Changes from V2 - +/* Changes from V2 - * PATH_LEN_V3 as described above * Explicitly specify field bit lengths for systems with different * lengths for the usual C types. Not sure whether char or @@ -90,15 +90,15 @@ union cow_header { #define DIV_ROUND(x, len) (((x) + (len) - 1) / (len)) #define ROUND_UP(x, align) DIV_ROUND(x, align) * (align) -void cow_sizes(int version, __u64 size, int sectorsize, int align, - int bitmap_offset, unsigned long *bitmap_len_out, +void cow_sizes(int version, __u64 size, int sectorsize, int align, + int bitmap_offset, unsigned long *bitmap_len_out, int *data_offset_out) { if(version < 3){ *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize); *data_offset_out = bitmap_offset + *bitmap_len_out; - *data_offset_out = (*data_offset_out + sectorsize - 1) / + *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize; *data_offset_out *= sectorsize; } @@ -117,7 +117,7 @@ static int absolutize(char *to, int size, char *from) int remaining; if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) { - cow_printf("absolutize : unable to get cwd - errno = %d\n", + cow_printf("absolutize : unable to get cwd - errno = %d\n", errno); return(-1); } @@ -126,7 +126,7 @@ static int absolutize(char *to, int size, char *from) *slash = '\0'; if(chdir(from)){ *slash = '/'; - cow_printf("absolutize : Can't cd to '%s' - " + cow_printf("absolutize : Can't cd to '%s' - " "errno = %d\n", from, errno); return(-1); } @@ -158,7 +158,7 @@ static int absolutize(char *to, int size, char *from) return(0); } -int write_cow_header(char *cow_file, int fd, char *backing_file, +int write_cow_header(char *cow_file, int fd, char *backing_file, int sectorsize, int alignment, long long *size) { struct cow_header_v3 *header; @@ -183,12 +183,12 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, err = -EINVAL; if(strlen(backing_file) > sizeof(header->backing_file) - 1){ cow_printf("Backing file name \"%s\" is too long - names are " - "limited to %d characters\n", backing_file, + "limited to %d characters\n", backing_file, sizeof(header->backing_file) - 1); goto out_free; } - if(absolutize(header->backing_file, sizeof(header->backing_file), + if(absolutize(header->backing_file, sizeof(header->backing_file), backing_file)) goto out_free; @@ -234,10 +234,10 @@ int file_reader(__u64 offset, char *buf, int len, void *arg) /* XXX Need to sanity-check the values read from the header */ -int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, - __u32 *version_out, char **backing_file_out, - time_t *mtime_out, __u64 *size_out, - int *sectorsize_out, __u32 *align_out, +int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, + __u32 *version_out, char **backing_file_out, + time_t *mtime_out, __u64 *size_out, + int *sectorsize_out, __u32 *align_out, int *bitmap_offset_out) { union cow_header *header; @@ -310,7 +310,7 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, } else { cow_printf("read_cow_header - invalid COW version\n"); - goto out; + goto out; } err = -ENOMEM; *backing_file_out = cow_strdup(file); @@ -326,18 +326,18 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, } int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize, - int alignment, int *bitmap_offset_out, + int alignment, int *bitmap_offset_out, unsigned long *bitmap_len_out, int *data_offset_out) { __u64 size, offset; char zero = 0; int err; - err = write_cow_header(cow_file, fd, backing_file, sectorsize, + err = write_cow_header(cow_file, fd, backing_file, sectorsize, alignment, &size); - if(err) + if(err) goto out; - + *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment); cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out, bitmap_len_out, data_offset_out); @@ -349,9 +349,9 @@ int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize, goto out; } - /* does not really matter how much we write it is just to set EOF + /* does not really matter how much we write it is just to set EOF * this also sets the entire COW bitmap - * to zero without having to allocate it + * to zero without having to allocate it */ err = cow_write_file(fd, &zero, sizeof(zero)); if(err != sizeof(zero)){ diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index 6223a314a..d5742783e 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -214,7 +214,7 @@ static int hostaudio_release(struct inode *inode, struct file *file) printk("hostaudio: release called\n"); #endif - os_close_file(state->fd); + os_close_file(state->fd); kfree(state); return(0); @@ -271,7 +271,7 @@ static int hostmixer_release(struct inode *inode, struct file *file) printk("hostmixer: release called\n"); #endif - os_close_file(state->fd); + os_close_file(state->fd); kfree(state); return(0); diff --git a/arch/um/drivers/hostaudio_user.c b/arch/um/drivers/hostaudio_user.c index b89fefb4a..c32fa1b0a 100644 --- a/arch/um/drivers/hostaudio_user.c +++ b/arch/um/drivers/hostaudio_user.c @@ -4,6 +4,9 @@ */ #include +#include +#include +#include #include #include #include "hostaudio.h" @@ -17,31 +20,45 @@ ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer, size_t count, loff_t *ppos) { + ssize_t ret; + #ifdef DEBUG printk("hostaudio: read_user called, count = %d\n", count); #endif - return(os_read_file(state->fd, buffer, count)); + ret = read(state->fd, buffer, count); + + if(ret < 0) return(-errno); + return(ret); } ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer, size_t count, loff_t *ppos) { + ssize_t ret; + #ifdef DEBUG printk("hostaudio: write_user called, count = %d\n", count); #endif - return(os_write_file(state->fd, buffer, count)); + ret = write(state->fd, buffer, count); + + if(ret < 0) return(-errno); + return(ret); } int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd, unsigned long arg) { + int ret; #ifdef DEBUG printk("hostaudio: ioctl_user called, cmd = %u\n", cmd); #endif - return(os_ioctl_generic(state->fd, cmd, arg)); + ret = ioctl(state->fd, cmd, arg); + + if(ret < 0) return(-errno); + return(ret); } int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp) @@ -50,15 +67,14 @@ int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp) printk("hostaudio: open_user called\n"); #endif - state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); + state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); + + if(state->fd >= 0) return(0); - if(state->fd < 0) { - printk("hostaudio_open_user failed to open '%s', err = %d\n", - dsp, -state->fd); - return(state->fd); - } + printk("hostaudio_open_user failed to open '%s', errno = %d\n", + dsp, errno); - return(0); + return(-errno); } int hostaudio_release_user(struct hostaudio_state *state) @@ -66,10 +82,10 @@ int hostaudio_release_user(struct hostaudio_state *state) #ifdef DEBUG printk("hostaudio: release called\n"); #endif - if(state->fd >= 0){ - os_close_file(state->fd); - state->fd = -1; - } + if(state->fd >= 0){ + close(state->fd); + state->fd=-1; + } return(0); } @@ -79,11 +95,15 @@ int hostaudio_release_user(struct hostaudio_state *state) int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, unsigned int cmd, unsigned long arg) { + int ret; #ifdef DEBUG printk("hostmixer: ioctl_user called cmd = %u\n",cmd); #endif - return(os_ioctl_generic(state->fd, cmd, arg)); + ret = ioctl(state->fd, cmd, arg); + if(ret < 0) + return(-errno); + return(ret); } int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w, @@ -95,13 +115,12 @@ int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w, state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); - if(state->fd < 0) { - printk("hostaudio_open_mixdev_user failed to open '%s', " - "err = %d\n", mixer, state->fd); - return(state->fd); - } + if(state->fd >= 0) return(0); + + printk("hostaudio_open_mixdev_user failed to open '%s', errno = %d\n", + mixer, errno); - return(0); + return(-errno); } int hostmixer_release_mixdev_user(struct hostmixer_state *state) @@ -111,7 +130,7 @@ int hostmixer_release_mixdev_user(struct hostmixer_state *state) #endif if(state->fd >= 0){ - os_close_file(state->fd); + close(state->fd); state->fd = -1; } diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index ef8a1a942..2e4e1d49f 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -175,6 +175,7 @@ static int change_tramp(char **argv, char *output, int output_len) os_close_file(fds[1]); read_output(fds[0], output, output_len); + CATCH_EINTR(err = waitpid(pid, NULL, 0)); return(pid); } diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 6f1730d74..53fba09ad 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -783,7 +783,6 @@ int ubd_driver_init(void){ io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), &thread_fd); if(io_pid < 0){ - io_pid = -1; printk(KERN_ERR "ubd : Failed to start I/O thread (errno = %d) - " "falling back to synchronous I/O\n", -io_pid); diff --git a/arch/um/dyn.lds.S b/arch/um/dyn.lds.S index a331e2bde..361d9305a 100644 --- a/arch/um/dyn.lds.S +++ b/arch/um/dyn.lds.S @@ -1,23 +1,21 @@ -#include - OUTPUT_FORMAT(ELF_FORMAT) OUTPUT_ARCH(ELF_ARCH) ENTRY(_start) jiffies = jiffies_64; +SEARCH_DIR("/usr/local/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ SECTIONS { . = START + SIZEOF_HEADERS; .interp : { *(.interp) } + . = ALIGN(4096); __binary_start = .; . = ALIGN(4096); /* Init code and data */ _stext = .; __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } + .text.init : { *(.text.init) } . = ALIGN(4096); @@ -57,9 +55,7 @@ SECTIONS } =0x90909090 .plt : { *(.plt) } .text : { - *(.text) - SCHED_TEXT - *(.stub .text.* .gnu.linkonce.t.*) + *(.text .stub .text.* .gnu.linkonce.t.*) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) } =0x90909090 @@ -71,7 +67,7 @@ SECTIONS #include "asm/common.lds.S" - init.data : { *(.init.data) } + .data.init : { *(.data.init) } /* Ensure the __preinit_array_start label is properly aligned. We could instead move the label definition inside the section, but diff --git a/arch/um/include/filehandle.h b/arch/um/include/filehandle.h deleted file mode 100644 index adc51087a..000000000 --- a/arch/um/include/filehandle.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __FILEHANDLE_H__ -#define __FILEHANDLE_H__ - -#include "linux/list.h" -#include "linux/fs.h" -#include "os.h" - -struct file_handle { - struct list_head list; - int fd; - char *(*get_name)(struct inode *); - struct inode *inode; - struct openflags flags; -}; - -extern struct file_handle bad_filehandle; - -extern int open_file(char *name, struct openflags flags, int mode); -extern void *open_dir(char *file); -extern int open_filehandle(char *name, struct openflags flags, int mode, - struct file_handle *fh); -extern int read_file(struct file_handle *fh, unsigned long long offset, - char *buf, int len); -extern int write_file(struct file_handle *fh, unsigned long long offset, - const char *buf, int len); -extern int truncate_file(struct file_handle *fh, unsigned long long size); -extern int close_file(struct file_handle *fh); -extern void not_reclaimable(struct file_handle *fh); -extern void is_reclaimable(struct file_handle *fh, - char *(name_proc)(struct inode *), - struct inode *inode); -extern int filehandle_fd(struct file_handle *fh); -extern int make_pipe(struct file_handle *fhs); - -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/include/init.h b/arch/um/include/init.h index 52c393fa3..f1d82e025 100644 --- a/arch/um/include/init.h +++ b/arch/um/include/init.h @@ -100,16 +100,6 @@ extern struct uml_param __uml_setup_start, __uml_setup_end; #define __uml_postsetup_call __attribute__ ((unused,__section__ (".uml.postsetup.init"))) #define __uml_exit_call __attribute__ ((unused,__section__ (".uml.exitcall.exit"))) -#ifndef __KERNEL__ - -#define __initcall(fn) static initcall_t __initcall_##fn __init_call = fn -#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn - -#define __init_call __attribute__ ((unused,__section__ (".initcall.init"))) -#define __exit_call __attribute__ ((unused,__section__ (".exitcall.exit"))) - -#endif - #endif /* _LINUX_UML_INIT_H */ /* diff --git a/arch/um/include/os.h b/arch/um/include/os.h index b966b6e00..07340c8cf 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -52,12 +52,10 @@ struct openflags { unsigned int a : 1; /* O_APPEND */ unsigned int e : 1; /* O_EXCL */ unsigned int cl : 1; /* FD_CLOEXEC */ - unsigned int d : 1; /* O_DIRECT */ }; #define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \ - .t = 0, .a = 0, .e = 0, .cl = 0, \ - .d = 0 }) + .t = 0, .a = 0, .e = 0, .cl = 0 }) static inline struct openflags of_read(struct openflags flags) { @@ -136,16 +134,6 @@ extern int os_mode_fd(int fd, int mode); extern int os_seek_file(int fd, __u64 offset); extern int os_open_file(char *file, struct openflags flags, int mode); -extern void *os_open_dir(char *dir, int *err_out); -extern int os_seek_dir(void *stream, unsigned long long pos); -extern int os_read_dir(void *stream, unsigned long long *ino_out, - char **name_out); -extern int os_tell_dir(void *stream); -extern int os_close_dir(void *stream); -extern int os_remove_file(const char *file); -extern int os_move_file(const char *from, const char *to); -extern int os_truncate_file(const char *file, unsigned long long len); -extern int os_truncate_fd(int fd, unsigned long long len); extern int os_read_file(int fd, void *buf, int len); extern int os_write_file(int fd, const void *buf, int count); extern int os_file_size(char *file, long long *size_out); diff --git a/arch/um/include/skas_ptregs.h b/arch/um/include/skas_ptregs.h deleted file mode 100644 index afd5fc34f..000000000 --- a/arch/um/include/skas_ptregs.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Automatically generated by arch/um/kernel/skas/util/mk_ptregs */ - -#ifndef __SKAS_PT_REGS_ -#define __SKAS_PT_REGS_ - -#define HOST_FRAME_SIZE 17 -#define HOST_FP_SIZE 27 -#define HOST_XFP_SIZE 128 -#define HOST_IP 12 -#define HOST_SP 15 -#define HOST_EFLAGS 14 -#define HOST_EAX 6 -#define HOST_EBX 0 -#define HOST_ECX 1 -#define HOST_EDX 2 -#define HOST_ESI 3 -#define HOST_EDI 4 -#define HOST_EBP 5 -#define HOST_CS 13 -#define HOST_SS 16 -#define HOST_DS 7 -#define HOST_FS 9 -#define HOST_ES 8 -#define HOST_GS 10 - -#endif diff --git a/arch/um/kernel/filehandle.c b/arch/um/kernel/filehandle.c deleted file mode 100644 index a44dccf08..000000000 --- a/arch/um/kernel/filehandle.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include "linux/slab.h" -#include "linux/list.h" -#include "linux/spinlock.h" -#include "linux/fs.h" -#include "linux/errno.h" -#include "filehandle.h" -#include "os.h" -#include "kern_util.h" - -static spinlock_t open_files_lock = SPIN_LOCK_UNLOCKED; -static struct list_head open_files = LIST_HEAD_INIT(open_files); - -#define NUM_RECLAIM 128 - -static void reclaim_fds(void) -{ - struct file_handle *victim; - int closed = NUM_RECLAIM; - - spin_lock(&open_files_lock); - while(!list_empty(&open_files) && closed--){ - victim = list_entry(open_files.prev, struct file_handle, list); - os_close_file(victim->fd); - victim->fd = -1; - list_del_init(&victim->list); - } - spin_unlock(&open_files_lock); -} - -int open_file(char *name, struct openflags flags, int mode) -{ - int fd; - - fd = os_open_file(name, flags, mode); - if(fd != -EMFILE) - return(fd); - - reclaim_fds(); - fd = os_open_file(name, flags, mode); - - return(fd); -} - -void *open_dir(char *file) -{ - void *dir; - int err; - - dir = os_open_dir(file, &err); - if(dir != NULL) - return(dir); - if(err != -EMFILE) - return(ERR_PTR(err)); - - reclaim_fds(); - - dir = os_open_dir(file, &err); - if(dir == NULL) - dir = ERR_PTR(err); - - return(dir); -} - -void not_reclaimable(struct file_handle *fh) -{ - char *name; - - if(fh->get_name == NULL) - return; - - if(list_empty(&fh->list)){ - name = (*fh->get_name)(fh->inode); - if(name != NULL){ - fh->fd = open_file(name, fh->flags, 0); - kfree(name); - } - else printk("File descriptor %d has no name\n", fh->fd); - } - else { - spin_lock(&open_files_lock); - list_del_init(&fh->list); - spin_unlock(&open_files_lock); - } -} - -void is_reclaimable(struct file_handle *fh, char *(name_proc)(struct inode *), - struct inode *inode) -{ - fh->get_name = name_proc; - fh->inode = inode; - - spin_lock(&open_files_lock); - list_add(&fh->list, &open_files); - spin_unlock(&open_files_lock); -} - -static int active_handle(struct file_handle *fh) -{ - int fd; - char *name; - - if(!list_empty(&fh->list)) - list_move(&fh->list, &open_files); - - if(fh->fd != -1) - return(0); - - if(fh->inode == NULL) - return(-ENOENT); - - name = (*fh->get_name)(fh->inode); - if(name == NULL) - return(-ENOMEM); - - fd = open_file(name, fh->flags, 0); - kfree(name); - if(fd < 0) - return(fd); - - fh->fd = fd; - is_reclaimable(fh, fh->get_name, fh->inode); - - return(0); -} - -int filehandle_fd(struct file_handle *fh) -{ - int err; - - err = active_handle(fh); - if(err) - return(err); - - return(fh->fd); -} - -static void init_fh(struct file_handle *fh, int fd, struct openflags flags) -{ - flags.c = 0; - *fh = ((struct file_handle) { .list = LIST_HEAD_INIT(fh->list), - .fd = fd, - .get_name = NULL, - .inode = NULL, - .flags = flags }); -} - -int open_filehandle(char *name, struct openflags flags, int mode, - struct file_handle *fh) -{ - int fd; - - fd = open_file(name, flags, mode); - if(fd < 0) - return(fd); - - init_fh(fh, fd, flags); - return(0); -} - -int close_file(struct file_handle *fh) -{ - spin_lock(&open_files_lock); - list_del(&fh->list); - spin_unlock(&open_files_lock); - - os_close_file(fh->fd); - - fh->fd = -1; - return(0); -} - -int read_file(struct file_handle *fh, unsigned long long offset, char *buf, - int len) -{ - int err; - - err = active_handle(fh); - if(err) - return(err); - - err = os_seek_file(fh->fd, offset); - if(err) - return(err); - - return(os_read_file(fh->fd, buf, len)); -} - -int write_file(struct file_handle *fh, unsigned long long offset, - const char *buf, int len) -{ - int err; - - err = active_handle(fh); - if(err) - return(err); - - if(offset != -1) - err = os_seek_file(fh->fd, offset); - if(err) - return(err); - - return(os_write_file(fh->fd, buf, len)); -} - -int truncate_file(struct file_handle *fh, unsigned long long size) -{ - int err; - - err = active_handle(fh); - if(err) - return(err); - - return(os_truncate_fd(fh->fd, size)); -} - -int make_pipe(struct file_handle *fhs) -{ - int fds[2], err; - - err = os_pipe(fds, 1, 1); - if(err && (err != -EMFILE)) - return(err); - - if(err){ - reclaim_fds(); - err = os_pipe(fds, 1, 1); - } - if(err) - return(err); - - init_fh(&fhs[0], fds[0], OPENFLAGS()); - init_fh(&fhs[1], fds[1], OPENFLAGS()); - return(0); -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/kernel/helper.c b/arch/um/kernel/helper.c index 6c7114417..0e3d409d9 100644 --- a/arch/um/kernel/helper.c +++ b/arch/um/kernel/helper.c @@ -100,13 +100,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, CATCH_EINTR(n = waitpid(pid, NULL, 0)); pid = -errno; } - err = pid; - out_close: - os_close_file(fds[0]); - out_free: - if(stack_out == NULL) - free_stack(stack, 0); + if(stack_out == NULL) free_stack(stack, 0); else *stack_out = stack; return(pid); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index e795546d5..d2f0e82ca 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -57,7 +57,7 @@ void init_new_thread_signals(int altstack) { int flags = altstack ? SA_ONSTACK : 0; - set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags, + set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index bae4b7327..18255bd75 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c @@ -19,11 +19,8 @@ #include "linux/capability.h" #include "linux/vmalloc.h" #include "linux/spinlock.h" -#include "linux/vs_cvirt.h" #include "linux/proc_fs.h" #include "linux/ptrace.h" -#include "linux/vs_cvirt.h" - #include "asm/unistd.h" #include "asm/mman.h" #include "asm/segment.h" diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index a8439e2a2..e8caff95d 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -55,8 +55,6 @@ long sys_ptrace(long request, long pid, long addr, long data) read_unlock(&tasklist_lock); if (!child) goto out; - if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) - goto out_tsk; ret = -EPERM; if (pid == 1) /* you may not mess with init */ diff --git a/arch/um/kernel/skas/exec_user.c b/arch/um/kernel/skas/exec_user.c new file mode 100644 index 000000000..d50633a70 --- /dev/null +++ b/arch/um/kernel/skas/exec_user.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include +#include +#include "user.h" +#include "kern_util.h" +#include "user_util.h" +#include "os.h" +#include "time_user.h" + +static int user_thread_tramp(void *arg) +{ + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) + panic("user_thread_tramp - PTRACE_TRACEME failed, " + "errno = %d\n", errno); + enable_timer(); + os_stop_process(os_getpid()); + return(0); +} + +int user_thread(unsigned long stack, int flags) +{ + int pid, status, err; + + pid = clone(user_thread_tramp, (void *) stack_sp(stack), + flags | CLONE_FILES | SIGCHLD, NULL); + if(pid < 0){ + printk("user_thread - clone failed, errno = %d\n", errno); + return(pid); + } + + CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); + if(err < 0){ + printk("user_thread - waitpid failed, errno = %d\n", errno); + return(-errno); + } + + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){ + printk("user_thread - trampoline didn't stop, status = %d\n", + status); + return(-EINVAL); + } + + return(pid); +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/arch/um/include/aio.h b/arch/um/kernel/skas/include/mmu.h similarity index 50% rename from arch/um/include/aio.h rename to arch/um/kernel/skas/include/mmu.h index 6096f4f4e..cfbc062bd 100644 --- a/arch/um/include/aio.h +++ b/arch/um/kernel/skas/include/mmu.h @@ -1,27 +1,18 @@ /* - * Copyright (C) 2004 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ -#ifndef AIO_H__ -#define AIO_H__ +#ifndef __SKAS_MMU_H +#define __SKAS_MMU_H -enum aio_type { AIO_READ, AIO_WRITE, AIO_MMAP }; +#include "linux/list.h" +#include "linux/spinlock.h" -struct aio_thread_reply { - void *data; - int err; +struct mmu_context_skas { + int mm_fd; }; -struct aio_context { - int reply_fd; -}; - -#define INIT_AIO_CONTEXT { .reply_fd = -1 } - -extern int submit_aio(enum aio_type type, int fd, char *buf, int len, - unsigned long long offset, int reply_fd, void *data); - #endif /* diff --git a/arch/um/kernel/skas/include/mode.h b/arch/um/kernel/skas/include/mode.h new file mode 100644 index 000000000..285edc50a --- /dev/null +++ b/arch/um/kernel/skas/include/mode.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __MODE_SKAS_H__ +#define __MODE_SKAS_H__ + +extern unsigned long exec_regs[]; +extern unsigned long exec_fp_regs[]; +extern unsigned long exec_fpx_regs[]; +extern int have_fpx_regs; + +extern void user_time_init_skas(void); +extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, + void *from_ptr); +extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, + union uml_pt_regs *regs, + unsigned long fault_addr, int fault_type); +extern void sig_handler_common_skas(int sig, void *sc_ptr); +extern void halt_skas(void); +extern void reboot_skas(void); +extern void kill_off_processes_skas(void); +extern int is_skas_winch(int pid, int fd, void *data); + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/arch/um/kernel/skas/include/mode_kern.h b/arch/um/kernel/skas/include/mode_kern.h new file mode 100644 index 000000000..3597c0908 --- /dev/null +++ b/arch/um/kernel/skas/include/mode_kern.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __SKAS_MODE_KERN_H__ +#define __SKAS_MODE_KERN_H__ + +#include "linux/sched.h" +#include "asm/page.h" +#include "asm/ptrace.h" + +extern void flush_thread_skas(void); +extern void *switch_to_skas(void *prev, void *next); +extern void start_thread_skas(struct pt_regs *regs, unsigned long eip, + unsigned long esp); +extern int copy_thread_skas(int nr, unsigned long clone_flags, + unsigned long sp, unsigned long stack_top, + struct task_struct *p, struct pt_regs *regs); +extern void release_thread_skas(struct task_struct *task); +extern void exit_thread_skas(void); +extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); +extern void init_idle_skas(void); +extern void flush_tlb_kernel_range_skas(unsigned long start, + unsigned long end); +extern void flush_tlb_kernel_vm_skas(void); +extern void __flush_tlb_one_skas(unsigned long addr); +extern void flush_tlb_range_skas(struct vm_area_struct *vma, + unsigned long start, unsigned long end); +extern void flush_tlb_mm_skas(struct mm_struct *mm); +extern void force_flush_all_skas(void); +extern long execute_syscall_skas(void *r); +extern void before_mem_skas(unsigned long unused); +extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, + unsigned long *task_size_out); +extern int start_uml_skas(void); +extern int external_pid_skas(struct task_struct *task); +extern int thread_pid_skas(struct task_struct *task); + +#define kmem_end_skas (host_task_size - 1024 * 1024) + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/arch/um/kernel/skas/include/uaccess.h b/arch/um/kernel/skas/include/uaccess.h new file mode 100644 index 000000000..0d6f30bf7 --- /dev/null +++ b/arch/um/kernel/skas/include/uaccess.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __SKAS_UACCESS_H +#define __SKAS_UACCESS_H + +#include "asm/errno.h" + +#define access_ok_skas(type, addr, size) \ + ((segment_eq(get_fs(), KERNEL_DS)) || \ + (((unsigned long) (addr) < TASK_SIZE) && \ + ((unsigned long) (addr) + (size) <= TASK_SIZE))) + +static inline int verify_area_skas(int type, const void * addr, + unsigned long size) +{ + return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); +} + +extern int copy_from_user_skas(void *to, const void *from, int n); +extern int copy_to_user_skas(void *to, const void *from, int n); +extern int strncpy_from_user_skas(char *dst, const char *src, int count); +extern int __clear_user_skas(void *mem, int len); +extern int clear_user_skas(void *mem, int len); +extern int strnlen_user_skas(const void *str, int len); + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c index 2afef5c53..a549b3b14 100644 --- a/arch/um/kernel/syscall_kern.c +++ b/arch/um/kernel/syscall_kern.c @@ -15,8 +15,6 @@ #include "linux/unistd.h" #include "linux/slab.h" #include "linux/utime.h" -#include - #include "asm/mman.h" #include "asm/uaccess.h" #include "asm/ipc.h" @@ -58,9 +56,10 @@ long sys_vfork(void) } /* common code for old and new mmaps */ -long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, unsigned long fd, - unsigned long pgoff) +static inline long do_mmap2( + unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) { int error = -EBADF; struct file * file = NULL; @@ -72,9 +71,9 @@ long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len, goto out; } - down_write(&mm->mmap_sem); - error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff); - up_write(&mm->mmap_sem); + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); if (file) fput(file); @@ -86,7 +85,7 @@ long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { - return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff); + return do_mmap2(addr, len, prot, flags, fd, pgoff); } /* @@ -113,8 +112,7 @@ long old_mmap(unsigned long addr, unsigned long len, if (offset & ~PAGE_MASK) goto out; - err = do_mmap2(current->mm, addr, len, prot, flags, fd, - offset >> PAGE_SHIFT); + err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); out: return err; } @@ -226,7 +224,7 @@ long sys_uname(struct old_utsname * name) if (!name) return -EFAULT; down_read(&uts_sem); - err=copy_to_user(name, vx_new_utsname(), sizeof (*name)); + err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -234,7 +232,6 @@ long sys_uname(struct old_utsname * name) long sys_olduname(struct oldold_utsname * name) { long error; - struct new_utsname *ptr; if (!name) return -EFAULT; @@ -243,20 +240,19 @@ long sys_olduname(struct oldold_utsname * name) down_read(&uts_sem); - ptr = vx_new_utsname(); - error = __copy_to_user(&name->sysname,ptr->sysname, + error = __copy_to_user(&name->sysname,&system_utsname.sysname, __OLD_UTS_LEN); error |= __put_user(0,name->sysname+__OLD_UTS_LEN); - error |= __copy_to_user(&name->nodename,ptr->nodename, + error |= __copy_to_user(&name->nodename,&system_utsname.nodename, __OLD_UTS_LEN); error |= __put_user(0,name->nodename+__OLD_UTS_LEN); - error |= __copy_to_user(&name->release,ptr->release, + error |= __copy_to_user(&name->release,&system_utsname.release, __OLD_UTS_LEN); error |= __put_user(0,name->release+__OLD_UTS_LEN); - error |= __copy_to_user(&name->version,ptr->version, + error |= __copy_to_user(&name->version,&system_utsname.version, __OLD_UTS_LEN); error |= __put_user(0,name->version+__OLD_UTS_LEN); - error |= __copy_to_user(&name->machine,ptr->machine, + error |= __copy_to_user(&name->machine,&system_utsname.machine, __OLD_UTS_LEN); error |= __put_user(0,name->machine+__OLD_UTS_LEN); diff --git a/arch/um/kernel/tt/include/mmu.h b/arch/um/kernel/tt/include/mmu.h new file mode 100644 index 000000000..6b146bd84 --- /dev/null +++ b/arch/um/kernel/tt/include/mmu.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __TT_MMU_H +#define __TT_MMU_H + +struct mmu_context_tt { +}; + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/arch/um/kernel/tt/include/mode.h b/arch/um/kernel/tt/include/mode.h new file mode 100644 index 000000000..1a64e753e --- /dev/null +++ b/arch/um/kernel/tt/include/mode.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __MODE_TT_H__ +#define __MODE_TT_H__ + +#include "sysdep/ptrace.h" + +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; + +extern int tracing_pid; + +extern int tracer(int (*init_proc)(void *), void *sp); +extern void user_time_init_tt(void); +extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data); +extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, + void *data); +extern void sig_handler_common_tt(int sig, void *sc); +extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); +extern void reboot_tt(void); +extern void halt_tt(void); +extern int is_tracer_winch(int pid, int fd, void *data); +extern void kill_off_processes_tt(void); + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/arch/um/kernel/tt/include/mode_kern.h b/arch/um/kernel/tt/include/mode_kern.h new file mode 100644 index 000000000..a8c31340d --- /dev/null +++ b/arch/um/kernel/tt/include/mode_kern.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __TT_MODE_KERN_H__ +#define __TT_MODE_KERN_H__ + +#include "linux/sched.h" +#include "asm/page.h" +#include "asm/ptrace.h" +#include "asm/uaccess.h" + +extern void *switch_to_tt(void *prev, void *next); +extern void flush_thread_tt(void); +extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, + unsigned long esp); +extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, + unsigned long stack_top, struct task_struct *p, + struct pt_regs *regs); +extern void release_thread_tt(struct task_struct *task); +extern void exit_thread_tt(void); +extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); +extern void init_idle_tt(void); +extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); +extern void flush_tlb_kernel_vm_tt(void); +extern void __flush_tlb_one_tt(unsigned long addr); +extern void flush_tlb_range_tt(struct vm_area_struct *vma, + unsigned long start, unsigned long end); +extern void flush_tlb_mm_tt(struct mm_struct *mm); +extern void force_flush_all_tt(void); +extern long execute_syscall_tt(void *r); +extern void before_mem_tt(unsigned long brk_start); +extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, + unsigned long *task_size_out); +extern int start_uml_tt(void); +extern int external_pid_tt(struct task_struct *task); +extern int thread_pid_tt(struct task_struct *task); + +#define kmem_end_tt (host_task_size - ABOVE_KMEM) + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/arch/um/kernel/tt/include/uaccess.h b/arch/um/kernel/tt/include/uaccess.h new file mode 100644 index 000000000..7399836cb --- /dev/null +++ b/arch/um/kernel/tt/include/uaccess.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#ifndef __TT_UACCESS_H +#define __TT_UACCESS_H + +#include "linux/string.h" +#include "linux/sched.h" +#include "asm/processor.h" +#include "asm/errno.h" +#include "asm/current.h" +#include "asm/a.out.h" +#include "uml_uaccess.h" + +#define ABOVE_KMEM (16 * 1024 * 1024) + +extern unsigned long end_vm; +extern unsigned long uml_physmem; + +#define under_task_size(addr, size) \ + (((unsigned long) (addr) < TASK_SIZE) && \ + (((unsigned long) (addr) + (size)) < TASK_SIZE)) + +#define is_stack(addr, size) \ + (((unsigned long) (addr) < STACK_TOP) && \ + ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \ + (((unsigned long) (addr) + (size)) <= STACK_TOP)) + +#define access_ok_tt(type, addr, size) \ + ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \ + (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ + (under_task_size(addr, size) || is_stack(addr, size)))) + +static inline int verify_area_tt(int type, const void * addr, + unsigned long size) +{ + return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); +} + +extern unsigned long get_fault_addr(void); + +extern int __do_copy_from_user(void *to, const void *from, int n, + void **fault_addr, void **fault_catcher); +extern int __do_strncpy_from_user(char *dst, const char *src, size_t n, + void **fault_addr, void **fault_catcher); +extern int __do_clear_user(void *mem, size_t len, void **fault_addr, + void **fault_catcher); +extern int __do_strnlen_user(const char *str, unsigned long n, + void **fault_addr, void **fault_catcher); + +extern int copy_from_user_tt(void *to, const void *from, int n); +extern int copy_to_user_tt(void *to, const void *from, int n); +extern int strncpy_from_user_tt(char *dst, const char *src, int count); +extern int __clear_user_tt(void *mem, int len); +extern int clear_user_tt(void *mem, int len); +extern int strnlen_user_tt(const void *str, int len); + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/arch/um/kernel/user_syms.c b/arch/um/kernel/user_syms.c new file mode 100644 index 000000000..2d32ea3c5 --- /dev/null +++ b/arch/um/kernel/user_syms.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "user_util.h" +#include "mem_user.h" +#include "uml-config.h" + +/* Had to steal this from linux/module.h because that file can't be included + * since this includes various user-level headers. + */ + +struct module_symbol +{ + unsigned long value; + const char *name; +}; + +/* Indirect stringification. */ + +#define __MODULE_STRING_1(x) #x +#define __MODULE_STRING(x) __MODULE_STRING_1(x) + +#if !defined(__AUTOCONF_INCLUDED__) + +#define __EXPORT_SYMBOL(sym,str) error config_must_be_included_before_module +#define EXPORT_SYMBOL(var) error config_must_be_included_before_module +#define EXPORT_SYMBOL_NOVERS(var) error config_must_be_included_before_module + +#elif !defined(UML_CONFIG_MODULES) + +#define __EXPORT_SYMBOL(sym,str) +#define EXPORT_SYMBOL(var) +#define EXPORT_SYMBOL_NOVERS(var) + +#else + +#define __EXPORT_SYMBOL(sym, str) \ +const char __kstrtab_##sym[] \ +__attribute__((section(".kstrtab"))) = str; \ +const struct module_symbol __ksymtab_##sym \ +__attribute__((section("__ksymtab"))) = \ +{ (unsigned long)&sym, __kstrtab_##sym } + +#if defined(__MODVERSIONS__) || !defined(UML_CONFIG_MODVERSIONS) +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) +#else +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var))) +#endif + +#define EXPORT_SYMBOL_NOVERS(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) + +#endif + +EXPORT_SYMBOL(__errno_location); + +EXPORT_SYMBOL(access); +EXPORT_SYMBOL(open); +EXPORT_SYMBOL(open64); +EXPORT_SYMBOL(close); +EXPORT_SYMBOL(read); +EXPORT_SYMBOL(write); +EXPORT_SYMBOL(dup2); +EXPORT_SYMBOL(__xstat); +EXPORT_SYMBOL(__lxstat); +EXPORT_SYMBOL(__lxstat64); +EXPORT_SYMBOL(lseek); +EXPORT_SYMBOL(lseek64); +EXPORT_SYMBOL(chown); +EXPORT_SYMBOL(truncate); +EXPORT_SYMBOL(utime); +EXPORT_SYMBOL(chmod); +EXPORT_SYMBOL(rename); +EXPORT_SYMBOL(__xmknod); + +EXPORT_SYMBOL(symlink); +EXPORT_SYMBOL(link); +EXPORT_SYMBOL(unlink); +EXPORT_SYMBOL(readlink); + +EXPORT_SYMBOL(mkdir); +EXPORT_SYMBOL(rmdir); +EXPORT_SYMBOL(opendir); +EXPORT_SYMBOL(readdir); +EXPORT_SYMBOL(closedir); +EXPORT_SYMBOL(seekdir); +EXPORT_SYMBOL(telldir); + +EXPORT_SYMBOL(ioctl); + +extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes, + __off64_t __offset); +extern ssize_t pwrite64 (int __fd, __const void *__buf, size_t __n, + __off64_t __offset); +EXPORT_SYMBOL(pread64); +EXPORT_SYMBOL(pwrite64); + +EXPORT_SYMBOL(statfs); +EXPORT_SYMBOL(statfs64); + +EXPORT_SYMBOL(memcpy); +EXPORT_SYMBOL(getuid); + +EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(strstr); + +EXPORT_SYMBOL(find_iomem); diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S index db0445e22..72b608cc9 100644 --- a/arch/um/kernel/vmlinux.lds.S +++ b/arch/um/kernel/vmlinux.lds.S @@ -1,5 +1,5 @@ #include - + OUTPUT_FORMAT(ELF_FORMAT) OUTPUT_ARCH(ELF_ARCH) ENTRY(_start) @@ -7,5 +7,92 @@ jiffies = jiffies_64; SECTIONS { -#include "asm/common.lds.S" + . = START + SIZEOF_HEADERS; + + __binary_start = .; +#ifdef MODE_TT + .thread_private : { + __start_thread_private = .; + errno = .; + . += 4; + arch/um/kernel/tt/unmap_fin.o (.data) + __end_thread_private = .; + } + . = ALIGN(4096); + .remap : { arch/um/kernel/tt/unmap_fin.o (.text) } +#endif + + . = ALIGN(4096); /* Init code and data */ + _stext = .; + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + . = ALIGN(4096); + .text : + { + *(.text) + SCHED_TEXT + LOCK_TEXT + *(.fixup) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } + + #include "asm/common.lds.S" + + init.data : { *(init.data) } + .data : + { + . = ALIGN(KERNEL_STACK_SIZE); /* init_task */ + *(.data.init_task) + *(.data) + *(.gnu.linkonce.d*) + CONSTRUCTORS + } + .data1 : { *(.data1) } + .ctors : + { + *(.ctors) + } + .dtors : + { + *(.dtors) + } + + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + . = ALIGN(0x1000); + .sbss : + { + __bss_start = .; + PROVIDE(_bss_start = .); + *(.sbss) + *(.scommon) + } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } } diff --git a/arch/um/main.c b/arch/um/main.c index 9d06171f6..386688425 100644 --- a/arch/um/main.c +++ b/arch/um/main.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -17,8 +16,6 @@ #include "kern_util.h" #include "mem_user.h" #include "signal_user.h" -#include "time_user.h" -#include "irq_user.h" #include "user.h" #include "init.h" #include "mode.h" @@ -126,14 +123,12 @@ int main(int argc, char **argv, char **envp) set_stklim(); - new_argv = malloc((argc + 1) * sizeof(char *)); - if(new_argv == NULL){ + if((new_argv = malloc((argc + 1) * sizeof(char *))) == NULL){ perror("Mallocing argv"); exit(1); } for(i=0;i= uml_physmem) && (addr < high_physmem)){ - if(CAN_KMALLOC()) - kfree(ptr); - } - else if((addr >= start_vm) && (addr < end_vm)){ - if(CAN_KMALLOC()) - vfree(ptr); - } + if(CAN_KMALLOC()) kfree(ptr); else __real_free(ptr); } diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c deleted file mode 100644 index 56b378276..000000000 --- a/arch/um/os-Linux/aio.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include "os.h" -#include "helper.h" -#include "aio.h" -#include "init.h" -#include "user.h" -#include "mode.h" - -struct aio_thread_req { - enum aio_type type; - int io_fd; - unsigned long long offset; - char *buf; - int len; - int reply_fd; - void *data; -}; - -static int aio_req_fd_r = -1; -static int aio_req_fd_w = -1; - -#if defined(HAVE_AIO_ABI) -#include - -/* If we have the headers, we are going to build with AIO enabled. - * If we don't have aio in libc, we define the necessary stubs here. - */ - -#if !defined(HAVE_AIO_LIBC) - -#define __NR_io_setup 245 -#define __NR_io_getevents 247 -#define __NR_io_submit 248 - -static long io_setup(int n, aio_context_t *ctxp) -{ - return(syscall(__NR_io_setup, n, ctxp)); -} - -static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp) -{ - return(syscall(__NR_io_submit, ctx, nr, iocbpp)); -} - -static long io_getevents(aio_context_t ctx_id, long min_nr, long nr, - struct io_event *events, struct timespec *timeout) -{ - return(syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout)); -} - -#endif - -/* The AIO_MMAP cases force the mmapped page into memory here - * rather than in whatever place first touches the data. I used - * to do this by touching the page, but that's delicate because - * gcc is prone to optimizing that away. So, what's done here - * is we read from the descriptor from which the page was - * mapped. The caller is required to pass an offset which is - * inside the page that was mapped. Thus, when the read - * returns, we know that the page is in the page cache, and - * that it now backs the mmapped area. - */ - -static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf, - int len, unsigned long long offset, void *data) -{ - struct iocb iocb, *iocbp = &iocb; - char c; - int err; - - iocb = ((struct iocb) { .aio_data = (unsigned long) data, - .aio_reqprio = 0, - .aio_fildes = fd, - .aio_buf = (unsigned long) buf, - .aio_nbytes = len, - .aio_offset = offset, - .aio_reserved1 = 0, - .aio_reserved2 = 0, - .aio_reserved3 = 0 }); - - switch(type){ - case AIO_READ: - iocb.aio_lio_opcode = IOCB_CMD_PREAD; - err = io_submit(ctx, 1, &iocbp); - break; - case AIO_WRITE: - iocb.aio_lio_opcode = IOCB_CMD_PWRITE; - err = io_submit(ctx, 1, &iocbp); - break; - case AIO_MMAP: - iocb.aio_lio_opcode = IOCB_CMD_PREAD; - iocb.aio_buf = (unsigned long) &c; - iocb.aio_nbytes = sizeof(c); - err = io_submit(ctx, 1, &iocbp); - break; - default: - printk("Bogus op in do_aio - %d\n", type); - err = -EINVAL; - break; - } - if(err > 0) - err = 0; - - return(err); -} - -static aio_context_t ctx = 0; - -static int aio_thread(void *arg) -{ - struct aio_thread_reply reply; - struct io_event event; - int err, n, reply_fd; - - signal(SIGWINCH, SIG_IGN); - - while(1){ - n = io_getevents(ctx, 1, 1, &event, NULL); - if(n < 0){ - if(errno == EINTR) - continue; - printk("aio_thread - io_getevents failed, " - "errno = %d\n", errno); - } - else { - reply = ((struct aio_thread_reply) - { .data = (void *) event.data, - .err = event.res }); - reply_fd = - ((struct aio_context *) event.data)->reply_fd; - err = os_write_file(reply_fd, &reply, sizeof(reply)); - if(err != sizeof(reply)) - printk("not_aio_thread - write failed, " - "fd = %d, err = %d\n", - aio_req_fd_r, -err); - } - } - return(0); -} - -#endif - -static int do_not_aio(struct aio_thread_req *req) -{ - char c; - int err; - - switch(req->type){ - case AIO_READ: - err = os_seek_file(req->io_fd, req->offset); - if(err) - goto out; - - err = os_read_file(req->io_fd, req->buf, req->len); - break; - case AIO_WRITE: - err = os_seek_file(req->io_fd, req->offset); - if(err) - goto out; - - err = os_write_file(req->io_fd, req->buf, req->len); - break; - case AIO_MMAP: - err = os_seek_file(req->io_fd, req->offset); - if(err) - goto out; - - err = os_read_file(req->io_fd, &c, sizeof(c)); - break; - default: - printk("do_not_aio - bad request type : %d\n", req->type); - err = -EINVAL; - break; - } - - out: - return(err); -} - -static int not_aio_thread(void *arg) -{ - struct aio_thread_req req; - struct aio_thread_reply reply; - int err; - - signal(SIGWINCH, SIG_IGN); - while(1){ - err = os_read_file(aio_req_fd_r, &req, sizeof(req)); - if(err != sizeof(req)){ - if(err < 0) - printk("not_aio_thread - read failed, fd = %d, " - "err = %d\n", aio_req_fd_r, -err); - else { - printk("not_aio_thread - short read, fd = %d, " - "length = %d\n", aio_req_fd_r, err); - } - continue; - } - err = do_not_aio(&req); - reply = ((struct aio_thread_reply) { .data = req.data, - .err = err }); - err = os_write_file(req.reply_fd, &reply, sizeof(reply)); - if(err != sizeof(reply)) - printk("not_aio_thread - write failed, fd = %d, " - "err = %d\n", aio_req_fd_r, -err); - } -} - -static int aio_pid = -1; - -static int init_aio_24(void) -{ - unsigned long stack; - int fds[2], err; - - err = os_pipe(fds, 1, 1); - if(err) - goto out; - - aio_req_fd_w = fds[0]; - aio_req_fd_r = fds[1]; - err = run_helper_thread(not_aio_thread, NULL, - CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); - if(err < 0) - goto out_close_pipe; - - aio_pid = err; - goto out; - - out_close_pipe: - os_close_file(fds[0]); - os_close_file(fds[1]); - aio_req_fd_w = -1; - aio_req_fd_r = -1; - out: - return(0); -} - -#ifdef HAVE_AIO_ABI -#define DEFAULT_24_AIO 0 -static int init_aio_26(void) -{ - unsigned long stack; - int err; - - if(io_setup(256, &ctx)){ - printk("aio_thread failed to initialize context, err = %d\n", - errno); - return(-errno); - } - - err = run_helper_thread(aio_thread, NULL, - CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); - if(err < 0) - return(-errno); - - aio_pid = err; - err = 0; - out: - return(err); -} - -int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, - unsigned long long offset, int reply_fd, void *data) -{ - struct aio_thread_reply reply; - int err; - - ((struct aio_context *) data)->reply_fd = reply_fd; - - err = do_aio(ctx, type, io_fd, buf, len, offset, data); - if(err){ - reply = ((struct aio_thread_reply) { .data = data, - .err = err }); - err = os_write_file(reply_fd, &reply, sizeof(reply)); - if(err != sizeof(reply)) - printk("submit_aio_26 - write failed, " - "fd = %d, err = %d\n", reply_fd, -err); - else err = 0; - } - - return(err); -} - -#else -#define DEFAULT_24_AIO 1 -static int init_aio_26(void) -{ - return(-ENOSYS); -} - -int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, - unsigned long long offset, int reply_fd, void *data) -{ - return(-ENOSYS); -} -#endif - -static int aio_24 = DEFAULT_24_AIO; - -static int __init set_aio_24(char *name, int *add) -{ - aio_24 = 1; - return(0); -} - -__uml_setup("aio=2.4", set_aio_24, -"aio=2.4\n" -" This is used to force UML to use 2.4-style AIO even when 2.6 AIO is\n" -" available. 2.4 AIO is a single thread that handles one request at a\n" -" time, synchronously. 2.6 AIO is a thread which uses 2.5 AIO interface\n" -" to handle an arbitrary number of pending requests. 2.6 AIO is not\n" -" available in tt mode, on 2.4 hosts, or when UML is built with\n" -" /usr/include/linux/aio_abi no available.\n\n" -); - -static int init_aio(void) -{ - int err; - - CHOOSE_MODE(({ - if(!aio_24){ - printk("Disabling 2.6 AIO in tt mode\n"); - aio_24 = 1; - } }), (void) 0); - - if(!aio_24){ - err = init_aio_26(); - if(err && (errno == ENOSYS)){ - printk("2.6 AIO not supported on the host - " - "reverting to 2.4 AIO\n"); - aio_24 = 1; - } - else return(err); - } - - if(aio_24) - return(init_aio_24()); - - return(0); -} - -__initcall(init_aio); - -static void exit_aio(void) -{ - if(aio_pid != -1) - os_kill_process(aio_pid, 1); -} - -__uml_exitcall(exit_aio); - -int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len, - unsigned long long offset, int reply_fd, void *data) -{ - struct aio_thread_req req = { .type = type, - .io_fd = io_fd, - .offset = offset, - .buf = buf, - .len = len, - .reply_fd = reply_fd, - .data = data, - }; - int err; - - err = os_write_file(aio_req_fd_w, &req, sizeof(req)); - if(err == sizeof(req)) - err = 0; - - return(err); -} - -int submit_aio(enum aio_type type, int io_fd, char *buf, int len, - unsigned long long offset, int reply_fd, void *data) -{ - if(aio_24) - return(submit_aio_24(type, io_fd, buf, len, offset, reply_fd, - data)); - else { - return(submit_aio_26(type, io_fd, buf, len, offset, reply_fd, - data)); - } -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 53a4a15b4..77d4066d1 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -15,8 +15,6 @@ #include #include #include -#include -#include #include "os.h" #include "user.h" #include "kern_util.h" @@ -268,7 +266,6 @@ int os_open_file(char *file, struct openflags flags, int mode) if(flags.c) f |= O_CREAT; if(flags.t) f |= O_TRUNC; if(flags.e) f |= O_EXCL; - if(flags.d) f |= O_DIRECT; fd = open64(file, f, mode); if(fd < 0) diff --git a/arch/um/sys-i386/bitops.c b/arch/um/sys-i386/bitops.c deleted file mode 100644 index 97db3853d..000000000 --- a/arch/um/sys-i386/bitops.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include - -/** - * find_next_bit - find the first set bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The maximum size to search - */ -int find_next_bit(const unsigned long *addr, int size, int offset) -{ - const unsigned long *p = addr + (offset >> 5); - int set = 0, bit = offset & 31, res; - - if (bit) { - /* - * Look for nonzero in the first 32 bits: - */ - __asm__("bsfl %1,%0\n\t" - "jne 1f\n\t" - "movl $32, %0\n" - "1:" - : "=r" (set) - : "r" (*p >> bit)); - if (set < (32 - bit)) - return set + offset; - set = 32 - bit; - p++; - } - /* - * No set bit yet, search remaining full words for a bit - */ - res = find_first_bit (p, size - 32 * (p - addr)); - return (offset + set + res); -} -EXPORT_SYMBOL(find_next_bit); - -/** - * find_next_zero_bit - find the first zero bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The maximum size to search - */ -int find_next_zero_bit(const unsigned long *addr, int size, int offset) -{ - unsigned long * p = ((unsigned long *) addr) + (offset >> 5); - int set = 0, bit = offset & 31, res; - - if (bit) { - /* - * Look for zero in the first 32 bits. - */ - __asm__("bsfl %1,%0\n\t" - "jne 1f\n\t" - "movl $32, %0\n" - "1:" - : "=r" (set) - : "r" (~(*p >> bit))); - if (set < (32 - bit)) - return set + offset; - set = 32 - bit; - p++; - } - /* - * No zero yet, search remaining full bytes for a zero - */ - res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); - return (offset + set + res); -} -EXPORT_SYMBOL(find_next_zero_bit); diff --git a/arch/um/sys-i386/extable.c b/arch/um/sys-i386/extable.c new file mode 100644 index 000000000..946e7ad6f --- /dev/null +++ b/arch/um/sys-i386/extable.c @@ -0,0 +1,30 @@ +/* + * linux/arch/i386/mm/extable.c + */ + +#include +#include +#include +#include + +/* Simple binary search */ +const struct exception_table_entry * +search_extable(const struct exception_table_entry *first, + const struct exception_table_entry *last, + unsigned long value) +{ + while (first <= last) { + const struct exception_table_entry *mid; + long diff; + + mid = (last - first) / 2 + first; + diff = mid->insn - value; + if (diff == 0) + return mid; + else if (diff < 0) + first = mid+1; + else + last = mid-1; + } + return NULL; +} diff --git a/arch/um/sys-i386/semaphore.c b/arch/um/sys-i386/semaphore.c deleted file mode 100644 index 073912cfc..000000000 --- a/arch/um/sys-i386/semaphore.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * i386 semaphore implementation. - * - * (C) Copyright 1999 Linus Torvalds - * - * Portions Copyright 1999 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * rw semaphores implemented November 1999 by Benjamin LaHaise - */ -#include -#include -#include -#include -#include - -/* - * Semaphores are implemented using a two-way counter: - * The "count" variable is decremented for each process - * that tries to acquire the semaphore, while the "sleeping" - * variable is a count of such acquires. - * - * Notably, the inline "up()" and "down()" functions can - * efficiently test if they need to do any extra work (up - * needs to do something only if count was negative before - * the increment operation. - * - * "sleeping" and the contention routine ordering is protected - * by the spinlock in the semaphore's waitqueue head. - * - * Note that these functions are only called when there is - * contention on the lock, and as such all this is the - * "non-critical" part of the whole semaphore business. The - * critical part is the inline stuff in - * where we want to avoid any extra jumps and calls. - */ - -/* - * Logic: - * - only on a boundary condition do we need to care. When we go - * from a negative count to a non-negative, we wake people up. - * - when we go from a non-negative count to a negative do we - * (a) synchronize with the "sleeper" count and (b) make sure - * that we're on the wakeup list before we synchronize so that - * we cannot lose wakeup events. - */ - -asmlinkage void __up(struct semaphore *sem) -{ - wake_up(&sem->wait); -} - -asmlinkage void __sched __down(struct semaphore * sem) -{ - struct task_struct *tsk = current; - DECLARE_WAITQUEUE(wait, tsk); - unsigned long flags; - - tsk->state = TASK_UNINTERRUPTIBLE; - spin_lock_irqsave(&sem->wait.lock, flags); - add_wait_queue_exclusive_locked(&sem->wait, &wait); - - sem->sleepers++; - for (;;) { - int sleepers = sem->sleepers; - - /* - * Add "everybody else" into it. They aren't - * playing, because we own the spinlock in - * the wait_queue_head. - */ - if (!atomic_add_negative(sleepers - 1, &sem->count)) { - sem->sleepers = 0; - break; - } - sem->sleepers = 1; /* us - see -1 above */ - spin_unlock_irqrestore(&sem->wait.lock, flags); - - schedule(); - - spin_lock_irqsave(&sem->wait.lock, flags); - tsk->state = TASK_UNINTERRUPTIBLE; - } - remove_wait_queue_locked(&sem->wait, &wait); - wake_up_locked(&sem->wait); - spin_unlock_irqrestore(&sem->wait.lock, flags); - tsk->state = TASK_RUNNING; -} - -asmlinkage int __sched __down_interruptible(struct semaphore * sem) -{ - int retval = 0; - struct task_struct *tsk = current; - DECLARE_WAITQUEUE(wait, tsk); - unsigned long flags; - - tsk->state = TASK_INTERRUPTIBLE; - spin_lock_irqsave(&sem->wait.lock, flags); - add_wait_queue_exclusive_locked(&sem->wait, &wait); - - sem->sleepers++; - for (;;) { - int sleepers = sem->sleepers; - - /* - * With signals pending, this turns into - * the trylock failure case - we won't be - * sleeping, and we* can't get the lock as - * it has contention. Just correct the count - * and exit. - */ - if (signal_pending(current)) { - retval = -EINTR; - sem->sleepers = 0; - atomic_add(sleepers, &sem->count); - break; - } - - /* - * Add "everybody else" into it. They aren't - * playing, because we own the spinlock in - * wait_queue_head. The "-1" is because we're - * still hoping to get the semaphore. - */ - if (!atomic_add_negative(sleepers - 1, &sem->count)) { - sem->sleepers = 0; - break; - } - sem->sleepers = 1; /* us - see -1 above */ - spin_unlock_irqrestore(&sem->wait.lock, flags); - - schedule(); - - spin_lock_irqsave(&sem->wait.lock, flags); - tsk->state = TASK_INTERRUPTIBLE; - } - remove_wait_queue_locked(&sem->wait, &wait); - wake_up_locked(&sem->wait); - spin_unlock_irqrestore(&sem->wait.lock, flags); - - tsk->state = TASK_RUNNING; - return retval; -} - -/* - * Trylock failed - make sure we correct for - * having decremented the count. - * - * We could have done the trylock with a - * single "cmpxchg" without failure cases, - * but then it wouldn't work on a 386. - */ -asmlinkage int __down_trylock(struct semaphore * sem) -{ - int sleepers; - unsigned long flags; - - spin_lock_irqsave(&sem->wait.lock, flags); - sleepers = sem->sleepers + 1; - sem->sleepers = 0; - - /* - * Add "everybody else" and us into it. They aren't - * playing, because we own the spinlock in the - * wait_queue_head. - */ - if (!atomic_add_negative(sleepers, &sem->count)) { - wake_up_locked(&sem->wait); - } - - spin_unlock_irqrestore(&sem->wait.lock, flags); - return 1; -} - - -/* - * The semaphore operations have a special calling sequence that - * allow us to do a simpler in-line version of them. These routines - * need to convert that sequence back into the C sequence when - * there is contention on the semaphore. - * - * %ecx contains the semaphore pointer on entry. Save the C-clobbered - * registers (%eax, %edx and %ecx) except %eax when used as a return - * value.. - */ -asm( -".section .sched.text\n" -".align 4\n" -".globl __down_failed\n" -"__down_failed:\n\t" -#if defined(CONFIG_FRAME_POINTER) - "pushl %ebp\n\t" - "movl %esp,%ebp\n\t" -#endif - "pushl %eax\n\t" - "pushl %edx\n\t" - "pushl %ecx\n\t" - "call __down\n\t" - "popl %ecx\n\t" - "popl %edx\n\t" - "popl %eax\n\t" -#if defined(CONFIG_FRAME_POINTER) - "movl %ebp,%esp\n\t" - "popl %ebp\n\t" -#endif - "ret" -); - -asm( -".section .sched.text\n" -".align 4\n" -".globl __down_failed_interruptible\n" -"__down_failed_interruptible:\n\t" -#if defined(CONFIG_FRAME_POINTER) - "pushl %ebp\n\t" - "movl %esp,%ebp\n\t" -#endif - "pushl %edx\n\t" - "pushl %ecx\n\t" - "call __down_interruptible\n\t" - "popl %ecx\n\t" - "popl %edx\n\t" -#if defined(CONFIG_FRAME_POINTER) - "movl %ebp,%esp\n\t" - "popl %ebp\n\t" -#endif - "ret" -); - -asm( -".section .sched.text\n" -".align 4\n" -".globl __down_failed_trylock\n" -"__down_failed_trylock:\n\t" -#if defined(CONFIG_FRAME_POINTER) - "pushl %ebp\n\t" - "movl %esp,%ebp\n\t" -#endif - "pushl %edx\n\t" - "pushl %ecx\n\t" - "call __down_trylock\n\t" - "popl %ecx\n\t" - "popl %edx\n\t" -#if defined(CONFIG_FRAME_POINTER) - "movl %ebp,%esp\n\t" - "popl %ebp\n\t" -#endif - "ret" -); - -asm( -".section .sched.text\n" -".align 4\n" -".globl __up_wakeup\n" -"__up_wakeup:\n\t" - "pushl %eax\n\t" - "pushl %edx\n\t" - "pushl %ecx\n\t" - "call __up\n\t" - "popl %ecx\n\t" - "popl %edx\n\t" - "popl %eax\n\t" - "ret" -); - -/* - * rw spinlock fallbacks - */ -#if defined(CONFIG_SMP) -asm( -".section .sched.text\n" -".align 4\n" -".globl __write_lock_failed\n" -"__write_lock_failed:\n\t" - LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax)\n" -"1: rep; nop\n\t" - "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" - "jne 1b\n\t" - LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" - "jnz __write_lock_failed\n\t" - "ret" -); - -asm( -".section .sched.text\n" -".align 4\n" -".globl __read_lock_failed\n" -"__read_lock_failed:\n\t" - LOCK "incl (%eax)\n" -"1: rep; nop\n\t" - "cmpl $1,(%eax)\n\t" - "js 1b\n\t" - LOCK "decl (%eax)\n\t" - "js __read_lock_failed\n\t" - "ret" -); -#endif diff --git a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile index 42e743262..34860f9ca 100644 --- a/arch/um/sys-i386/util/Makefile +++ b/arch/um/sys-i386/util/Makefile @@ -1,5 +1,3 @@ -host-progs := mk_sc mk_thread -always := $(host-progs) hostprogs-y := mk_sc mk_thread always := $(hostprogs-y) diff --git a/arch/um/uml.lds.S b/arch/um/uml.lds.S index 3c2fdec13..d182fb5de 100644 --- a/arch/um/uml.lds.S +++ b/arch/um/uml.lds.S @@ -9,6 +9,7 @@ SECTIONS { . = START + SIZEOF_HEADERS; + . = ALIGN(4096); __binary_start = .; #ifdef MODE_TT .thread_private : { @@ -25,16 +26,11 @@ SECTIONS . = ALIGN(4096); /* Init code and data */ _stext = .; __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } + .text.init : { *(.text.init) } . = ALIGN(4096); .text : { *(.text) - SCHED_TEXT /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) *(.gnu.linkonce.t*) @@ -42,7 +38,7 @@ SECTIONS #include "asm/common.lds.S" - init.data : { *(init.data) } + .data.init : { *(.data.init) } .data : { . = ALIGN(KERNEL_STACK_SIZE); /* init_task */ diff --git a/fs/Makefile b/fs/Makefile index 82730d528..c58878280 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -93,7 +93,6 @@ obj-$(CONFIG_JFS_FS) += jfs/ obj-$(CONFIG_XFS_FS) += xfs/ obj-$(CONFIG_AFS_FS) += afs/ obj-$(CONFIG_BEFS_FS) += befs/ -obj-$(CONFIG_EXTERNFS) += hostfs/ obj-$(CONFIG_RCFS_FS) += rcfs/ obj-$(CONFIG_HOSTFS) += hostfs/ obj-$(CONFIG_HPPFS) += hppfs/ diff --git a/fs/hostfs/externfs.c b/fs/hostfs/externfs.c deleted file mode 100644 index 884c33c83..000000000 --- a/fs/hostfs/externfs.c +++ /dev/null @@ -1,1317 +0,0 @@ -/* - * Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "hostfs.h" -#include "kern_util.h" -#include "kern.h" -#include "user_util.h" -#include "2_5compat.h" -#include "mem.h" -#include "filehandle.h" - -struct externfs { - struct list_head list; - struct externfs_mount_ops *mount_ops; - struct file_system_type type; -}; - -static inline struct externfs_inode *EXTERNFS_I(struct inode *inode) -{ - return(container_of(inode, struct externfs_inode, vfs_inode)); -} - -#define file_externfs_i(file) EXTERNFS_I((file)->f_dentry->d_inode) - -int externfs_d_delete(struct dentry *dentry) -{ - return(1); -} - -struct dentry_operations externfs_dentry_ops = { -}; - -#define EXTERNFS_SUPER_MAGIC 0x00c0ffee - -static struct inode_operations externfs_iops; -static struct inode_operations externfs_dir_iops; -static struct address_space_operations externfs_link_aops; - -static char *dentry_name(struct dentry *dentry, int extra) -{ - struct dentry *parent; - char *name; - int len; - - len = 0; - parent = dentry; - while(parent->d_parent != parent){ - len += parent->d_name.len + 1; - parent = parent->d_parent; - } - - name = kmalloc(len + extra + 1, GFP_KERNEL); - if(name == NULL) return(NULL); - - name[len] = '\0'; - parent = dentry; - while(parent->d_parent != parent){ - len -= parent->d_name.len + 1; - name[len] = '/'; - strncpy(&name[len + 1], parent->d_name.name, - parent->d_name.len); - parent = parent->d_parent; - } - - return(name); -} - -char *inode_name(struct inode *ino, int extra) -{ - struct dentry *dentry; - - dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias); - return(dentry_name(dentry, extra)); -} - -char *inode_name_prefix(struct inode *inode, char *prefix) -{ - int len; - char *name; - - len = strlen(prefix); - name = inode_name(inode, len); - if(name == NULL) - return(name); - - memmove(&name[len], name, strlen(name) + 1); - memcpy(name, prefix, strlen(prefix)); - return(name); -} - -static int read_name(struct inode *ino, char *name) -{ - struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; - /* The non-int inode fields are copied into ints by stat_file and - * then copied into the inode because passing the actual pointers - * in and having them treated as int * breaks on big-endian machines - */ - dev_t i_rdev; - int err; - int i_mode, i_nlink, i_blksize; - unsigned long atime, mtime, ctime; - unsigned long long i_size; - unsigned long long i_ino; - unsigned long long i_blocks; - - err = (*ops->stat_file)(name, ino->i_sb->s_fs_info, &i_rdev, &i_ino, - &i_mode, &i_nlink, &ino->i_uid, &ino->i_gid, - &i_size, &atime, &mtime, &ctime, &i_blksize, - &i_blocks); - if(err) return(err); - - ino->i_atime.tv_sec = atime; - ino->i_atime.tv_nsec = 0; - - ino->i_ctime.tv_sec = ctime; - ino->i_ctime.tv_nsec = 0; - - ino->i_mtime.tv_sec = mtime; - ino->i_mtime.tv_nsec = 0; - - ino->i_ino = i_ino; - ino->i_rdev = i_rdev; - ino->i_mode = i_mode; - ino->i_nlink = i_nlink; - ino->i_size = i_size; - ino->i_blksize = i_blksize; - ino->i_blocks = i_blocks; - return(0); -} - -static char *follow_link(char *link, - int (*do_read_link)(char *path, int uid, int gid, - char *buf, int size, - struct externfs_data *ed), - int uid, int gid, struct externfs_data *ed) -{ - int len, n; - char *name, *resolved, *end; - - len = 64; - while(1){ - n = -ENOMEM; - name = kmalloc(len, GFP_KERNEL); - if(name == NULL) - goto out; - - n = (*do_read_link)(link, uid, gid, name, len, ed); - if(n < len) - break; - len *= 2; - kfree(name); - } - if(n < 0) - goto out_free; - - if(*name == '/') - return(name); - - end = strrchr(link, '/'); - if(end == NULL) - return(name); - - *(end + 1) = '\0'; - len = strlen(link) + strlen(name) + 1; - - resolved = kmalloc(len, GFP_KERNEL); - if(resolved == NULL){ - n = -ENOMEM; - goto out_free; - } - - sprintf(resolved, "%s%s", link, name); - kfree(name); - return(resolved); - - out_free: - kfree(name); - out: - return(ERR_PTR(n)); -} - -static int read_inode(struct inode *ino) -{ - struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; - struct externfs_data *ed = ino->i_sb->s_fs_info; - char *name, *new; - int err = 0, type; - - /* Unfortunately, we are called from iget() when we don't have a dentry - * allocated yet. - */ - if(list_empty(&ino->i_dentry)) - goto out; - - err = -ENOMEM; - name = inode_name(ino, 0); - if(name == NULL) - goto out; - - type = (*ops->file_type)(name, NULL, ed); - if(type < 0){ - err = type; - goto out_free; - } - - if(type == OS_TYPE_SYMLINK){ - new = follow_link(name, ops->read_link, current->fsuid, - current->fsgid, ed); - if(IS_ERR(new)){ - err = PTR_ERR(new); - goto out_free; - } - kfree(name); - name = new; - } - - err = read_name(ino, name); - out_free: - kfree(name); - out: - return(err); -} - -int externfs_statfs(struct super_block *sb, struct kstatfs *sf) -{ - /* do_statfs uses struct statfs64 internally, but the linux kernel - * struct statfs still has 32-bit versions for most of these fields, - * so we convert them here - */ - int err; - long long f_blocks; - long long f_bfree; - long long f_bavail; - long long f_files; - long long f_ffree; - struct externfs_data *ed = sb->s_fs_info; - - err = (*ed->file_ops->statfs)(&sf->f_bsize, &f_blocks, &f_bfree, - &f_bavail, &f_files, &f_ffree, - &sf->f_fsid, sizeof(sf->f_fsid), - &sf->f_namelen, sf->f_spare, ed); - if(err) - return(err); - - sf->f_blocks = f_blocks; - sf->f_bfree = f_bfree; - sf->f_bavail = f_bavail; - sf->f_files = f_files; - sf->f_ffree = f_ffree; - sf->f_type = EXTERNFS_SUPER_MAGIC; - return(0); -} - -static struct inode *externfs_alloc_inode(struct super_block *sb) -{ - struct externfs_data *ed = sb->s_fs_info; - struct externfs_inode *ext; - - ext = (*ed->mount_ops->init_file)(ed); - if(ext == NULL) - return(NULL); - - *ext = ((struct externfs_inode) { .ops = ed->file_ops }); - - inode_init_once(&ext->vfs_inode); - return(&ext->vfs_inode); -} - -static void externfs_destroy_inode(struct inode *inode) -{ - struct externfs_inode *ext = EXTERNFS_I(inode); - - (*ext->ops->close_file)(ext, inode->i_size); -} - -static void externfs_read_inode(struct inode *inode) -{ - read_inode(inode); -} - -static struct super_operations externfs_sbops = { - .alloc_inode = externfs_alloc_inode, - .destroy_inode = externfs_destroy_inode, - .read_inode = externfs_read_inode, - .statfs = externfs_statfs, -}; - -int externfs_readdir(struct file *file, void *ent, filldir_t filldir) -{ - void *dir; - char *name; - unsigned long long next, ino; - int error, len; - struct externfs_file_ops *ops = file_externfs_i(file)->ops; - struct externfs_data *ed = file->f_dentry->d_inode->i_sb->s_fs_info; - - name = dentry_name(file->f_dentry, 0); - if(name == NULL) - return(-ENOMEM); - - dir = (*ops->open_dir)(name, current->fsuid, current->fsgid, ed); - kfree(name); - if(IS_ERR(dir)) - return(PTR_ERR(dir)); - - next = file->f_pos; - while((name = (*ops->read_dir)(dir, &next, &ino, &len, ed)) != NULL){ - error = (*filldir)(ent, name, len, file->f_pos, ino, - DT_UNKNOWN); - if(error) - break; - file->f_pos = next; - } - (*ops->close_dir)(dir, ed); - return(0); -} - -int externfs_file_open(struct inode *ino, struct file *file) -{ - ino->i_nlink++; - return(0); -} - -int externfs_fsync(struct file *file, struct dentry *dentry, int datasync) -{ - struct externfs_file_ops *ops = file_externfs_i(file)->ops; - struct inode *inode = dentry->d_inode; - struct externfs_data *ed = inode->i_sb->s_fs_info; - - return((*ops->truncate_file)(EXTERNFS_I(inode), inode->i_size, ed)); -} - -static struct file_operations externfs_file_fops = { - .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, - .mmap = generic_file_mmap, - .open = externfs_file_open, - .release = NULL, - .fsync = externfs_fsync, -}; - -static struct file_operations externfs_dir_fops = { - .readdir = externfs_readdir, - .read = generic_read_dir, -}; - -struct wp_info { - struct page *page; - int count; - unsigned long long start; - unsigned long long size; - int (*truncate)(struct externfs_inode *ext, __u64 size, - struct externfs_data *ed); - struct externfs_inode *ei; - struct externfs_data *ed; -}; - -static void externfs_finish_writepage(char *buffer, int res, void *arg) -{ - struct wp_info *wp = arg; - - if(res == wp->count){ - ClearPageError(wp->page); - if(wp->start + res > wp->size) - (*wp->truncate)(wp->ei, wp->size, wp->ed); - } - else { - SetPageError(wp->page); - ClearPageUptodate(wp->page); - } - - kunmap(wp->page); - unlock_page(wp->page); - kfree(wp); -} - -int externfs_writepage(struct page *page, struct writeback_control *wbc) -{ - struct address_space *mapping = page->mapping; - struct inode *inode = mapping->host; - struct externfs_file_ops *ops = EXTERNFS_I(inode)->ops; - struct wp_info *wp; - struct externfs_data *ed = inode->i_sb->s_fs_info; - char *buffer; - unsigned long long base; - int count = PAGE_CACHE_SIZE; - int end_index = inode->i_size >> PAGE_CACHE_SHIFT; - int err, offset; - - base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT; - - /* If we are entirely outside the file, then return an error */ - err = -EIO; - offset = inode->i_size & (PAGE_CACHE_SIZE-1); - if (page->index > end_index || - ((page->index == end_index) && !offset)) - goto out_unlock; - - err = -ENOMEM; - wp = kmalloc(sizeof(*wp), GFP_KERNEL); - if(wp == NULL) - goto out_unlock; - - *wp = ((struct wp_info) { .page = page, - .count = count, - .start = base, - .size = inode->i_size, - .truncate = ops->truncate_file, - .ei = EXTERNFS_I(inode), - .ed = ed }); - - buffer = kmap(page); - err = (*ops->write_file)(EXTERNFS_I(inode), base, buffer, 0, - count, externfs_finish_writepage, wp, ed); - - return err; - - out_unlock: - unlock_page(page); - return(err); -} - -static void externfs_finish_readpage(char *buffer, int res, void *arg) -{ - struct page *page = arg; - struct inode *inode; - - if(res < 0){ - SetPageError(page); - goto out; - } - - inode = page->mapping->host; - if(inode->i_size >> PAGE_CACHE_SHIFT == page->index) - res = inode->i_size % PAGE_CACHE_SIZE; - - memset(&buffer[res], 0, PAGE_CACHE_SIZE - res); - - flush_dcache_page(page); - SetPageUptodate(page); - if (PageError(page)) - ClearPageError(page); - out: - kunmap(page); - unlock_page(page); -} - -static int externfs_readpage(struct file *file, struct page *page) -{ - struct inode *ino = page->mapping->host; - struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; - struct externfs_data *ed = ino->i_sb->s_fs_info; - char *buffer; - long long start; - int err = 0; - - start = (long long) page->index << PAGE_CACHE_SHIFT; - buffer = kmap(page); - - if(ops->map_file_page != NULL){ - /* XXX What happens when PAGE_SIZE != PAGE_CACHE_SIZE? */ - err = (*ops->map_file_page)(file_externfs_i(file), start, - buffer, file->f_mode & FMODE_WRITE, - ed); - if(!err) - err = PAGE_CACHE_SIZE; - } - else err = (*ops->read_file)(file_externfs_i(file), start, buffer, - PAGE_CACHE_SIZE, 0, 0, - externfs_finish_readpage, page, ed); - - if(err > 0) - err = 0; - return(err); -} - -struct writepage_info { - struct semaphore sem; - int res; -}; - -static void externfs_finish_prepare(char *buffer, int res, void *arg) -{ - struct writepage_info *wp = arg; - - wp->res = res; - up(&wp->sem); -} - -int externfs_prepare_write(struct file *file, struct page *page, - unsigned int from, unsigned int to) -{ - struct address_space *mapping = page->mapping; - struct inode *inode = mapping->host; - struct externfs_file_ops *ops = EXTERNFS_I(inode)->ops; - struct externfs_data *ed = inode->i_sb->s_fs_info; - char *buffer; - long long start; - int err; - struct writepage_info wp; - - if(PageUptodate(page)) - return(0); - - start = (long long) page->index << PAGE_CACHE_SHIFT; - buffer = kmap(page); - - if(ops->map_file_page != NULL){ - err = (*ops->map_file_page)(file_externfs_i(file), start, - buffer, file->f_mode & FMODE_WRITE, - ed); - goto out; - - } - - init_MUTEX_LOCKED(&wp.sem); - err = (*ops->read_file)(file_externfs_i(file), start, buffer, - PAGE_CACHE_SIZE, from, to, - externfs_finish_prepare, &wp, ed); - down(&wp.sem); - if(err < 0) - goto out; - - err = wp.res; - if(err < 0) - goto out; - - if(from > 0) - memset(buffer, 0, from); - if(to < PAGE_CACHE_SIZE) - memset(buffer + to, 0, PAGE_CACHE_SIZE - to); - - SetPageUptodate(page); - err = 0; - out: - kunmap(page); - return(err); -} - -static int externfs_commit_write(struct file *file, struct page *page, - unsigned from, unsigned to) -{ - struct address_space *mapping = page->mapping; - struct inode *inode = mapping->host; - struct externfs_file_ops *ops = EXTERNFS_I(inode)->ops; - unsigned long long size; - long long start; - int err; - - start = (long long) (page->index << PAGE_CACHE_SHIFT); - - if(ops->map_file_page != NULL) - err = to - from; - else { - size = start + to; - if(size > inode->i_size){ - inode->i_size = size; - mark_inode_dirty(inode); - } - } - - set_page_dirty(page); - return(to - from); -} - -static int externfs_removepage(struct page *page, int gfpmask) -{ - physmem_remove_mapping(page_address(page)); - return(0); -} - -static struct address_space_operations externfs_aops = { - .writepage = externfs_writepage, - .readpage = externfs_readpage, - .releasepage = externfs_removepage, -/* .set_page_dirty = __set_page_dirty_nobuffers, */ - .prepare_write = externfs_prepare_write, - .commit_write = externfs_commit_write -}; - -static int init_inode(struct inode *inode, struct dentry *dentry) -{ - char *name = NULL; - int type, err = -ENOMEM, rdev; - struct externfs_inode *ext = EXTERNFS_I(inode); - struct externfs_file_ops *ops = ext->ops; - struct externfs_data *ed = inode->i_sb->s_fs_info; - - if(dentry){ - name = dentry_name(dentry, 0); - if(name == NULL) - goto out; - type = (*ops->file_type)(name, &rdev, ed); - } - else type = OS_TYPE_DIR; - - err = 0; - if(type == OS_TYPE_SYMLINK) - inode->i_op = &page_symlink_inode_operations; - else if(type == OS_TYPE_DIR) - inode->i_op = &externfs_dir_iops; - else inode->i_op = &externfs_iops; - - if(type == OS_TYPE_DIR) inode->i_fop = &externfs_dir_fops; - else inode->i_fop = &externfs_file_fops; - - if(type == OS_TYPE_SYMLINK) - inode->i_mapping->a_ops = &externfs_link_aops; - else inode->i_mapping->a_ops = &externfs_aops; - - switch (type) { - case OS_TYPE_CHARDEV: - init_special_inode(inode, S_IFCHR, rdev); - break; - case OS_TYPE_BLOCKDEV: - init_special_inode(inode, S_IFBLK, rdev); - break; - case OS_TYPE_FIFO: - init_special_inode(inode, S_IFIFO, 0); - break; - case OS_TYPE_SOCK: - init_special_inode(inode, S_IFSOCK, 0); - break; - case OS_TYPE_SYMLINK: - inode->i_mode = S_IFLNK | S_IRWXUGO; - } - - err = (*ops->open_file)(ext, name, current->fsuid, current->fsgid, - inode, ed); - if((err != -EISDIR) && (err != -ENOENT) && (err != -ENXIO)) - goto out_put; - - err = 0; - - out_free: - kfree(name); - out: - return(err); - - out_put: - iput(inode); - goto out_free; -} - -int externfs_create(struct inode *dir, struct dentry *dentry, int mode, - struct nameidata *nd) -{ - struct externfs_inode *ext = EXTERNFS_I(dir); - struct externfs_file_ops *ops = ext->ops; - struct inode *inode; - struct externfs_data *ed = dir->i_sb->s_fs_info; - char *name; - int err = -ENOMEM; - - inode = iget(dir->i_sb, 0); - if(inode == NULL) - goto out; - - err = init_inode(inode, dentry); - if(err) - goto out_put; - - err = -ENOMEM; - name = dentry_name(dentry, 0); - if(name == NULL) - goto out_put; - - err = (*ops->create_file)(ext, name, mode, current->fsuid, - current->fsuid, inode, ed); - if(err) - goto out_free; - - err = read_name(inode, name); - if(err) - goto out_rm; - - inode->i_nlink++; - d_instantiate(dentry, inode); - kfree(name); - out: - return(err); - - out_rm: - (*ops->unlink_file)(name, ed); - out_free: - kfree(name); - out_put: - inode->i_nlink = 0; - iput(inode); - goto out; -} - -struct dentry *externfs_lookup(struct inode *ino, struct dentry *dentry, - struct nameidata *nd) -{ - struct inode *inode; - char *name; - int err = -ENOMEM; - - inode = iget(ino->i_sb, 0); - if(inode == NULL) - goto out; - - err = init_inode(inode, dentry); - if(err) - goto out_put; - - err = -ENOMEM; - name = dentry_name(dentry, 0); - if(name == NULL) - goto out_put; - - err = read_name(inode, name); - kfree(name); - if(err){ - if(err != -ENOENT) - goto out_put; - - inode->i_nlink = 0; - iput(inode); - inode = NULL; - } - d_add(dentry, inode); - dentry->d_op = &externfs_dentry_ops; - return(NULL); - - out_put: - inode->i_nlink = 0; - iput(inode); - out: - return(ERR_PTR(err)); -} - -static char *inode_dentry_name(struct inode *ino, struct dentry *dentry) -{ - char *file; - int len; - - file = inode_name(ino, dentry->d_name.len + 1); - if(file == NULL) return(NULL); - strcat(file, "/"); - len = strlen(file); - strncat(file, dentry->d_name.name, dentry->d_name.len); - file[len + dentry->d_name.len] = '\0'; - return(file); -} - -int externfs_link(struct dentry *to, struct inode *ino, struct dentry *from) -{ - struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; - struct externfs_data *ed = ino->i_sb->s_fs_info; - char *from_name, *to_name; - int err = -ENOMEM; - - from_name = inode_dentry_name(ino, from); - if(from_name == NULL) - goto out; - - to_name = dentry_name(to, 0); - if(to_name == NULL) - goto out_free_from; - - err = (*ops->link_file)(to_name, from_name, current->fsuid, - current->fsgid, ed); - if(err) - goto out_free_to; - - d_instantiate(from, to->d_inode); - to->d_inode->i_nlink++; - atomic_inc(&to->d_inode->i_count); - - out_free_to: - kfree(to_name); - out_free_from: - kfree(from_name); - out: - return(err); -} - -int externfs_unlink(struct inode *ino, struct dentry *dentry) -{ - struct inode *inode; - struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; - struct externfs_data *ed = ino->i_sb->s_fs_info; - char *file; - int err; - - file = inode_dentry_name(ino, dentry); - if(file == NULL) - return(-ENOMEM); - - inode = dentry->d_inode; - if((inode->i_nlink == 1) && (ops->invisible != NULL)) - (*ops->invisible)(EXTERNFS_I(inode)); - - err = (*ops->unlink_file)(file, ed); - kfree(file); - - inode->i_nlink--; - - return(err); -} - -int externfs_symlink(struct inode *ino, struct dentry *dentry, const char *to) -{ - struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; - struct inode *inode; - struct externfs_data *ed = ino->i_sb->s_fs_info; - char *file; - int err; - - file = inode_dentry_name(ino, dentry); - if(file == NULL) - return(-ENOMEM); - err = (*ops->make_symlink)(file, to, current->fsuid, current->fsgid, - ed); - kfree(file); - if(err) - goto out; - - err = -ENOMEM; - inode = iget(ino->i_sb, 0); - if(inode == NULL) - goto out; - - err = init_inode(inode, dentry); - if(err) - goto out_put; - - d_instantiate(dentry, inode); - inode->i_nlink++; - out: - return(err); - - out_put: - iput(inode); - goto out; -} - -int externfs_make_dir(struct inode *ino, struct dentry *dentry, int mode) -{ - struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; - struct inode *inode; - struct externfs_data *ed = ino->i_sb->s_fs_info; - char *file; - int err = -ENOMEM; - - file = inode_dentry_name(ino, dentry); - if(file == NULL) - goto out; - err = (*ops->make_dir)(file, mode, current->fsuid, current->fsgid, ed); - - err = -ENOMEM; - inode = iget(ino->i_sb, 0); - if(inode == NULL) - goto out_free; - - err = init_inode(inode, dentry); - if(err) - goto out_put; - - err = read_name(inode, file); - if(err) - goto out_put; - - kfree(file); - d_instantiate(dentry, inode); - inode->i_nlink = 2; - inode->i_mode = S_IFDIR | mode; - - ino->i_nlink++; - out: - return(err); - out_put: - inode->i_nlink = 0; - iput(inode); - out_free: - kfree(file); - goto out; -} - -int externfs_remove_dir(struct inode *ino, struct dentry *dentry) -{ - struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; - struct externfs_data *ed = ino->i_sb->s_fs_info; - char *file; - int err; - - file = inode_dentry_name(ino, dentry); - if(file == NULL) - return(-ENOMEM); - err = (*ops->remove_dir)(file, current->fsuid, current->fsgid, ed); - kfree(file); - - dentry->d_inode->i_nlink = 0; - ino->i_nlink--; - return(err); -} - -int externfs_make_node(struct inode *dir, struct dentry *dentry, int mode, - dev_t dev) -{ - struct externfs_file_ops *ops = EXTERNFS_I(dir)->ops; - struct externfs_data *ed = dir->i_sb->s_fs_info; - struct inode *inode; - char *name; - int err = -ENOMEM; - - inode = iget(dir->i_sb, 0); - if(inode == NULL) - goto out; - - err = init_inode(inode, dentry); - if(err) - goto out_put; - - err = -ENOMEM; - name = dentry_name(dentry, 0); - if(name == NULL) - goto out_put; - - init_special_inode(inode, mode, dev); - err = (*ops->make_node)(name, mode & S_IRWXUGO, current->fsuid, - current->fsgid, mode & S_IFMT, MAJOR(dev), - MINOR(dev), ed); - if(err) - goto out_free; - - err = read_name(inode, name); - if(err) - goto out_rm; - - inode->i_nlink++; - d_instantiate(dentry, inode); - kfree(name); - out: - return(err); - - out_rm: - (*ops->unlink_file)(name, ed); - out_free: - kfree(name); - out_put: - inode->i_nlink = 0; - iput(inode); - goto out; -} - -int externfs_rename(struct inode *from_ino, struct dentry *from, - struct inode *to_ino, struct dentry *to) -{ - struct externfs_file_ops *ops = EXTERNFS_I(from_ino)->ops; - struct externfs_data *ed = from_ino->i_sb->s_fs_info; - char *from_name, *to_name; - int err; - - from_name = inode_dentry_name(from_ino, from); - if(from_name == NULL) - return(-ENOMEM); - to_name = inode_dentry_name(to_ino, to); - if(to_name == NULL){ - kfree(from_name); - return(-ENOMEM); - } - err = (*ops->rename_file)(from_name, to_name, ed); - kfree(from_name); - kfree(to_name); - - from_ino->i_nlink--; - to_ino->i_nlink++; - return(err); -} - -void externfs_truncate(struct inode *ino) -{ - struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; - struct externfs_data *ed = ino->i_sb->s_fs_info; - - (*ops->truncate_file)(EXTERNFS_I(ino), ino->i_size, ed); -} - -int externfs_permission(struct inode *ino, int desired, struct nameidata *nd) -{ - struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; - struct externfs_data *ed = ino->i_sb->s_fs_info; - char *name; - int r = 0, w = 0, x = 0, err; - - if(ops->access_file == NULL) - return(vfs_permission(ino, desired)); - - if(desired & MAY_READ) r = 1; - if(desired & MAY_WRITE) w = 1; - if(desired & MAY_EXEC) x = 1; - name = inode_name(ino, 0); - if(name == NULL) - return(-ENOMEM); - - err = (*ops->access_file)(name, r, w, x, current->fsuid, - current->fsgid, ed); - kfree(name); - - if(!err) - err = vfs_permission(ino, desired); - return(err); -} - -int externfs_setattr(struct dentry *dentry, struct iattr *attr) -{ - struct externfs_file_ops *ops = EXTERNFS_I(dentry->d_inode)->ops; - struct externfs_data *ed = dentry->d_inode->i_sb->s_fs_info; - struct externfs_iattr attrs; - char *name; - int err; - - attrs.ia_valid = 0; - if(attr->ia_valid & ATTR_MODE){ - attrs.ia_valid |= EXTERNFS_ATTR_MODE; - attrs.ia_mode = attr->ia_mode; - } - if(attr->ia_valid & ATTR_UID){ - attrs.ia_valid |= EXTERNFS_ATTR_UID; - attrs.ia_uid = attr->ia_uid; - } - if(attr->ia_valid & ATTR_GID){ - attrs.ia_valid |= EXTERNFS_ATTR_GID; - attrs.ia_gid = attr->ia_gid; - } - if(attr->ia_valid & ATTR_SIZE){ - attrs.ia_valid |= EXTERNFS_ATTR_SIZE; - attrs.ia_size = attr->ia_size; - } - if(attr->ia_valid & ATTR_ATIME){ - attrs.ia_valid |= EXTERNFS_ATTR_ATIME; - attrs.ia_atime = attr->ia_atime.tv_sec; - } - if(attr->ia_valid & ATTR_MTIME){ - attrs.ia_valid |= EXTERNFS_ATTR_MTIME; - attrs.ia_mtime = attr->ia_mtime.tv_sec; - } - if(attr->ia_valid & ATTR_CTIME){ - attrs.ia_valid |= EXTERNFS_ATTR_CTIME; - attrs.ia_ctime = attr->ia_ctime.tv_sec; - } - if(attr->ia_valid & ATTR_ATIME_SET){ - attrs.ia_valid |= EXTERNFS_ATTR_ATIME_SET; - attrs.ia_atime = attr->ia_atime.tv_sec; - } - if(attr->ia_valid & ATTR_MTIME_SET){ - attrs.ia_valid |= EXTERNFS_ATTR_MTIME_SET; - } - name = dentry_name(dentry, 0); - if(name == NULL) - return(-ENOMEM); - err = (*ops->set_attr)(name, &attrs, ed); - kfree(name); - if(err) - return(err); - - return(inode_setattr(dentry->d_inode, attr)); -} - -int externfs_getattr(struct vfsmount *mnt, struct dentry *dentry, - struct kstat *stat) -{ - generic_fillattr(dentry->d_inode, stat); - return(0); -} - -static struct inode_operations externfs_iops = { - .create = externfs_create, - .link = externfs_link, - .unlink = externfs_unlink, - .symlink = externfs_symlink, - .mkdir = externfs_make_dir, - .rmdir = externfs_remove_dir, - .mknod = externfs_make_node, - .rename = externfs_rename, - .truncate = externfs_truncate, - .permission = externfs_permission, - .setattr = externfs_setattr, - .getattr = externfs_getattr, -}; - -static struct inode_operations externfs_dir_iops = { - .create = externfs_create, - .lookup = externfs_lookup, - .link = externfs_link, - .unlink = externfs_unlink, - .symlink = externfs_symlink, - .mkdir = externfs_make_dir, - .rmdir = externfs_remove_dir, - .mknod = externfs_make_node, - .rename = externfs_rename, - .truncate = externfs_truncate, - .permission = externfs_permission, - .setattr = externfs_setattr, - .getattr = externfs_getattr, -}; - -int externfs_link_readpage(struct file *file, struct page *page) -{ - struct inode *ino = page->mapping->host; - struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; - struct externfs_data *ed = ino->i_sb->s_fs_info; - char *buffer, *name; - long long start; - int err; - - start = page->index << PAGE_CACHE_SHIFT; - buffer = kmap(page); - name = inode_name(ino, 0); - if(name == NULL) - return(-ENOMEM); - - err = (*ops->read_link)(name, current->fsuid, current->fsgid, buffer, - PAGE_CACHE_SIZE, ed); - - kfree(name); - if(err == PAGE_CACHE_SIZE) - err = -E2BIG; - else if(err > 0){ - flush_dcache_page(page); - SetPageUptodate(page); - if (PageError(page)) ClearPageError(page); - err = 0; - } - kunmap(page); - unlock_page(page); - return(err); -} - -static int externfs_flushpage(struct page *page, unsigned long offset) -{ - return(externfs_writepage(page, NULL)); -} - -struct externfs_data *inode_externfs_info(struct inode *inode) -{ - return(inode->i_sb->s_fs_info); -} - -static struct address_space_operations externfs_link_aops = { - .readpage = externfs_link_readpage, - .releasepage = externfs_removepage, - .invalidatepage = externfs_flushpage, -}; - -DECLARE_MUTEX(externfs_sem); -struct list_head externfses = LIST_HEAD_INIT(externfses); - -static struct externfs *find_externfs(struct file_system_type *type) -{ - struct list_head *ele; - struct externfs *fs; - - down(&externfs_sem); - list_for_each(ele, &externfses){ - fs = list_entry(ele, struct externfs, list); - if(&fs->type == type) - goto out; - } - fs = NULL; - out: - up(&externfs_sem); - return(fs); -} - -#define DEFAULT_ROOT "/" - -char *host_root_filename(char *mount_arg) -{ - char *root = DEFAULT_ROOT; - - if((mount_arg != NULL) && (*mount_arg != '\0')) - root = mount_arg; - - return(uml_strdup(root)); -} - -static int externfs_fill_sb(struct super_block *sb, void *data, int silent) -{ - struct externfs *fs; - struct inode *root_inode; - struct externfs_data *sb_data; - int err = -EINVAL; - - sb->s_blocksize = 1024; - sb->s_blocksize_bits = 10; - sb->s_magic = EXTERNFS_SUPER_MAGIC; - sb->s_op = &externfs_sbops; - - fs = find_externfs(sb->s_type); - if(fs == NULL){ - printk("Couldn't find externfs for filesystem '%s'\n", - sb->s_type->name); - goto out; - } - - sb_data = (*fs->mount_ops->mount)(data); - if(IS_ERR(sb_data)){ - err = PTR_ERR(sb_data); - goto out; - } - - sb->s_fs_info = sb_data; - sb_data->mount_ops = fs->mount_ops; - - root_inode = iget(sb, 0); - if(root_inode == NULL) - goto out; - - err = init_inode(root_inode, NULL); - if(err) - goto out_put; - - err = -ENOMEM; - sb->s_root = d_alloc_root(root_inode); - if(sb->s_root == NULL) - goto out_put; - - err = read_inode(root_inode); - if(err) - goto out_put; - - out: - return(err); - - out_put: - iput(root_inode); - goto out; -} - -struct super_block *externfs_read_super(struct file_system_type *type, - int flags, const char *dev_name, - void *data) -{ - return(get_sb_nodev(type, flags, data, externfs_fill_sb)); -} - -void init_externfs(struct externfs_data *ed, struct externfs_file_ops *ops) -{ - ed->file_ops = ops; -} - -int register_externfs(char *name, struct externfs_mount_ops *mount_ops) -{ - struct externfs *new; - int err = -ENOMEM; - - new = kmalloc(sizeof(*new), GFP_KERNEL); - if(new == NULL) - goto out; - - memset(new, 0, sizeof(*new)); - *new = ((struct externfs) { .list = LIST_HEAD_INIT(new->list), - .mount_ops = mount_ops, - .type = { .name = name, - .get_sb = externfs_read_super, - .kill_sb = kill_anon_super, - .fs_flags = 0, - .owner = THIS_MODULE } }); - list_add(&new->list, &externfses); - - err = register_filesystem(&new->type); - if(err) - goto out_del; - return(0); - - out_del: - list_del(&new->list); - kfree(new); - out: - return(err); -} - -void unregister_externfs(char *name) -{ - struct list_head *ele; - struct externfs *fs; - - down(&externfs_sem); - list_for_each(ele, &externfses){ - fs = list_entry(ele, struct externfs, list); - if(!strcmp(fs->type.name, name)){ - list_del(ele); - up(&externfs_sem); - return; - } - } - up(&externfs_sem); - printk("Unregister_externfs - filesystem '%s' not found\n", name); -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/fs/hostfs/host_file.c b/fs/hostfs/host_file.c deleted file mode 100644 index e8eb90165..000000000 --- a/fs/hostfs/host_file.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include "linux/stddef.h" -#include "linux/string.h" -#include "linux/errno.h" -#include "linux/types.h" -#include "linux/slab.h" -#include "linux/fs.h" -#include "asm/fcntl.h" -#include "hostfs.h" -#include "filehandle.h" - -extern int append; - -char *get_path(const char *path[], char *buf, int size) -{ - const char **s; - char *p; - int new = 1; - - for(s = path; *s != NULL; s++){ - new += strlen(*s); - if((*(s + 1) != NULL) && (strlen(*s) > 0) && - ((*s)[strlen(*s) - 1] != '/')) - new++; - } - - if(new > size){ - buf = kmalloc(new, GFP_KERNEL); - if(buf == NULL) - return(NULL); - } - - p = buf; - for(s = path; *s != NULL; s++){ - strcpy(p, *s); - p += strlen(*s); - if((*(s + 1) != NULL) && (strlen(*s) > 0) && - ((*s)[strlen(*s) - 1] != '/')) - strcpy(p++, "/"); - } - - return(buf); -} - -void free_path(const char *buf, char *tmp) -{ - if((buf != tmp) && (buf != NULL)) - kfree((char *) buf); -} - -int host_open_file(const char *path[], int r, int w, struct file_handle *fh) -{ - char tmp[HOSTFS_BUFSIZE], *file; - int mode = 0, err; - struct openflags flags = OPENFLAGS(); - - if (r) - flags = of_read(flags); - if (w) - flags = of_write(flags); - if(append) - flags = of_append(flags); - - err = -ENOMEM; - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = open_filehandle(file, flags, mode, fh); - out: - free_path(file, tmp); - return(err); -} - -void *host_open_dir(const char *path[]) -{ - char tmp[HOSTFS_BUFSIZE], *file; - void *dir = ERR_PTR(-ENOMEM); - - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - dir = open_dir(file); - out: - free_path(file, tmp); - return(dir); -} - -char *host_read_dir(void *stream, unsigned long long *pos, - unsigned long long *ino_out, int *len_out) -{ - int err; - char *name; - - err = os_seek_dir(stream, *pos); - if(err) - return(ERR_PTR(err)); - - err = os_read_dir(stream, ino_out, &name); - if(err) - return(ERR_PTR(err)); - - if(name == NULL) - return(NULL); - - *len_out = strlen(name); - *pos = os_tell_dir(stream); - return(name); -} - -int host_file_type(const char *path[], int *rdev) -{ - char tmp[HOSTFS_BUFSIZE], *file; - struct uml_stat buf; - int ret; - - ret = -ENOMEM; - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - if(rdev != NULL){ - ret = os_lstat_file(file, &buf); - if(ret) - goto out; - *rdev = MKDEV(buf.ust_rmajor, buf.ust_rminor); - } - - ret = os_file_type(file); - out: - free_path(file, tmp); - return(ret); -} - -int host_create_file(const char *path[], int mode, struct file_handle *fh) -{ - char tmp[HOSTFS_BUFSIZE], *file; - int err = -ENOMEM; - - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = open_filehandle(file, of_create(of_rdwr(OPENFLAGS())), mode, fh); - out: - free_path(file, tmp); - return(err); -} - -static int do_stat_file(const char *path, int *dev_out, - unsigned long long *inode_out, int *mode_out, - int *nlink_out, int *uid_out, int *gid_out, - unsigned long long *size_out, unsigned long *atime_out, - unsigned long *mtime_out, unsigned long *ctime_out, - int *blksize_out, unsigned long long *blocks_out) -{ - struct uml_stat buf; - int err; - - err = os_lstat_file(path, &buf); - if(err < 0) - return(err); - - if(dev_out != NULL) *dev_out = MKDEV(buf.ust_major, buf.ust_minor); - if(inode_out != NULL) *inode_out = buf.ust_ino; - if(mode_out != NULL) *mode_out = buf.ust_mode; - if(nlink_out != NULL) *nlink_out = buf.ust_nlink; - if(uid_out != NULL) *uid_out = buf.ust_uid; - if(gid_out != NULL) *gid_out = buf.ust_gid; - if(size_out != NULL) *size_out = buf.ust_size; - if(atime_out != NULL) *atime_out = buf.ust_atime; - if(mtime_out != NULL) *mtime_out = buf.ust_mtime; - if(ctime_out != NULL) *ctime_out = buf.ust_ctime; - if(blksize_out != NULL) *blksize_out = buf.ust_blksize; - if(blocks_out != NULL) *blocks_out = buf.ust_blocks; - - return(0); -} - -int host_stat_file(const char *path[], int *dev_out, - unsigned long long *inode_out, int *mode_out, - int *nlink_out, int *uid_out, int *gid_out, - unsigned long long *size_out, unsigned long *atime_out, - unsigned long *mtime_out, unsigned long *ctime_out, - int *blksize_out, unsigned long long *blocks_out) -{ - char tmp[HOSTFS_BUFSIZE], *file; - int err; - - err = -ENOMEM; - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = do_stat_file(file, dev_out, inode_out, mode_out, nlink_out, - uid_out, gid_out, size_out, atime_out, mtime_out, - ctime_out, blksize_out, blocks_out); - out: - free_path(file, tmp); - return(err); -} - -int host_set_attr(const char *path[], struct externfs_iattr *attrs) -{ - char tmp[HOSTFS_BUFSIZE], *file; - unsigned long time; - int err = 0, ma; - - if(append && (attrs->ia_valid & EXTERNFS_ATTR_SIZE)) - return(-EPERM); - - err = -ENOMEM; - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - if(attrs->ia_valid & EXTERNFS_ATTR_MODE){ - err = os_set_file_perms(file, attrs->ia_mode); - if(err < 0) - goto out; - } - if(attrs->ia_valid & EXTERNFS_ATTR_UID){ - err = os_set_file_owner(file, attrs->ia_uid, -1); - if(err < 0) - goto out; - } - if(attrs->ia_valid & EXTERNFS_ATTR_GID){ - err = os_set_file_owner(file, -1, attrs->ia_gid); - if(err < 0) - goto out; - } - if(attrs->ia_valid & EXTERNFS_ATTR_SIZE){ - err = os_truncate_file(file, attrs->ia_size); - if(err < 0) - goto out; - } - ma = EXTERNFS_ATTR_ATIME_SET | EXTERNFS_ATTR_MTIME_SET; - if((attrs->ia_valid & ma) == ma){ - err = os_set_file_time(file, attrs->ia_atime, attrs->ia_mtime); - if(err) - goto out; - } - else { - if(attrs->ia_valid & EXTERNFS_ATTR_ATIME_SET){ - err = do_stat_file(file, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, &time, - NULL, NULL, NULL); - if(err != 0) - goto out; - - err = os_set_file_time(file, attrs->ia_atime, time); - if(err) - goto out; - } - if(attrs->ia_valid & EXTERNFS_ATTR_MTIME_SET){ - err = do_stat_file(file, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, &time, NULL, - NULL, NULL, NULL); - if(err != 0) - goto out; - - err = os_set_file_time(file, time, attrs->ia_mtime); - if(err) - goto out; - } - } - if(attrs->ia_valid & EXTERNFS_ATTR_CTIME) ; - if(attrs->ia_valid & (EXTERNFS_ATTR_ATIME | EXTERNFS_ATTR_MTIME)){ - err = do_stat_file(file, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, &attrs->ia_atime, - &attrs->ia_mtime, NULL, NULL, NULL); - if(err != 0) - goto out; - } - - err = 0; - out: - free_path(file, tmp); - return(err); -} - -int host_make_symlink(const char *from[], const char *to) -{ - char tmp[HOSTFS_BUFSIZE], *file; - int err = -ENOMEM; - - file = get_path(from, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = os_make_symlink(to, file); - out: - free_path(file, tmp); - return(err); -} - -int host_unlink_file(const char *path[]) -{ - char tmp[HOSTFS_BUFSIZE], *file; - int err = -ENOMEM; - - if(append) - return(-EPERM); - - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = os_remove_file(file); - out: - free_path(file, tmp); - return(err); -} - -int host_make_dir(const char *path[], int mode) -{ - char tmp[HOSTFS_BUFSIZE], *file; - int err = -ENOMEM; - - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = os_make_dir(file, mode); - out: - free_path(file, tmp); - return(err); -} - -int host_remove_dir(const char *path[]) -{ - char tmp[HOSTFS_BUFSIZE], *file; - int err = -ENOMEM; - - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = os_remove_dir(file); - out: - free_path(file, tmp); - return(err); -} - -int host_link_file(const char *to[], const char *from[]) -{ - char from_tmp[HOSTFS_BUFSIZE], *f, to_tmp[HOSTFS_BUFSIZE], *t; - int err = -ENOMEM; - - f = get_path(from, from_tmp, sizeof(from_tmp)); - t = get_path(to, to_tmp, sizeof(to_tmp)); - if((f == NULL) || (t == NULL)) - goto out; - - err = os_link_file(t, f); - out: - free_path(f, from_tmp); - free_path(t, to_tmp); - return(err); -} - -int host_read_link(const char *path[], char *buf, int size) -{ - char tmp[HOSTFS_BUFSIZE], *file; - int n = -ENOMEM; - - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - n = os_read_symlink(file, buf, size); - if(n < size) - buf[n] = '\0'; - out: - free_path(file, tmp); - return(n); -} - -int host_rename_file(const char *from[], const char *to[]) -{ - char from_tmp[HOSTFS_BUFSIZE], *f, to_tmp[HOSTFS_BUFSIZE], *t; - int err = -ENOMEM; - - f = get_path(from, from_tmp, sizeof(from_tmp)); - t = get_path(to, to_tmp, sizeof(to_tmp)); - if((f == NULL) || (t == NULL)) - goto out; - - err = os_move_file(f, t); - out: - free_path(f, from_tmp); - free_path(t, to_tmp); - return(err); -} - -int host_stat_fs(const char *path[], long *bsize_out, long long *blocks_out, - long long *bfree_out, long long *bavail_out, - long long *files_out, long long *ffree_out, void *fsid_out, - int fsid_size, long *namelen_out, long *spare_out) -{ - char tmp[HOSTFS_BUFSIZE], *file; - int err = -ENOMEM; - - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = os_stat_filesystem(file, bsize_out, blocks_out, bfree_out, - bavail_out, files_out, ffree_out, fsid_out, - fsid_size, namelen_out, spare_out); - out: - free_path(file, tmp); - return(err); -} - -char *generic_host_read_dir(void *stream, unsigned long long *pos, - unsigned long long *ino_out, int *len_out, - void *mount) -{ - return(host_read_dir(stream, pos, ino_out, len_out)); -} - -int generic_host_truncate_file(struct file_handle *fh, __u64 size, void *m) -{ - return(truncate_file(fh, size)); -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/fs/hostfs/host_fs.c b/fs/hostfs/host_fs.c deleted file mode 100644 index c059539c5..000000000 --- a/fs/hostfs/host_fs.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include "linux/stddef.h" -#include "linux/string.h" -#include "linux/types.h" -#include "linux/errno.h" -#include "linux/slab.h" -#include "linux/init.h" -#include "linux/fs.h" -#include "linux/stat.h" -#include "hostfs.h" -#include "kern.h" -#include "init.h" -#include "kern_util.h" -#include "filehandle.h" -#include "os.h" - -/* Changed in hostfs_args before the kernel starts running */ -static char *jail_dir = "/"; -int append = 0; - -static int __init hostfs_args(char *options, int *add) -{ - char *ptr; - - ptr = strchr(options, ','); - if(ptr != NULL) - *ptr++ = '\0'; - if(*options != '\0') - jail_dir = options; - - options = ptr; - while(options){ - ptr = strchr(options, ','); - if(ptr != NULL) - *ptr++ = '\0'; - if(*options != '\0'){ - if(!strcmp(options, "append")) - append = 1; - else printf("hostfs_args - unsupported option - %s\n", - options); - } - options = ptr; - } - return(0); -} - -__uml_setup("hostfs=", hostfs_args, -"hostfs=,,...\n" -" This is used to set hostfs parameters. The root directory argument\n" -" is used to confine all hostfs mounts to within the specified directory\n" -" tree on the host. If this isn't specified, then a user inside UML can\n" -" mount anything on the host that's accessible to the user that's running\n" -" it.\n" -" The only flag currently supported is 'append', which specifies that all\n" -" files opened by hostfs will be opened in append mode.\n\n" -); - -struct hostfs_data { - struct externfs_data ext; - char *mount; -}; - -struct hostfs_file { - struct externfs_inode ext; - struct file_handle fh; -}; - -static int hostfs_access_file(char *file, int uid, int w, int x, int gid, - int r, struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - char tmp[HOSTFS_BUFSIZE]; - int err, mode = 0; - - if(r) mode = OS_ACC_R_OK; - if(w) mode |= OS_ACC_W_OK; - if(x) mode |= OS_ACC_X_OK; - - err = -ENOMEM; - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = os_access(file, mode); - free_path(file, tmp); - out: - return(err); -} - -static int hostfs_make_node(const char *file, int mode, int uid, int gid, - int type, int major, int minor, - struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - char tmp[HOSTFS_BUFSIZE]; - int err = -ENOMEM; - - file = get_path(path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - /* XXX Pass type in an OS-independent way */ - mode |= type; - - err = os_make_dev(file, mode, major, minor); - free_path(file, tmp); - out: - return(err); -} - -static int hostfs_stat_file(const char *file, struct externfs_data *ed, - dev_t *dev_out, unsigned long long *inode_out, - int *mode_out, int *nlink_out, int *uid_out, - int *gid_out, unsigned long long *size_out, - unsigned long *atime_out, unsigned long *mtime_out, - unsigned long *ctime_out, int *blksize_out, - unsigned long long *blocks_out) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - - /* XXX Why pretend everything is owned by root? */ - *uid_out = 0; - *gid_out = 0; - return(host_stat_file(path, dev_out, inode_out, mode_out, nlink_out, - NULL, NULL, size_out, atime_out, mtime_out, - ctime_out, blksize_out, blocks_out)); -} - -static int hostfs_file_type(const char *file, int *rdev, - struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - - return(host_file_type(path, rdev)); -} - -static char *hostfs_name(struct inode *inode) -{ - struct externfs_data *ed = inode_externfs_info(inode); - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - - return(inode_name_prefix(inode, mount)); -} - -static struct externfs_inode *hostfs_init_file(struct externfs_data *ed) -{ - struct hostfs_file *hf; - - hf = kmalloc(sizeof(*hf), GFP_KERNEL); - if(hf == NULL) - return(NULL); - - hf->fh.fd = -1; - return(&hf->ext); -} - -static int hostfs_open_file(struct externfs_inode *ext, char *file, - int uid, int gid, struct inode *inode, - struct externfs_data *ed) -{ - struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext); - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - int err; - - err = host_open_file(path, 1, 1, &hf->fh); - if(err == -EISDIR) - goto out; - - if(err == -EACCES) - err = host_open_file(path, 1, 0, &hf->fh); - - if(err) - goto out; - - is_reclaimable(&hf->fh, hostfs_name, inode); - out: - return(err); -} - -static void *hostfs_open_dir(char *file, int uid, int gid, - struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - - return(host_open_dir(path)); -} - -static void hostfs_close_dir(void *stream, struct externfs_data *ed) -{ - os_close_dir(stream); -} - -static char *hostfs_read_dir(void *stream, unsigned long long *pos, - unsigned long long *ino_out, int *len_out, - struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - - return(generic_host_read_dir(stream, pos, ino_out, len_out, mount)); -} - -static int hostfs_read_file(struct externfs_inode *ext, - unsigned long long offset, char *buf, int len, - int ignore_start, int ignore_end, - void (*completion)(char *, int, void *), void *arg, - struct externfs_data *ed) -{ - struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext); - int err = 0; - - if(ignore_start != 0){ - err = read_file(&hf->fh, offset, buf, ignore_start); - if(err < 0) - goto out; - } - - if(ignore_end != len) - err = read_file(&hf->fh, offset + ignore_end, buf + ignore_end, - len - ignore_end); - - out: - - (*completion)(buf, err, arg); - if (err > 0) - err = 0; - return(err); -} - -static int hostfs_write_file(struct externfs_inode *ext, - unsigned long long offset, const char *buf, - int start, int len, - void (*completion)(char *, int, void *), - void *arg, struct externfs_data *ed) -{ - struct file_handle *fh; - int err; - - fh = &container_of(ext, struct hostfs_file, ext)->fh; - err = write_file(fh, offset + start, buf + start, len); - - (*completion)((char *) buf, err, arg); - if (err > 0) - err = 0; - - return(err); -} - -static int hostfs_create_file(struct externfs_inode *ext, char *file, int mode, - int uid, int gid, struct inode *inode, - struct externfs_data *ed) -{ - struct hostfs_file *hf = container_of(ext, struct hostfs_file, - ext); - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - int err = -ENOMEM; - - err = host_create_file(path, mode, &hf->fh); - if(err) - goto out; - - is_reclaimable(&hf->fh, hostfs_name, inode); - out: - return(err); -} - -static int hostfs_set_attr(const char *file, struct externfs_iattr *attrs, - struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - - return(host_set_attr(path, attrs)); -} - -static int hostfs_make_symlink(const char *from, const char *to, int uid, - int gid, struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, from, NULL }; - - return(host_make_symlink(path, to)); -} - -static int hostfs_link_file(const char *to, const char *from, int uid, int gid, - struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *to_path[] = { jail_dir, mount, to, NULL }; - const char *from_path[] = { jail_dir, mount, from, NULL }; - - return(host_link_file(to_path, from_path)); -} - -static int hostfs_unlink_file(const char *file, struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - - return(host_unlink_file(path)); -} - -static int hostfs_make_dir(const char *file, int mode, int uid, int gid, - struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - - return(host_make_dir(path, mode)); -} - -static int hostfs_remove_dir(const char *file, int uid, int gid, - struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - - return(host_remove_dir(path)); -} - -static int hostfs_read_link(char *file, int uid, int gid, char *buf, int size, - struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, file, NULL }; - - return(host_read_link(path, buf, size)); -} - -static int hostfs_rename_file(char *from, char *to, struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *to_path[] = { jail_dir, mount, to, NULL }; - const char *from_path[] = { jail_dir, mount, from, NULL }; - - return(host_rename_file(from_path, to_path)); -} - -static int hostfs_stat_fs(long *bsize_out, long long *blocks_out, - long long *bfree_out, long long *bavail_out, - long long *files_out, long long *ffree_out, - void *fsid_out, int fsid_size, long *namelen_out, - long *spare_out, struct externfs_data *ed) -{ - char *mount = container_of(ed, struct hostfs_data, ext)->mount; - const char *path[] = { jail_dir, mount, NULL }; - - return(host_stat_fs(path, bsize_out, blocks_out, bfree_out, bavail_out, - files_out, ffree_out, fsid_out, fsid_size, - namelen_out, spare_out)); -} - -void hostfs_close_file(struct externfs_inode *ext, - unsigned long long size) -{ - struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext); - - if(hf->fh.fd != -1){ - truncate_file(&hf->fh, size); - close_file(&hf->fh); - } - - kfree(hf); -} - -int hostfs_truncate_file(struct externfs_inode *ext, __u64 size, - struct externfs_data *ed) -{ - struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext); - - return(truncate_file(&hf->fh, size)); -} - -static struct externfs_file_ops hostfs_file_ops = { - .stat_file = hostfs_stat_file, - .file_type = hostfs_file_type, - .access_file = hostfs_access_file, - .open_file = hostfs_open_file, - .open_dir = hostfs_open_dir, - .read_dir = hostfs_read_dir, - .read_file = hostfs_read_file, - .write_file = hostfs_write_file, - .map_file_page = NULL, - .close_file = hostfs_close_file, - .close_dir = hostfs_close_dir, - .invisible = NULL, - .create_file = hostfs_create_file, - .set_attr = hostfs_set_attr, - .make_symlink = hostfs_make_symlink, - .unlink_file = hostfs_unlink_file, - .make_dir = hostfs_make_dir, - .remove_dir = hostfs_remove_dir, - .make_node = hostfs_make_node, - .link_file = hostfs_link_file, - .read_link = hostfs_read_link, - .rename_file = hostfs_rename_file, - .statfs = hostfs_stat_fs, - .truncate_file = hostfs_truncate_file -}; - -static struct externfs_data *mount_fs(char *mount_arg) -{ - struct hostfs_data *hd; - int err = -ENOMEM; - - hd = kmalloc(sizeof(*hd), GFP_KERNEL); - if(hd == NULL) - goto out; - - hd->mount = host_root_filename(mount_arg); - if(hd->mount == NULL) - goto out_free; - - init_externfs(&hd->ext, &hostfs_file_ops); - - return(&hd->ext); - - out_free: - kfree(hd); - out: - return(ERR_PTR(err)); -} - -static struct externfs_mount_ops hostfs_mount_ops = { - .init_file = hostfs_init_file, - .mount = mount_fs, -}; - -static int __init init_hostfs(void) -{ - return(register_externfs("hostfs", &hostfs_mount_ops)); -} - -static void __exit exit_hostfs(void) -{ - unregister_externfs("hostfs"); -} - -__initcall(init_hostfs); -__exitcall(exit_hostfs); - -#if 0 -module_init(init_hostfs) -module_exit(exit_hostfs) -MODULE_LICENSE("GPL"); -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/fs/hostfs/humfs.c b/fs/hostfs/humfs.c deleted file mode 100644 index 7878be5a3..000000000 --- a/fs/hostfs/humfs.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "linux/init.h" -#include "linux/workqueue.h" -#include -#include "hostfs.h" -#include "mem.h" -#include "os.h" -#include "mode.h" -#include "aio.h" -#include "irq_user.h" -#include "irq_kern.h" -#include "filehandle.h" -#include "metadata.h" - -#define HUMFS_VERSION 2 - -static int humfs_stat_file(const char *path, struct externfs_data *ed, - dev_t *dev_out, unsigned long long *inode_out, - int *mode_out, int *nlink_out, int *uid_out, - int *gid_out, unsigned long long *size_out, - unsigned long *atime_out, unsigned long *mtime_out, - unsigned long *ctime_out, int *blksize_out, - unsigned long long *blocks_out) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - const char *data_path[3] = { mount->data, path, NULL }; - int err, mode, perms, major, minor; - char type; - - err = host_stat_file(data_path, NULL, inode_out, mode_out, - nlink_out, NULL, NULL, size_out, atime_out, - mtime_out, ctime_out, blksize_out, blocks_out); - if(err) - return(err); - - err = (*mount->meta->ownerships)(path, &perms, uid_out, gid_out, - &type, &major, &minor, mount); - if(err) - return(err); - - *mode_out = (*mode_out & ~S_IRWXUGO) | perms; - - mode = 0; - switch(type){ - case 'c': - mode = S_IFCHR; - *dev_out = MKDEV(major, minor); - break; - case 'b': - mode = S_IFBLK; - *dev_out = MKDEV(major, minor); - break; - case 's': - mode = S_IFSOCK; - break; - default: - break; - } - - if(mode != 0) - *mode_out = (*mode_out & ~S_IFMT) | mode; - - return(0); -} - -static int meta_type(const char *path, int *dev_out, void *m) -{ - struct humfs *mount = m; - int err, type, maj, min; - char c; - - err = (*mount->meta->ownerships)(path, NULL, NULL, NULL, &c, &maj, - &min, mount); - if(err) - return(err); - - if(c == 0) - return(0); - - if(dev_out) - *dev_out = MKDEV(maj, min); - - switch(c){ - case 'c': - type = OS_TYPE_CHARDEV; - break; - case 'b': - type = OS_TYPE_BLOCKDEV; - break; - case 'p': - type = OS_TYPE_FIFO; - break; - case 's': - type = OS_TYPE_SOCK; - break; - default: - type = -EINVAL; - break; - } - - return(type); -} - -static int humfs_file_type(const char *path, int *dev_out, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - const char *data_path[3] = { mount->data, path, NULL }; - int type; - - type = meta_type(path, dev_out, mount); - if(type != 0) - return(type); - - return(host_file_type(data_path, dev_out)); -} - -static char *humfs_data_name(struct inode *inode) -{ - struct externfs_data *ed = inode_externfs_info(inode); - struct humfs *mount = container_of(ed, struct humfs, ext); - - return(inode_name_prefix(inode, mount->data)); -} - -static struct externfs_inode *humfs_init_file(struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - struct humfs_file *hf; - - hf = (*mount->meta->init_file)(); - if(hf == NULL) - return(NULL); - - hf->data.fd = -1; - return(&hf->ext); -} - -static int humfs_open_file(struct externfs_inode *ext, char *path, int uid, - int gid, struct inode *inode, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - struct humfs_file *hf = container_of(ext, struct humfs_file, ext); - const char *data_path[3] = { mount->data, path, NULL }; - struct openflags flags; - char tmp[HOSTFS_BUFSIZE], *file; - int err = -ENOMEM; - - file = get_path(data_path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - flags = of_rdwr(OPENFLAGS()); - if(mount->direct) - flags = of_direct(flags); - - if(path == NULL) - path = ""; - err = (*mount->meta->open_file)(hf, path, inode, mount); - if(err) - goto out_free; - - err = open_filehandle(file, flags, 0, &hf->data); - if(err == -EISDIR) - goto out; - else if(err == -EPERM){ - flags = of_set_rw(flags, 1, 0); - err = open_filehandle(file, flags, 0, &hf->data); - } - - if(err) - goto out_close; - - hf->mount = mount; - is_reclaimable(&hf->data, humfs_data_name, inode); - - out_free: - free_path(file, tmp); - out: - return(err); - - out_close: - (*mount->meta->close_file)(hf); - goto out_free; -} - -static void *humfs_open_dir(char *path, int uid, int gid, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - const char *data_path[3] = { mount->data, path, NULL }; - - return(host_open_dir(data_path)); -} - -static void humfs_close_dir(void *stream, struct externfs_data *ed) -{ - os_close_dir(stream); -} - -static char *humfs_read_dir(void *stream, unsigned long long *pos, - unsigned long long *ino_out, int *len_out, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - - return(generic_host_read_dir(stream, pos, ino_out, len_out, mount)); -} - -LIST_HEAD(humfs_replies); - -struct humfs_aio { - struct aio_context aio; - struct list_head list; - void (*completion)(char *, int, void *); - char *buf; - int real_len; - int err; - void *data; -}; - -static int humfs_reply_fd = -1; - -struct humfs_aio last_task_aio, last_intr_aio; -struct humfs_aio *last_task_aio_ptr, *last_intr_aio_ptr; - -void humfs_work_proc(void *unused) -{ - struct humfs_aio *aio; - unsigned long flags; - - while(!list_empty(&humfs_replies)){ - local_irq_save(flags); - aio = list_entry(humfs_replies.next, struct humfs_aio, list); - - last_task_aio = *aio; - last_task_aio_ptr = aio; - - list_del(&aio->list); - local_irq_restore(flags); - - if(aio->err >= 0) - aio->err = aio->real_len; - (*aio->completion)(aio->buf, aio->err, aio->data); - kfree(aio); - } -} - -DECLARE_WORK(humfs_work, humfs_work_proc, NULL); - -static irqreturn_t humfs_interrupt(int irq, void *dev_id, - struct pt_regs *unused) -{ - struct aio_thread_reply reply; - struct humfs_aio *aio; - int err, fd = (int) dev_id; - - while(1){ - err = os_read_file(fd, &reply, sizeof(reply)); - if(err < 0){ - if(err == -EAGAIN) - break; - printk("humfs_interrupt - read returned err %d\n", - -err); - return(IRQ_HANDLED); - } - aio = reply.data; - aio->err = reply.err; - list_add(&aio->list, &humfs_replies); - last_intr_aio = *aio; - last_intr_aio_ptr = aio; - } - - if(!list_empty(&humfs_replies)) - schedule_work(&humfs_work); - reactivate_fd(fd, HUMFS_IRQ); - return(IRQ_HANDLED); -} - -static int init_humfs_aio(void) -{ - int fds[2], err; - - err = os_pipe(fds, 1, 1); - if(err){ - printk("init_humfs_aio - pipe failed, err = %d\n", -err); - goto out; - } - - err = um_request_irq(HUMFS_IRQ, fds[0], IRQ_READ, humfs_interrupt, - SA_INTERRUPT | SA_SAMPLE_RANDOM, "humfs", - (void *) fds[0]); - if(err){ - printk("init_humfs_aio - : um_request_irq failed, err = %d\n", - err); - goto out_close; - } - - humfs_reply_fd = fds[1]; - goto out; - - out_close: - os_close_file(fds[0]); - os_close_file(fds[1]); - out: - return(0); -} - -__initcall(init_humfs_aio); - -static int humfs_aio(enum aio_type type, int fd, unsigned long long offset, - char *buf, int len, int real_len, - void (*completion)(char *, int, void *), void *arg) -{ - struct humfs_aio *aio; - int err = -ENOMEM; - - aio = kmalloc(sizeof(*aio), GFP_KERNEL); - if(aio == NULL) - goto out; - *aio = ((struct humfs_aio) { .aio = INIT_AIO_CONTEXT, - .list = LIST_HEAD_INIT(aio->list), - .completion= completion, - .buf = buf, - .err = 0, - .real_len = real_len, - .data = arg }); - - err = submit_aio(type, fd, buf, len, offset, humfs_reply_fd, aio); - if(err) - (*completion)(buf, err, arg); - - out: - return(err); -} - -static int humfs_read_file(struct externfs_inode *ext, - unsigned long long offset, char *buf, int len, - int ignore_start, int ignore_end, - void (*completion)(char *, int, void *), void *arg, - struct externfs_data *ed) -{ - struct humfs_file *hf = container_of(ext, struct humfs_file, ext); - int fd = filehandle_fd(&hf->data); - - if(fd < 0){ - (*completion)(buf, fd, arg); - return(fd); - } - - return(humfs_aio(AIO_READ, fd, offset, buf, len, len, completion, - arg)); -} - -static int humfs_write_file(struct externfs_inode *ext, - unsigned long long offset, - const char *buf, int start, int len, - void (*completion)(char *, int, void *), void *arg, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - struct humfs_file *hf = container_of(ext, struct humfs_file, ext); - int err, orig_len = len, fd = filehandle_fd(&hf->data); - - if(fd < 0){ - (*completion)((char *) buf, fd, arg); - return(fd); - } - - if(mount->direct) - len = PAGE_SIZE; - else { - offset += start; - buf += start; - } - - err = humfs_aio(AIO_WRITE, fd, offset, (char *) buf, len, orig_len, - completion, arg); - - if(err < 0) - return(err); - - if(mount->direct) - err = orig_len; - - return(err); -} - -static int humfs_map_file_page(struct externfs_inode *ext, - unsigned long long offset, char *buf, int w, - struct externfs_data *ed) -{ - struct humfs_file *hf = container_of(ext, struct humfs_file, ext); - unsigned long long size, need; - int err, fd = filehandle_fd(&hf->data); - - if(fd < 0) - return(fd); - - err = os_fd_size(fd, &size); - if(err) - return(err); - - need = offset + PAGE_SIZE; - if(size < need){ - err = os_truncate_fd(fd, need); - if(err) - return(err); - } - - return(physmem_subst_mapping(buf, fd, offset, w)); -} - -static void humfs_close_file(struct externfs_inode *ext, - unsigned long long size) -{ - struct humfs_file *hf = container_of(ext, struct humfs_file, ext); - int fd; - - if(hf->data.fd == -1) - return; - - fd = filehandle_fd(&hf->data); - physmem_forget_descriptor(fd); - truncate_file(&hf->data, size); - close_file(&hf->data); - - (*hf->mount->meta->close_file)(hf); -} - -/* XXX Assumes that you can't make a normal file */ - -static int humfs_make_node(const char *path, int mode, int uid, int gid, - int type, int major, int minor, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - struct file_handle fh; - const char *data_path[3] = { mount->data, path, NULL }; - int err; - char t; - - err = host_create_file(data_path, S_IRWXUGO, &fh); - if(err) - goto out; - - close_file(&fh); - - switch(type){ - case S_IFCHR: - t = 'c'; - break; - case S_IFBLK: - t = 'b'; - break; - case S_IFIFO: - t = 'p'; - break; - case S_IFSOCK: - t = 's'; - break; - default: - err = -EINVAL; - printk("make_node - bad node type : %d\n", type); - goto out_rm; - } - - err = (*mount->meta->make_node)(path, mode, uid, gid, t, major, minor, - mount); - if(err) - goto out_rm; - - out: - return(err); - - out_rm: - host_unlink_file(data_path); - goto out; -} - -static int humfs_create_file(struct externfs_inode *ext, char *path, int mode, - int uid, int gid, struct inode *inode, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - struct humfs_file *hf = container_of(ext, struct humfs_file, ext); - const char *data_path[3] = { mount->data, path, NULL }; - int err; - - err = (*mount->meta->create_file)(hf, path, mode, uid, gid, inode, - mount); - if(err) - goto out; - - err = host_create_file(data_path, S_IRWXUGO, &hf->data); - if(err) - goto out_rm; - - - is_reclaimable(&hf->data, humfs_data_name, inode); - - return(0); - - out_rm: - (*mount->meta->remove_file)(path, mount); - (*mount->meta->close_file)(hf); - out: - return(err); -} - -static int humfs_set_attr(const char *path, struct externfs_iattr *attrs, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - const char *data_path[3] = { mount->data, path, NULL }; - int (*chown)(const char *, int, int, int, struct humfs *); - int err; - - chown = mount->meta->change_ownerships; - if(attrs->ia_valid & EXTERNFS_ATTR_MODE){ - err = (*chown)(path, attrs->ia_mode, -1, -1, mount); - if(err) - return(err); - } - if(attrs->ia_valid & EXTERNFS_ATTR_UID){ - err = (*chown)(path, -1, attrs->ia_uid, -1, mount); - if(err) - return(err); - } - if(attrs->ia_valid & EXTERNFS_ATTR_GID){ - err = (*chown)(path, -1, -1, attrs->ia_gid, mount); - if(err) - return(err); - } - - attrs->ia_valid &= ~(EXTERNFS_ATTR_MODE | EXTERNFS_ATTR_UID | - EXTERNFS_ATTR_GID); - - return(host_set_attr(data_path, attrs)); -} - -static int humfs_make_symlink(const char *from, const char *to, int uid, - int gid, struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - struct humfs_file *hf; - const char *data_path[3] = { mount->data, from, NULL }; - int err = -ENOMEM; - - hf = (*mount->meta->init_file)(); - if(hf == NULL) - goto out; - - err = (*mount->meta->create_file)(hf, from, S_IRWXUGO, uid, gid, NULL, - mount); - if(err) - goto out_close; - - err = host_make_symlink(data_path, to); - if(err) - (*mount->meta->remove_file)(from, mount); - - out_close: - (*mount->meta->close_file)(hf); - out: - return(err); -} - -static int humfs_link_file(const char *to, const char *from, int uid, int gid, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - const char *data_path_from[3] = { mount->data, from, NULL }; - const char *data_path_to[3] = { mount->data, to, NULL }; - int err; - - err = (*mount->meta->create_link)(to, from, mount); - if(err) - return(err); - - err = host_link_file(data_path_to, data_path_from); - if(err) - (*mount->meta->remove_file)(from, mount); - - return(err); -} - -static int humfs_unlink_file(const char *path, struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - const char *data_path[3] = { mount->data, path, NULL }; - int err; - - err = (*mount->meta->remove_file)(path, mount); - if (err) - return err; - - (*mount->meta->remove_file)(path, mount); - return(host_unlink_file(data_path)); -} - -static void humfs_invisible(struct externfs_inode *ext) -{ - struct humfs_file *hf = container_of(ext, struct humfs_file, ext); - struct humfs *mount = hf->mount; - - (*mount->meta->invisible)(hf); - not_reclaimable(&hf->data); -} - -static int humfs_make_dir(const char *path, int mode, int uid, int gid, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - const char *data_path[3] = { mount->data, path, NULL }; - int err; - - err = (*mount->meta->create_dir)(path, mode, uid, gid, mount); - if(err) - return(err); - - err = host_make_dir(data_path, S_IRWXUGO); - if(err) - (*mount->meta->remove_dir)(path, mount); - - return(err); -} - -static int humfs_remove_dir(const char *path, int uid, int gid, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - const char *data_path[3] = { mount->data, path, NULL }; - int err; - - err = host_remove_dir(data_path); - if (err) - return err; - - (*mount->meta->remove_dir)(path, mount); - - return(err); -} - -static int humfs_read_link(char *file, int uid, int gid, char *buf, int size, - struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - const char *data_path[3] = { mount->data, file, NULL }; - - return(host_read_link(data_path, buf, size)); -} - -struct humfs *inode_humfs_info(struct inode *inode) -{ - return(container_of(inode_externfs_info(inode), struct humfs, ext)); -} - -static int humfs_rename_file(char *from, char *to, struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - const char *data_path_from[3] = { mount->data, from, NULL }; - const char *data_path_to[3] = { mount->data, to, NULL }; - int err; - - err = (*mount->meta->rename_file)(from, to, mount); - if(err) - return(err); - - err = host_rename_file(data_path_from, data_path_to); - if(err) - (*mount->meta->rename_file)(to, from, mount); - - return(err); -} - -static int humfs_stat_fs(long *bsize_out, long long *blocks_out, - long long *bfree_out, long long *bavail_out, - long long *files_out, long long *ffree_out, - void *fsid_out, int fsid_size, long *namelen_out, - long *spare_out, struct externfs_data *ed) -{ - struct humfs *mount = container_of(ed, struct humfs, ext); - const char *data_path[3] = { mount->data, NULL }; - int err; - - /* XXX Needs to maintain this info as metadata */ - err = host_stat_fs(data_path, bsize_out, blocks_out, bfree_out, - bavail_out, files_out, ffree_out, fsid_out, - fsid_size, namelen_out, spare_out); - if(err) - return(err); - - *blocks_out = mount->total / *bsize_out; - *bfree_out = (mount->total - mount->used) / *bsize_out; - *bavail_out = (mount->total - mount->used) / *bsize_out; - return(0); -} - -int humfs_truncate_file(struct externfs_inode *ext, __u64 size, - struct externfs_data *ed) -{ - struct humfs_file *hf = container_of(ext, struct humfs_file, ext); - - return(truncate_file(&hf->data, size)); -} - -char *humfs_path(char *dir, char *file) -{ - int need_slash, len = strlen(dir) + strlen(file); - char *new; - - need_slash = (dir[strlen(dir) - 1] != '/'); - if(need_slash) - len++; - - new = kmalloc(len + 1, GFP_KERNEL); - if(new == NULL) - return(NULL); - - strcpy(new, dir); - if(need_slash) - strcat(new, "/"); - strcat(new, file); - - return(new); -} - -DECLARE_MUTEX(meta_sem); -struct list_head metas = LIST_HEAD_INIT(metas); - -static struct humfs_meta_ops *find_meta(const char *name) -{ - struct list_head *ele; - struct humfs_meta_ops *m; - - down(&meta_sem); - list_for_each(ele, &metas){ - m = list_entry(ele, struct humfs_meta_ops, list); - if(!strcmp(m->name, name)) - goto out; - } - m = NULL; - out: - up(&meta_sem); - return(m); -} - -void register_meta(struct humfs_meta_ops *ops) -{ - down(&meta_sem); - list_add(&ops->list, &metas); - up(&meta_sem); -} - -void unregister_meta(struct humfs_meta_ops *ops) -{ - down(&meta_sem); - list_del(&ops->list); - up(&meta_sem); -} - -static struct humfs *read_superblock(char *root) -{ - struct humfs *mount; - struct humfs_meta_ops *meta = NULL; - struct file_handle *fh; - const char *path[] = { root, "superblock", NULL }; - u64 used, total; - char meta_buf[33], line[HOSTFS_BUFSIZE], *newline; - unsigned long long pos; - int version, i, n, err; - - fh = kmalloc(sizeof(*fh), GFP_KERNEL); - if(fh == NULL) - return(ERR_PTR(-ENOMEM)); - - err = host_open_file(path, 1, 0, fh); - if(err){ - printk("Failed to open %s/%s, errno = %d\n", path[0], - path[1], err); - return(ERR_PTR(err)); - } - - used = 0; - total = 0; - pos = 0; - i = 0; - while(1){ - n = read_file(fh, pos, &line[i], sizeof(line) - i - 1); - if((n == 0) && (i == 0)) - break; - if(n < 0) - return(ERR_PTR(n)); - - pos += n; - if(n > 0) - line[n + i] = '\0'; - - newline = strchr(line, '\n'); - if(newline == NULL){ - printk("read_superblock - line too long : '%s'\n", - line); - return(ERR_PTR(-EINVAL)); - } - newline++; - - if(sscanf(line, "version %d\n", &version) == 1){ - if(version != HUMFS_VERSION){ - printk("humfs version mismatch - want version " - "%d, got version %d.\n", HUMFS_VERSION, - version); - return(ERR_PTR(-EINVAL)); - } - } - else if(sscanf(line, "used %Lu\n", &used) == 1) ; - else if(sscanf(line, "total %Lu\n", &total) == 1) ; - else if(sscanf(line, "metadata %32s\n", meta_buf) == 1){ - meta = find_meta(meta_buf); - if(meta == NULL){ - printk("read_superblock - meta api \"%s\" not " - "registered\n", meta_buf); - return(ERR_PTR(-EINVAL)); - } - } - - else { - printk("read_superblock - bogus line : '%s'\n", line); - return(ERR_PTR(-EINVAL)); - } - - i = newline - line; - memmove(line, newline, sizeof(line) - i); - i = strlen(line); - } - - if(used == 0){ - printk("read_superblock - used not specified or set to " - "zero\n"); - return(ERR_PTR(-EINVAL)); - } - if(total == 0){ - printk("read_superblock - total not specified or set to " - "zero\n"); - return(ERR_PTR(-EINVAL)); - } - if(used > total){ - printk("read_superblock - used is greater than total\n"); - return(ERR_PTR(-EINVAL)); - } - - if(meta == NULL){ - meta = find_meta("shadow_fs"); - } - - if(meta == NULL){ - printk("read_superblock - valid meta api was not specified\n"); - return(ERR_PTR(-EINVAL)); - } - - mount = (*meta->init_mount)(root); - if(IS_ERR(mount)) - return(mount); - - *mount = ((struct humfs) { .total = total, - .used = used, - .meta = meta }); - return(mount); -} - -struct externfs_file_ops humfs_no_mmap_file_ops = { - .stat_file = humfs_stat_file, - .file_type = humfs_file_type, - .access_file = NULL, - .open_file = humfs_open_file, - .open_dir = humfs_open_dir, - .read_dir = humfs_read_dir, - .read_file = humfs_read_file, - .write_file = humfs_write_file, - .map_file_page = NULL, - .close_file = humfs_close_file, - .close_dir = humfs_close_dir, - .invisible = humfs_invisible, - .create_file = humfs_create_file, - .set_attr = humfs_set_attr, - .make_symlink = humfs_make_symlink, - .unlink_file = humfs_unlink_file, - .make_dir = humfs_make_dir, - .remove_dir = humfs_remove_dir, - .make_node = humfs_make_node, - .link_file = humfs_link_file, - .read_link = humfs_read_link, - .rename_file = humfs_rename_file, - .statfs = humfs_stat_fs, - .truncate_file = humfs_truncate_file -}; - -struct externfs_file_ops humfs_mmap_file_ops = { - .stat_file = humfs_stat_file, - .file_type = humfs_file_type, - .access_file = NULL, - .open_file = humfs_open_file, - .open_dir = humfs_open_dir, - .invisible = humfs_invisible, - .read_dir = humfs_read_dir, - .read_file = humfs_read_file, - .write_file = humfs_write_file, - .map_file_page = humfs_map_file_page, - .close_file = humfs_close_file, - .close_dir = humfs_close_dir, - .create_file = humfs_create_file, - .set_attr = humfs_set_attr, - .make_symlink = humfs_make_symlink, - .unlink_file = humfs_unlink_file, - .make_dir = humfs_make_dir, - .remove_dir = humfs_remove_dir, - .make_node = humfs_make_node, - .link_file = humfs_link_file, - .read_link = humfs_read_link, - .rename_file = humfs_rename_file, - .statfs = humfs_stat_fs, - .truncate_file = humfs_truncate_file -}; - -static struct externfs_data *mount_fs(char *mount_arg) -{ - char *root, *data, *flags; - struct humfs *mount; - struct externfs_file_ops *file_ops; - int err, do_mmap = 0; - - if(mount_arg == NULL){ - printk("humfs - no host directory specified\n"); - return(NULL); - } - - flags = strchr((char *) mount_arg, ','); - if(flags != NULL){ - do { - *flags++ = '\0'; - - if(!strcmp(flags, "mmap")) - do_mmap = 1; - - flags = strchr(flags, ','); - } while(flags != NULL); - } - - err = -ENOMEM; - root = host_root_filename(mount_arg); - if(root == NULL) - goto err; - - mount = read_superblock(root); - if(IS_ERR(mount)){ - err = PTR_ERR(mount); - goto err_free_root; - } - - data = humfs_path(root, "data/"); - if(data == NULL) - goto err_free_mount; - - if(CHOOSE_MODE(do_mmap, 0)){ - printk("humfs doesn't support mmap in tt mode\n"); - do_mmap = 0; - } - - mount->data = data; - mount->mmap = do_mmap; - - file_ops = do_mmap ? &humfs_mmap_file_ops : &humfs_no_mmap_file_ops; - init_externfs(&mount->ext, file_ops); - - return(&mount->ext); - - err_free_mount: - kfree(mount); - err_free_root: - kfree(root); - err: - return(NULL); -} - -struct externfs_mount_ops humfs_mount_ops = { - .init_file = humfs_init_file, - .mount = mount_fs, -}; - -static int __init init_humfs(void) -{ - return(register_externfs("humfs", &humfs_mount_ops)); -} - -static void __exit exit_humfs(void) -{ - unregister_externfs("humfs"); -} - -__initcall(init_humfs); -__exitcall(exit_humfs); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/fs/hostfs/meta_fs.c b/fs/hostfs/meta_fs.c deleted file mode 100644 index 74641496e..000000000 --- a/fs/hostfs/meta_fs.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include -#include -#include "hostfs.h" -#include "metadata.h" -#include "kern_util.h" - -#define METADATA_FILE_PATH(meta) (meta)->root, "file_metadata" -#define METADATA_DIR_PATH(meta) (meta)->root, "dir_metadata" - -struct meta_fs { - struct humfs humfs; - char *root; -}; - -struct meta_file { - struct humfs_file humfs; - struct file_handle fh; -}; - -static int meta_file_path(const char *path, struct meta_fs *meta, - const char *path_out[]) -{ - const char *data_path[] = { meta->root, "data", path, NULL }; - char data_tmp[HOSTFS_BUFSIZE]; - char *data_file = get_path(data_path, data_tmp, sizeof(data_tmp)); - - if(data_file == NULL) - return(-ENOMEM); - - path_out[0] = meta->root; - path_out[2] = path; - if(os_file_type(data_file) == OS_TYPE_DIR){ - path_out[1] = "dir_metadata"; - path_out[3] = "metadata"; - path_out[4] = NULL; - } - else { - path_out[1] = "file_metadata"; - path_out[3] = NULL; - } - - return(0); -} - -static int open_meta_file(const char *path, struct humfs *humfs, - struct file_handle *fh) -{ - struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs); - const char *meta_path[5]; - char meta_tmp[HOSTFS_BUFSIZE]; - char *meta_file; - int err; - - err = meta_file_path(path, meta, meta_path); - if(err) - goto out; - - meta_file = get_path(meta_path, meta_tmp, sizeof(meta_tmp)); - if(meta_file == NULL) - goto out; - - err = open_filehandle(meta_file, of_rdwr(OPENFLAGS()), 0, fh); - - out: - return(err); -} - -static char *meta_fs_name(struct inode *inode) -{ - struct humfs *mount = inode_humfs_info(inode); - struct meta_fs *meta = container_of(mount, struct meta_fs, humfs); - const char *metadata_path[5]; - char tmp[HOSTFS_BUFSIZE], *name, *file; - - if(meta_file_path("", meta, metadata_path)) - return(NULL); - - file = get_path(metadata_path, tmp, sizeof(tmp)); - if(file == NULL) - return(NULL); - - name = inode_name_prefix(inode, file); - - free_path(file, tmp); - return(name); -} - -static void metafs_invisible(struct humfs_file *hf) -{ - struct meta_file *mf = container_of(hf, struct meta_file, humfs); - - not_reclaimable(&mf->fh); -} - -static struct humfs_file *metafs_init_file(void) -{ - struct meta_file *mf; - int err = -ENOMEM; - - mf = kmalloc(sizeof(*mf), GFP_KERNEL); - if(mf == NULL) - return(ERR_PTR(err)); - - return(&mf->humfs); -} - -static int metafs_open_file(struct humfs_file *hf, const char *path, - struct inode *inode, struct humfs *humfs) -{ - struct meta_file *mf = container_of(hf, struct meta_file, humfs); - int err; - - err = open_meta_file(path, humfs, &mf->fh); - if(err) - return(err); - - is_reclaimable(&mf->fh, meta_fs_name, inode); - - return(0); -} - -static void metafs_close_file(struct humfs_file *hf) -{ - struct meta_file *meta = container_of(hf, struct meta_file, humfs); - - close_file(&meta->fh); - kfree(meta); -} - -static int metafs_create_file(struct humfs_file *hf, const char *path, - int mode, int uid, int gid, struct inode *inode, - struct humfs *humfs) -{ - struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs); - struct meta_file *mf = container_of(hf, struct meta_file, humfs); - char tmp[HOSTFS_BUFSIZE]; - const char *metadata_path[] = { METADATA_FILE_PATH(meta), path, NULL }; - char *file = get_path(metadata_path, tmp, sizeof(tmp)); - char buf[sizeof("mmmm uuuuuuuuuu gggggggggg")]; - int err = -ENOMEM; - - if(file == NULL) - goto out; - - err = open_filehandle(file, of_write(of_create(OPENFLAGS())), 0644, - &mf->fh); - if(err) - goto out_free_path; - - if(inode != NULL) - is_reclaimable(&mf->fh, meta_fs_name, inode); - - sprintf(buf, "%d %d %d\n", mode & S_IRWXUGO, uid, gid); - err = write_file(&mf->fh, 0, buf, strlen(buf)); - if(err < 0) - goto out_rm; - - free_path(file, tmp); - return(0); - - out_rm: - close_file(&mf->fh); - os_remove_file(file); - out_free_path: - free_path(file, tmp); - out: - return(err); -} - -static int metafs_create_link(const char *to, const char *from, - struct humfs *humfs) -{ - struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs); - const char *path_to[] = { METADATA_FILE_PATH(meta), to, NULL }; - const char *path_from[] = { METADATA_FILE_PATH(meta), from, NULL }; - - return(host_link_file(path_to, path_from)); -} - -static int metafs_remove_file(const char *path, struct humfs *humfs) -{ - struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs); - char tmp[HOSTFS_BUFSIZE]; - const char *metadata_path[] = { METADATA_FILE_PATH(meta), path, NULL }; - char *file = get_path(metadata_path, tmp, sizeof(tmp)); - int err = -ENOMEM; - - if(file == NULL) - goto out; - - err = os_remove_file(file); - - out: - free_path(file, tmp); - return(err); -} - -static int metafs_create_directory(const char *path, int mode, int uid, - int gid, struct humfs *humfs) -{ - struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs); - char tmp[HOSTFS_BUFSIZE]; - const char *dir_path[] = { METADATA_DIR_PATH(meta), path, NULL, NULL }; - const char *file_path[] = { METADATA_FILE_PATH(meta), path, NULL, - NULL }; - char *file, dir_meta[sizeof("mmmm uuuuuuuuuu gggggggggg\n")]; - int err, fd; - - err = host_make_dir(dir_path, 0755); - if(err) - goto out; - - err = host_make_dir(file_path, 0755); - if(err) - goto out_rm; - - /* This to make the index independent of the number of elements in - * METADATA_DIR_PATH(). - */ - dir_path[sizeof(dir_path) / sizeof(dir_path[0]) - 2] = "metadata"; - - err = -ENOMEM; - file = get_path(dir_path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - fd = os_open_file(file, of_create(of_rdwr(OPENFLAGS())), 0644); - if(fd < 0){ - err = fd; - goto out_free; - } - - sprintf(dir_meta, "%d %d %d\n", mode & S_IRWXUGO, uid, gid); - err = os_write_file(fd, dir_meta, strlen(dir_meta)); - if(err > 0) - err = 0; - - os_close_file(fd); - - out_free: - free_path(file, tmp); - out_rm: - host_remove_dir(dir_path); - out: - return(err); -} - -static int metafs_remove_directory(const char *path, struct humfs *humfs) -{ - struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs); - char tmp[HOSTFS_BUFSIZE], *file; - const char *dir_path[] = { METADATA_DIR_PATH(meta), path, "metadata", - NULL }; - const char *file_path[] = { METADATA_FILE_PATH(meta), path, NULL }; - char *slash; - int err; - - err = -ENOMEM; - file = get_path(dir_path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = os_remove_file(file); - if(err) - goto out_free; - - slash = strrchr(file, '/'); - if(slash == NULL){ - printk("remove_shadow_directory failed to find last slash\n"); - goto out_free; - } - *slash = '\0'; - err = os_remove_dir(file); - free_path(file, tmp); - - file = get_path(file_path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = os_remove_dir(file); - if(err) - goto out_free; - - out: - return(err); - out_free: - free_path(file, tmp); - goto out; -} - -static int metafs_make_node(const char *path, int mode, int uid, int gid, - int type, int maj, int min, struct humfs *humfs) -{ - struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs); - struct file_handle fh; - char tmp[HOSTFS_BUFSIZE]; - const char *metadata_path[] = { METADATA_FILE_PATH(meta), path, NULL }; - int err; - char buf[sizeof("mmmm uuuuuuuuuu gggggggggg x nnn mmm\n")], *file; - - sprintf(buf, "%d %d %d %c %d %d\n", mode & S_IRWXUGO, uid, gid, type, - maj, min); - - err = -ENOMEM; - file = get_path(metadata_path, tmp, sizeof(tmp)); - if(file == NULL) - goto out; - - err = open_filehandle(file, - of_create(of_rdwr(OPENFLAGS())), 0644, &fh); - if(err) - goto out_free; - - err = write_file(&fh, 0, buf, strlen(buf)); - if(err > 0) - err = 0; - - close_file(&fh); - - out_free: - free_path(file, tmp); - out: - return(err); -} - -static int metafs_ownerships(const char *path, int *mode_out, int *uid_out, - int *gid_out, char *type_out, int *maj_out, - int *min_out, struct humfs *humfs) -{ - struct file_handle fh; - char buf[sizeof("mmmm uuuuuuuuuu gggggggggg x nnn mmm\n")]; - int err, n, mode, uid, gid, maj, min; - char type; - - err = open_meta_file(path, humfs, &fh); - if(err) - goto out; - - err = os_read_file(fh.fd, buf, sizeof(buf) - 1); - if(err < 0) - goto out_close; - - buf[err] = '\0'; - err = 0; - - n = sscanf(buf, "%d %d %d %c %d %d", &mode, &uid, &gid, &type, &maj, - &min); - if(n == 3){ - maj = -1; - min = -1; - type = 0; - err = 0; - } - else if(n != 6) - err = -EINVAL; - - if(mode_out != NULL) - *mode_out = mode; - if(uid_out != NULL) - *uid_out = uid; - if(gid_out != NULL) - *gid_out = uid; - if(type_out != NULL) - *type_out = type; - if(maj_out != NULL) - *maj_out = maj; - if(min_out != NULL) - *min_out = min; - - out_close: - close_file(&fh); - out: - return(err); -} - -static int metafs_change_ownerships(const char *path, int mode, int uid, - int gid, struct humfs *humfs) -{ - struct file_handle fh; - char type; - char buf[sizeof("mmmm uuuuuuuuuu gggggggggg x nnn mmm\n")]; - int err = -ENOMEM, old_mode, old_uid, old_gid, n, maj, min; - - err = open_meta_file(path, humfs, &fh); - if(err) - goto out; - - err = read_file(&fh, 0, buf, sizeof(buf) - 1); - if(err < 0) - goto out_close; - - buf[err] = '\0'; - - n = sscanf(buf, "%d %d %d %c %d %d\n", &old_mode, &old_uid, &old_gid, - &type, &maj, &min); - if((n != 3) && (n != 6)){ - err = -EINVAL; - goto out_close; - } - - if(mode == -1) - mode = old_mode; - if(uid == -1) - uid = old_uid; - if(gid == -1) - gid = old_gid; - - if(n == 3) - sprintf(buf, "%d %d %d\n", mode & S_IRWXUGO, uid, gid); - else - sprintf(buf, "%d %d %d %c %d %d\n", mode & S_IRWXUGO, uid, gid, - type, maj, min); - - err = write_file(&fh, 0, buf, strlen(buf)); - if(err > 0) - err = 0; - - err = truncate_file(&fh, strlen(buf)); - - out_close: - close_file(&fh); - out: - return(err); -} - -static int metafs_rename_file(const char *from, const char *to, - struct humfs *humfs) -{ - struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs); - const char *metadata_path_from[5], *metadata_path_to[5]; - int err; - - err = meta_file_path(from, meta, metadata_path_from); - if(err) - return(err); - - err = meta_file_path(to, meta, metadata_path_to); - if(err) - return(err); - - return(host_rename_file(metadata_path_from, metadata_path_to)); -} - -static struct humfs *metafs_init_mount(char *root) -{ - struct meta_fs *meta; - int err = -ENOMEM; - - meta = kmalloc(sizeof(*meta), GFP_KERNEL); - if(meta == NULL) - goto out; - - meta->root = uml_strdup(root); - if(meta->root == NULL) - goto out_free_meta; - - return(&meta->humfs); - - out_free_meta: - kfree(meta); - out: - return(ERR_PTR(err)); -} - -static void metafs_free_mount(struct humfs *humfs) -{ - struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs); - - kfree(meta); -} - -struct humfs_meta_ops hum_fs_meta_fs_ops = { - .list = LIST_HEAD_INIT(hum_fs_meta_fs_ops.list), - .name = "shadow_fs", - .init_file = metafs_init_file, - .open_file = metafs_open_file, - .close_file = metafs_close_file, - .ownerships = metafs_ownerships, - .make_node = metafs_make_node, - .create_file = metafs_create_file, - .create_link = metafs_create_link, - .remove_file = metafs_remove_file, - .create_dir = metafs_create_directory, - .remove_dir = metafs_remove_directory, - .change_ownerships = metafs_change_ownerships, - .rename_file = metafs_rename_file, - .invisible = metafs_invisible, - .init_mount = metafs_init_mount, - .free_mount = metafs_free_mount, -}; - -static int __init init_meta_fs(void) -{ - register_meta(&hum_fs_meta_fs_ops); - return(0); -} - -static void __exit exit_meta_fs(void) -{ - unregister_meta(&hum_fs_meta_fs_ops); -} - -__initcall(init_meta_fs); -__exitcall(exit_meta_fs); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/fs/hostfs/metadata.h b/fs/hostfs/metadata.h deleted file mode 100644 index 924fb5bf2..000000000 --- a/fs/hostfs/metadata.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2004 Piotr Neuman (sikkh@wp.pl) and - * Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __UM_FS_METADATA -#define __UM_FS_METADATA - -#include "linux/fs.h" -#include "linux/list.h" -#include "os.h" -#include "hostfs.h" - -struct humfs { - struct externfs_data ext; - __u64 used; - __u64 total; - char *data; - int mmap; - int direct; - struct humfs_meta_ops *meta; -}; - -struct humfs_file { - struct humfs *mount; - struct file_handle data; - struct externfs_inode ext; -}; - -struct humfs_meta_ops { - struct list_head list; - char *name; - struct humfs_file *(*init_file)(void); - int (*open_file)(struct humfs_file *hf, const char *path, - struct inode *inode, struct humfs *humfs); - int (*create_file)(struct humfs_file *hf, const char *path, int mode, - int uid, int gid, struct inode *inode, - struct humfs *humfs); - void (*close_file)(struct humfs_file *humfs); - int (*ownerships)(const char *path, int *mode_out, int *uid_out, - int *gid_out, char *type_out, int *maj_out, - int *min_out, struct humfs *humfs); - int (*make_node)(const char *path, int mode, int uid, int gid, - int type, int major, int minor, struct humfs *humfs); - int (*create_link)(const char *to, const char *from, - struct humfs *humfs); - int (*remove_file)(const char *path, struct humfs *humfs); - int (*create_dir)(const char *path, int mode, int uid, int gid, - struct humfs *humfs); - int (*remove_dir)(const char *path, struct humfs *humfs); - int (*change_ownerships)(const char *path, int mode, int uid, int gid, - struct humfs *humfs); - int (*rename_file)(const char *from, const char *to, - struct humfs *humfs); - void (*invisible)(struct humfs_file *hf); - struct humfs *(*init_mount)(char *root); - void (*free_mount)(struct humfs *humfs); -}; - -extern void register_meta(struct humfs_meta_ops *ops); -extern void unregister_meta(struct humfs_meta_ops *ops); - -extern char *humfs_path(char *dir, char *file); -extern char *humfs_name(struct inode *inode, char *prefix); -extern struct humfs *inode_humfs_info(struct inode *inode); - -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/include/asm-um/cpumask.h b/include/asm-um/cpumask.h new file mode 100644 index 000000000..90f0d003d --- /dev/null +++ b/include/asm-um/cpumask.h @@ -0,0 +1,6 @@ +#ifndef _ASM_UM_CPUMASK_H +#define _ASM_UM_CPUMASK_H + +#include + +#endif /* _ASM_UM_CPUMASK_H */ diff --git a/include/asm-um/init.h b/include/asm-um/init.h new file mode 100644 index 000000000..1e271ca7c --- /dev/null +++ b/include/asm-um/init.h @@ -0,0 +1,11 @@ +#ifndef _UM_INIT_H +#define _UM_INIT_H + +#ifdef notdef +#define __init +#define __initdata +#define __initfunc(__arginit) __arginit +#define __cacheline_aligned +#endif + +#endif diff --git a/include/asm-um/irq.h b/include/asm-um/irq.h index bccf537ec..de389a477 100644 --- a/include/asm-um/irq.h +++ b/include/asm-um/irq.h @@ -15,9 +15,8 @@ #define SIGIO_WRITE_IRQ 11 #define TELNETD_IRQ 12 #define XTERM_IRQ 13 -#define HUMFS_IRQ 14 - -#define LAST_IRQ HUMFS_IRQ + +#define LAST_IRQ XTERM_IRQ #define NR_IRQS (LAST_IRQ + 1) #endif diff --git a/include/asm-um/module.h b/include/asm-um/module.h index dae3ddf6b..b44105777 100644 --- a/include/asm-um/module.h +++ b/include/asm-um/module.h @@ -1,5 +1,5 @@ -#ifndef __UM_MODULE_H -#define __UM_MODULE_H +#ifndef __UM_MODULE_I386_H +#define __UM_MODULE_I386_H /* UML is simple */ struct mod_arch_specific @@ -9,5 +9,9 @@ struct mod_arch_specific #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr +#define Elf_Rel Elf32_Rel +#define Elf_Rela Elf32_Rela +#define ELF_R_TYPE(X) ELF32_R_TYPE(X) +#define ELF_R_SYM(X) ELF32_R_SYM(X) #endif diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h index e82fda71c..ec58334fb 100644 --- a/include/asm-um/processor-generic.h +++ b/include/asm-um/processor-generic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -107,7 +107,6 @@ static inline void mm_copy_segments(struct mm_struct *from_mm, */ extern unsigned long task_size; -#undef TASK_SIZE #define TASK_SIZE (task_size) /* This decides where the kernel will search for a free chunk of vm diff --git a/include/asm-um/smplock.h b/include/asm-um/smplock.h new file mode 100644 index 000000000..aacda39c5 --- /dev/null +++ b/include/asm-um/smplock.h @@ -0,0 +1,6 @@ +#ifndef __UM_SMPLOCK_H +#define __UM_SMPLOCK_H + +#include "asm/arch/smplock.h" + +#endif diff --git a/include/asm-um/spinlock.h b/include/asm-um/spinlock.h new file mode 100644 index 000000000..f18c82886 --- /dev/null +++ b/include/asm-um/spinlock.h @@ -0,0 +1,6 @@ +#ifndef __UM_SPINLOCK_H +#define __UM_SPINLOCK_H + +#include "asm/arch/spinlock.h" + +#endif diff --git a/include/linux/gfp.h b/include/linux/gfp.h index fbcabf701..e7fb254fa 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -80,13 +80,14 @@ static inline void arch_free_page(struct page *page, int order) { } extern struct page * FASTCALL(__alloc_pages(unsigned int, unsigned int, struct zonelist *)); -static inline struct page * alloc_pages_node(int nid, unsigned int gfp_mask, - unsigned int order) + +static inline struct page *alloc_pages_node(int nid, unsigned int gfp_mask, + unsigned int order) { if (unlikely(order >= MAX_ORDER)) return NULL; - return __alloc_pages(gfp_mask, order, + return __alloc_pages(gfp_mask, order, NODE_DATA(nid)->node_zonelists + (gfp_mask & GFP_ZONEMASK)); } diff --git a/include/linux/ghash.h b/include/linux/ghash.h deleted file mode 100644 index a24798866..000000000 --- a/include/linux/ghash.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * include/linux/ghash.h -- generic hashing with fuzzy retrieval - * - * (C) 1997 Thomas Schoebel-Theuer - * - * The algorithms implemented here seem to be a completely new invention, - * and I'll publish the fundamentals in a paper. - */ - -#ifndef _GHASH_H -#define _GHASH_H -/* HASHSIZE _must_ be a power of two!!! */ - - -#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \ -\ -struct NAME##_table {\ - TYPE * hashtable[HASHSIZE];\ - TYPE * sorted_list;\ - int nr_entries;\ -};\ -\ -struct NAME##_ptrs {\ - TYPE * next_hash;\ - TYPE * prev_hash;\ - TYPE * next_sorted;\ - TYPE * prev_sorted;\ -}; - -#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\ -\ -LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -{\ - int ix = HASHFN(elem->KEY);\ - TYPE ** base = &tbl->hashtable[ix];\ - TYPE * ptr = *base;\ - TYPE * prev = NULL;\ -\ - tbl->nr_entries++;\ - while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\ - base = &ptr->PTRS.next_hash;\ - prev = ptr;\ - ptr = *base;\ - }\ - elem->PTRS.next_hash = ptr;\ - elem->PTRS.prev_hash = prev;\ - if(ptr) {\ - ptr->PTRS.prev_hash = elem;\ - }\ - *base = elem;\ -\ - ptr = prev;\ - if(!ptr) {\ - ptr = tbl->sorted_list;\ - prev = NULL;\ - } else {\ - prev = ptr->PTRS.prev_sorted;\ - }\ - while(ptr) {\ - TYPE * next = ptr->PTRS.next_hash;\ - if(next && KEYCMP(next->KEY, elem->KEY)) {\ - prev = ptr;\ - ptr = next;\ - } else if(KEYCMP(ptr->KEY, elem->KEY)) {\ - prev = ptr;\ - ptr = ptr->PTRS.next_sorted;\ - } else\ - break;\ - }\ - elem->PTRS.next_sorted = ptr;\ - elem->PTRS.prev_sorted = prev;\ - if(ptr) {\ - ptr->PTRS.prev_sorted = elem;\ - }\ - if(prev) {\ - prev->PTRS.next_sorted = elem;\ - } else {\ - tbl->sorted_list = elem;\ - }\ -}\ -\ -LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -{\ - TYPE * next = elem->PTRS.next_hash;\ - TYPE * prev = elem->PTRS.prev_hash;\ -\ - tbl->nr_entries--;\ - if(next)\ - next->PTRS.prev_hash = prev;\ - if(prev)\ - prev->PTRS.next_hash = next;\ - else {\ - int ix = HASHFN(elem->KEY);\ - tbl->hashtable[ix] = next;\ - }\ -\ - next = elem->PTRS.next_sorted;\ - prev = elem->PTRS.prev_sorted;\ - if(next)\ - next->PTRS.prev_sorted = prev;\ - if(prev)\ - prev->PTRS.next_sorted = next;\ - else\ - tbl->sorted_list = next;\ -}\ -\ -LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\ -{\ - int ix = hashfn(pos);\ - TYPE * ptr = tbl->hashtable[ix];\ - while(ptr && KEYCMP(ptr->KEY, pos))\ - ptr = ptr->PTRS.next_hash;\ - if(ptr && !KEYEQ(ptr->KEY, pos))\ - ptr = NULL;\ - return ptr;\ -}\ -\ -LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\ -{\ - int ix;\ - int offset;\ - TYPE * ptr;\ - TYPE * next;\ -\ - ptr = tbl->sorted_list;\ - if(!ptr || KEYCMP(pos, ptr->KEY))\ - return NULL;\ - ix = HASHFN(pos);\ - offset = HASHSIZE;\ - do {\ - offset >>= 1;\ - next = tbl->hashtable[(ix+offset) & ((HASHSIZE)-1)];\ - if(next && (KEYCMP(next->KEY, pos) || KEYEQ(next->KEY, pos))\ - && KEYCMP(ptr->KEY, next->KEY))\ - ptr = next;\ - } while(offset);\ -\ - for(;;) {\ - next = ptr->PTRS.next_hash;\ - if(next) {\ - if(KEYCMP(next->KEY, pos)) {\ - ptr = next;\ - continue;\ - }\ - }\ - next = ptr->PTRS.next_sorted;\ - if(next && KEYCMP(next->KEY, pos)) {\ - ptr = next;\ - continue;\ - }\ - return ptr;\ - }\ - return NULL;\ -} - -/* LINKAGE - empty or "static", depending on whether you want the definitions to - * be public or not - * NAME - a string to stick in names to make this hash table type distinct from - * any others - * HASHSIZE - number of buckets - * TYPE - type of data contained in the buckets - must be a structure, one - * field is of type NAME_ptrs, another is the hash key - * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that - * field - * KEYTYPE - type of the key field within TYPE - * KEY - name of the key field within TYPE - * KEYCMP - pointer to function that compares KEYTYPEs to each other - the - * prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal, - * non-zero for not equal - * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE), - * it returns a number in the range 0 ... HASHSIZE - 1 - * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call - * DEF_HASH. - */ - -#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \ -\ -struct NAME##_table {\ - TYPE * hashtable[HASHSIZE];\ - int nr_entries;\ -};\ -\ -struct NAME##_ptrs {\ - TYPE * next_hash;\ - TYPE * prev_hash;\ -}; - -#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\ -\ -LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -{\ - int ix = HASHFN(elem->KEY);\ - TYPE ** base = &tbl->hashtable[ix];\ - TYPE * ptr = *base;\ - TYPE * prev = NULL;\ -\ - tbl->nr_entries++;\ - while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\ - base = &ptr->PTRS.next_hash;\ - prev = ptr;\ - ptr = *base;\ - }\ - elem->PTRS.next_hash = ptr;\ - elem->PTRS.prev_hash = prev;\ - if(ptr) {\ - ptr->PTRS.prev_hash = elem;\ - }\ - *base = elem;\ -}\ -\ -LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -{\ - TYPE * next = elem->PTRS.next_hash;\ - TYPE * prev = elem->PTRS.prev_hash;\ -\ - tbl->nr_entries--;\ - if(next)\ - next->PTRS.prev_hash = prev;\ - if(prev)\ - prev->PTRS.next_hash = next;\ - else {\ - int ix = HASHFN(elem->KEY);\ - tbl->hashtable[ix] = next;\ - }\ -}\ -\ -LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\ -{\ - int ix = HASHFN(pos);\ - TYPE * ptr = tbl->hashtable[ix];\ - while(ptr && KEYCMP(ptr->KEY, pos))\ - ptr = ptr->PTRS.next_hash;\ - return ptr;\ -} - -#endif diff --git a/include/linux/mm.h b/include/linux/mm.h index 503fbfdf3..d025bcbc6 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -619,9 +619,6 @@ int clear_page_dirty_for_io(struct page *page); */ typedef int (*shrinker_t)(int nr_to_scan, unsigned int gfp_mask); -asmlinkage long do_mprotect(struct mm_struct *mm, unsigned long start, - size_t len, unsigned long prot); - /* * Add an aging callback. The int is the number of 'seeks' it takes * to recreate one of the objects that these functions age. @@ -698,10 +695,9 @@ static inline unsigned long get_unmapped_area(struct file * file, unsigned long return get_unmapped_area_prot(file, addr, len, pgoff, flags, 0); } -extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file, - unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flag, - unsigned long pgoff); +extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long pgoff); static inline unsigned long do_mmap(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, @@ -711,8 +707,7 @@ static inline unsigned long do_mmap(struct file *file, unsigned long addr, if ((offset + PAGE_ALIGN(len)) < offset) goto out; if (!(offset & ~PAGE_MASK)) - ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, - offset >> PAGE_SHIFT); + ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); out: return ret; } diff --git a/include/linux/proc_mm.h b/include/linux/proc_mm.h deleted file mode 100644 index 254f8b4b8..000000000 --- a/include/linux/proc_mm.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __PROC_MM_H -#define __PROC_MM_H - -#include "linux/sched.h" - -#define MM_MMAP 54 -#define MM_MUNMAP 55 -#define MM_MPROTECT 56 -#define MM_COPY_SEGMENTS 57 - -struct mm_mmap { - unsigned long addr; - unsigned long len; - unsigned long prot; - unsigned long flags; - unsigned long fd; - unsigned long offset; -}; - -struct mm_munmap { - unsigned long addr; - unsigned long len; -}; - -struct mm_mprotect { - unsigned long addr; - unsigned long len; - unsigned int prot; -}; - -struct proc_mm_op { - int op; - union { - struct mm_mmap mmap; - struct mm_munmap munmap; - struct mm_mprotect mprotect; - int copy_segments; - } u; -}; - -extern struct mm_struct *proc_mm_get_mm(int fd); - -#endif diff --git a/mm/Makefile b/mm/Makefile index d2ca5bb27..01cd3ded4 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_OOM_KILL) += oom_kill.o obj-$(CONFIG_OOM_PANIC) += oom_panic.o obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o obj-$(CONFIG_HUGETLBFS) += hugetlb.o -obj-$(CONFIG_PROC_MM) += proc_mm.o obj-$(CONFIG_NUMA) += mempolicy.o obj-$(CONFIG_SHMEM) += shmem.o obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o diff --git a/mm/mmap.c b/mm/mmap.c index 9c2e112e4..432fd4946 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -766,11 +766,11 @@ void __vm_stat_account(struct mm_struct *mm, unsigned long flags, * The caller must hold down_write(current->mm->mmap_sem). */ -unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, - unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long pgoff) +unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flags, unsigned long pgoff) { + struct mm_struct * mm = current->mm; struct vm_area_struct * vma, * prev; struct inode *inode; unsigned int vm_flags;