[PATCH 06/12] HPPFS: add ->release method to fix struct file leak

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

 



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

When hppfs_open is called, we in turn open with dentry_open a file,
referring to the file we are wrapping, and also other resources are
allocated (including a host fd - I have a old report of fd leaks with
hppfs, and this patch seems quite the fix to it).

Add a release method to release all these resources.

Also, clean whitespace where I'm touching code and remove an unused
parameter.

And add copyright.
Signed-off-by: Paolo 'Blaisorblade' Giarrusso <[email protected]>
---

 fs/hppfs/hppfs_kern.c |   47 ++++++++++++++++++++++++++++++++++-------------
 1 files changed, 34 insertions(+), 13 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
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2002 Jeff Dike ([email protected])
+ * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso <[email protected]>
  * Licensed under the GPL
  */
 
@@ -316,6 +317,7 @@ static ssize_t hppfs_read(struct file *f
 
 		if(off + count > hppfs->len)
 			count = hppfs->len - off;
+		/*XXX: we should walk the list of remaining buffers! */
 		err = copy_to_user(buf, &data->contents[off], count);
 		count -= err;
 		if (!count)
@@ -388,7 +390,6 @@ static void free_contents(struct hppfs_d
 
 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;
@@ -502,7 +503,6 @@ static int hppfs_open(struct inode *inod
 
 	proc_dentry = HPPFS_I(inode)->proc_dentry;
 
-	/* XXX This isn't closed anywhere */
 	data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_submnt),
 				      file_mode(file->f_mode));
 	err = PTR_ERR(data->proc_file);
@@ -510,7 +510,7 @@ static int hppfs_open(struct inode *inod
 		goto out_free1;
 
 	type = os_file_type(host_file);
-	if(type == OS_TYPE_FILE){
+	if (type == OS_TYPE_FILE) {
 		fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
 		if (fd >= 0)
 			data->host_fd = fd;
@@ -518,33 +518,53 @@ static int hppfs_open(struct inode *inod
 			    host_file, -fd);
 
 		data->contents = NULL;
-	}
-	else if(type == OS_TYPE_DIR){
+	} 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->len);
+			if (likely(!IS_ERR(data->contents))) {
 				data->host_fd = fd;
-		}
-		else printk("hppfs_open : failed to open a socket in "
+			} else {
+				printk("hppfs_open : failed to read data from "
+						"host, err = %ld\n",
+						PTR_ERR(data->contents));
+				data->contents = NULL;
+			}
+		} else {
+			printk("hppfs_open : failed to open a socket in "
 			    "'%s', err = %d\n", host_file, -fd);
+		}
 	}
 	kfree(host_file);
 
 	file->private_data = data;
 	return(0);
 
- out_free1:
+out_free1:
 	kfree(host_file);
- out_free2:
-	free_contents(data->contents);
+out_free2:
 	kfree(data);
- out:
+out:
 	return(err);
 }
 
+static int hppfs_release(struct inode *inode, struct file *file)
+{
+	struct hppfs_private *data = file->private_data;
+
+	WARN_ON(file_count(data->proc_file) != 1);
+	fput(data->proc_file);
+	free_contents(data->contents);
+
+	/* close() works on sockets too. */
+	os_close_file(data->host_fd);
+
+	kfree(data);
+	return 0;
+}
+
 static int hppfs_dir_open(struct inode *inode, struct file *file)
 {
 	struct hppfs_private *data;
@@ -595,6 +615,7 @@ static struct file_operations hppfs_file
 	.read		= hppfs_read,
 	.write		= hppfs_write,
 	.open		= hppfs_open,
+	.release	= hppfs_release,
 };
 
 struct hppfs_dirent {

-
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