mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [patch] F_GETPATH implementation
@ 2008-04-14 19:40 Davide Libenzi
  2008-04-14 22:48 ` Linus Torvalds
  0 siblings, 1 reply; 3+ messages in thread
From: Davide Libenzi @ 2008-04-14 19:40 UTC (permalink / raw)
  To: Linux Kernel Mailing List
  Cc: Linus Torvalds, Andrew Morton, Arnd Bergmann, Al Viro,
	Michael Kerrisk, Christoph Hellwig

This is a small patch to support BSD's F_GETPATH on Linux. I removed the 
unneeded export, like Arnd pointed out.
IMO the simplicity of the patch and the portability advantages makes it 
worth it. I'll leave to others to further comments it.
Built and tested on my box against 2.6.25-rc9. Simple test program here:

http://www.xmailserver.org/fgetpath-test.c



Signed-off-by: Davide Libenzi <davidel@xmailserver.org>


- Davide


---
 fs/fcntl.c                  |   26 ++++++++++++++++++++++++++
 fs/proc/base.c              |   26 +-------------------------
 include/asm-generic/fcntl.h |    1 +
 include/linux/fs.h          |    1 +
 4 files changed, 29 insertions(+), 25 deletions(-)

Index: linux-2.6.mod/fs/fcntl.c
===================================================================
--- linux-2.6.mod.orig/fs/fcntl.c	2008-04-13 15:01:09.000000000 -0700
+++ linux-2.6.mod/fs/fcntl.c	2008-04-13 18:37:56.000000000 -0700
@@ -316,6 +316,28 @@
 	return pid;
 }
 
+int fcntl_getpath(struct path *fpath, char __user *path, int maxsize)
+{
+	int size;
+	char *buf, *pathname;
+
+	buf = (char *) __get_free_page(GFP_TEMPORARY);
+	if (!buf)
+		return -ENOMEM;
+	pathname = d_path(fpath, buf, PAGE_SIZE);
+	size = PTR_ERR(pathname);
+	if (IS_ERR(pathname))
+		goto error;
+	size = buf + PAGE_SIZE - 1 - pathname;
+	if (size > maxsize)
+		size = maxsize;
+	if (copy_to_user(path, pathname, size))
+		size = -EFAULT;
+error:
+	free_page((unsigned long) buf);
+	return size;
+}
+
 static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
 		struct file *filp)
 {
@@ -381,6 +403,10 @@
 	case F_NOTIFY:
 		err = fcntl_dirnotify(fd, filp, arg);
 		break;
+	case F_GETPATH:
+		err = fcntl_getpath(&filp->f_path, (char __user *) arg,
+				    PATH_MAX);
+		break;
 	default:
 		break;
 	}
Index: linux-2.6.mod/include/asm-generic/fcntl.h
===================================================================
--- linux-2.6.mod.orig/include/asm-generic/fcntl.h	2008-04-13 15:01:09.000000000 -0700
+++ linux-2.6.mod/include/asm-generic/fcntl.h	2008-04-13 18:37:35.000000000 -0700
@@ -73,6 +73,7 @@
 #define F_SETSIG	10	/* for sockets. */
 #define F_GETSIG	11	/* for sockets. */
 #endif
+#define F_GETPATH	12
 
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
Index: linux-2.6.mod/fs/proc/base.c
===================================================================
--- linux-2.6.mod.orig/fs/proc/base.c	2008-04-13 15:01:09.000000000 -0700
+++ linux-2.6.mod/fs/proc/base.c	2008-04-13 18:37:35.000000000 -0700
@@ -1192,30 +1192,6 @@
 	return ERR_PTR(error);
 }
 
-static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
-{
-	char *tmp = (char*)__get_free_page(GFP_TEMPORARY);
-	char *pathname;
-	int len;
-
-	if (!tmp)
-		return -ENOMEM;
-
-	pathname = d_path(path, tmp, PAGE_SIZE);
-	len = PTR_ERR(pathname);
-	if (IS_ERR(pathname))
-		goto out;
-	len = tmp + PAGE_SIZE - 1 - pathname;
-
-	if (len > buflen)
-		len = buflen;
-	if (copy_to_user(buffer, pathname, len))
-		len = -EFAULT;
- out:
-	free_page((unsigned long)tmp);
-	return len;
-}
-
 static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int buflen)
 {
 	int error = -EACCES;
@@ -1230,7 +1206,7 @@
 	if (error)
 		goto out;
 
-	error = do_proc_readlink(&path, buffer, buflen);
+	error = fcntl_getpath(&path, buffer, buflen);
 	path_put(&path);
 out:
 	return error;
Index: linux-2.6.mod/include/linux/fs.h
===================================================================
--- linux-2.6.mod.orig/include/linux/fs.h	2008-04-13 15:01:09.000000000 -0700
+++ linux-2.6.mod/include/linux/fs.h	2008-04-13 18:37:35.000000000 -0700
@@ -960,6 +960,7 @@
 /* only for net: no internal synchronization */
 extern void __kill_fasync(struct fasync_struct *, int, int);
 
+extern int fcntl_getpath(struct path *fpath, char __user *path, int maxsize);
 extern int __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
 extern int f_setown(struct file *filp, unsigned long arg, int force);
 extern void f_delown(struct file *filp);

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

* Re: [patch] F_GETPATH implementation
  2008-04-14 19:40 [patch] F_GETPATH implementation Davide Libenzi
@ 2008-04-14 22:48 ` Linus Torvalds
  2008-04-14 23:09   ` Davide Libenzi
  0 siblings, 1 reply; 3+ messages in thread
From: Linus Torvalds @ 2008-04-14 22:48 UTC (permalink / raw)
  To: Davide Libenzi
  Cc: Linux Kernel Mailing List, Andrew Morton, Arnd Bergmann, Al Viro,
	Michael Kerrisk, Christoph Hellwig



On Mon, 14 Apr 2008, Davide Libenzi wrote:
> Index: linux-2.6.mod/include/asm-generic/fcntl.h
> ===================================================================
> --- linux-2.6.mod.orig/include/asm-generic/fcntl.h	2008-04-13 15:01:09.000000000 -0700
> +++ linux-2.6.mod/include/asm-generic/fcntl.h	2008-04-13 18:37:35.000000000 -0700
> @@ -73,6 +73,7 @@
>  #define F_SETSIG	10	/* for sockets. */
>  #define F_GETSIG	11	/* for sockets. */
>  #endif
> +#define F_GETPATH	12

This won't work.

Different architectures have different F_xyzzy numbers, and 12 is already 
used by various ones (it's F_SETOWN in asm-parisc/fcntl.h, for example).

I think you'd have to do it in terms of F_LINUX_SPECIFIC_BASE, like 
F_NOTIFY is done, for example. That way you avoid these issues.

		Linus

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

* Re: [patch] F_GETPATH implementation
  2008-04-14 22:48 ` Linus Torvalds
