[PATCH 03/12] HPPFS: various simple fixes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Paolo 'Blaisorblade' Giarrusso <[email protected]>

*) Fix Oops when the underlying file doesn't support
read/write/follow_link/read_link (ported from 2.4)

*) fix get_fs()/set_fs() stuff - would affect anything with get_fs() ==
KERNEL_DS calling hppfs_open, i.e. opening a file.

*) forward-port various fixes from 2.4

*) better error handling, and correct error messages

*) learn that if open() returned 0, it succeeded (see 1st hunk in the
patch).

*) also various whitespace and codingstyle cleanups.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <[email protected]>
---

 fs/hppfs/hppfs_kern.c |  110 +++++++++++++++++++++++++++++++------------------
 1 files changed, 70 insertions(+), 40 deletions(-)

diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -128,7 +128,7 @@ static int file_removed(struct dentry *d
 
 	fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
 	kfree(host_file);
-	if(fd > 0){
+	if (fd >= 0) {
 		os_close_file(fd);
 		return(1);
 	}
@@ -221,16 +221,22 @@ static ssize_t read_proc(struct file *fi
 {
 	ssize_t (*read)(struct file *, char *, size_t, loff_t *);
 	ssize_t n;
+	mm_segment_t old_fs;
 
 	read = file->f_dentry->d_inode->i_fop->read;
 
-	if(!is_user)
+	if (read == NULL)
+		return -EINVAL;
+
+	if (!is_user) {
+		old_fs = get_fs();
 		set_fs(KERNEL_DS);
+	}
 
 	n = (*read)(file, buf, count, &file->f_pos);
 
-	if(!is_user)
-		set_fs(USER_DS);
+	if (!is_user)
+		set_fs(old_fs);
 
 	if(ppos) *ppos = file->f_pos;
 	return n;
@@ -253,8 +259,7 @@ static ssize_t hppfs_read_file(int fd, c
 		cur = min_t(ssize_t, count, PAGE_SIZE);
 		err = os_read_file(fd, new_buf, cur);
 		if(err < 0){
-			printk("hppfs_read : read failed, errno = %d\n",
-			       err);
+			printk("hppfs_read : read failed, errno = %d\n", -err);
 			n = err;
 			goto out_free;
 		}
@@ -282,7 +287,7 @@ static ssize_t hppfs_read(struct file *f
 	loff_t off;
 	int err;
 
-	if(hppfs->contents != NULL){
+	if (hppfs->contents != NULL) {
 		if(*ppos >= hppfs->len) return(0);
 
 		data = hppfs->contents;
@@ -297,18 +302,17 @@ static ssize_t hppfs_read(struct file *f
 			count = hppfs->len - off;
 		copy_to_user(buf, &data->contents[off], count);
 		*ppos += count;
-	}
-	else if(hppfs->host_fd != -1){
+	} else if(hppfs->host_fd != -1) {
 		err = os_seek_file(hppfs->host_fd, *ppos);
-		if(err){
+		if (err < 0){
 			printk("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);
+	} else
+		count = read_proc(hppfs->proc_file, buf, count, ppos, 1);
 
 	return(count);
 }
@@ -323,6 +327,9 @@ static ssize_t hppfs_write(struct file *
 
 	write = proc_file->f_dentry->d_inode->i_fop->write;
 
+	if (write == NULL)
+		return -EINVAL;
+
 	proc_file->f_pos = file->f_pos;
 	err = (*write)(proc_file, buf, len, &proc_file->f_pos);
 	file->f_pos = proc_file->f_pos;
@@ -339,7 +346,7 @@ static int open_host_sock(char *host_fil
 	strcpy(end, "/rw");
 	*filter_out = 1;
 	fd = os_connect_socket(host_file);
-	if(fd > 0)
+	if (fd >= 0)
 		return(fd);
 
 	strcpy(end, "/r");
@@ -368,9 +375,9 @@ static struct hppfs_data *hppfs_get_data
 					 loff_t *size_out)
 {
 	struct hppfs_data *data, *new, *head;
-	int n, err;
+	int ret;
 
-	err = -ENOMEM;
+	ret = -ENOMEM;
 	data = kmalloc(sizeof(*data), GFP_KERNEL);
 	if(data == NULL){
 		printk("hppfs_get_data : head allocation failed\n");
@@ -382,37 +389,44 @@ static struct hppfs_data *hppfs_get_data
 	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){
+	if (filter) {
+		int err = 0;
+		while ((ret = read_proc(proc_file, data->contents,
+			     sizeof(data->contents), NULL, 0)) > 0) {
+			err = os_write_file(fd, data->contents, ret);
+			if (err != ret)
+				printk("hppfs_get_data : failed to write out "
+				       "%d bytes, err = %d\n", ret, -err);
+		}
+		ret = os_shutdown_socket(fd, 0, 1);
+		if (ret) {
 			printk("hppfs_get_data : failed to shut down "
 			       "socket\n");
 			goto failed_free;
 		}
+		/* Handle this *after* closing the socket. */
+		if (err)
+			goto failed_free;
 	}
-	while(1){
-		n = os_read_file(fd, data->contents, sizeof(data->contents));
-		if(n < 0){
-			err = n;
+	while (1) {
+		ret = os_read_file(fd, data->contents, sizeof(data->contents));
+		if (ret < 0) {
 			printk("hppfs_get_data : read failed, errno = %d\n",
-			       err);
+			       -ret);
 			goto failed_free;
 		}
-		else if(n == 0)
+		else if(ret == 0)
 			break;
 
-		*size_out += n;
+		*size_out += ret;
 
-		if(n < sizeof(data->contents))
+		if(ret < sizeof(data->contents))
 			break;
 
 		new = kmalloc(sizeof(*data), GFP_KERNEL);
 		if(new == 0){
 			printk("hppfs_get_data : data allocation failed\n");
-			err = -ENOMEM;
+			ret = -ENOMEM;
 			goto failed_free;
 		}
 
@@ -420,12 +434,12 @@ static struct hppfs_data *hppfs_get_data
 		list_add(&new->list, &data->list);
 		data = new;
 	}
-	return(head);
+	return head;
 
- failed_free:
+failed_free:
 	free_contents(head);
- failed:
-	return(ERR_PTR(err));
+failed:
+	return ERR_PTR(ret);
 }
 
 static struct hppfs_private *hppfs_data(void)
@@ -481,16 +495,16 @@ static int hppfs_open(struct inode *inod
 	type = os_file_type(host_file);
 	if(type == OS_TYPE_FILE){
 		fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
-		if(fd >= 0)
+		if (fd >= 0)
 			data->host_fd = fd;
-		else printk("hppfs_open : failed to open '%s', errno = %d\n",
+		else printk("hppfs_open : failed to open '%s', err = %d\n",
 			    host_file, -fd);
 
 		data->contents = NULL;
 	}
 	else if(type == OS_TYPE_DIR){
 		fd = open_host_sock(host_file, &filter);
-		if(fd > 0){
+		if (fd >= 0){
 			data->contents = hppfs_get_data(fd, filter,
 							data->proc_file,
 							file, &data->len);
@@ -498,7 +512,7 @@ static int hppfs_open(struct inode *inod
 				data->host_fd = fd;
 		}
 		else printk("hppfs_open : failed to open a socket in "
-			    "'%s', errno = %d\n", host_file, -fd);
+			    "'%s', err = %d\n", host_file, -fd);
 	}
 	kfree(host_file);
 
@@ -589,13 +603,15 @@ static int hppfs_readdir(struct file *fi
 	struct hppfs_private *data = file->private_data;
 	struct file *proc_file = data->proc_file;
 	int (*readdir)(struct file *, void *, filldir_t);
+	int err;
 	struct hppfs_dirent dirent = ((struct hppfs_dirent)
 		                      { .vfs_dirent  	= ent,
 					.filldir 	= filldir,
 					.dentry  	= file->f_dentry } );
-	int err;
 
 	readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
+	if (readdir == NULL)
+		return -ENOTDIR;
 
 	proc_file->f_pos = file->f_pos;
 	err = (*readdir)(proc_file, &dirent, hppfs_filldir);
@@ -662,6 +678,7 @@ static int hppfs_readlink(struct dentry 
 {
 	struct file *proc_file;
 	struct dentry *proc_dentry;
+	int (*readlink)(struct dentry *, char *, int);
 	int ret;
 
 	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
@@ -669,6 +686,10 @@ static int hppfs_readlink(struct dentry 
 	if (IS_ERR(proc_file))
 		return PTR_ERR(proc_file);
 
+	readlink = proc_dentry->d_inode->i_op->readlink;
+	if (readlink == NULL)
+		return -EINVAL;
+	ret = (*readlink)(proc_dentry, buffer, buflen);
 	ret = proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, buflen);
 
 	fput(proc_file);
@@ -680,6 +701,7 @@ static void* hppfs_follow_link(struct de
 {
 	struct file *proc_file;
 	struct dentry *proc_dentry;
+	void * (*follow_link)(struct dentry *, struct nameidata *);
 	void *ret;
 
 	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
@@ -687,7 +709,15 @@ static void* hppfs_follow_link(struct de
 	if (IS_ERR(proc_file))
 		return proc_file;
 
-	ret = proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
+	follow_link = proc_dentry->d_inode->i_op->follow_link;
+
+	/* XXX: I took this from 2.4, but we're only called when we're a
+	 * symbolic link (see init_inode S_ISLNK test below). Should we drop
+	 * this check? */
+	if (follow_link == NULL)
+		return ERR_PTR(-EOPNOTSUPP);
+
+	ret = follow_link(proc_dentry, nd);
 
 	fput(proc_file);
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux