All of lore.kernel.org
 help / color / mirror / Atom feed
* procfs proc_write_file bug
@ 2004-11-19 14:12 Petr Grillinger
  2004-11-19 16:26 ` Greg KH
  0 siblings, 1 reply; 9+ messages in thread
From: Petr Grillinger @ 2004-11-19 14:12 UTC (permalink / raw)
  To: linux-fsdevel

[-- Attachment #1: Type: text/plain, Size: 801 bytes --]

Hello,

I needed recently to write a large file into the /proc FS,
there is however a bug that makes this impossible. I am working
with 2.4.25 kernel, but the bug is present even in the 2.6 line.

The problem is that the proc_file_write function (in fs/proc/generic.c)
does not pass the file position (loff_r *ppos) to the registered
handling function - it cannot. The prototype for this function
(defined in include/linux/proc_fs.h) does not include the needed
argument.

I have made a patch that solves this problem by adding another hook
for an alternative write handler. This does not break old code using
the procfs write function and allows to write large files properly.
It is however not "very nice".

Do you have some ideas how to solve this problem?

(patch is attached)


	Petr Grillinger


[-- Attachment #2: linux-2.4.25-pg.patch --]
[-- Type: text/plain, Size: 3282 bytes --]

diff -uNrp linux-2.4.25-rtai/fs/proc/generic.c linux-2.4.25-pg/fs/proc/generic.c
--- linux-2.4.25-rtai/fs/proc/generic.c	2003-11-28 19:26:21.000000000 +0100
+++ linux-2.4.25-pg/fs/proc/generic.c	2004-11-19 14:20:40.000000000 +0100
@@ -120,20 +120,38 @@ proc_file_read(struct file * file, char 
 	return retval;
 }
 
-static ssize_t
-proc_file_write(struct file * file, const char * buffer,
-		size_t count, loff_t *ppos)
-{
-	struct inode *inode = file->f_dentry->d_inode;
-	struct proc_dir_entry * dp;
+
+/* 
+ * Added support for files larger than one PAGE 
+ * 2004/11/19, Petr Grillinger, pgrillin@kiv.zcu.cz 
+ *
+ * The old 'write_proc' entry doesn't allow to write files larger than one
+ * PAGE. A new 'write_proc2' entry can be used to implement an alternative
+ * handler - the new version handler gets an additional argument (ppos) which
+ * is a pointer to the current file position. The handler must update this
+ * position after each successful write operation - if there are more data from
+ * the user-space, it will be called again.
+ *
+ * The old interface is available with no changes. The new interface can be
+ * used by assigning a function address to the write_proc2 field of
+ * proc_dir_entry.  If a new interface function is available it is used instead
+ * of the old one.
+ *
+ * The handler should return the number of written bytes or a negative value
+ * for error conditions.
+ */
+static ssize_t proc_file_write(struct file * file, const char * buffer, size_t
+        count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode;
+    struct proc_dir_entry * dp;
 	
 	dp = (struct proc_dir_entry *) inode->u.generic_ip;
-
-	if (!dp->write_proc)
-		return -EIO;
-
-	/* FIXME: does this routine need ppos?  probably... */
-	return dp->write_proc(file, buffer, count, dp->data);
+   
+    if (dp->write_proc2)  /* new interface */
+        return dp->write_proc2(file, buffer, ppos, count, dp->data);
+    if (dp->write_proc)  /* old interface */
+        return dp->write_proc(file, buffer, count, dp->data);
+ 
+    return -EIO;
 }
 
 
diff -uNrp linux-2.4.25-rtai/include/linux/proc_fs.h linux-2.4.25-pg/include/linux/proc_fs.h
--- linux-2.4.25-rtai/include/linux/proc_fs.h	2003-11-28 19:26:21.000000000 +0100
+++ linux-2.4.25-pg/include/linux/proc_fs.h	2004-11-19 14:10:56.000000000 +0100
@@ -48,6 +48,13 @@ typedef	int (read_proc_t)(char *page, ch
 			  int count, int *eof, void *data);
 typedef	int (write_proc_t)(struct file *file, const char *buffer,
 			   unsigned long count, void *data);
+/* A write function must have the ppos pointer to be able to access
+ * larger files than one page. Not including it was a bug which 
+ * cannot be corrected without breaking old code. That is why there
+ * is a new write_proc2 entry in the proc_dir_entry structure that
+ * uses this corrected prototype. */
+typedef	int (write_proc2_t)(struct file *file, const char *buffer,
+			   loff_t *ppos, unsigned long count, void *data);
 typedef int (get_info_t)(char *, char **, off_t, int);
 
 struct proc_dir_entry {
@@ -67,6 +74,7 @@ struct proc_dir_entry {
 	void *data;
 	read_proc_t *read_proc;
 	write_proc_t *write_proc;
+	write_proc2_t *write_proc2;
 	atomic_t count;		/* use count */
 	int deleted;		/* delete flag */
 	kdev_t	rdev;

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2004-11-20  9:05 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-11-19 14:12 procfs proc_write_file bug Petr Grillinger
2004-11-19 16:26 ` Greg KH
2004-11-19 16:48   ` Petr Grillinger
2004-11-19 16:56     ` Greg KH
2004-11-19 18:21       ` Petr Grillinger
2004-11-19 18:28         ` Greg KH
2004-11-19 23:09     ` Bryan Henderson
2004-11-19 23:23       ` Greg KH
2004-11-20  9:05       ` Petr Grillinger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.