@ 2008-04-14 23:09   ` Davide Libenzi
  0 siblings, 0 replies; 3+ messages in thread
From: Davide Libenzi @ 2008-04-14 23:09 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Linux Kernel Mailing List, Andrew Morton, Arnd Bergmann, Al Viro,
	Michael Kerrisk, Christoph Hellwig

On Mon, 14 Apr 2008, Linus Torvalds wrote:

> 
> 
> On Mon, 14 Apr 2008, Davide Libenzi wrote:
> > Index: linux-2.6.mod/include/asm-generic/fcntl.h
> > ===================================================================
> > --- linux-2.6.mod.orig/include/asm-generic/fcntl.h	2008-04-13 15:01:09.000000000 -0700
> > +++ linux-2.6.mod/include/asm-generic/fcntl.h	2008-04-13 18:37:35.000000000 -0700
> > @@ -73,6 +73,7 @@
> >  #define F_SETSIG	10	/* for sockets. */
> >  #define F_GETSIG	11	/* for sockets. */
> >  #endif
> > +#define F_GETPATH	12
> 
> This won't work.
> 
> Different architectures have different F_xyzzy numbers, and 12 is already 
> used by various ones (it's F_SETOWN in asm-parisc/fcntl.h, for example).
> 
> I think you'd have to do it in terms of F_LINUX_SPECIFIC_BASE, like 
> F_NOTIFY is done, for example. That way you avoid these issues.

Right. Will re-munge ...



- Davide



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

end of thread, other threads:[~2008-04-14 23:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-04-14 19:40 [patch] F_GETPATH implementation Davide Libenzi
2008-04-14 22:48 ` Linus Torvalds
2008-04-14 23:09   ` Davide Libenzi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®