Commit a0612b1f authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

uml: hppfs fixes

hppfs tidying and fixes noticed during hch's get_inode work -
      style fixes
      a copy_to_user got its return value checked
      hppfs_write no longer fiddles file->f_pos because it gets and
returns pos in its arguments
      hppfs_delete_inode dputs the underlyng procfs dentry stored in
its private data and mntputs the vfsmnt stashed in s_fs_info
      hppfs_put_super no longer needs to mntput the s_fs_info, so it
no longer needs to exist
      hppfs_readlink and hppfs_follow_link were doing a bunch of stuff
with a struct file which they didn't use
      there is now a ->permission which calls generic_permission
      get_inode was always returning 0 for some reason - it now
returns an inode if nothing bad happened
Signed-off-by: default avatarJeff Dike <jdike@linux.intel.com>
Cc: WANG Cong <xiyou.wangcong@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 96cee304
...@@ -52,7 +52,7 @@ static int is_pid(struct dentry *dentry) ...@@ -52,7 +52,7 @@ static int is_pid(struct dentry *dentry)
int i; int i;
sb = dentry->d_sb; sb = dentry->d_sb;
if ((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root)) if (dentry->d_parent != sb->s_root)
return 0; return 0;
for (i = 0; i < dentry->d_name.len; i++) { for (i = 0; i < dentry->d_name.len; i++) {
...@@ -254,6 +254,8 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count, ...@@ -254,6 +254,8 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
int err; int err;
if (hppfs->contents != NULL) { if (hppfs->contents != NULL) {
int rem;
if (*ppos >= hppfs->len) if (*ppos >= hppfs->len)
return 0; return 0;
...@@ -267,8 +269,10 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count, ...@@ -267,8 +269,10 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
if (off + count > hppfs->len) if (off + count > hppfs->len)
count = hppfs->len - off; count = hppfs->len - off;
copy_to_user(buf, &data->contents[off], count); rem = copy_to_user(buf, &data->contents[off], count);
*ppos += count; *ppos += count - rem;
if (rem > 0)
return -EFAULT;
} else if (hppfs->host_fd != -1) { } else if (hppfs->host_fd != -1) {
err = os_seek_file(hppfs->host_fd, *ppos); err = os_seek_file(hppfs->host_fd, *ppos);
if (err) { if (err) {
...@@ -285,21 +289,15 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count, ...@@ -285,21 +289,15 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
return count; return count;
} }
static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len, static ssize_t hppfs_write(struct file *file, const char __user *buf,
loff_t *ppos) size_t len, loff_t *ppos)
{ {
struct hppfs_private *data = file->private_data; struct hppfs_private *data = file->private_data;
struct file *proc_file = data->proc_file; struct file *proc_file = data->proc_file;
ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
int err;
write = proc_file->f_path.dentry->d_inode->i_fop->write; write = proc_file->f_path.dentry->d_inode->i_fop->write;
return (*write)(proc_file, buf, len, ppos);
proc_file->f_pos = file->f_pos;
err = (*write)(proc_file, buf, len, &proc_file->f_pos);
file->f_pos = proc_file->f_pos;
return err;
} }
static int open_host_sock(char *host_file, int *filter_out) static int open_host_sock(char *host_file, int *filter_out)
...@@ -429,8 +427,8 @@ static int file_mode(int fmode) ...@@ -429,8 +427,8 @@ static int file_mode(int fmode)
static int hppfs_open(struct inode *inode, struct file *file) static int hppfs_open(struct inode *inode, struct file *file)
{ {
struct hppfs_private *data; struct hppfs_private *data;
struct dentry *proc_dentry;
struct vfsmount *proc_mnt; struct vfsmount *proc_mnt;
struct dentry *proc_dentry;
char *host_file; char *host_file;
int err, fd, type, filter; int err, fd, type, filter;
...@@ -492,8 +490,8 @@ static int hppfs_open(struct inode *inode, struct file *file) ...@@ -492,8 +490,8 @@ static int hppfs_open(struct inode *inode, struct file *file)
static int hppfs_dir_open(struct inode *inode, struct file *file) static int hppfs_dir_open(struct inode *inode, struct file *file)
{ {
struct hppfs_private *data; struct hppfs_private *data;
struct dentry *proc_dentry;
struct vfsmount *proc_mnt; struct vfsmount *proc_mnt;
struct dentry *proc_dentry;
int err; int err;
err = -ENOMEM; err = -ENOMEM;
...@@ -620,6 +618,9 @@ static struct inode *hppfs_alloc_inode(struct super_block *sb) ...@@ -620,6 +618,9 @@ static struct inode *hppfs_alloc_inode(struct super_block *sb)
void hppfs_delete_inode(struct inode *ino) void hppfs_delete_inode(struct inode *ino)
{ {
dput(HPPFS_I(ino)->proc_dentry);
mntput(ino->i_sb->s_fs_info);
clear_inode(ino); clear_inode(ino);
} }
...@@ -628,69 +629,46 @@ static void hppfs_destroy_inode(struct inode *inode) ...@@ -628,69 +629,46 @@ static void hppfs_destroy_inode(struct inode *inode)
kfree(HPPFS_I(inode)); kfree(HPPFS_I(inode));
} }
static void hppfs_put_super(struct super_block *sb)
{
mntput(sb->s_fs_info);
}
static const struct super_operations hppfs_sbops = { static const struct super_operations hppfs_sbops = {
.alloc_inode = hppfs_alloc_inode, .alloc_inode = hppfs_alloc_inode,
.destroy_inode = hppfs_destroy_inode, .destroy_inode = hppfs_destroy_inode,
.delete_inode = hppfs_delete_inode, .delete_inode = hppfs_delete_inode,
.statfs = hppfs_statfs, .statfs = hppfs_statfs,
.put_super = hppfs_put_super,
}; };
static int hppfs_readlink(struct dentry *dentry, char __user *buffer, static int hppfs_readlink(struct dentry *dentry, char __user *buffer,
int buflen) int buflen)
{ {
struct file *proc_file;
struct dentry *proc_dentry; struct dentry *proc_dentry;
struct vfsmount *proc_mnt;
int ret;
proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
proc_mnt = dentry->d_sb->s_fs_info; return proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer,
buflen);
proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
if (IS_ERR(proc_file))
return PTR_ERR(proc_file);
ret = proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, buflen);
fput(proc_file);
return ret;
} }
static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) static void *hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{ {
struct file *proc_file;
struct dentry *proc_dentry; struct dentry *proc_dentry;
struct vfsmount *proc_mnt;
void *ret;
proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
proc_mnt = dentry->d_sb->s_fs_info;
proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
if (IS_ERR(proc_file))
return proc_file;
ret = proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
fput(proc_file); return proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
}
return ret; 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 = { static const struct inode_operations hppfs_dir_iops = {
.lookup = hppfs_lookup, .lookup = hppfs_lookup,
.permission = hppfs_permission,
}; };
static const struct inode_operations hppfs_link_iops = { static const struct inode_operations hppfs_link_iops = {
.readlink = hppfs_readlink, .readlink = hppfs_readlink,
.follow_link = hppfs_follow_link, .follow_link = hppfs_follow_link,
.permission = hppfs_permission,
}; };
static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
...@@ -712,7 +690,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) ...@@ -712,7 +690,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
inode->i_fop = &hppfs_file_fops; inode->i_fop = &hppfs_file_fops;
} }
HPPFS_I(inode)->proc_dentry = dentry; HPPFS_I(inode)->proc_dentry = dget(dentry);
inode->i_uid = proc_ino->i_uid; inode->i_uid = proc_ino->i_uid;
inode->i_gid = proc_ino->i_gid; inode->i_gid = proc_ino->i_gid;
...@@ -725,7 +703,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) ...@@ -725,7 +703,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
inode->i_size = proc_ino->i_size; inode->i_size = proc_ino->i_size;
inode->i_blocks = proc_ino->i_blocks; inode->i_blocks = proc_ino->i_blocks;
return 0; return inode;
} }
static int hppfs_fill_super(struct super_block *sb, void *d, int silent) static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment