UML - Move hppfs_kern.c to hppfs.c
PATCH 7/19 UML - Move hppfs_kern.c to hppfs.c
There's no reason for the _kern in hppfs_kern.c, so move it to hppfs.c.
--- fs/hppfs/Makefile | 6 fs/hppfs/hppfs.c | 771 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/hppfs/hppfs_kern.c | 771 -------------------------------------------------- 3 files changed, 774 insertions(+), 774 deletions(-)
fs/hppfs/hppfs.c new file +771 -0
@@ -0,0 +1,771 @@ +/* +* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) +* Licensed under the GPL +*/ + +#include <linux/ctype.h> +#include <linux/dcache.h> +#include <linux/file.h> +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/mount.h> +#include <linux/slab.h> +#include <linux/statfs.h> +#include <linux/types.h> +#include <asm/uaccess.h> +#include "os.h" + +static struct inode *get_inode (struct super_block *,struct dentry *); + +struct hppfs_data { +struct list_head list; +char contents[PAGE_SIZE -sizeof (struct list_head )]; +}; + +struct hppfs_private { +struct file *proc_file; +int host_fd; +loff_t len; +struct hppfs_data *contents; +}; + +struct hppfs_inode_info { +struct dentry *proc_dentry; +struct inode vfs_inode; +}; + +static inline struct hppfs_inode_info *HPPFS_I (struct inode *inode) +{ + return container_of(inode, struct hppfs_inode_info, vfs_inode); +} + +#define HPPFS_SUPER_MAGIC 0xb00000ee + +static const struct super_operations hppfs_sbops; + +static int is_pid (struct dentry *dentry) +{ +struct super_block *sb; +int i; + + sb = dentry->d_sb; +if (dentry->d_parent != sb->s_root) +return 0 ; + +for (i =0 ; i < dentry->d_name.len; i++) { +if (!isdigit (dentry->d_name.name[i])) +return 0 ; + } +return 1 ; +} + +static char *dentry_name (struct dentry *dentry,int extra) +{ +struct dentry *parent; +char *root, *name; +const char *seg_name; +int len, seg_len; + + len =0 ; + parent = dentry; +while (parent->d_parent != parent) { +if (is_pid (parent)) + len +=strlen ("pid" ) +1 ; +else len += parent->d_name.len +1 ; + parent = parent->d_parent; + } + + root ="proc" ; + len +=strlen (root); + name =kmalloc (len + extra +1 ,GFP_KERNEL ); +if (name ==NULL ) +return NULL ; + + name[len] ='\0' ; + parent = dentry; +while (parent->d_parent != parent) { +if (is_pid (parent)) { + seg_name ="pid" ; + seg_len =strlen ("pid" ); + } +else { + seg_name = parent->d_name.name; + seg_len = parent->d_name.len; + } + + len -= seg_len +1 ; + name[len] ='/' ; +strncpy (&name[len +1 ], seg_name, seg_len); + parent = parent->d_parent; + } +strncpy (name, root,strlen (root)); +return name; +} + +static int file_removed (struct dentry *dentry,const char *file) +{ +char *host_file; +int extra, fd; + + extra =0 ; +if (file !=NULL ) + extra +=strlen (file) +1 ; + + host_file =dentry_name (dentry, extra +strlen ("/remove" )); +if (host_file ==NULL ) { +printk (KERN_ERR "file_removed : allocation failed\n" ); +return -ENOMEM ; + } + +if (file !=NULL ) { +strcat (host_file,"/" ); +strcat (host_file, file); + } +strcat (host_file,"/remove" ); + + fd =os_open_file (host_file,of_read (OPENFLAGS ()),0 ); +kfree (host_file); +if (fd >0 ) { +os_close_file (fd); +return 1 ; + } +return 0 ; +} + +static struct dentry *hppfs_lookup (struct inode *ino,struct dentry *dentry, +struct nameidata *nd) +{ +struct dentry *proc_dentry, *new, *parent; +struct inode *inode; +int err, deleted; + + deleted =file_removed (dentry,NULL ); +if (deleted <0 ) +return ERR_PTR (deleted); +else if (deleted) +return ERR_PTR (-ENOENT ); + + err = -ENOMEM ; + parent =HPPFS_I (ino)->proc_dentry; +mutex_lock (&parent->d_inode->i_mutex); + proc_dentry =d_lookup (parent, &dentry->d_name); +if (proc_dentry ==NULL ) { + proc_dentry =d_alloc (parent, &dentry->d_name); +if (proc_dentry ==NULL ) { +mutex_unlock (&parent->d_inode->i_mutex); + goto out; + } + new = (*parent->d_inode->i_op->lookup)(parent->d_inode, + proc_dentry,NULL ); +if (new) { +dput (proc_dentry); + proc_dentry = new; + } + } +mutex_unlock (&parent->d_inode->i_mutex); + +if (IS_ERR (proc_dentry)) +return proc_dentry; + + err = -ENOMEM ; + inode =get_inode (ino->i_sb, proc_dentry); +if (!inode) + goto out_dput; + +d_add (dentry, inode); +return NULL ; + + out_dput: +dput (proc_dentry); + out: +return ERR_PTR (err); +} + +static const struct inode_operations hppfs_file_iops = { +}; + +static ssize_t read_proc (struct file *file,char __user *buf,ssize_t count, +loff_t *ppos,int is_user) +{ +ssize_t (*read)(struct file *,char __user *,size_t ,loff_t *); +ssize_t n; + + read = file->f_path.dentry->d_inode->i_fop->read; + +if (!is_user) +set_fs (KERNEL_DS ); + + n = (*read)(file, buf, count, &file->f_pos); + +if (!is_user) +set_fs (USER_DS ); + +if (ppos) + *ppos = file->f_pos; +return n; +} + +static ssize_t hppfs_read_file (int fd,char __user *buf,ssize_t count) +{ +ssize_t n; +int cur, err; +char *new_buf; + + n = -ENOMEM ; + new_buf =kmalloc (PAGE_SIZE ,GFP_KERNEL ); +if (new_buf ==NULL ) { +printk (KERN_ERR "hppfs_read_file : kmalloc failed\n" ); + goto out; + } + n =0 ; +while (count >0 ) { + cur =min_t (ssize_t, count,PAGE_SIZE ); + err =os_read_file (fd, new_buf, cur); +if (err <0 ) { +printk (KERN_ERR "hppfs_read : read failed, " +"errno = %d\n" , err); + n = err; + goto out_free; + }else if (err ==0 ) +break ; + +if (copy_to_user (buf, new_buf, err)) { + n = -EFAULT ; + goto out_free; + } + n += err; + count -= err; + } + out_free: +kfree (new_buf); + out: +return n; +} + +static ssize_t hppfs_read (struct file *file,char __user *buf,size_t count, +loff_t *ppos) +{ +struct hppfs_private *hppfs = file->private_data; +struct hppfs_data *data; +loff_t off; +int err; + +if (hppfs->contents !=NULL ) { +int rem; + +if (*ppos >= hppfs->len) +return 0 ; + + data = hppfs->contents; + off = *ppos; +while (off >=sizeof (data->contents)) { + data = list_entry(data->list.next, struct hppfs_data, + list); + off -=sizeof (data->contents); + } + +if (off + count > hppfs->len) + count = hppfs->len - off; + rem =copy_to_user (buf, &data->contents[off], count); + *ppos += count - rem; +if (rem >0 ) +return -EFAULT ; + }else if (hppfs->host_fd !=-1 ) { + err =os_seek_file (hppfs->host_fd, *ppos); +if (err) { +printk (KERN_ERR "hppfs_read : seek failed, " +"errno = %d\n" , err); +return err; + } + count =hppfs_read_file (hppfs->host_fd, buf, count); +if (count >0 ) + *ppos += count; + } +else count =read_proc (hppfs->proc_file, buf, count, ppos,1 ); + +return count; +} + +static ssize_t hppfs_write (struct file *file,const char __user *buf, +size_t len,loff_t *ppos) +{ +struct hppfs_private *data = file->private_data; +struct file *proc_file = data->proc_file; +ssize_t (*write)(struct file *,const char __user *,size_t ,loff_t *); + + write = proc_file->f_path.dentry->d_inode->i_fop->write; +return (*write)(proc_file, buf, len, ppos); +} + +static int open_host_sock (char *host_file,int *filter_out) +{ +char *end; +int fd; + + end = &host_file[strlen (host_file)]; +strcpy (end,"/rw" ); + *filter_out =1 ; + fd =os_connect_socket (host_file); +if (fd >0 ) +return fd; + +strcpy (end,"/r" ); + *filter_out =0 ; + fd =os_connect_socket (host_file); +return fd; +} + +static void free_contents (struct hppfs_data *head) +{ +struct hppfs_data *data; +struct list_head *ele, *next; + +if (head ==NULL ) +return ; + +list_for_each_safe (ele, next, &head->list) { + data = list_entry(ele, struct hppfs_data, list); +kfree (data); + } +kfree (head); +} + +static struct hppfs_data *hppfs_get_data (int fd,int filter, +struct file *proc_file, +struct file *hppfs_file, +loff_t *size_out) +{ +struct hppfs_data *data, *new, *head; +int n, err; + + err = -ENOMEM ; + data =kmalloc (sizeof (*data),GFP_KERNEL ); +if (data ==NULL ) { +printk (KERN_ERR "hppfs_get_data : head allocation failed\n" ); + goto failed; + } + +INIT_LIST_HEAD (&data->list); + + head = data; + *size_out =0 ; + +if (filter) { +while ((n =read_proc (proc_file, data->contents, +sizeof (data->contents),NULL ,0 )) >0 ) +os_write_file (fd, data->contents, n); + err =os_shutdown_socket (fd,0 ,1 ); +if (err) { +printk (KERN_ERR "hppfs_get_data : failed to shut down " +"socket\n" ); + goto failed_free; + } + } +while (1 ) { + n =os_read_file (fd, data->contents,sizeof (data->contents)); +if (n <0 ) { + err = n; +printk (KERN_ERR "hppfs_get_data : read failed, " +"errno = %d\n" , err); + goto failed_free; + }else if (n ==0 ) +break ; + + *size_out += n; + +if (n <sizeof (data->contents)) +break ; + + new =kmalloc (sizeof (*data),GFP_KERNEL ); +if (new ==0 ) { +printk (KERN_ERR "hppfs_get_data : data allocation " +"failed\n" ); + err = -ENOMEM ; + goto failed_free; + } + +INIT_LIST_HEAD (&new->list); +list_add (&new->list, &data->list); + data = new; + } +return head; + + failed_free: +free_contents (head); + failed: +return ERR_PTR (err); +} + +static struct hppfs_private *hppfs_data (void ) +{ +struct hppfs_private *data; + + data =kmalloc (sizeof (*data),GFP_KERNEL ); +if (data ==NULL ) +return data; + + *data = ((struct hppfs_private ) { .host_fd =-1 , + .len =-1 , + .contents =NULL } ); +return data; +} + +static int file_mode (int fmode) +{ +if (fmode == (FMODE_READ |FMODE_WRITE )) +return O_RDWR ; +if (fmode ==FMODE_READ ) +return O_RDONLY ; +if (fmode ==FMODE_WRITE ) +return O_WRONLY ; +return 0 ; +} + +static int hppfs_open (struct inode *inode,struct file *file) +{ +struct hppfs_private *data; +struct vfsmount *proc_mnt; +struct dentry *proc_dentry; +char *host_file; +int err, fd, type, filter; + + err = -ENOMEM ; + data =hppfs_data (); +if (data ==NULL ) + goto out; + + host_file =dentry_name (file->f_path.dentry,strlen ("/rw" )); +if (host_file ==NULL ) + goto out_free2; + + proc_dentry =HPPFS_I (inode)->proc_dentry; + proc_mnt = inode->i_sb->s_fs_info; + +/* XXX This isn't closed anywhere */ + data->proc_file =dentry_open (dget (proc_dentry),mntget (proc_mnt), +file_mode (file->f_mode)); + err =PTR_ERR (data->proc_file); +if (IS_ERR (data->proc_file)) + goto out_free1; + + type =os_file_type (host_file); +if (type ==OS_TYPE_FILE ) { + fd =os_open_file (host_file,of_read (OPENFLAGS ()),0 ); +if (fd >=0 ) + data->host_fd = fd; +else +printk (KERN_ERR "hppfs_open : failed to open '%s', " +"errno = %d\n" , host_file, -fd); + + data->contents =NULL ; + }else if (type ==OS_TYPE_DIR ) { + fd =open_host_sock (host_file, &filter); +if (fd >0 ) { + data->contents =hppfs_get_data (fd, filter, + data->proc_file, + file, &data->len); +if (!IS_ERR (data->contents)) + data->host_fd = fd; + }else +printk (KERN_ERR "hppfs_open : failed to open a socket " +"in '%s', errno = %d\n" , host_file, -fd); + } +kfree (host_file); + + file->private_data = data; +return 0 ; + + out_free1: +kfree (host_file); + out_free2: +free_contents (data->contents); +kfree (data); + out: +return err; +} + +static int hppfs_dir_open (struct inode *inode,struct file *file) +{ +struct hppfs_private *data; +struct vfsmount *proc_mnt; +struct dentry *proc_dentry; +int err; + + err = -ENOMEM ; + data =hppfs_data (); +if (data ==NULL ) + goto out; + + proc_dentry =HPPFS_I (inode)->proc_dentry; + proc_mnt = inode->i_sb->s_fs_info; + data->proc_file =dentry_open (dget (proc_dentry),mntget (proc_mnt), +file_mode (file->f_mode)); + err =PTR_ERR (data->proc_file); +if (IS_ERR (data->proc_file)) + goto out_free; + + file->private_data = data; +return 0 ; + + out_free: +kfree (data); + out: +return err; +} + +static loff_t hppfs_llseek (struct file *file,loff_t off,int where) +{ +struct hppfs_private *data = file->private_data; +struct file *proc_file = data->proc_file; +loff_t (*llseek)(struct file *,loff_t ,int ); +loff_t ret; + + llseek = proc_file->f_path.dentry->d_inode->i_fop->llseek; +if (llseek !=NULL ) { + ret = (*llseek)(proc_file, off, where); +if (ret <0 ) +return ret; + } + +return default_llseek (file, off, where); +} + +static const struct file_operations hppfs_file_fops = { + .owner =NULL , + .llseek = hppfs_llseek, + .read = hppfs_read, + .write = hppfs_write, + .open = hppfs_open, +}; + +struct hppfs_dirent { +void *vfs_dirent; +filldir_t filldir; +struct dentry *dentry; +}; + +static int hppfs_filldir (void *d,const char *name,int size, +loff_t offset,u64 inode,unsigned int type) +{ +struct hppfs_dirent *dirent = d; + +if (file_removed (dirent->dentry, name)) +return 0 ; + +return (*dirent->filldir)(dirent->vfs_dirent, name, size, offset, + inode, type); +} + +static int hppfs_readdir (struct file *file,void *ent,filldir_t filldir) +{ +struct hppfs_private *data = file->private_data; +struct file *proc_file = data->proc_file; +int (*readdir)(struct file *,void *,filldir_t ); +struct hppfs_dirent dirent = ((struct hppfs_dirent ) + { .vfs_dirent = ent, + .filldir = filldir, + .dentry = file->f_path.dentry + }); +int err; + + readdir = proc_file->f_path.dentry->d_inode->i_fop->readdir; + + proc_file->f_pos = file->f_pos; + err = (*readdir)(proc_file, &dirent, hppfs_filldir); + file->f_pos = proc_file->f_pos; + +return err; +} + +static int hppfs_fsync (struct file *file,struct dentry *dentry,int datasync) +{ +return 0 ; +} + +static const struct file_operations hppfs_dir_fops = { + .owner =NULL , + .readdir = hppfs_readdir, + .open = hppfs_dir_open, + .fsync = hppfs_fsync, +}; + +static int hppfs_statfs (struct dentry *dentry,struct kstatfs *sf) +{ + sf->f_blocks =0 ; + sf->f_bfree =0 ; + sf->f_bavail =0 ; + sf->f_files =0 ; + sf->f_ffree =0 ; + sf->f_type =HPPFS_SUPER_MAGIC ; +return 0 ; +} + +static struct inode *hppfs_alloc_inode (struct super_block *sb) +{ +struct hppfs_inode_info *hi; + + hi =kmalloc (sizeof (*hi),GFP_KERNEL ); +if (!hi) +return NULL ; + + hi->proc_dentry =NULL ; +inode_init_once (&hi->vfs_inode); +return &hi->vfs_inode; +} + +void hppfs_delete_inode (struct inode *ino) +{ +dput (HPPFS_I (ino)->proc_dentry); +mntput (ino->i_sb->s_fs_info); + +clear_inode (ino); +} + +static void hppfs_destroy_inode (struct inode *inode) +{ +kfree (HPPFS_I (inode)); +} + +static const struct super_operations hppfs_sbops = { + .alloc_inode = hppfs_alloc_inode, + .destroy_inode = hppfs_destroy_inode, + .delete_inode = hppfs_delete_inode, + .statfs = hppfs_statfs, +}; + +static int hppfs_readlink (struct dentry *dentry,char __user *buffer, +int buflen) +{ +struct dentry *proc_dentry; + + proc_dentry =HPPFS_I (dentry->d_inode)->proc_dentry; +return proc_dentry->d_inode->i_op->readlink (proc_dentry, buffer, + buflen); +} + +static void *hppfs_follow_link (struct dentry *dentry,struct nameidata *nd) +{ +struct dentry *proc_dentry; + + proc_dentry =HPPFS_I (dentry->d_inode)->proc_dentry; + +return proc_dentry->d_inode->i_op->follow_link (proc_dentry, nd); +} + +int hppfs_permission (struct inode *inode,int mask,struct nameidata *nd) +{ +return generic_permission (inode, mask,NULL ); +} + +static const struct inode_operations hppfs_dir_iops = { + .lookup = hppfs_lookup, + .permission = hppfs_permission, +}; + +static const struct inode_operations hppfs_link_iops = { + .readlink = hppfs_readlink, + .follow_link = hppfs_follow_link, + .permission = hppfs_permission, +}; + +static struct inode *get_inode (struct super_block *sb,struct dentry *dentry) +{ +struct inode *proc_ino = dentry->d_inode; +struct inode *inode =new_inode (sb); + +if (!inode) +return ERR_PTR (-ENOMEM ); + +if (S_ISDIR (dentry->d_inode->i_mode)) { + inode->i_op = &hppfs_dir_iops; + inode->i_fop = &hppfs_dir_fops; + }else if (S_ISLNK (dentry->d_inode->i_mode)) { + inode->i_op = &hppfs_link_iops; + inode->i_fop = &hppfs_file_fops; + }else { + inode->i_op = &hppfs_file_iops; + inode->i_fop = &hppfs_file_fops; + } + +HPPFS_I (inode)->proc_dentry =dget (dentry); + + inode->i_uid = proc_ino->i_uid; + inode->i_gid = proc_ino->i_gid; + inode->i_atime = proc_ino->i_atime; + inode->i_mtime = proc_ino->i_mtime; + inode->i_ctime = proc_ino->i_ctime; + inode->i_ino = proc_ino->i_ino; + inode->i_mode = proc_ino->i_mode; + inode->i_nlink = proc_ino->i_nlink; + inode->i_size = proc_ino->i_size; + inode->i_blocks = proc_ino->i_blocks; + +return inode; +} + +static int hppfs_fill_super (struct super_block *sb,void *d,int silent) +{ +struct inode *root_inode; +struct vfsmount *proc_mnt; +int err = -ENOENT ; + + proc_mnt =do_kern_mount ("proc" ,0 ,"proc" ,NULL ); +if (IS_ERR (proc_mnt)) + goto out; + + sb->s_blocksize =1024 ; + sb->s_blocksize_bits =10 ; + sb->s_magic =HPPFS_SUPER_MAGIC ; + sb->s_op = &hppfs_sbops; + sb->s_fs_info = proc_mnt; + + err = -ENOMEM ; + root_inode =get_inode (sb, proc_mnt->mnt_sb->s_root); +if (!root_inode) + goto out_mntput; + + sb->s_root =d_alloc_root (root_inode); +if (!sb->s_root) + goto out_iput; + +return 0 ; + + out_iput: +iput (root_inode); + out_mntput: +mntput (proc_mnt); + out: +return (err); +} + +static int hppfs_read_super (struct file_system_type *type, +int flags,const char *dev_name, +void *data,struct vfsmount *mnt) +{ +return get_sb_nodev (type, flags, data, hppfs_fill_super, mnt); +} + +static struct file_system_type hppfs_type = { + .owner =THIS_MODULE , + .name ="hppfs" , + .get_sb = hppfs_read_super, + .kill_sb = kill_anon_super, + .fs_flags =0 , +}; + +static int __init init_hppfs (void ) +{ +return register_filesystem (&hppfs_type); +} + +static void __exit exit_hppfs(void) +{ +unregister_filesystem (&hppfs_type); +} + +module_init(init_hppfs) +module_exit(exit_hppfs) +MODULE_LICENSE("GPL");
fs/hppfs/hppfs_kern.c deleted +0 -771
771 lines not on this page · raw message
fs/hppfs/Makefile +3 -3
@@ -1,9 +1,9 @@ # -# Copyright (C) 2002, 2003 Jeff Dike ([email protected]) +# Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) # Licensed under the GPL # -hppfs-objs := hppfs_kern.o +hppfs-objs := hppfs.o obj-y = -obj-$(CONFIG_HPPFS) += hppfs.o +obj-$(CONFIG_HPPFS) += $(hppfs-objs)
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
User-mode-linux-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
From: Jeff Dike <[email protected]>
Date: Fri, 25 Apr 2008 13:56:09 -0400
Quoted 49 lines
There's no reason for the
_kerninhppfs_kern.c, so move it tohppfs.c.Signed-off-by Jeff Dike <[email protected]>--- fs/hppfs/Makefile | 6 fs/hppfs/hppfs.c | 771 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/hppfs/hppfs_kern.c | 771 -------------------------------------------------- 3 files changed, 774 insertions(+), 774 deletions(-)Index:
linux-2.6-git/fs/hppfs/hppfs.c
===================================================================fs/hppfs/hppfs.c new file +35
-0@@ -0,0 +1,771 @@ +/* +* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) +* Licensed under the GPL +*/ + +#include <linux/ctype.h> +#include <linux/dcache.h> +#include <linux/file.h> +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/mount.h> +#include <linux/slab.h> +#include <linux/statfs.h> +#include <linux/types.h> +#include <asm/uaccess.h> +#include "os.h" + +static struct inode *get_inode (struct super_block *,struct dentry *); + +struct hppfs_data { +struct list_head list; +char contents[PAGE_SIZE -sizeof (struct list_head )]; +}; + +struct hppfs_private { +struct file *proc_file; +int host_fd; +loff_t len; +struct hppfs_data *contents; +}; + +struct hppfs_inode_info {
fs/hppfs/hppfs.c line 45
Quoted 10 lines
fs/hppfs/hppfs.c new file +10
-0+struct dentry *proc_dentry; +struct inode vfs_inode; +}; + +static inline struct hppfs_inode_info *HPPFS_I (struct inode *inode) +{ + return container_of(inode, struct hppfs_inode_info, vfs_inode); +} + +#define HPPFS_SUPER_MAGIC 0xb00000ee
These can be put into a single header, e.g. hppfs.h.
Quoted 18 lines
fs/hppfs/hppfs.c new file +18
-0+ +static const struct super_operations hppfs_sbops; + +static int is_pid (struct dentry *dentry) +{ +struct super_block *sb; +int i; + + sb = dentry->d_sb; +if (dentry->d_parent != sb->s_root) +return 0 ; + +for (i =0 ; i < dentry->d_name.len; i++) { +if (!isdigit (dentry->d_name.name[i])) +return 0 ; + } +return 1 ; +}
fs/hppfs/hppfs.c line 73
Quoted 10 lines
fs/hppfs/hppfs.c new file +10
-0+ +static char *dentry_name (struct dentry *dentry,int extra) +{ +struct dentry *parent; +char *root, *name; +const char *seg_name; +int len, seg_len; + + len =0 ; + parent = dentry;
These can be put into initialization, I think, that's more readable.
fs/hppfs/hppfs.c line 81
Quoted 8 lines
fs/hppfs/hppfs.c new file +8
-0+while (parent->d_parent != parent) { +if (is_pid (parent)) + len +=strlen ("pid" ) +1 ; +else len += parent->d_name.len +1 ; + parent = parent->d_parent; + } + + root ="proc" ;
This can be put into initialization of 'root', too.
Quoted 43 lines
fs/hppfs/hppfs.c new file +43
-0+ len +=strlen (root); + name =kmalloc (len + extra +1 ,GFP_KERNEL ); +if (name ==NULL ) +return NULL ; + + name[len] ='\0' ; + parent = dentry; +while (parent->d_parent != parent) { +if (is_pid (parent)) { + seg_name ="pid" ; + seg_len =strlen ("pid" ); + } +else { + seg_name = parent->d_name.name; + seg_len = parent->d_name.len; + } + + len -= seg_len +1 ; + name[len] ='/' ; +strncpy (&name[len +1 ], seg_name, seg_len); + parent = parent->d_parent; + } +strncpy (name, root,strlen (root)); +return name; +} + +static int file_removed (struct dentry *dentry,const char *file) +{ +char *host_file; +int extra, fd; + + extra =0 ; +if (file !=NULL ) + extra +=strlen (file) +1 ; + + host_file =dentry_name (dentry, extra +strlen ("/remove" )); +if (host_file ==NULL ) { +printk (KERN_ERR "file_removed : allocation failed\n" ); +return -ENOMEM ; + } + +if (file !=NULL ) { +strcat (host_file,"/" );
fs/hppfs/hppfs.c line 134
Quoted 10 lines
fs/hppfs/hppfs.c new file +10
-0+strcat (host_file, file); + } +strcat (host_file,"/remove" ); + + fd =os_open_file (host_file,of_read (OPENFLAGS ()),0 ); +kfree (host_file); +if (fd >0 ) { +os_close_file (fd); +return 1 ; + }
How about 'fd < 0' ?
Quoted 73 lines
fs/hppfs/hppfs.c new file +73
-0+return 0 ; +} + +static struct dentry *hppfs_lookup (struct inode *ino,struct dentry *dentry, +struct nameidata *nd) +{ +struct dentry *proc_dentry, *new, *parent; +struct inode *inode; +int err, deleted; + + deleted =file_removed (dentry,NULL ); +if (deleted <0 ) +return ERR_PTR (deleted); +else if (deleted) +return ERR_PTR (-ENOENT ); + + err = -ENOMEM ; + parent =HPPFS_I (ino)->proc_dentry; +mutex_lock (&parent->d_inode->i_mutex); + proc_dentry =d_lookup (parent, &dentry->d_name); +if (proc_dentry ==NULL ) { + proc_dentry =d_alloc (parent, &dentry->d_name); +if (proc_dentry ==NULL ) { +mutex_unlock (&parent->d_inode->i_mutex); + goto out; + } + new = (*parent->d_inode->i_op->lookup)(parent->d_inode, + proc_dentry,NULL ); +if (new) { +dput (proc_dentry); + proc_dentry = new; + } + } +mutex_unlock (&parent->d_inode->i_mutex); + +if (IS_ERR (proc_dentry)) +return proc_dentry; + + err = -ENOMEM ; + inode =get_inode (ino->i_sb, proc_dentry); +if (!inode) + goto out_dput; + +d_add (dentry, inode); +return NULL ; + + out_dput: +dput (proc_dentry); + out: +return ERR_PTR (err); +} + +static const struct inode_operations hppfs_file_iops = { +}; + +static ssize_t read_proc (struct file *file,char __user *buf,ssize_t count, +loff_t *ppos,int is_user) +{ +ssize_t (*read)(struct file *,char __user *,size_t ,loff_t *); +ssize_t n; + + read = file->f_path.dentry->d_inode->i_fop->read; + +if (!is_user) +set_fs (KERNEL_DS ); + + n = (*read)(file, buf, count, &file->f_pos); + +if (!is_user) +set_fs (USER_DS ); + +if (ppos) + *ppos = file->f_pos;
fs/hppfs/hppfs.c line 217
Quoted 10 lines
fs/hppfs/hppfs.c new file +10
-0+return n; +} + +static ssize_t hppfs_read_file (int fd,char __user *buf,ssize_t count) +{ +ssize_t n; +int cur, err; +char *new_buf; + + n = -ENOMEM ;
This can be put into initialization.
Quoted 156 lines
fs/hppfs/hppfs.c new file +156
-0+ new_buf =kmalloc (PAGE_SIZE ,GFP_KERNEL ); +if (new_buf ==NULL ) { +printk (KERN_ERR "hppfs_read_file : kmalloc failed\n" ); + goto out; + } + n =0 ; +while (count >0 ) { + cur =min_t (ssize_t, count,PAGE_SIZE ); + err =os_read_file (fd, new_buf, cur); +if (err <0 ) { +printk (KERN_ERR "hppfs_read : read failed, " +"errno = %d\n" , err); + n = err; + goto out_free; + }else if (err ==0 ) +break ; + +if (copy_to_user (buf, new_buf, err)) { + n = -EFAULT ; + goto out_free; + } + n += err; + count -= err; + } + out_free: +kfree (new_buf); + out: +return n; +} + +static ssize_t hppfs_read (struct file *file,char __user *buf,size_t count, +loff_t *ppos) +{ +struct hppfs_private *hppfs = file->private_data; +struct hppfs_data *data; +loff_t off; +int err; + +if (hppfs->contents !=NULL ) { +int rem; + +if (*ppos >= hppfs->len) +return 0 ; + + data = hppfs->contents; + off = *ppos; +while (off >=sizeof (data->contents)) { + data = list_entry(data->list.next, struct hppfs_data, + list); + off -=sizeof (data->contents); + } + +if (off + count > hppfs->len) + count = hppfs->len - off; + rem =copy_to_user (buf, &data->contents[off], count); + *ppos += count - rem; +if (rem >0 ) +return -EFAULT ; + }else if (hppfs->host_fd !=-1 ) { + err =os_seek_file (hppfs->host_fd, *ppos); +if (err) { +printk (KERN_ERR "hppfs_read : seek failed, " +"errno = %d\n" , err); +return err; + } + count =hppfs_read_file (hppfs->host_fd, buf, count); +if (count >0 ) + *ppos += count; + } +else count =read_proc (hppfs->proc_file, buf, count, ppos,1 ); + +return count; +} + +static ssize_t hppfs_write (struct file *file,const char __user *buf, +size_t len,loff_t *ppos) +{ +struct hppfs_private *data = file->private_data; +struct file *proc_file = data->proc_file; +ssize_t (*write)(struct file *,const char __user *,size_t ,loff_t *); + + write = proc_file->f_path.dentry->d_inode->i_fop->write; +return (*write)(proc_file, buf, len, ppos); +} + +static int open_host_sock (char *host_file,int *filter_out) +{ +char *end; +int fd; + + end = &host_file[strlen (host_file)]; +strcpy (end,"/rw" ); + *filter_out =1 ; + fd =os_connect_socket (host_file); +if (fd >0 ) +return fd; + +strcpy (end,"/r" ); + *filter_out =0 ; + fd =os_connect_socket (host_file); +return fd; +} + +static void free_contents (struct hppfs_data *head) +{ +struct hppfs_data *data; +struct list_head *ele, *next; + +if (head ==NULL ) +return ; + +list_for_each_safe (ele, next, &head->list) { + data = list_entry(ele, struct hppfs_data, list); +kfree (data); + } +kfree (head); +} + +static struct hppfs_data *hppfs_get_data (int fd,int filter, +struct file *proc_file, +struct file *hppfs_file, +loff_t *size_out) +{ +struct hppfs_data *data, *new, *head; +int n, err; + + err = -ENOMEM ; + data =kmalloc (sizeof (*data),GFP_KERNEL ); +if (data ==NULL ) { +printk (KERN_ERR "hppfs_get_data : head allocation failed\n" ); + goto failed; + } + +INIT_LIST_HEAD (&data->list); + + head = data; + *size_out =0 ; + +if (filter) { +while ((n =read_proc (proc_file, data->contents, +sizeof (data->contents),NULL ,0 )) >0 ) +os_write_file (fd, data->contents, n); + err =os_shutdown_socket (fd,0 ,1 ); +if (err) { +printk (KERN_ERR "hppfs_get_data : failed to shut down " +"socket\n" ); + goto failed_free; + } + } +while (1 ) { + n =os_read_file (fd, data->contents,sizeof (data->contents)); +if (n <0 ) { + err = n; +printk (KERN_ERR "hppfs_get_data : read failed, " +"errno = %d\n" , err); + goto failed_free;
fs/hppfs/hppfs.c line 383
Quoted 10 lines
fs/hppfs/hppfs.c new file +10
-0+ }else if (n ==0 ) +break ; + + *size_out += n; + +if (n <sizeof (data->contents)) +break ; + + new =kmalloc (sizeof (*data),GFP_KERNEL ); +if (new ==0 ) {
Using NULL is better, at least sparse complains about this. ;)
Quoted 163 lines
fs/hppfs/hppfs.c new file +163
-0+printk (KERN_ERR "hppfs_get_data : data allocation " +"failed\n" ); + err = -ENOMEM ; + goto failed_free; + } + +INIT_LIST_HEAD (&new->list); +list_add (&new->list, &data->list); + data = new; + } +return head; + + failed_free: +free_contents (head); + failed: +return ERR_PTR (err); +} + +static struct hppfs_private *hppfs_data (void ) +{ +struct hppfs_private *data; + + data =kmalloc (sizeof (*data),GFP_KERNEL ); +if (data ==NULL ) +return data; + + *data = ((struct hppfs_private ) { .host_fd =-1 , + .len =-1 , + .contents =NULL } ); +return data; +} + +static int file_mode (int fmode) +{ +if (fmode == (FMODE_READ |FMODE_WRITE )) +return O_RDWR ; +if (fmode ==FMODE_READ ) +return O_RDONLY ; +if (fmode ==FMODE_WRITE ) +return O_WRONLY ; +return 0 ; +} + +static int hppfs_open (struct inode *inode,struct file *file) +{ +struct hppfs_private *data; +struct vfsmount *proc_mnt; +struct dentry *proc_dentry; +char *host_file; +int err, fd, type, filter; + + err = -ENOMEM ; + data =hppfs_data (); +if (data ==NULL ) + goto out; + + host_file =dentry_name (file->f_path.dentry,strlen ("/rw" )); +if (host_file ==NULL ) + goto out_free2; + + proc_dentry =HPPFS_I (inode)->proc_dentry; + proc_mnt = inode->i_sb->s_fs_info; + +/* XXX This isn't closed anywhere */ + data->proc_file =dentry_open (dget (proc_dentry),mntget (proc_mnt), +file_mode (file->f_mode)); + err =PTR_ERR (data->proc_file); +if (IS_ERR (data->proc_file)) + goto out_free1; + + type =os_file_type (host_file); +if (type ==OS_TYPE_FILE ) { + fd =os_open_file (host_file,of_read (OPENFLAGS ()),0 ); +if (fd >=0 ) + data->host_fd = fd; +else +printk (KERN_ERR "hppfs_open : failed to open '%s', " +"errno = %d\n" , host_file, -fd); + + data->contents =NULL ; + }else if (type ==OS_TYPE_DIR ) { + fd =open_host_sock (host_file, &filter); +if (fd >0 ) { + data->contents =hppfs_get_data (fd, filter, + data->proc_file, + file, &data->len); +if (!IS_ERR (data->contents)) + data->host_fd = fd; + }else +printk (KERN_ERR "hppfs_open : failed to open a socket " +"in '%s', errno = %d\n" , host_file, -fd); + } +kfree (host_file); + + file->private_data = data; +return 0 ; + + out_free1: +kfree (host_file); + out_free2: +free_contents (data->contents); +kfree (data); + out: +return err; +} + +static int hppfs_dir_open (struct inode *inode,struct file *file) +{ +struct hppfs_private *data; +struct vfsmount *proc_mnt; +struct dentry *proc_dentry; +int err; + + err = -ENOMEM ; + data =hppfs_data (); +if (data ==NULL ) + goto out; + + proc_dentry =HPPFS_I (inode)->proc_dentry; + proc_mnt = inode->i_sb->s_fs_info; + data->proc_file =dentry_open (dget (proc_dentry),mntget (proc_mnt), +file_mode (file->f_mode)); + err =PTR_ERR (data->proc_file); +if (IS_ERR (data->proc_file)) + goto out_free; + + file->private_data = data; +return 0 ; + + out_free: +kfree (data); + out: +return err; +} + +static loff_t hppfs_llseek (struct file *file,loff_t off,int where) +{ +struct hppfs_private *data = file->private_data; +struct file *proc_file = data->proc_file; +loff_t (*llseek)(struct file *,loff_t ,int ); +loff_t ret; + + llseek = proc_file->f_path.dentry->d_inode->i_fop->llseek; +if (llseek !=NULL ) { + ret = (*llseek)(proc_file, off, where); +if (ret <0 ) +return ret; + } + +return default_llseek (file, off, where); +} + +static const struct file_operations hppfs_file_fops = { + .owner =NULL , + .llseek = hppfs_llseek, + .read = hppfs_read, + .write = hppfs_write, + .open = hppfs_open, +}; + +struct hppfs_dirent { +void *vfs_dirent; +filldir_t filldir;
fs/hppfs/hppfs.c line 556
Quoted 10 lines
fs/hppfs/hppfs.c new file +10
-0+struct dentry *dentry; +}; + +static int hppfs_filldir (void *d,const char *name,int size, +loff_t offset,u64 inode,unsigned int type) +{ +struct hppfs_dirent *dirent = d; + +if (file_removed (dirent->dentry, name)) +return 0 ;
If returning 0 indicates success, this is wrong, since file_removed() may return -ENOMEM.
Or I miss something that is too obvious? ;-)
<snip>
Thanks!
Cong
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
User-mode-linux-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
Quoted 20 lines · WANG Cong
Quoted 20 lines
fs/hppfs/hppfs.c new file +20
-0+static struct inode *get_inode (struct super_block *,struct dentry *); + +struct hppfs_data { +struct list_head list; +char contents[PAGE_SIZE -sizeof (struct list_head )]; +}; + +struct hppfs_private { +struct file *proc_file; +int host_fd; +loff_t len; +struct hppfs_data *contents; +}; + +struct hppfs_inode_info { +struct dentry *proc_dentry; +struct inode vfs_inode; +}; + +static inline struct hppfs_inode_info *HPPFS_I (struct inode *inode)
Quoted 8 lines
fs/hppfs/hppfs.c line 45
Quoted 5 lines
fs/hppfs/hppfs.c new file +5
-0+{ + return container_of(inode, struct hppfs_inode_info, vfs_inode); +} + +#define HPPFS_SUPER_MAGIC 0xb00000eeThese can be put into a single header, e.g.
hppfs.h.
Why, when this one C file is the only user?
Quoted 11 lines
fs/hppfs/hppfs.c line 73
Quoted 9 lines
fs/hppfs/hppfs.c new file +9
-0+static char *dentry_name (struct dentry *dentry,int extra) +{ +struct dentry *parent; +char *root, *name; +const char *seg_name; +int len, seg_len; + + len =0 ; + parent = dentry;These can be put into initialization, I think, that's more readable.
Yup.
Quoted 7 lines
fs/hppfs/hppfs.c line 134
Quoted 4 lines
fs/hppfs/hppfs.c new file +4
-0+if (fd >0 ) { +os_close_file (fd); +return 1 ; + }How about 'fd < 0' ?
OK, that would remove the braces at least...
Quoted 5 lines
fs/hppfs/hppfs.c line 383
Quoted 2 lines
fs/hppfs/hppfs.c new file +2
-0+ new =kmalloc (sizeof (*data),GFP_KERNEL ); +if (new ==0 ) {Using NULL is better, at least sparse complains about this. ;)
Good, I never liked using 0 (or !ptr) in place of NULL anyway.
Quoted 11 lines
fs/hppfs/hppfs.c line 556
Quoted 7 lines
fs/hppfs/hppfs.c new file +7
-0+static int hppfs_filldir (void *d,const char *name,int size, +loff_t offset,u64 inode,unsigned int type) +{ +struct hppfs_dirent *dirent = d; + +if (file_removed (dirent->dentry, name)) +return 0 ;If returning 0 indicates success, this is wrong, since
file_removed()may return-ENOMEM.
Quoted 1 line
Or I miss something that is too obvious? ;-)
Oops, nice spotting.
See what you think about the patch below...
Jeff
Signature · 105 lines
Work email - jdike at linux dot intel dot com
Index: linux-2.6.22/fs/hppfs/hppfs.c
===================================================================
--- linux-2.6.22.orig/fs/hppfs/hppfs.c 2008-04-28 11:21:38.000000000 -0400
+++ linux-2.6.22/fs/hppfs/hppfs.c 2008-04-28 11:34:58.000000000 -0400
@@ -64,13 +64,11 @@ static int is_pid(struct dentry *dentry)
static char *dentry_name(struct dentry *dentry, int extra)
{
- struct dentry *parent;
- char *root, *name;
+ struct dentry *parent = dentry;
+ char *root = "proc", *name;
const char *seg_name;
- int len, seg_len;
+ int len = 0, seg_len;
- len = 0;
- parent = dentry;
while (parent->d_parent != parent) {
if (is_pid(parent))
len += strlen("pid") + 1;
@@ -78,7 +76,6 @@ static char *dentry_name(struct dentry *
parent = parent->d_parent;
}
- root = "proc";
len += strlen(root);
name = kmalloc(len + extra + 1, GFP_KERNEL);
if (name == NULL)
@@ -128,11 +125,11 @@ static int file_removed(struct dentry *d
fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
kfree(host_file);
- if (fd > 0) {
- os_close_file(fd);
- return 1;
- }
- return 0;
+ if (fd < 0)
+ return 0;
+
+ os_close_file(fd);
+ return 1;
}
static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
@@ -210,11 +207,10 @@ static ssize_t read_proc(struct file *fi
static ssize_t hppfs_read_file(int fd, char __user *buf, ssize_t count)
{
- ssize_t n;
+ ssize_t n = -ENOMEM;
int cur, err;
char *new_buf;
- n = -ENOMEM;
new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (new_buf == NULL) {
printk(KERN_ERR "hppfs_read_file : kmalloc failed\n");
@@ -271,8 +267,10 @@ static ssize_t hppfs_read(struct file *f
count = hppfs->len - off;
rem = copy_to_user(buf, &data->contents[off], count);
*ppos += count - rem;
- if (rem > 0)
+ if (rem == count)
return -EFAULT;
+ else if (rem > 0)
+ return count - rem;
} else if (hppfs->host_fd != -1) {
err = os_seek_file(hppfs->host_fd, *ppos);
if (err) {
@@ -380,7 +378,7 @@ static struct hppfs_data *hppfs_get_data
break;
new = kmalloc(sizeof(*data), GFP_KERNEL);
- if (new == 0) {
+ if (new == NULL) {
printk(KERN_ERR "hppfs_get_data : data allocation "
"failed\n");
err = -ENOMEM;
@@ -551,8 +549,11 @@ static int hppfs_filldir(void *d, const
loff_t offset, u64 inode, unsigned int type)
{
struct hppfs_dirent *dirent = d;
+ int gone = file_removed(dirent->dentry, name);
- if (file_removed(dirent->dentry, name))
+ if (gone < 0)
+ return gone;
+ else if (gone)
return 0;
return (*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-develQuoted 30 lines · Jeff Dike
Quoted 20 lines · WANG Cong
Quoted 20 lines
fs/hppfs/hppfs.c new file +20
-0+static struct inode *get_inode (struct super_block *,struct dentry *); + +struct hppfs_data { +struct list_head list; +char contents[PAGE_SIZE -sizeof (struct list_head )]; +}; + +struct hppfs_private { +struct file *proc_file; +int host_fd; +loff_t len; +struct hppfs_data *contents; +}; + +struct hppfs_inode_info { +struct dentry *proc_dentry; +struct inode vfs_inode; +}; + +static inline struct hppfs_inode_info *HPPFS_I (struct inode *inode)Quoted 8 lines
fs/hppfs/hppfs.c line 45
Quoted 5 lines
fs/hppfs/hppfs.c new file +5
-0+{ + return container_of(inode, struct hppfs_inode_info, vfs_inode); +} + +#define HPPFS_SUPER_MAGIC 0xb00000eeThese can be put into a single header, e.g.
hppfs.h.
Quoted 1 line
Why, when this one C file is the only user?
Just looks cleaner for me. ;-)
<snip>
Quoted 4 lines
Oops, nice spotting.
See what you think about the patch below...
<snip>
This patch looks OK for me. Thank you!
Cong
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
User-mode-linux-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel