# This patch copies a bunch of cleanups that I made in the process of porting # externfs, hostfs, and humfs to 2.6. # Devices are split into major and minor numbers in the lower-level code, and # put back together in externfs just before vfs sees them. This is necessary # because the host may have a different idea of how a dev_t is organized than # UML does. ubd_user is included here because it uses the uml_stat struct, # and was affected by this change. # inode.u.hostfs_i is no longer used. Instead, a pointer to the externfs # data is hung off inode.u.generic_ip. This data is contained inside the # lower-level data in the 2.6 way, and the lower level module used container-of # to get its own data. # Names were all changed to make sense and to eliminate functions with the # same names in different files. So, externfs names contain "externfs" # rather than "hostfs", and hostfs and humfs names begin with "hostfs" and # "humfs" respectively. # void * data items are now gone. # externfs no longer knows anything about file handles. Those, if present, # are contained in the lower-level data. # Because of the 2.6 split between allocating inodes and initializing them, # when externfs makes a new inode, it calls both the init and open or create # routines in the underlying module. Index: um/arch/um/drivers/ubd_user.c =================================================================== --- um.orig/arch/um/drivers/ubd_user.c 2004-08-09 16:51:46.000000000 -0400 +++ um/arch/um/drivers/ubd_user.c 2004-08-09 16:53:23.000000000 -0400 @@ -44,7 +44,9 @@ printk("Couldn't stat '%s', err = %d\n", from_cow, -err); return(1); } - if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino)) + if((buf1.ust_major == buf2.ust_major) && + (buf1.ust_minor == buf2.ust_minor) && + (buf1.ust_ino == buf2.ust_ino)) return(1); printk("Backing file mismatch - \"%s\" requested,\n" Index: um/arch/um/fs/hostfs/externfs.c =================================================================== --- um.orig/arch/um/fs/hostfs/externfs.c 2004-08-09 16:51:46.000000000 -0400 +++ um/arch/um/fs/hostfs/externfs.c 2004-08-09 16:53:23.000000000 -0400 @@ -22,25 +22,30 @@ struct externfs { struct list_head list; - struct externfs_mount_ops *ops; + struct externfs_mount_ops *mount_ops; struct file_system_type type; }; -#define file_hostfs_i(file) (&(file)->f_dentry->d_inode->u.hostfs_i) +static inline struct externfs_inode *EXTERNFS_I(struct inode *inode) +{ + return(inode->u.generic_ip); +} + +#define file_externfs_i(file) EXTERNFS_I((file)->f_dentry->d_inode) -int hostfs_d_delete(struct dentry *dentry) +int externfs_d_delete(struct dentry *dentry) { return(1); } -struct dentry_operations hostfs_dentry_ops = { +struct dentry_operations externfs_dentry_ops = { }; -#define HOSTFS_SUPER_MAGIC 0x00c0ffee +#define EXTERNFS_SUPER_MAGIC 0x00c0ffee -static struct inode_operations hostfs_iops; -static struct inode_operations hostfs_dir_iops; -static struct address_space_operations hostfs_link_aops; +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) { @@ -96,7 +101,7 @@ static int read_name(struct inode *ino, char *name) { - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; + 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 @@ -107,10 +112,11 @@ unsigned long long i_ino; unsigned long long i_blocks; - err = (*ops->stat_file)(name, ino->i_sb->u.generic_sbp, &i_dev, &i_ino, - &i_mode, &i_nlink, &ino->i_uid, &ino->i_gid, - &i_size, &ino->i_atime, &ino->i_mtime, - &ino->i_ctime, &i_blksize, &i_blocks); + err = (*ops->stat_file)(name, ino->i_sb->u.generic_sbp, + (dev_t *) &i_dev, &i_ino, &i_mode, &i_nlink, + &ino->i_uid, &ino->i_gid, &i_size, + &ino->i_atime, &ino->i_mtime, &ino->i_ctime, + &i_blksize, &i_blocks); if(err) return(err); ino->i_ino = i_ino; ino->i_dev = i_dev; @@ -124,8 +130,9 @@ static char *follow_link(char *link, int (*do_read_link)(char *path, int uid, int gid, - char *buf, int size, void *mount), - int uid, int gid, void *mount) + char *buf, int size, + struct externfs_data *ed), + int uid, int gid, struct externfs_data *ed) { int len, n; char *name, *resolved, *end; @@ -137,7 +144,7 @@ if(name == NULL) goto out; - n = (*do_read_link)(link, uid, gid, name, len, mount); + n = (*do_read_link)(link, uid, gid, name, len, ed); if(n < len) break; len *= 2; @@ -174,8 +181,8 @@ static int read_inode(struct inode *ino) { - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; - void *mount = ino->i_sb->u.generic_sbp; + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; + struct externfs_data *ed = ino->i_sb->u.generic_sbp; char *name, *new; int err, type; @@ -184,7 +191,7 @@ if(name == NULL) goto out; - type = (*ops->file_type)(name, NULL, mount); + type = (*ops->file_type)(name, NULL, ed); if(type < 0){ err = type; goto out_free; @@ -192,7 +199,7 @@ if(type == OS_TYPE_SYMLINK){ new = follow_link(name, ops->read_link, current->fsuid, - current->fsgid, mount); + current->fsgid, ed); if(IS_ERR(new)){ err = PTR_ERR(new); goto out_free; @@ -208,17 +215,17 @@ return(err); } -void hostfs_delete_inode(struct inode *ino) +void externfs_delete_inode(struct inode *ino) { - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; + struct externfs_inode *ext = EXTERNFS_I(ino); + struct externfs_file_ops *ops = ext->ops; - if(ino->u.hostfs_i.fh != NULL) - (*ops->close_file)(ino->u.hostfs_i.fh, ino->i_size); + (*ops->close_file)(ext, ino->i_size); clear_inode(ino); } -int hostfs_statfs(struct super_block *sb, struct statfs *sf) +int externfs_statfs(struct super_block *sb, struct statfs *sf) { /* do_statfs uses struct statfs64 internally, but the linux kernel * struct statfs still has 32-bit versions for most of these fields, @@ -230,15 +237,12 @@ long long f_bavail; long long f_files; long long f_ffree; - struct inode *ino = sb->s_root->d_inode; - void *mount = sb->u.generic_sbp; + struct externfs_data *ed = sb->u.generic_sbp; - err = (*ino->u.hostfs_i.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, - mount); + 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); @@ -247,88 +251,87 @@ sf->f_bavail = f_bavail; sf->f_files = f_files; sf->f_ffree = f_ffree; - sf->f_type = HOSTFS_SUPER_MAGIC; + sf->f_type = EXTERNFS_SUPER_MAGIC; return(0); } -static struct super_operations hostfs_sbops = { - .delete_inode = hostfs_delete_inode, - .statfs = hostfs_statfs, +static struct super_operations externfs_sbops = { + .delete_inode = externfs_delete_inode, + .statfs = externfs_statfs, }; -int hostfs_readdir(struct file *file, void *ent, filldir_t filldir) +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_hostfs_i(file)->ops; - void *mount = file->f_dentry->d_inode->i_sb->u.generic_sbp; + struct externfs_file_ops *ops = file_externfs_i(file)->ops; + struct externfs_data *ed = + file->f_dentry->d_inode->i_sb->u.generic_sbp; name = dentry_name(file->f_dentry, 0); if(name == NULL) return(-ENOMEM); - dir = (*ops->open_dir)(name, current->fsuid, current->fsgid, mount); + 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, - mount)) != NULL){ + 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, mount); + (*ops->close_dir)(dir, ed); return(0); } -int hostfs_file_open(struct inode *ino, struct file *file) +int externfs_file_open(struct inode *ino, struct file *file) { ino->i_nlink++; return(0); } -int hostfs_dir_open(struct inode *ino, struct file *file) +int externfs_dir_open(struct inode *ino, struct file *file) { return(0); } -int hostfs_dir_release(struct inode *ino, struct file *file) +int externfs_dir_release(struct inode *ino, struct file *file) { return(0); } -int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) +int externfs_fsync(struct file *file, struct dentry *dentry, int datasync) { - struct externfs_file_ops *ops = file_hostfs_i(file)->ops; + struct externfs_file_ops *ops = file_externfs_i(file)->ops; struct inode *inode = dentry->d_inode; - void *mount = inode->i_sb->u.generic_sbp; + struct externfs_data *ed = inode->i_sb->u.generic_sbp; - return((*ops->truncate_file)(inode->u.hostfs_i.fh, inode->i_size, - mount)); + return((*ops->truncate_file)(EXTERNFS_I(inode), inode->i_size, ed)); } -static struct file_operations hostfs_file_fops = { +static struct file_operations externfs_file_fops = { .owner = NULL, .read = generic_file_read, .write = generic_file_write, .mmap = generic_file_mmap, - .open = hostfs_file_open, + .open = externfs_file_open, .release = NULL, - .fsync = hostfs_fsync, + .fsync = externfs_fsync, }; -static struct file_operations hostfs_dir_fops = { +static struct file_operations externfs_dir_fops = { .owner = NULL, - .readdir = hostfs_readdir, - .open = hostfs_dir_open, - .release = hostfs_dir_release, - .fsync = hostfs_fsync, + .readdir = externfs_readdir, + .open = externfs_dir_open, + .release = externfs_dir_release, + .fsync = externfs_fsync, }; struct wp_info { @@ -336,19 +339,20 @@ int count; unsigned long long start; unsigned long long size; - int (*truncate)(struct file_handle *fh, __u64 size, void *m); - struct file_handle *fh; - void *mount; + int (*truncate)(struct externfs_inode *ei, __u64 size, + struct externfs_data *ed); + struct externfs_inode *ei; + struct externfs_data *ed; }; -static void hostfs_finish_writepage(char *buffer, int res, void *arg) +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->fh, wp->size, wp->mount); + (*wp->truncate)(wp->ei, wp->size, wp->ed); } else { SetPageError(wp->page); @@ -360,13 +364,13 @@ kfree(wp); } -int hostfs_writepage(struct page *page) +static int externfs_writepage(struct page *page) { struct address_space *mapping = page->mapping; struct inode *inode = mapping->host; - struct externfs_file_ops *ops = inode->u.hostfs_i.ops; + struct externfs_file_ops *ops = EXTERNFS_I(inode)->ops; struct wp_info *wp; - void *mount = inode->i_sb->u.generic_sbp; + struct externfs_data *ed = inode->i_sb->u.generic_sbp; char *buffer; unsigned long long base; int count = PAGE_CACHE_SIZE; @@ -392,12 +396,12 @@ .start = base, .size = inode->i_size, .truncate = ops->truncate_file, - .fh = inode->u.hostfs_i.fh, - .mount = mount }); + .ei = EXTERNFS_I(inode), + .ed = ed }); buffer = kmap(page); - err = (*ops->write_file)(inode->u.hostfs_i.fh, base, buffer, 0, - count, hostfs_finish_writepage, wp, mount); + err = (*ops->write_file)(EXTERNFS_I(inode), base, buffer, 0, + count, externfs_finish_writepage, wp, ed); return err; @@ -406,7 +410,7 @@ return(err); } -static void hostfs_finish_readpage(char *buffer, int res, void *arg) +static void externfs_finish_readpage(char *buffer, int res, void *arg) { struct page *page = arg; struct inode *inode; @@ -431,11 +435,11 @@ unlock_page(page); } -static int hostfs_readpage(struct file *file, struct page *page) +static int externfs_readpage(struct file *file, struct page *page) { struct inode *ino = page->mapping->host; - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; - void *mount = ino->i_sb->u.generic_sbp; + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; + struct externfs_data *ed = ino->i_sb->u.generic_sbp; char *buffer; long long start; int err = 0; @@ -445,15 +449,15 @@ if(ops->map_file_page != NULL){ /* XXX What happens when PAGE_SIZE != PAGE_CACHE_SIZE? */ - err = (*ops->map_file_page)(file_hostfs_i(file)->fh, start, + err = (*ops->map_file_page)(file_externfs_i(file), start, buffer, file->f_mode & FMODE_WRITE, - mount); + ed); if(!err) err = PAGE_CACHE_SIZE; } - else err = (*ops->read_file)(file_hostfs_i(file)->fh, start, buffer, + else err = (*ops->read_file)(file_externfs_i(file), start, buffer, PAGE_CACHE_SIZE, 0, 0, - hostfs_finish_readpage, page, mount); + externfs_finish_readpage, page, ed); if(err > 0) err = 0; @@ -465,7 +469,7 @@ int res; }; -static void hostfs_finish_prepare(char *buffer, int res, void *arg) +static void externfs_finish_prepare(char *buffer, int res, void *arg) { struct writepage_info *wp = arg; @@ -473,13 +477,13 @@ up(&wp->sem); } -int hostfs_prepare_write(struct file *file, struct page *page, +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 = inode->u.hostfs_i.ops; - void *mount = inode->i_sb->u.generic_sbp; + struct externfs_file_ops *ops = EXTERNFS_I(inode)->ops; + struct externfs_data *ed = inode->i_sb->u.generic_sbp; char *buffer; long long start; int err; @@ -492,17 +496,16 @@ buffer = kmap(page); if(ops->map_file_page != NULL){ - err = (*ops->map_file_page)(file_hostfs_i(file)->fh, start, + err = (*ops->map_file_page)(file_externfs_i(file), start, buffer, file->f_mode & FMODE_WRITE, - mount); + ed); goto out; - } init_MUTEX_LOCKED(&wp.sem); - err = (*ops->read_file)(file_hostfs_i(file)->fh, start, buffer, + err = (*ops->read_file)(file_externfs_i(file), start, buffer, PAGE_CACHE_SIZE, from, to, - hostfs_finish_prepare, &wp, mount); + externfs_finish_prepare, &wp, ed); down(&wp.sem); if(err < 0) goto out; @@ -523,12 +526,12 @@ return(err); } -static int hostfs_commit_write(struct file *file, struct page *page, +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 = inode->u.hostfs_i.ops; + struct externfs_file_ops *ops = EXTERNFS_I(inode)->ops; unsigned long long size; long long start; int err; @@ -549,36 +552,34 @@ return(to - from); } -static void hostfs_removepage(struct page *page) +static void externfs_removepage(struct page *page) { physmem_remove_mapping(page_address(page)); } -static struct address_space_operations hostfs_aops = { - .writepage = hostfs_writepage, - .readpage = hostfs_readpage, - .removepage = hostfs_removepage, +static struct address_space_operations externfs_aops = { + .writepage = externfs_writepage, + .readpage = externfs_readpage, + .removepage = externfs_removepage, /* .set_page_dirty = __set_page_dirty_nobuffers, */ - .prepare_write = hostfs_prepare_write, - .commit_write = hostfs_commit_write + .prepare_write = externfs_prepare_write, + .commit_write = externfs_commit_write }; -static struct externfs *find_externfs(struct file_system_type *type); - static struct inode *get_inode(struct super_block *sb, struct dentry *dentry, - struct externfs_file_ops *ops, int need_fh) + int need_fh) { struct inode *inode; - void *mount = sb->u.generic_sbp; + struct externfs_data *ed = sb->u.generic_sbp; + struct externfs_mount_ops *ops = ed->mount_ops; char *name = NULL; int type, err = -ENOMEM, rdev; - struct file_handle *fh; if(dentry){ name = dentry_name(dentry, 0); if(name == NULL) goto out; - type = (*ops->file_type)(name, &rdev, mount); + type = (*ed->file_ops->file_type)(name, &rdev, ed); } else type = OS_TYPE_DIR; @@ -586,21 +587,20 @@ if(inode == NULL) goto out_free; - inode->u.hostfs_i.ops = ops; insert_inode_hash(inode); if(type == OS_TYPE_SYMLINK) inode->i_op = &page_symlink_inode_operations; else if(type == OS_TYPE_DIR) - inode->i_op = &hostfs_dir_iops; - else inode->i_op = &hostfs_iops; + inode->i_op = &externfs_dir_iops; + else inode->i_op = &externfs_iops; - if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops; - else inode->i_fop = &hostfs_file_fops; + 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 = &hostfs_link_aops; - else inode->i_mapping->a_ops = &hostfs_aops; + inode->i_mapping->a_ops = &externfs_link_aops; + else inode->i_mapping->a_ops = &externfs_aops; switch (type) { case OS_TYPE_CHARDEV: @@ -620,15 +620,20 @@ } if(need_fh){ - fh = (*ops->init_file)(name, current->fsuid, current->fsgid, - inode, mount); - if(IS_ERR(fh)){ - err = PTR_ERR(fh); - if(err == -ENOENT) - fh = NULL; - else goto out_put; - } - inode->u.hostfs_i.fh = fh; + struct externfs_inode *ei; + + err = -ENOMEM; + ei = (*ops->init_file)(ed); + if(ei == NULL) + goto out_put; + + *ei = ((struct externfs_inode) { .ops = ed->file_ops }); + inode->u.generic_ip = ei; + + err = (*ed->file_ops->open_file)(ei, name, current->fsuid, + current->fsgid, inode, ed); + if(err && ((err != -ENOENT) && (err != -EISDIR))) + goto out_put; } return(inode); @@ -641,38 +646,43 @@ return(ERR_PTR(err)); } -int hostfs_create(struct inode *dir, struct dentry *dentry, int mode) +int externfs_create(struct inode *dir, struct dentry *dentry, int mode) { - struct externfs_file_ops *ops = dir->u.hostfs_i.ops; + struct externfs_file_ops *ops = EXTERNFS_I(dir)->ops; struct inode *inode; - void *mount = dir->i_sb->u.generic_sbp; + struct externfs_data *ed = dir->i_sb->u.generic_sbp; + struct externfs_inode *ei; char *name; int err = -ENOMEM; - struct file_handle *fh; name = dentry_name(dentry, 0); if(name == NULL) goto out; - inode = get_inode(dir->i_sb, dentry, ops, 0); + inode = get_inode(dir->i_sb, dentry, 0); if(IS_ERR(inode)){ err = PTR_ERR(inode); goto out_free; } - fh = (*ops->create_file)(name, mode, current->fsuid, current->fsuid, - inode, mount); - if(IS_ERR(fh)){ - err = PTR_ERR(fh); + ei = (*ed->mount_ops->init_file)(ed); + if(ei == NULL) + /* XXX need a free_file() */ + goto out_put; + + *ei = ((struct externfs_inode) { .ops = ed->file_ops }); + inode->u.generic_ip = ei; + + err = (*ops->create_file)(ei, name, mode, current->fsuid, + current->fsuid, inode, ed); + if(err) goto out_put; - } err = read_name(inode, name); if(err) goto out_rm; inode->i_nlink++; - inode->u.hostfs_i.fh = fh; d_instantiate(dentry, inode); out_free: kfree(name); @@ -680,21 +690,20 @@ return(err); out_rm: - (*ops->unlink_file)(name, mount); + (*ops->unlink_file)(name, ed); out_put: inode->i_nlink = 0; iput(inode); goto out_free; } -struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry) +struct dentry *externfs_lookup(struct inode *ino, struct dentry *dentry) { struct inode *inode; - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; char *name; int err; - inode = get_inode(ino->i_sb, dentry, ops, 1); + inode = get_inode(ino->i_sb, dentry, 1); if(IS_ERR(inode)){ err = PTR_ERR(inode); goto out; @@ -716,7 +725,7 @@ inode = NULL; } d_add(dentry, inode); - dentry->d_op = &hostfs_dentry_ops; + dentry->d_op = &externfs_dentry_ops; return(NULL); out_put: @@ -740,10 +749,10 @@ return(file); } -int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from) +int externfs_link(struct dentry *to, struct inode *ino, struct dentry *from) { - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; - void *mount = ino->i_sb->u.generic_sbp; + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; + struct externfs_data *ed = ino->i_sb->u.generic_sbp; char *from_name, *to_name; int err = -ENOMEM; @@ -756,7 +765,7 @@ goto out_free_from; err = (*ops->link_file)(to_name, from_name, current->fsuid, - current->fsgid, mount); + current->fsgid, ed); if(err) goto out_free_to; @@ -772,11 +781,11 @@ return(err); } -int hostfs_unlink(struct inode *ino, struct dentry *dentry) +int externfs_unlink(struct inode *ino, struct dentry *dentry) { struct inode *inode; - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; - void *mount = ino->i_sb->u.generic_sbp; + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; + struct externfs_data *ed = ino->i_sb->u.generic_sbp; char *file; int err; @@ -785,11 +794,10 @@ return(-ENOMEM); inode = dentry->d_inode; - if((inode->i_nlink == 1) && (ops->invisible != NULL) && - (inode->u.hostfs_i.fh != NULL)) - (*ops->invisible)(inode->u.hostfs_i.fh); + if((inode->i_nlink == 1) && (ops->invisible != NULL)) + (*ops->invisible)(EXTERNFS_I(inode)); - err = (*ops->unlink_file)(file, mount); + err = (*ops->unlink_file)(file, ed); kfree(file); inode->i_nlink--; @@ -797,11 +805,11 @@ return(err); } -int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to) +int externfs_symlink(struct inode *ino, struct dentry *dentry, const char *to) { - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; + struct externfs_data *ed = ino->i_sb->u.generic_sbp; struct inode *inode; - void *mount = ino->i_sb->u.generic_sbp; char *file; int err; @@ -809,10 +817,10 @@ if(file == NULL) return(-ENOMEM); err = (*ops->make_symlink)(file, to, current->fsuid, current->fsgid, - mount); + ed); kfree(file); - inode = get_inode(ino->i_sb, dentry, ops, 1); + inode = get_inode(ino->i_sb, dentry, 1); if(IS_ERR(inode)){ err = PTR_ERR(inode); goto out; @@ -825,21 +833,20 @@ return(err); } -int hostfs_make_dir(struct inode *ino, struct dentry *dentry, int mode) +int externfs_make_dir(struct inode *ino, struct dentry *dentry, int mode) { - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; + struct externfs_data *ed = ino->i_sb->u.generic_sbp; struct inode *inode; - void *mount = ino->i_sb->u.generic_sbp; char *file; int err; file = inode_dentry_name(ino, dentry); if(file == NULL) return(-ENOMEM); - err = (*ops->make_dir)(file, mode, current->fsuid, current->fsgid, - mount); + err = (*ops->make_dir)(file, mode, current->fsuid, current->fsgid, ed); - inode = get_inode(ino->i_sb, dentry, ops, 1); + inode = get_inode(ino->i_sb, dentry, 1); if(IS_ERR(inode)){ err = PTR_ERR(inode); goto out_free; @@ -866,9 +873,9 @@ goto out; } -int hostfs_remove_dir(struct inode *ino, struct dentry *dentry) +int externfs_remove_dir(struct inode *ino, struct dentry *dentry) { - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; void *mount = ino->i_sb->u.generic_sbp; char *file; int err; @@ -884,11 +891,11 @@ return(err); } -int hostfs_make_node(struct inode *dir, struct dentry *dentry, int mode, +int externfs_make_node(struct inode *dir, struct dentry *dentry, int mode, int dev) { - struct externfs_file_ops *ops = dir->u.hostfs_i.ops; - void *mount = dir->i_sb->u.generic_sbp; + struct externfs_file_ops *ops = EXTERNFS_I(dir)->ops; + struct externfs_data *ed = dir->i_sb->u.generic_sbp; struct inode *inode; char *name; int err = -ENOMEM; @@ -897,7 +904,7 @@ if(name == NULL) goto out; - inode = get_inode(dir->i_sb, dentry, ops, 1); + inode = get_inode(dir->i_sb, dentry, 1); if(IS_ERR(inode)){ err = PTR_ERR(inode); goto out_free; @@ -906,7 +913,7 @@ 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), mount); + minor(dev), ed); if(err) goto out_put; @@ -921,18 +928,18 @@ return(err); out_rm: - (*ops->unlink_file)(name, mount); + (*ops->unlink_file)(name, ed); out_put: inode->i_nlink = 0; iput(inode); goto out_free; } -int hostfs_rename(struct inode *from_ino, struct dentry *from, +int externfs_rename(struct inode *from_ino, struct dentry *from, struct inode *to_ino, struct dentry *to) { - struct externfs_file_ops *ops = from_ino->u.hostfs_i.ops; - void *mount = from_ino->i_sb->u.generic_sbp; + struct externfs_file_ops *ops = EXTERNFS_I(from_ino)->ops; + struct externfs_data *ed = from_ino->i_sb->u.generic_sbp; char *from_name, *to_name; int err; @@ -944,7 +951,7 @@ kfree(from_name); return(-ENOMEM); } - err = (*ops->rename_file)(from_name, to_name, mount); + err = (*ops->rename_file)(from_name, to_name, ed); kfree(from_name); kfree(to_name); @@ -953,18 +960,18 @@ return(err); } -void hostfs_truncate(struct inode *ino) +void externfs_truncate(struct inode *ino) { - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; - void *mount = ino->i_sb->u.generic_sbp; + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; + struct externfs_data *ed = ino->i_sb->u.generic_sbp; - (*ops->truncate_file)(ino->u.hostfs_i.fh, ino->i_size, mount); + (*ops->truncate_file)(EXTERNFS_I(ino), ino->i_size, ed); } -int hostfs_permission(struct inode *ino, int desired) +int externfs_permission(struct inode *ino, int desired) { - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; - void *mount = ino->i_sb->u.generic_sbp; + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; + struct externfs_data *ed = ino->i_sb->u.generic_sbp; char *name; int r = 0, w = 0, x = 0, err; @@ -978,8 +985,8 @@ if(name == NULL) return(-ENOMEM); - err = (*ops->access_file)(name, r, w, x, current->fsuid, current->fsgid, - mount); + err = (*ops->access_file)(name, r, w, x, current->fsuid, + current->fsgid, ed); kfree(name); if(!err) @@ -987,53 +994,53 @@ return(err); } -int hostfs_setattr(struct dentry *dentry, struct iattr *attr) +int externfs_setattr(struct dentry *dentry, struct iattr *attr) { - struct externfs_file_ops *ops = dentry->d_inode->u.hostfs_i.ops; - void *mount = dentry->d_inode->i_sb->u.generic_sbp; - struct hostfs_iattr attrs; + struct externfs_file_ops *ops = EXTERNFS_I(dentry->d_inode)->ops; + struct externfs_data *ed = dentry->d_inode->i_sb->u.generic_sbp; + struct externfs_iattr attrs; char *name; int err; attrs.ia_valid = 0; if(attr->ia_valid & ATTR_MODE){ - attrs.ia_valid |= HOSTFS_ATTR_MODE; + attrs.ia_valid |= EXTERNFS_ATTR_MODE; attrs.ia_mode = attr->ia_mode; } if(attr->ia_valid & ATTR_UID){ - attrs.ia_valid |= HOSTFS_ATTR_UID; + attrs.ia_valid |= EXTERNFS_ATTR_UID; attrs.ia_uid = attr->ia_uid; } if(attr->ia_valid & ATTR_GID){ - attrs.ia_valid |= HOSTFS_ATTR_GID; + attrs.ia_valid |= EXTERNFS_ATTR_GID; attrs.ia_gid = attr->ia_gid; } if(attr->ia_valid & ATTR_SIZE){ - attrs.ia_valid |= HOSTFS_ATTR_SIZE; + attrs.ia_valid |= EXTERNFS_ATTR_SIZE; attrs.ia_size = attr->ia_size; } if(attr->ia_valid & ATTR_ATIME){ - attrs.ia_valid |= HOSTFS_ATTR_ATIME; + attrs.ia_valid |= EXTERNFS_ATTR_ATIME; attrs.ia_atime = attr->ia_atime; } if(attr->ia_valid & ATTR_MTIME){ - attrs.ia_valid |= HOSTFS_ATTR_MTIME; + attrs.ia_valid |= EXTERNFS_ATTR_MTIME; attrs.ia_mtime = attr->ia_mtime; } if(attr->ia_valid & ATTR_CTIME){ - attrs.ia_valid |= HOSTFS_ATTR_CTIME; + attrs.ia_valid |= EXTERNFS_ATTR_CTIME; attrs.ia_ctime = attr->ia_ctime; } if(attr->ia_valid & ATTR_ATIME_SET){ - attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET; + attrs.ia_valid |= EXTERNFS_ATTR_ATIME_SET; } if(attr->ia_valid & ATTR_MTIME_SET){ - attrs.ia_valid |= HOSTFS_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, mount); + err = (*ops->set_attr)(name, &attrs, ed); kfree(name); if(err) return(err); @@ -1041,48 +1048,48 @@ return(inode_setattr(dentry->d_inode, attr)); } -int hostfs_getattr(struct dentry *dentry, struct iattr *attr) +int externfs_getattr(struct dentry *dentry, struct iattr *attr) { not_implemented(); return(-EINVAL); } -static struct inode_operations hostfs_iops = { - .create = hostfs_create, - .link = hostfs_link, - .unlink = hostfs_unlink, - .symlink = hostfs_symlink, - .mkdir = hostfs_make_dir, - .rmdir = hostfs_remove_dir, - .mknod = hostfs_make_node, - .rename = hostfs_rename, - .truncate = hostfs_truncate, - .permission = hostfs_permission, - .setattr = hostfs_setattr, - .getattr = hostfs_getattr, +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 hostfs_dir_iops = { - .create = hostfs_create, - .lookup = hostfs_lookup, - .link = hostfs_link, - .unlink = hostfs_unlink, - .symlink = hostfs_symlink, - .mkdir = hostfs_make_dir, - .rmdir = hostfs_remove_dir, - .mknod = hostfs_make_node, - .rename = hostfs_rename, - .truncate = hostfs_truncate, - .permission = hostfs_permission, - .setattr = hostfs_setattr, - .getattr = hostfs_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 hostfs_link_readpage(struct file *file, struct page *page) +int externfs_link_readpage(struct file *file, struct page *page) { struct inode *ino = page->mapping->host; - struct externfs_file_ops *ops = ino->u.hostfs_i.ops; - void *mount = ino->i_sb->u.generic_sbp; + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops; + struct externfs_data *ed = ino->i_sb->u.generic_sbp; char *buffer, *name; long long start; int err; @@ -1094,7 +1101,7 @@ return(-ENOMEM); err = (*ops->read_link)(name, current->fsuid, current->fsgid, buffer, - PAGE_CACHE_SIZE, mount); + PAGE_CACHE_SIZE, ed); kfree(name); if(err == PAGE_CACHE_SIZE) @@ -1110,15 +1117,20 @@ return(err); } -static int hostfs_flushpage(struct page *page, unsigned long offset) +static int externfs_flushpage(struct page *page, unsigned long offset) +{ + return(externfs_writepage(page)); +} + +struct externfs_data *inode_externfs_info(struct inode *inode) { - return(hostfs_writepage(page)); + return(inode->i_sb->u.generic_sbp); } -static struct address_space_operations hostfs_link_aops = { - .readpage = hostfs_link_readpage, - .removepage = hostfs_removepage, - .flushpage = hostfs_flushpage, +static struct address_space_operations externfs_link_aops = { + .readpage = externfs_link_readpage, + .removepage = externfs_removepage, + .flushpage = externfs_flushpage, }; DECLARE_MUTEX(externfs_sem); @@ -1153,17 +1165,18 @@ return(uml_strdup(root)); } -struct super_block *hostfs_read_super(struct super_block *sb, void *data, - int silent) +struct super_block *externfs_read_super(struct super_block *sb, void *data, + int silent) { struct externfs *fs; struct inode *root_inode; - struct externfs_file_ops *file_ops; + struct externfs_data *sb_data; + int err = -EINVAL; sb->s_blocksize = 1024; sb->s_blocksize_bits = 10; - sb->s_magic = HOSTFS_SUPER_MAGIC; - sb->s_op = &hostfs_sbops; + sb->s_magic = EXTERNFS_SUPER_MAGIC; + sb->s_op = &externfs_sbops; fs = find_externfs(sb->s_type); if(fs == NULL){ @@ -1172,16 +1185,19 @@ goto out; } - file_ops = (*fs->ops->mount)(data, &sb->u.generic_sbp); - if(file_ops == NULL) + sb_data = (*fs->mount_ops->mount)(data); + if(IS_ERR(sb_data)){ + err = PTR_ERR(sb_data); goto out; + } + + sb->u.generic_sbp = sb_data; + sb_data->mount_ops = fs->mount_ops; - root_inode = get_inode(sb, NULL, file_ops, 1); + root_inode = get_inode(sb, NULL, 1); if(IS_ERR(root_inode)) goto out; - root_inode->u.hostfs_i.ops = file_ops; - sb->s_root = d_alloc_root(root_inode); if(sb->s_root == NULL) goto out_put; @@ -1202,7 +1218,12 @@ return(NULL); } -int register_externfs(char *name, struct externfs_mount_ops *ops) +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; @@ -1213,9 +1234,9 @@ memset(new, 0, sizeof(*new)); *new = ((struct externfs) { .list = LIST_HEAD_INIT(new->list), - .ops = ops, + .mount_ops = mount_ops, .type = { .name = name, - .read_super = hostfs_read_super, + .read_super = externfs_read_super, .fs_flags = 0, .owner = THIS_MODULE } }); list_add(&new->list, &externfses); Index: um/arch/um/fs/hostfs/host_file.c =================================================================== --- um.orig/arch/um/fs/hostfs/host_file.c 2004-08-09 16:51:46.000000000 -0400 +++ um/arch/um/fs/hostfs/host_file.c 2004-08-10 13:42:03.000000000 -0400 @@ -8,29 +8,12 @@ #include "linux/errno.h" #include "linux/types.h" #include "linux/slab.h" +#include "linux/blkdev.h" #include "asm/fcntl.h" #include "hostfs.h" extern int append; -int host_get_mode(int ur, int uw, int ux, int gr, int gw, int gx, - int or, int ow, int ox) -{ - int mode = 0; - - mode |= ur ? S_IRUSR : 0; - mode |= uw ? S_IWUSR : 0; - mode |= ux ? S_IXUSR : 0; - mode |= gr ? S_IRGRP : 0; - mode |= gw ? S_IWGRP : 0; - mode |= gx ? S_IXGRP : 0; - mode |= or ? S_IROTH : 0; - mode |= ow ? S_IWOTH : 0; - mode |= ox ? S_IXOTH : 0; - - return mode; -} - char *get_path(const char *path[], char *buf, int size) { const char **s; @@ -129,11 +112,6 @@ return(name); } -void host_close_dir(void *stream) -{ - os_close_dir(stream); -} - int host_file_type(const char *path[], int *rdev) { char tmp[HOSTFS_BUFSIZE], *file; @@ -149,7 +127,7 @@ ret = os_lstat_file(file, &buf); if(ret) goto out; - *rdev = buf.ust_rdev; + *rdev = MKDEV(buf.ust_rmajor, buf.ust_rminor); } ret = os_file_type(file); @@ -173,7 +151,7 @@ return(err); } -static int do_stat_file(const char *path, int *dev_out, +static int do_stat_file(const char *path, 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, @@ -187,8 +165,7 @@ if(err < 0) return(err); - if(dev_out != NULL) *dev_out = buf.ust_dev; - + 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; @@ -204,7 +181,7 @@ return(0); } -int host_stat_file(const char *path[], int *dev_out, +int host_stat_file(const char *path[], 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, @@ -227,13 +204,13 @@ return(err); } -int host_set_attr(const char *path[], struct hostfs_iattr *attrs) +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 & HOSTFS_ATTR_SIZE)) + if(append && (attrs->ia_valid & EXTERNFS_ATTR_SIZE)) return(-EPERM); err = -ENOMEM; @@ -241,34 +218,34 @@ if(file == NULL) goto out; - if(attrs->ia_valid & HOSTFS_ATTR_MODE){ + 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 & HOSTFS_ATTR_UID){ + 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 & HOSTFS_ATTR_GID){ + 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 & HOSTFS_ATTR_SIZE){ + if(attrs->ia_valid & EXTERNFS_ATTR_SIZE){ err = os_truncate_file(file, attrs->ia_size); if(err < 0) goto out; } - ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET; + 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 & HOSTFS_ATTR_ATIME_SET){ + 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); @@ -279,7 +256,7 @@ if(err) goto out; } - if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){ + 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); @@ -291,8 +268,8 @@ goto out; } } - if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ; - if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){ + 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); @@ -447,11 +424,6 @@ return(host_read_dir(stream, pos, ino_out, len_out)); } -void generic_host_close_dir(void *stream, void *mount) -{ - return(host_close_dir(stream)); -} - int generic_host_truncate_file(struct file_handle *fh, __u64 size, void *m) { return(truncate_file(fh, size)); Index: um/arch/um/fs/hostfs/host_fs.c =================================================================== --- um.orig/arch/um/fs/hostfs/host_fs.c 2004-08-09 16:51:46.000000000 -0400 +++ um/arch/um/fs/hostfs/host_fs.c 2004-08-09 16:53:23.000000000 -0400 @@ -15,6 +15,8 @@ #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 = "/"; @@ -57,9 +59,20 @@ " files opened by hostfs will be opened in append mode.\n\n" ); -static int access_file(char *file, int uid, int gid, int r, int w, int x, - void *mount) +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 r, int w, int x, 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 }; char tmp[HOSTFS_BUFSIZE]; int err, mode = 0; @@ -79,9 +92,11 @@ return(err); } -static int make_node(const char *file, int mode, int uid, int gid, int type, - int major, int minor, void *mount) +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; @@ -99,16 +114,18 @@ return(err); } -static int stat_file(const char *file, void *mount, 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) +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, @@ -116,75 +133,99 @@ ctime_out, blksize_out, blocks_out)); } -static int file_type(const char *file, int *rdev, void *mount) +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)); } -char *hostfs_name(struct inode *inode) +static char *hostfs_name(struct inode *inode) { - char *mount = inode->i_sb->u.generic_sbp; + 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 file_handle *hostfs_init_file(char *file, int uid, int gid, - struct inode *inode, void *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 }; - struct file_handle *fh; int err; - err = -ENOMEM; - fh = kmalloc(sizeof(*fh), GFP_KERNEL); - if(fh == NULL) + err = host_open_file(path, 1, 1, &hf->fh); + if(err == -EISDIR) goto out; - err = host_open_file(path, 1, 1, fh); - if(err == -EISDIR){ - kfree(fh); - return(NULL); - } if(err == -EACCES) - err = host_open_file(path, 1, 0, fh); + err = host_open_file(path, 1, 0, &hf->fh); if(err) - goto out_free; - - is_reclaimable(fh, hostfs_name, inode); - return(fh); + goto out; - out_free: - kfree(fh); + is_reclaimable(&hf->fh, hostfs_name, inode); out: - return(ERR_PTR(err)); + return(err); } -static void *hostfs_open_dir(char *file, int uid, int gid, void *mount) +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 int hostfs_read_file(struct file_handle *fh, unsigned long long offset, - char *buf, int len, int ignore_start, - int ignore_end, +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, - void *mount) + 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(fh, offset, buf, ignore_start); + err = read_file(&hf->fh, offset, buf, ignore_start); if(err < 0) goto out; } if(ignore_end != len) - err = read_file(fh, offset + ignore_end, buf + ignore_end, + err = read_file(&hf->fh, offset + ignore_end, buf + ignore_end, len - ignore_end); out: @@ -195,13 +236,16 @@ return(err); } -static int hostfs_write_file(struct file_handle *fh, unsigned long long offset, - const char *buf, int start, int len, +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, void *mount) + 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); @@ -211,99 +255,104 @@ return(err); } -static struct file_handle *hostfs_create_file(char *file, int mode, int uid, - int gid, struct inode *inode, - void *mount) -{ - struct file_handle *fh; +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; - fh = kmalloc(sizeof(*fh), GFP_KERNEL); - if(fh == NULL) - goto out; - - err = host_create_file(path, mode, fh); + err = host_create_file(path, mode, &hf->fh); if(err) - goto out_free; - - is_reclaimable(fh, hostfs_name, inode); - return(fh); + goto out; - out_free: - kfree(fh); + is_reclaimable(&hf->fh, hostfs_name, inode); out: - return(ERR_PTR(err)); + return(err); } -static int set_attr(const char *file, struct hostfs_iattr *attrs, - void *mount) +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 make_symlink(const char *from, const char *to, int uid, int gid, - void *mount) +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 link_file(const char *to, const char *from, int uid, int gid, - void *mount) +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 unlink_file(const char *file, void *mount) +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 make_dir(const char *file, int mode, int uid, int gid, void *mount) +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 remove_dir(const char *file, int uid, int gid, void *mount) +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 read_link(char *file, int uid, int gid, char *buf, int size, - void *mount) +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 rename_file(char *from, char *to, void *mount) +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 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, void *mount) +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, @@ -311,53 +360,77 @@ namelen_out, spare_out)); } -void hostfs_close_file(struct file_handle *fh, unsigned long long size) +static void hostfs_close_file(struct externfs_inode *ext, + unsigned long long size) { - close_file(fh); + struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext); + + if(hf->fh.fd == -1) + return; + + truncate_file(&hf->fh, size); + close_file(&hf->fh); +} + +static 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 = stat_file, - .file_type = file_type, - .access_file = access_file, - .init_file = hostfs_init_file, + .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 = generic_host_read_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 = generic_host_close_dir, + .close_dir = hostfs_close_dir, .invisible = NULL, .create_file = hostfs_create_file, - .set_attr = set_attr, - .make_symlink = make_symlink, - .unlink_file = unlink_file, - .make_dir = make_dir, - .remove_dir = remove_dir, - .make_node = make_node, - .link_file = link_file, - .read_link = read_link, - .rename_file = rename_file, - .statfs = stat_fs, - .truncate_file = generic_host_truncate_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_file_ops *mount_fs(char *mount_arg, - void **mount_data_out) +static struct externfs_data *mount_fs(char *mount_arg) { - char *root; + struct hostfs_data *hd; + int err = -ENOMEM; - root = host_root_filename(mount_arg); - if(root == NULL) - return(NULL); + hd = kmalloc(sizeof(*hd), GFP_KERNEL); + if(hd == NULL) + goto out; - *mount_data_out = root; + hd->mount = host_root_filename(mount_arg); + if(hd->mount == NULL) + goto out_free; + + init_externfs(&hd->ext, &hostfs_file_ops); - return(&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, }; Index: um/arch/um/fs/hostfs/hostfs.h =================================================================== --- um.orig/arch/um/fs/hostfs/hostfs.h 2004-08-09 16:51:46.000000000 -0400 +++ um/arch/um/fs/hostfs/hostfs.h 2004-08-10 13:40:12.000000000 -0400 @@ -7,6 +7,7 @@ #define __UM_FS_HOSTFS #include "linux/fs.h" +#include "linux/blkdev.h" #include "filehandle.h" #include "os.h" @@ -14,19 +15,31 @@ * changed so that this file can be included in both kernel and user files. */ -#define HOSTFS_ATTR_MODE 1 -#define HOSTFS_ATTR_UID 2 -#define HOSTFS_ATTR_GID 4 -#define HOSTFS_ATTR_SIZE 8 -#define HOSTFS_ATTR_ATIME 16 -#define HOSTFS_ATTR_MTIME 32 -#define HOSTFS_ATTR_CTIME 64 -#define HOSTFS_ATTR_ATIME_SET 128 -#define HOSTFS_ATTR_MTIME_SET 256 -#define HOSTFS_ATTR_FORCE 512 /* Not a change, but a change it */ -#define HOSTFS_ATTR_ATTR_FLAG 1024 +#define EXTERNFS_ATTR_MODE 1 +#define EXTERNFS_ATTR_UID 2 +#define EXTERNFS_ATTR_GID 4 +#define EXTERNFS_ATTR_SIZE 8 +#define EXTERNFS_ATTR_ATIME 16 +#define EXTERNFS_ATTR_MTIME 32 +#define EXTERNFS_ATTR_CTIME 64 +#define EXTERNFS_ATTR_ATIME_SET 128 +#define EXTERNFS_ATTR_MTIME_SET 256 +#define EXTERNFS_ATTR_FORCE 512 /* Not a change, but a change it */ +#define EXTERNFS_ATTR_ATTR_FLAG 1024 + +/** + * container_of - cast a member of a structure out to the containing structure + * + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) -struct hostfs_iattr { +struct externfs_iattr { unsigned int ia_valid; mode_t ia_mode; uid_t ia_uid; @@ -38,75 +51,94 @@ unsigned int ia_attr_flags; }; +struct externfs_data { + struct externfs_file_ops *file_ops; + struct externfs_mount_ops *mount_ops; +}; + +struct externfs_inode { + struct externfs_file_ops *ops; +}; + +struct externfs_mount_ops { + struct externfs_data *(*mount)(char *mount_arg); + struct externfs_inode *(*init_file)(struct externfs_data *ed); +}; + struct externfs_file_ops { - int (*stat_file)(const char *path, void *mount, 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, + int (*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); - int (*file_type)(const char *path, int *rdev, void *mount); - int (*access_file)(char *path, int uid, int gid, int r, int w, int x, - void *mount); - struct file_handle *(*init_file)(char *path, int uid, int gid, - struct inode *inode, void *mount); - void *(*open_dir)(char *path, int uid, int gid, void *mount); + int (*file_type)(const char *path, int *rdev, + struct externfs_data *ed); + int (*access_file)(char *path, int r, int w, int x, int uid, int gid, + struct externfs_data *ed); + int (*open_file)(struct externfs_inode *ext, char *file, + int uid, int gid, struct inode *inode, + struct externfs_data *ed); + void (*close_file)(struct externfs_inode *ext, + unsigned long long size); + void *(*open_dir)(char *path, int uid, int gid, + struct externfs_data *ed); char *(*read_dir)(void *stream, unsigned long long *pos, unsigned long long *ino_out, int *len_out, - void *mount); - int (*read_file)(struct file_handle *fh, unsigned long long offset, - char *buf, int len, int ignore_start, int ignore_end, + struct externfs_data *ed); + int (*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, - void *mount); - int (*write_file)(struct file_handle *fh, unsigned long long offset, - const char *buf, int start, int len, + struct externfs_data *ed); + int (*write_file)(struct externfs_inode *ext, + unsigned long long offset, const char *buf, + int start, int len, void (*completion)(char *, int, void *), void *arg, - void *mount); - int (*map_file_page)(struct file_handle *fh, unsigned long long offset, - char *buf, int w, void *mount); - void (*close_file)(struct file_handle *fh, unsigned long long size); - void (*close_dir)(void *stream, void *mount); - void (*invisible)(struct file_handle *f); - struct file_handle *(*create_file)(char *path, int mode, int uid, - int gid, struct inode *inode, - void *mount); - int (*set_attr)(const char *path, struct hostfs_iattr *attrs, - void *mount); + struct externfs_data *ed); + int (*map_file_page)(struct externfs_inode *ext, + unsigned long long offset, char *buf, int w, + struct externfs_data *ed); + void (*close_dir)(void *stream, struct externfs_data *ed); + void (*invisible)(struct externfs_inode *ext); + int (*create_file)(struct externfs_inode *ext, char *path, + int mode, int uid, int gid, struct inode *inode, + struct externfs_data *ed); + int (*set_attr)(const char *path, struct externfs_iattr *attrs, + struct externfs_data *ed); int (*make_symlink)(const char *from, const char *to, int uid, int gid, - void *mount); - int (*unlink_file)(const char *path, void *mount); + struct externfs_data *ed); + int (*unlink_file)(const char *path, struct externfs_data *ed); int (*make_dir)(const char *path, int mode, int uid, int gid, - void *mount); - int (*remove_dir)(const char *path, int uid, int gid, void *mount); + struct externfs_data *ed); + int (*remove_dir)(const char *path, int uid, int gid, + struct externfs_data *ed); int (*make_node)(const char *path, int mode, int uid, int gid, - int type, int maj, int min, void *mount); + int type, int maj, int min, struct externfs_data *ed); int (*link_file)(const char *to, const char *from, int uid, int gid, - void *mount); + struct externfs_data *ed); int (*read_link)(char *path, int uid, int gid, char *buf, int size, - void *mount); - int (*rename_file)(char *from, char *to, void *mount); + struct externfs_data *ed); + int (*rename_file)(char *from, char *to, struct externfs_data *ed); int (*statfs)(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, void *mount); - int (*truncate_file)(struct file_handle *fh, __u64 size, void *m); -}; - -struct externfs_mount_ops { - struct externfs_file_ops *(*mount)(char *mount_arg, - void **mount_data_out); + long *spare_out, struct externfs_data *ed); + int (*truncate_file)(struct externfs_inode *ext, __u64 size, + struct externfs_data *ed); }; #define HOSTFS_BUFSIZE 64 -extern int register_externfs(char *name, struct externfs_mount_ops *ops); +extern int register_externfs(char *name, struct externfs_mount_ops *mount_ops); extern void unregister_externfs(char *name); +extern void init_externfs(struct externfs_data *ed, + struct externfs_file_ops *ops); +struct externfs_data *inode_externfs_info(struct inode *inode); extern char *generic_root_filename(char *mount_arg); -extern int host_get_mode(int ur, int uw, int ux, int gr, int gw, int gx, - int or, int ow, int ox); extern void host_close_file(void *stream); extern int host_read_file(int fd, unsigned long long offset, char *buf, int len); @@ -115,14 +147,13 @@ extern void *host_open_dir(const char *path[]); extern char *host_read_dir(void *stream, unsigned long long *pos, unsigned long long *ino_out, int *len_out); -extern void host_close_dir(void *stream); extern int host_file_type(const char *path[], int *rdev); extern char *host_root_filename(char *mount_arg); extern char *get_path(const char *path[], char *buf, int size); extern void free_path(const char *buf, char *tmp); extern int host_create_file(const char *path[], int mode, struct file_handle *fh); -extern int host_set_attr(const char *path[], struct hostfs_iattr *attrs); +extern int host_set_attr(const char *path[], struct externfs_iattr *attrs); extern int host_make_symlink(const char *from[], const char *to); extern int host_unlink_file(const char *path[]); extern int host_make_dir(const char *path[], int mode); @@ -135,7 +166,7 @@ long long *bavail_out, long long *files_out, long long *ffree_out, void *fsid_out, int fsid_size, long *namelen_out, long *spare_out); -extern int host_stat_file(const char *path[], int *dev_out, +extern int host_stat_file(const char *path[], 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, @@ -150,7 +181,6 @@ int len, void *mount); extern void generic_host_close_file(void *stream, unsigned long long size, void *mount); -extern void generic_host_close_dir(void *stream, void *mount); extern int generic_host_truncate_file(struct file_handle *fh, __u64 size, void *m); Index: um/arch/um/fs/hostfs/humfs.c =================================================================== --- um.orig/arch/um/fs/hostfs/humfs.c 2004-08-09 16:51:46.000000000 -0400 +++ um/arch/um/fs/hostfs/humfs.c 2004-08-10 13:42:03.000000000 -0400 @@ -26,16 +26,17 @@ #define HUMFS_VERSION 2 -static int stat_file(const char *path, void *m, 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) +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 = m; + struct humfs *mount = container_of(ed, struct humfs, ext); const char *data_path[3] = { mount->data, path, NULL }; - int err, mode, perms; + int err, mode, perms, major, minor; char type; err = host_stat_file(data_path, dev_out, inode_out, mode_out, @@ -45,7 +46,7 @@ return(err); err = (*mount->meta->ownerships)(path, &perms, uid_out, gid_out, - &type, NULL, NULL, mount); + &type, &major, &minor, mount); if(err) return(err); @@ -110,9 +111,10 @@ return(type); } -static int file_type(const char *path, int *dev_out, void *m) +static int humfs_file_type(const char *path, int *dev_out, + struct externfs_data *ed) { - struct humfs *mount = m; + struct humfs *mount = container_of(ed, struct humfs, ext); const char *data_path[3] = { mount->data, path, NULL }; int type; @@ -123,20 +125,35 @@ return(host_file_type(data_path, dev_out)); } -char *humfs_data_name(struct inode *inode) +static char *humfs_data_name(struct inode *inode) { - struct humfs *mount = inode->i_sb->u.generic_sbp; + 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 file_handle *humfs_init_file(char *path, int uid, int gid, - struct inode *inode, void *m) +static struct externfs_inode *humfs_init_file(struct externfs_data *ed) { - struct humfs *mount = m; + struct humfs *mount = container_of(ed, struct humfs, ext); + struct humfs_file *hf; + + hf = (*mount->meta->init_file)(); + if(IS_ERR(hf)) + return((struct externfs_inode *) hf); + + 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; - struct humfs_file *hf; char tmp[HOSTFS_BUFSIZE], *file; int err = -ENOMEM; @@ -150,18 +167,13 @@ if(path == NULL) path = ""; - hf = (*mount->meta->init_file)(path, inode, mount); - if(IS_ERR(hf)){ - err = PTR_ERR(hf); + 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){ - (*mount->meta->close_file)(hf); - free_path(file, tmp); - return(NULL); - } + if(err == -EISDIR) + goto out; else if(err == -EPERM){ flags = of_set_rw(flags, 1, 0); err = open_filehandle(file, flags, 0, &hf->data); @@ -173,25 +185,39 @@ hf->mount = mount; is_reclaimable(&hf->data, humfs_data_name, inode); - free_path(file, tmp); - return(&hf->data); - - out_close: - (*mount->meta->close_file)(hf); out_free: free_path(file, tmp); out: - return(ERR_PTR(err)); + return(err); + + out_close: + (*mount->meta->close_file)(hf); + goto out_free; } -static void *humfs_open_dir(char *path, int uid, int gid, void *m) +static void *humfs_open_dir(char *path, int uid, int gid, + struct externfs_data *ed) { - struct humfs *mount = m; + 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 { @@ -320,28 +346,33 @@ return(err); } -static int humfs_read_file(struct file_handle *fh, unsigned long long offset, - char *buf, int len, int ignore_start, int ignore_end, +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, - void *mount) + struct externfs_data *ed) { - int fd = filehandle_fd(fh); + 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)); + return(humfs_aio(AIO_READ, fd, offset, buf, len, len, completion, + arg)); } -static int humfs_write_file(struct file_handle *fh, unsigned long long offset, - const char *buf, int start, int len, - void (*completion)(char *, int, void *), void *arg, - void *m) -{ - struct humfs *mount = m; - int err, orig_len = len, fd = filehandle_fd(fh); +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); @@ -367,16 +398,18 @@ return(err); } -static int map_file_page(struct file_handle *fh, unsigned long long offset, - char *buf, int w, void *m) +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(fh); + int err, fd = filehandle_fd(&hf->data); if(fd < 0) return(fd); - err = os_fd_size(fh->fd, &size); + err = os_fd_size(fd, &size); if(err) return(err); @@ -390,32 +423,30 @@ return(physmem_subst_mapping(buf, fd, offset, w)); } -static void humfs_close_file(struct file_handle *fh, unsigned long long size) +static void humfs_close_file(struct externfs_inode *ext, + unsigned long long size) { - struct humfs_file *hf; + struct humfs_file *hf = container_of(ext, struct humfs_file, ext); int fd; - if(fh == NULL) - return; - - fd = filehandle_fd(fh); - if(fd < 0) + if(hf->data.fd == -1) return; - hf = container_of(fh, struct humfs_file, data); + fd = filehandle_fd(&hf->data); physmem_forget_descriptor(fd); - truncate_file(fh, size); - close_file(fh); + 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 make_node(const char *path, int mode, int uid, int gid, int type, - int major, int minor, void *m) +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 = m; + struct humfs *mount = container_of(ed, struct humfs, ext); struct file_handle fh; const char *data_path[3] = { mount->data, path, NULL }; int err; @@ -442,7 +473,7 @@ break; default: err = -EINVAL; - printk("make_node - bad node type : %d\n", type); + printk("humfs_make_node - bad node type : %d\n", type); goto out_rm; } @@ -459,20 +490,19 @@ goto out; } -static struct file_handle *humfs_create_file(char *path, int mode, int uid, - int gid, struct inode *inode, - void *m) +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 = m; + 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 humfs_file *hf; int err; - hf = (*mount->meta->create_file)(path, mode, uid, gid, inode, mount); - if(IS_ERR(hf)){ - err = PTR_ERR(hf); + 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) @@ -481,71 +511,77 @@ is_reclaimable(&hf->data, humfs_data_name, inode); - return(&hf->data); + return(0); out_rm: (*mount->meta->remove_file)(path, mount); (*mount->meta->close_file)(hf); out: - return(ERR_PTR(err)); + return(err); } -static int set_attr(const char *path, struct hostfs_iattr *attrs, void *m) +static int humfs_set_attr(const char *path, struct externfs_iattr *attrs, + struct externfs_data *ed) { - struct humfs *mount = m; + 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 & HOSTFS_ATTR_MODE){ + if(attrs->ia_valid & EXTERNFS_ATTR_MODE){ err = (*chown)(path, attrs->ia_mode, -1, -1, mount); if(err) return(err); } - if(attrs->ia_valid & HOSTFS_ATTR_UID){ + if(attrs->ia_valid & EXTERNFS_ATTR_UID){ err = (*chown)(path, -1, attrs->ia_uid, -1, mount); if(err) return(err); } - if(attrs->ia_valid & HOSTFS_ATTR_GID){ + if(attrs->ia_valid & EXTERNFS_ATTR_GID){ err = (*chown)(path, -1, -1, attrs->ia_gid, mount); if(err) return(err); } - attrs->ia_valid &= ~(HOSTFS_ATTR_MODE | HOSTFS_ATTR_UID | - HOSTFS_ATTR_GID); + attrs->ia_valid &= ~(EXTERNFS_ATTR_MODE | EXTERNFS_ATTR_UID | + EXTERNFS_ATTR_GID); return(host_set_attr(data_path, attrs)); } -static int make_symlink(const char *from, const char *to, int uid, int gid, - void *m) +static int humfs_make_symlink(const char *from, const char *to, int uid, + int gid, struct externfs_data *ed) { - struct humfs *mount = m; + struct humfs *mount = container_of(ed, struct humfs, ext); struct humfs_file *hf; const char *data_path[3] = { mount->data, from, NULL }; - int err; + int err = -ENOMEM; - hf = (*mount->meta->create_file)(from, S_IRWXUGO, uid, gid, NULL, - mount); - if(IS_ERR(hf)) - return(PTR_ERR(hf)); + hf = (*mount->meta->init_file)(); + if(hf == NULL) + goto out; - (*mount->meta->close_file)(hf); + 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 link_file(const char *to, const char *from, int uid, int gid, - void *m) +static int humfs_link_file(const char *to, const char *from, int uid, int gid, + struct externfs_data *ed) { - struct humfs *mount = m; + 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; @@ -561,9 +597,9 @@ return(err); } -static int unlink_file(const char *path, void *m) +static int humfs_unlink_file(const char *path, struct externfs_data *ed) { - struct humfs *mount = m; + struct humfs *mount = container_of(ed, struct humfs, ext); const char *data_path[3] = { mount->data, path, NULL }; int err; @@ -575,18 +611,19 @@ return(host_unlink_file(data_path)); } -static void humfs_invisible(struct file_handle *fh) +static void humfs_invisible(struct externfs_inode *ext) { - struct humfs_file *hf = container_of(fh, struct humfs_file, data); + 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 make_dir(const char *path, int mode, int uid, int gid, void *m) +static int humfs_make_dir(const char *path, int mode, int uid, int gid, + struct externfs_data *ed) { - struct humfs *mount = m; + struct humfs *mount = container_of(ed, struct humfs, ext); const char *data_path[3] = { mount->data, path, NULL }; int err; @@ -601,9 +638,10 @@ return(err); } -static int remove_dir(const char *path, int uid, int gid, void *m) +static int humfs_remove_dir(const char *path, int uid, int gid, + struct externfs_data *ed) { - struct humfs *mount = m; + struct humfs *mount = container_of(ed, struct humfs, ext); const char *data_path[3] = { mount->data, path, NULL }; int err; @@ -616,18 +654,23 @@ return(err); } -static int read_link(char *file, int uid, int gid, char *buf, int size, - void *m) +static int humfs_read_link(char *file, int uid, int gid, char *buf, int size, + struct externfs_data *ed) { - struct humfs *mount = m; + 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)); } -static int rename_file(char *from, char *to, void *m) +struct humfs *inode_humfs_info(struct inode *inode) { - struct humfs *mount = m; + 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; @@ -643,12 +686,13 @@ return(err); } -static int 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, void *m) +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 = m; + struct humfs *mount = container_of(ed, struct humfs, ext); const char *data_path[3] = { mount->data, NULL }; int err; @@ -665,6 +709,14 @@ 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); @@ -829,64 +881,64 @@ } struct externfs_file_ops humfs_no_mmap_file_ops = { - .stat_file = stat_file, - .file_type = file_type, + .stat_file = humfs_stat_file, + .file_type = humfs_file_type, .access_file = NULL, - .init_file = humfs_init_file, + .open_file = humfs_open_file, .open_dir = humfs_open_dir, - .read_dir = generic_host_read_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 = generic_host_close_dir, + .close_dir = humfs_close_dir, .invisible = humfs_invisible, .create_file = humfs_create_file, - .set_attr = set_attr, - .make_symlink = make_symlink, - .unlink_file = unlink_file, - .make_dir = make_dir, - .remove_dir = remove_dir, - .make_node = make_node, - .link_file = link_file, - .read_link = read_link, - .rename_file = rename_file, - .statfs = stat_fs, - .truncate_file = generic_host_truncate_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 = stat_file, - .file_type = file_type, + .stat_file = humfs_stat_file, + .file_type = humfs_file_type, .access_file = NULL, - .init_file = humfs_init_file, + .open_file = humfs_open_file, .open_dir = humfs_open_dir, - .invisible = humfs_invisible, - .read_dir = generic_host_read_dir, + .read_dir = humfs_read_dir, .read_file = humfs_read_file, .write_file = humfs_write_file, - .map_file_page = map_file_page, + .map_file_page = humfs_map_file_page, .close_file = humfs_close_file, - .close_dir = generic_host_close_dir, + .close_dir = humfs_close_dir, + .invisible = humfs_invisible, .create_file = humfs_create_file, - .set_attr = set_attr, - .make_symlink = make_symlink, - .unlink_file = unlink_file, - .make_dir = make_dir, - .remove_dir = remove_dir, - .make_node = make_node, - .link_file = link_file, - .read_link = read_link, - .rename_file = rename_file, - .statfs = stat_fs, - .truncate_file = generic_host_truncate_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_file_ops *mount_fs(char *mount_arg, - void **mount_data_out) +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){ @@ -929,8 +981,10 @@ mount->data = data; mount->mmap = do_mmap; - *mount_data_out = mount; - return(do_mmap ? &humfs_mmap_file_ops : &humfs_no_mmap_file_ops); + 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); @@ -941,6 +995,7 @@ } struct externfs_mount_ops humfs_mount_ops = { + .init_file = humfs_init_file, .mount = mount_fs, }; Index: um/arch/um/fs/hostfs/meta_fs.c =================================================================== --- um.orig/arch/um/fs/hostfs/meta_fs.c 2004-08-12 13:14:30.000000000 -0400 +++ um/arch/um/fs/hostfs/meta_fs.c 2004-08-12 13:14:44.000000000 -0400 @@ -89,38 +89,41 @@ return(name); } -static void invisible(struct humfs_file *hf) +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 *init_file(const char *path, struct inode *inode, - struct humfs *humfs) +static struct humfs_file *metafs_init_file(void) { struct meta_file *mf; int err = -ENOMEM; mf = kmalloc(sizeof(*mf), GFP_KERNEL); if(mf == NULL) - goto out; + 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) - goto out_free; + return(err); is_reclaimable(&mf->fh, meta_fs_name, inode); - return(&mf->humfs); - - out_free: - kfree(mf); - out: - return(ERR_PTR(err)); + return(0); } -static void meta_close_file(struct humfs_file *hf) +static void metafs_close_file(struct humfs_file *hf) { struct meta_file *meta = container_of(hf, struct meta_file, humfs); @@ -128,12 +131,12 @@ kfree(meta); } -static struct humfs_file *create_file(const char *path, int mode, int uid, - int gid, struct inode *inode, - struct humfs *humfs) +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; + 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)); @@ -143,14 +146,10 @@ if(file == NULL) goto out; - mf = kmalloc(sizeof(*mf), GFP_KERNEL); - if(mf == NULL) - goto out_free_path; - err = open_filehandle(file, of_write(of_create(OPENFLAGS())), 0644, &mf->fh); if(err) - goto out_free_meta; + goto out_free_path; if(inode != NULL) is_reclaimable(&mf->fh, meta_fs_name, inode); @@ -161,20 +160,19 @@ goto out_rm; free_path(file, tmp); - return(&mf->humfs); + return(0); out_rm: close_file(&mf->fh); os_remove_file(file); - out_free_meta: - kfree(meta); out_free_path: free_path(file, tmp); out: - return(ERR_PTR(err)); + return(err); } -static int create_link(const char *to, const char *from, struct humfs *humfs) +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 }; @@ -183,7 +181,7 @@ return(host_link_file(path_to, path_from)); } -static int remove_file(const char *path, struct humfs *humfs) +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]; @@ -201,8 +199,8 @@ return(err); } -static int create_directory(const char *path, int mode, int uid, int gid, - struct humfs *humfs) +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]; @@ -251,7 +249,7 @@ return(err); } -static int remove_directory(const char *path, struct humfs *humfs) +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; @@ -294,8 +292,8 @@ goto out; } -static int make_node(const char *path, int mode, int uid, int gid, int type, - int maj, int min, struct humfs *humfs) +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; @@ -329,9 +327,9 @@ return(err); } -static 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) +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")]; @@ -379,8 +377,8 @@ return(err); } -static int change_ownerships(const char *path, int mode, int uid, int gid, - struct humfs *humfs) +static int metafs_change_ownerships(const char *path, int mode, int uid, + int gid, struct humfs *humfs) { struct file_handle fh; char type; @@ -429,7 +427,8 @@ return(err); } -static int rename_file(const char *from, const char *to, struct humfs *humfs) +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]; @@ -446,7 +445,7 @@ return(host_rename_file(metadata_path_from, metadata_path_to)); } -static struct humfs *init_mount(char *root) +static struct humfs *metafs_init_mount(char *root) { struct meta_fs *meta; int err = -ENOMEM; @@ -467,7 +466,7 @@ return(ERR_PTR(err)); } -static void free_mount(struct humfs *humfs) +static void metafs_free_mount(struct humfs *humfs) { struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs); @@ -477,20 +476,21 @@ struct humfs_meta_ops hum_fs_meta_fs_ops = { .list = LIST_HEAD_INIT(hum_fs_meta_fs_ops.list), .name = "shadow_fs", - .init_file = init_file, - .close_file = meta_close_file, - .ownerships = ownerships, - .make_node = make_node, - .create_file = create_file, - .create_link = create_link, - .remove_file = remove_file, - .create_dir = create_directory, - .remove_dir = remove_directory, - .change_ownerships = change_ownerships, - .rename_file = rename_file, - .invisible = invisible, - .init_mount = init_mount, - .free_mount = free_mount, + .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) Index: um/arch/um/fs/hostfs/metadata.h =================================================================== --- um.orig/arch/um/fs/hostfs/metadata.h 2004-08-10 11:35:53.000000000 -0400 +++ um/arch/um/fs/hostfs/metadata.h 2004-08-10 13:41:13.000000000 -0400 @@ -10,12 +10,15 @@ #include "linux/fs.h" #include "linux/list.h" #include "os.h" +#include "hostfs.h" +#include "filehandle.h" #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) struct humfs { + struct externfs_data ext; __u64 used; __u64 total; char *data; @@ -27,16 +30,18 @@ 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)(const char *path, struct inode *inode, - struct humfs *humfs); - struct humfs_file *(*create_file)(const char *path, int mode, int uid, - int gid, struct inode *inode, - struct humfs *humfs); + 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, @@ -63,6 +68,7 @@ char *humfs_path(char *dir, char *file); char *humfs_name(struct inode *inode, char *prefix); +extern struct humfs *inode_humfs_info(struct inode *inode); #endif Index: um/arch/um/include/os.h =================================================================== --- um.orig/arch/um/include/os.h 2004-08-09 16:51:46.000000000 -0400 +++ um/arch/um/include/os.h 2004-08-09 16:53:23.000000000 -0400 @@ -29,7 +29,8 @@ * (if they are wrong here, they are wrong there...). */ struct uml_stat { - int ust_dev; /* device */ + int ust_major; /* device */ + int ust_minor; unsigned long long ust_ino; /* inode */ int ust_mode; /* protection */ int ust_nlink; /* number of hard links */ @@ -41,7 +42,8 @@ unsigned long ust_atime; /* time of last access */ unsigned long ust_mtime; /* time of last modification */ unsigned long ust_ctime; /* time of last change */ - int ust_rdev; + int ust_rmajor; + int ust_rminor; }; struct openflags { @@ -156,7 +158,6 @@ 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_remove_dir(const char *file); 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); @@ -198,14 +199,12 @@ int r, int w, int x); extern int os_unmap_memory(void *addr, int len); extern void os_flush_stdout(void); -extern int os_can_direct_io(void); extern int os_stat_filesystem(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); - extern unsigned long long os_usecs(void); #endif Index: um/arch/um/os-Linux/file.c =================================================================== --- um.orig/arch/um/os-Linux/file.c 2004-08-09 16:51:46.000000000 -0400 +++ um/arch/um/os-Linux/file.c 2004-08-09 16:53:23.000000000 -0400 @@ -27,7 +27,8 @@ static void copy_stat(struct uml_stat *dst, struct stat64 *src) { *dst = ((struct uml_stat) { - .ust_dev = src->st_dev, /* device */ + .ust_major = MAJOR(src->st_dev), /* device */ + .ust_minor = MINOR(src->st_dev), .ust_ino = src->st_ino, /* inode */ .ust_mode = src->st_mode, /* protection */ .ust_nlink = src->st_nlink, /* number of hard links */ @@ -39,7 +40,8 @@ .ust_atime = src->st_atime, /* time of last access */ .ust_mtime = src->st_mtime, /* time of last modification */ .ust_ctime = src->st_ctime, /* time of last change */ - .ust_rdev = src->st_rdev, + .ust_rmajor = MAJOR(src->st_rdev), + .ust_rminor = MINOR(src->st_rdev), }); } @@ -896,19 +898,6 @@ return(err); } -int os_can_direct_io(void) -{ - struct utsname uts; - int err; - - err = uname(&uts); - if(err) - return(-errno); - - /* XXX This will break when 2.7 comes out */ - return(!strncmp(uts.release, "2.6", strlen("2.6"))); -} - int os_stat_filesystem(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,