* [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®