This patch adds functionality to mountfd so that a user can perform the
various types of umount (forced umount, not-busy umount, lazy-umount).
Signed-off-by: Mike Waychison <[email protected]>
---
fs/mountfd.c | 20 ++++++++++++++++++++
fs/namespace.c | 2 +-
include/linux/fs.h | 5 ++++-
3 files changed, 25 insertions(+), 2 deletions(-)
Index: linux-2.6.9-quilt/fs/mountfd.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/mountfd.c 2004-10-22 17:17:40.736271288 -0400
+++ linux-2.6.9-quilt/fs/mountfd.c 2004-10-22 17:17:41.367175376 -0400
@@ -11,6 +11,8 @@
#define VFSMOUNT(filp) ((struct vfsmount *)((filp)->private_data))
+extern int do_umount(struct vfsmount *mnt, int flags);
+
static struct vfsmount *mfdfs_mnt;
static void mfdfs_read_inode(struct inode *inode);
@@ -72,6 +74,18 @@ static int mfd_release(struct inode *ino
return 0;
}
+static long mfd_umount(struct file *mountfilp, int flags)
+{
+ struct vfsmount *mnt;
+ int error;
+
+ mnt = mntget(VFSMOUNT(mountfilp));
+
+ error = do_umount(mnt, flags);
+
+ return error;
+}
+
static int mfd_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
static struct file_operations mfd_file_ops = {
@@ -243,6 +257,12 @@ static int mfd_ioctl(struct inode *inode
switch (cmd) {
case MOUNTFD_IOC_GETDIRFD:
return mfd_getdirfd(filp);
+ case MOUNTFD_IOC_DETACH:
+ return mfd_umount(filp, MNT_DETACH);
+ case MOUNTFD_IOC_UNMOUNT:
+ return mfd_umount(filp, 0);
+ case MOUNTFD_IOC_FORCEDUNMOUNT:
+ return mfd_umount(filp, MNT_FORCE);
}
return -ENOTTY;
}
Index: linux-2.6.9-quilt/fs/namespace.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/namespace.c 2004-10-22 17:17:40.738270984 -0400
+++ linux-2.6.9-quilt/fs/namespace.c 2004-10-22 17:17:41.368175224 -0400
@@ -601,7 +601,7 @@ static void umount_tree(struct vfsmount
spin_lock(&vfsmount_lock);
}
-static int do_umount(struct vfsmount *mnt, int flags)
+int do_umount(struct vfsmount *mnt, int flags)
{
struct super_block * sb = mnt->mnt_sb;
int retval;
Index: linux-2.6.9-quilt/include/linux/fs.h
===================================================================
--- linux-2.6.9-quilt.orig/include/linux/fs.h 2004-10-22 17:17:40.739270832 -0400
+++ linux-2.6.9-quilt/include/linux/fs.h 2004-10-22 17:17:41.369175072 -0400
@@ -214,7 +214,10 @@ extern int leases_enable, dir_notify_ena
#define FIBMAP _IO(0x00,1) /* bmap access */
#define FIGETBSZ _IO(0x00,2) /* get the block size used for bmap */
-#define MOUNTFD_IOC_GETDIRFD _IO('p', 0xa0)
+#define MOUNTFD_IOC_GETDIRFD _IO('p', 0xa0)
+#define MOUNTFD_IOC_UNMOUNT _IO('p', 0xa1)
+#define MOUNTFD_IOC_DETACH _IO('p', 0xa2)
+#define MOUNTFD_IOC_FORCEDUNMOUNT _IO('p', 0xa3)
#ifdef __KERNEL__
Mount-related userspace tools will require the ability to detect whether what
looks like a regular directory is actually a autofs trigger. To handle this,
tools can statfs a given directory and check to see if statfs->f_type ==
AUTOFSNG_SUPER_MAGIC before walking into the directory (and causing the a
filesystem to automount).
To make this happen, we cannot allow statfs to follow_link.
NOTE: This may break any userspace that assumes it can statfs across a
last-component symlink. I can't think of any real world breakage however, as
mount(8) will drop the real path in /etc/mtab and /proc/mounts will always
show the true path.
Signed-off-by: Mike Waychison <[email protected]>
---
open.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
Index: linux-2.6.9-quilt/fs/open.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/open.c 2004-08-14 01:36:13.000000000 -0400
+++ linux-2.6.9-quilt/fs/open.c 2004-10-22 17:17:47.180291648 -0400
@@ -121,7 +121,7 @@ asmlinkage long sys_statfs(const char __
struct nameidata nd;
int error;
- error = user_path_walk(path, &nd);
+ error = user_path_walk_link(path, &nd);
if (!error) {
struct statfs tmp;
error = vfs_statfs_native(nd.dentry->d_inode->i_sb, &tmp);
@@ -140,7 +140,7 @@ asmlinkage long sys_statfs64(const char
if (sz != sizeof(*buf))
return -EINVAL;
- error = user_path_walk(path, &nd);
+ error = user_path_walk_link(path, &nd);
if (!error) {
struct statfs64 tmp;
error = vfs_statfs64(nd.dentry->d_inode->i_sb, &tmp);
Umounting direct mounts requires the ability to umount without following
->follow_link. We do this by adding a new flag called MNT_NOFOLLOW to
umount2.
Signed-off-by: Mike Waychison <[email protected]>
---
fs/namespace.c | 3 ++-
include/linux/fs.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
Index: linux-2.6.9-quilt/include/linux/fs.h
===================================================================
--- linux-2.6.9-quilt.orig/include/linux/fs.h 2004-10-22 17:17:43.766810576 -0400
+++ linux-2.6.9-quilt/include/linux/fs.h 2004-10-22 17:17:47.808196192 -0400
@@ -735,6 +735,7 @@ extern int send_sigurg(struct fown_struc
#define MNT_FORCE 0x00000001 /* Attempt to forcibily umount */
#define MNT_DETACH 0x00000002 /* Just detach from the tree */
+#define MNT_NOFOLLOW 0x00000004 /* Do not follow symlinks */
extern struct list_head super_blocks;
extern spinlock_t sb_lock;
Index: linux-2.6.9-quilt/fs/namespace.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/namespace.c 2004-10-22 17:17:45.491548376 -0400
+++ linux-2.6.9-quilt/fs/namespace.c 2004-10-22 17:17:47.809196040 -0400
@@ -693,8 +693,9 @@ asmlinkage long sys_umount(char __user *
{
struct nameidata nd;
int retval;
+ int walk_flags = flags & MNT_NOFOLLOW ? 0 : LOOKUP_FOLLOW;
- retval = __user_walk(name, LOOKUP_FOLLOW, &nd);
+ retval = __user_walk(name, walk_flags, &nd);
if (retval)
goto out;
retval = -EINVAL;
This patch extends the call_usermodehelper api by adding a callback variant.
The callback is made right when the system is about to call execve into the
new process. This allows for the caller to provide changes to the default
environment right before the exec takes place. Note: the context of the
callback will be _from within another process_.
Signed-off-by: Mike Waychison <[email protected]>
---
include/linux/kmod.h | 2 +
kernel/kmod.c | 80 ++++++++++++++++++++++++++++++++++++++-------------
2 files changed, 63 insertions(+), 19 deletions(-)
Index: linux-2.6.9-quilt/kernel/kmod.c
===================================================================
--- linux-2.6.9-quilt.orig/kernel/kmod.c 2004-08-14 01:36:44.000000000 -0400
+++ linux-2.6.9-quilt/kernel/kmod.c 2004-10-22 17:17:44.279732600 -0400
@@ -140,17 +140,22 @@ EXPORT_SYMBOL(hotplug_path);
struct subprocess_info {
struct completion *complete;
+ call_usermodehelper_cb_t cb;
+ void *cbdata;
+ int wait;
+ int retval;
+};
+
+struct simple_usermodehelper_info {
char *path;
char **argv;
char **envp;
- int wait;
- int retval;
};
/*
* This is the task which runs the usermode application
*/
-static int ____call_usermodehelper(void *data)
+static int ____call_usermodehelper_cb(void *data)
{
struct subprocess_info *sub_info = data;
int retval;
@@ -168,7 +173,7 @@ static int ____call_usermodehelper(void
retval = -EPERM;
if (current->fs->root)
- retval = execve(sub_info->path, sub_info->argv,sub_info->envp);
+ retval = (*sub_info->cb)(sub_info->cbdata);
/* Exec failed? */
sub_info->retval = retval;
@@ -190,7 +195,7 @@ static int wait_for_helper(void *data)
do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0);
allow_signal(SIGCHLD);
- pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
+ pid = kernel_thread(____call_usermodehelper_cb, sub_info, SIGCHLD);
if (pid < 0) {
sub_info->retval = pid;
} else {
@@ -211,7 +216,7 @@ static int wait_for_helper(void *data)
}
/* This is run by khelper thread */
-static void __call_usermodehelper(void *data)
+static void __call_usermodehelper_cb(void *data)
{
struct subprocess_info *sub_info = data;
pid_t pid;
@@ -223,7 +228,7 @@ static void __call_usermodehelper(void *
pid = kernel_thread(wait_for_helper, sub_info,
CLONE_FS | CLONE_FILES | SIGCHLD);
else
- pid = kernel_thread(____call_usermodehelper, sub_info,
+ pid = kernel_thread(____call_usermodehelper_cb, sub_info,
CLONE_VFORK | SIGCHLD);
if (pid < 0) {
@@ -234,12 +239,16 @@ static void __call_usermodehelper(void *
}
/**
- * call_usermodehelper - start a usermode application
- * @path: pathname for the application
- * @argv: null-terminated argument list
- * @envp: null-terminated environment list
+ * call_usermodehelper_cb - start a usermode application with a callback
+ * @cb: A user provided callback that will eventually execve.
+ * @cbdata: User supplied information that will be passed back to the callback.
* @wait: wait for the application to finish and return status.
*
+ * This call will do all the work required for setting up a usermode helper
+ * except perform the actual exec. It is the caller's responsibility to
+ * provide a callback that will eventually exec. This allows last minute
+ * changes to current.
+ *
* Runs a user-space application. The application is started
* asynchronously if wait is not set, and runs as a child of keventd.
* (ie. it runs with full root capabilities).
@@ -247,29 +256,62 @@ static void __call_usermodehelper(void *
* Must be called from process context. Returns a negative error code
* if program was not execed successfully, or 0.
*/
-int call_usermodehelper(char *path, char **argv, char **envp, int wait)
+int call_usermodehelper_cb(call_usermodehelper_cb_t cb, void *cbdata, int wait)
{
DECLARE_COMPLETION(done);
struct subprocess_info sub_info = {
.complete = &done,
- .path = path,
- .argv = argv,
- .envp = envp,
+ .cb = cb,
+ .cbdata = cbdata,
.wait = wait,
.retval = 0,
};
- DECLARE_WORK(work, __call_usermodehelper, &sub_info);
+ DECLARE_WORK(work, __call_usermodehelper_cb, &sub_info);
+ BUG_ON(!cb || !cbdata);
if (!khelper_wq)
return -EBUSY;
- if (path[0] == '\0')
- return 0;
-
queue_work(khelper_wq, &work);
wait_for_completion(&done);
return sub_info.retval;
}
+EXPORT_SYMBOL(call_usermodehelper_cb);
+
+static int call_usermodehelper_simple(void *cbdata)
+{
+ struct simple_usermodehelper_info *info = cbdata;
+ return execve(info->path, info->argv, info->envp);
+}
+
+/**
+ * call_usermodehelper - start a usermode application
+ * @path: pathname for the application
+ * @argv: null-terminated argument list
+ * @envp: null-terminated environment list
+ * @wait: wait for the application to finish and return status.
+ *
+ * Runs a user-space application. The application is started
+ * asynchronously if wait is not set, and runs as a child of keventd.
+ * (ie. it runs with full root capabilities).
+ *
+ * Must be called from process context. Returns a negative error code
+ * if program was not execed successfully, or 0.
+ */
+
+int call_usermodehelper(char *path, char **argv, char **envp, int wait)
+{
+ struct simple_usermodehelper_info info = {
+ .path = path,
+ .argv = argv,
+ .envp = envp,
+ };
+
+ if (path[0] == '\0')
+ return 0;
+
+ return call_usermodehelper_cb(call_usermodehelper_simple, &info, wait);
+}
EXPORT_SYMBOL(call_usermodehelper);
static __init int usermodehelper_init(void)
Index: linux-2.6.9-quilt/include/linux/kmod.h
===================================================================
--- linux-2.6.9-quilt.orig/include/linux/kmod.h 2004-08-14 01:36:32.000000000 -0400
+++ linux-2.6.9-quilt/include/linux/kmod.h 2004-10-22 17:17:44.279732600 -0400
@@ -34,6 +34,8 @@ static inline int request_module(const c
#endif
#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
+typedef int (*call_usermodehelper_cb_t)(void *cbdata);
+extern int call_usermodehelper_cb(call_usermodehelper_cb_t cb, void *cbdata, int wait);
extern int call_usermodehelper(char *path, char *argv[], char *envp[], int wait);
#ifdef CONFIG_HOTPLUG
On Mon, Oct 25, 2004 at 10:51:11AM -0400, Mike Waychison wrote:
> Mount-related userspace tools will require the ability to detect whether what
> looks like a regular directory is actually a autofs trigger. To handle this,
> tools can statfs a given directory and check to see if statfs->f_type ==
> AUTOFSNG_SUPER_MAGIC before walking into the directory (and causing the a
> filesystem to automount).
>
> To make this happen, we cannot allow statfs to follow_link.
>
> NOTE: This may break any userspace that assumes it can statfs across a
> last-component symlink. I can't think of any real world breakage however, as
> mount(8) will drop the real path in /etc/mtab and /proc/mounts will always
> show the true path.
Which means it's vetoed. It's a big change in syscall semantics. And
propabably breaks SuS (for statvfs(3) which requires full symlink
resolution when it just refers to a path on the filesystem.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Christoph Hellwig wrote:
> On Mon, Oct 25, 2004 at 10:51:11AM -0400, Mike Waychison wrote:
>
>>Mount-related userspace tools will require the ability to detect whether what
>>looks like a regular directory is actually a autofs trigger. To handle this,
>>tools can statfs a given directory and check to see if statfs->f_type ==
>>AUTOFSNG_SUPER_MAGIC before walking into the directory (and causing the a
>>filesystem to automount).
>>
>>To make this happen, we cannot allow statfs to follow_link.
>>
>>NOTE: This may break any userspace that assumes it can statfs across a
>>last-component symlink. I can't think of any real world breakage however, as
>>mount(8) will drop the real path in /etc/mtab and /proc/mounts will always
>>show the true path.
>
>
> Which means it's vetoed. It's a big change in syscall semantics. And
> propabably breaks SuS (for statvfs(3) which requires full symlink
> resolution when it just refers to a path on the filesystem.
>
Ya, I figured that would be the case. What do folks think about a
lstatfs(64)?
- --
Mike Waychison
Sun Microsystems, Inc.
1 (650) 352-5299 voice
1 (416) 202-8336 voice
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NOTICE: The opinions expressed in this email are held by me,
and may not represent the views of Sun Microsystems, Inc.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFBfRoUdQs4kOxk3/MRAgHoAKCApqvkE2hgLAJKXDkLWWJE7BqevgCfQlh9
BxBlFSMUPoo1VyOcntae7Y0=
=rR8G
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Christoph Hellwig wrote:
> On Mon, Oct 25, 2004 at 10:48:40AM -0400, Mike Waychison wrote:
>
>>This patch extends the call_usermodehelper api by adding a callback variant.
>>The callback is made right when the system is about to call execve into the
>>new process. This allows for the caller to provide changes to the default
>>environment right before the exec takes place. Note: the context of the
>>callback will be _from within another process_.
>
>
> I don't like this at all. First it's the usual fork() + exec() vs spawn() with
> gazillions of arguments debatte, second this sounds far too complex to do it in
> kernelspace to me. Why can't you do the enviroment changes from the program
> beeing executed?
>
I want to be able to do two things:
- - To 'call_usermodehelper' a program, but in current's namespace.
Namespaces can't be passed around in userspace.
- - To give the execed program an open file. The current interface
doesn't allow me to do that.
I figured the _cb way of doing it remove any need for adding ad-hoc api
anytime somebody wants to tweak a task before calling execve.
Does this clarify why I added this?
- --
Mike Waychison
Sun Microsystems, Inc.
1 (650) 352-5299 voice
1 (416) 202-8336 voice
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NOTICE: The opinions expressed in this email are held by me,
and may not represent the views of Sun Microsystems, Inc.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD4DBQFBfRvNdQs4kOxk3/MRAvInAJYmn4GlPasI0r7VcwSKv03GXoygAJ90FWDM
LVQOfOrpbKp7NDSmlFRt+A==
=aQ04
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Enigmail
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFBfR22dQs4kOxk3/MRAp3oAJ47d7sziVXF160UzQ4HBzLh3upjcACeNMaE
JUeekjsmZaQsGt/yZgGh2c8=
=WqbX
-----END PGP SIGNATURE-----
On Mon, Oct 25, 2004 at 10:48:40AM -0400, Mike Waychison wrote:
> This patch extends the call_usermodehelper api by adding a callback variant.
> The callback is made right when the system is about to call execve into the
> new process. This allows for the caller to provide changes to the default
> environment right before the exec takes place. Note: the context of the
> callback will be _from within another process_.
I don't like this at all. First it's the usual fork() + exec() vs spawn() with
gazillions of arguments debatte, second this sounds far too complex to do it in
kernelspace to me. Why can't you do the enviroment changes from the program
beeing executed?
This patch allows an unattached mountfd to be attached to a directory given a
direct fd.
NOTE: Probably requires CAP_SYSADMIN.. depends on what we want the security
model to be.
Signed-off-by: Mike Waychison <[email protected]>
---
fs/mountfd.c | 35 +++++++++++++++++++++++++++++++++++
include/linux/fs.h | 1 +
2 files changed, 36 insertions(+)
Index: linux-2.6.9-quilt/fs/mountfd.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/mountfd.c 2004-10-22 17:17:41.367175376 -0400
+++ linux-2.6.9-quilt/fs/mountfd.c 2004-10-22 17:17:42.011077488 -0400
@@ -5,6 +5,7 @@
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/security.h>
+#include <linux/namei.h>
#define MFDFS_MAGIC 0x4A9F2E43
#define MFDFS_ROOT_INO 1
@@ -251,6 +252,38 @@ out_filp:
return error;
}
+static long mfd_attach(struct file *mountfilp, int dirfd)
+{
+ struct file *dir;
+ struct vfsmount *mnt;
+ struct nameidata nd;
+ int ret;
+
+ mnt = mntget(VFSMOUNT(mountfilp));
+
+ ret = -EBADF;
+ dir = fget(dirfd);
+ if (!dir)
+ goto out;
+
+ ret = -ENOTDIR;
+ if (!S_ISDIR(dir->f_dentry->d_inode->i_mode))
+ goto out2;
+
+ memset(&nd, 0, sizeof(nd));
+ nd.dentry = dget(dir->f_dentry);
+ nd.mnt = mntget(dir->f_vfsmnt);
+
+ ret = do_graft_mount(mnt, &nd);
+
+ path_release(&nd);
+out2:
+ put_filp(dir);
+out:
+ mntput(mnt);
+ return ret;
+}
+
static int mfd_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -263,6 +296,8 @@ static int mfd_ioctl(struct inode *inode
return mfd_umount(filp, 0);
case MOUNTFD_IOC_FORCEDUNMOUNT:
return mfd_umount(filp, MNT_FORCE);
+ case MOUNTFD_IOC_ATTACH:
+ return mfd_attach(filp, arg);
}
return -ENOTTY;
}
Index: linux-2.6.9-quilt/include/linux/fs.h
===================================================================
--- linux-2.6.9-quilt.orig/include/linux/fs.h 2004-10-22 17:17:41.369175072 -0400
+++ linux-2.6.9-quilt/include/linux/fs.h 2004-10-22 17:17:42.012077336 -0400
@@ -218,6 +218,7 @@ extern int leases_enable, dir_notify_ena
#define MOUNTFD_IOC_UNMOUNT _IO('p', 0xa1)
#define MOUNTFD_IOC_DETACH _IO('p', 0xa2)
#define MOUNTFD_IOC_FORCEDUNMOUNT _IO('p', 0xa3)
+#define MOUNTFD_IOC_ATTACH _IOW('p', 0xa4, int)
#ifdef __KERNEL__
This patch is a hack while we don't have a proper way for code to call
execve. It simply introduces call_usermodehelper_execve(path, argv, envp)
that call the execve syscall with an errno set.
We need to figure out a proper way for code to call execve!
Signed-off-by: Mike Waychison <[email protected]>
---
include/linux/kmod.h | 1 +
kernel/kmod.c | 7 +++++++
2 files changed, 8 insertions(+)
Index: linux-2.6.9-quilt/kernel/kmod.c
===================================================================
--- linux-2.6.9-quilt.orig/kernel/kmod.c 2004-10-22 17:17:44.279732600 -0400
+++ linux-2.6.9-quilt/kernel/kmod.c 2004-10-22 17:17:44.879641400 -0400
@@ -278,6 +278,13 @@ int call_usermodehelper_cb(call_usermode
}
EXPORT_SYMBOL(call_usermodehelper_cb);
+/* This is an ugly hack while the __KERNEL_SYSCALLS__ cleanup occurs */
+int call_usermodehelper_execve(char *path, char *argv[], char *envp[])
+{
+ return execve(path, argv, envp);
+}
+EXPORT_SYMBOL(call_usermodehelper_execve);
+
static int call_usermodehelper_simple(void *cbdata)
{
struct simple_usermodehelper_info *info = cbdata;
Index: linux-2.6.9-quilt/include/linux/kmod.h
===================================================================
--- linux-2.6.9-quilt.orig/include/linux/kmod.h 2004-10-22 17:17:44.279732600 -0400
+++ linux-2.6.9-quilt/include/linux/kmod.h 2004-10-22 17:17:44.879641400 -0400
@@ -36,6 +36,7 @@ static inline int request_module(const c
#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
typedef int (*call_usermodehelper_cb_t)(void *cbdata);
extern int call_usermodehelper_cb(call_usermodehelper_cb_t cb, void *cbdata, int wait);
+extern int call_usermodehelper_execve(char *path, char *argv[], char *envp[]);
extern int call_usermodehelper(char *path, char *argv[], char *envp[], int wait);
#ifdef CONFIG_HOTPLUG
This patch exports the __put_namespace symbol so that autofsng can call it as
a module (used as part of the call-out mechanism).
Signed-off-by: Mike Waychison <[email protected]>
---
namespace.c | 1 +
1 files changed, 1 insertion(+)
Index: linux-2.6.9-quilt/fs/namespace.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/namespace.c 2004-10-22 17:17:41.368175224 -0400
+++ linux-2.6.9-quilt/fs/namespace.c 2004-10-22 17:17:45.491548376 -0400
@@ -1733,3 +1733,4 @@ void __put_namespace(struct namespace *n
mntput(namespace->root);
kfree(namespace);
}
+EXPORT_SYMBOL(__put_namespace);
When a follow_link dentry call is made, the implementation expects the
dentry to be followed as well as a nameidata struct to be filled in.
The received nd->mnt is expected to contain the vfsmount of the dentry
being followed, so that a subsequent call to vfs_follow_link may
properly pivot off that mount and onto another vfsmount as the path of
the link is walked, thus keeping reference counts proper.
The changes made in fs/[email protected] break this behaviour if the dentry
being follow_link'ed is a root dentry. This is because follow_mount
follows down next.mnt and not nd->mnt like it used to. So, if a root
dentry has a follow_link op, the nd->mnt it receives is in fact the
vfsmount of the mount it is mounted upon (which breaks reference counts).
Signed-off-by: Mike Waychison <[email protected]>
---
namei.c | 2 ++
1 files changed, 2 insertions(+)
Index: linux-2.6.9-quilt/fs/namei.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/namei.c 2004-10-22 17:17:34.762179488 -0400
+++ linux-2.6.9-quilt/fs/namei.c 2004-10-22 17:17:46.571384216 -0400
@@ -755,6 +755,7 @@ int fastcall link_path_walk(const char *
if (inode->i_op->follow_link) {
mntget(next.mnt);
+ nd->mnt = next.mnt;
err = do_follow_link(next.dentry, nd);
dput(next.dentry);
mntput(next.mnt);
@@ -809,6 +810,7 @@ last_component:
if ((lookup_flags & LOOKUP_FOLLOW)
&& inode && inode->i_op && inode->i_op->follow_link) {
mntget(next.mnt);
+ nd->mnt = next.mnt;
err = do_follow_link(next.dentry, nd);
dput(next.dentry);
mntput(next.mnt);
Export get_sb_pseudo for module use. Autofsng uses it to create files that
are used for feeding browsing information.
Signed-off-by: Mike Waychison <[email protected]>
---
libfs.c | 1 +
1 files changed, 1 insertion(+)
Index: linux-2.6.9-quilt/fs/libfs.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/libfs.c 2004-08-14 01:36:11.000000000 -0400
+++ linux-2.6.9-quilt/fs/libfs.c 2004-10-22 17:17:46.009469640 -0400
@@ -222,6 +222,7 @@ Enomem:
deactivate_super(s);
return ERR_PTR(-ENOMEM);
}
+EXPORT_SYMBOL(get_sb_pseudo);
int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
{
This patch adds a temporary syscall (to x86 only) that allows for quick
testing to make sure that mnt_expire works properly. Tests can be found in
the autofsng userspace package.
Signed-off-by: Mike Waychison <[email protected]>
---
arch/i386/kernel/entry.S | 1 +
fs/namespace.c | 32 ++++++++++++++++++++++++++++++++
include/asm-i386/unistd.h | 3 ++-
3 files changed, 35 insertions(+), 1 deletion(-)
Index: linux-2.6.9-quilt/arch/i386/kernel/entry.S
===================================================================
--- linux-2.6.9-quilt.orig/arch/i386/kernel/entry.S 2004-10-22 17:17:40.735271440 -0400
+++ linux-2.6.9-quilt/arch/i386/kernel/entry.S 2004-10-22 17:17:48.436100736 -0400
@@ -903,5 +903,6 @@ ENTRY(sys_call_table)
.long sys_ni_syscall
.long sys_ni_syscall
.long sys_mountfd /* 300 */
+ .long sys_mnt_expire
syscall_table_size=(.-sys_call_table)
Index: linux-2.6.9-quilt/include/asm-i386/unistd.h
===================================================================
--- linux-2.6.9-quilt.orig/include/asm-i386/unistd.h 2004-10-22 17:17:40.735271440 -0400
+++ linux-2.6.9-quilt/include/asm-i386/unistd.h 2004-10-22 17:17:48.436100736 -0400
@@ -290,8 +290,9 @@
#define __NR_mq_getsetattr (__NR_mq_open+5)
#define __NR_sys_kexec_load 283
#define __NR_mountfd 300
+#define __NR_mnt_expire 301
-#define NR_syscalls 301
+#define NR_syscalls 302
/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
Index: linux-2.6.9-quilt/fs/namespace.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/namespace.c 2004-10-22 17:17:47.809196040 -0400
+++ linux-2.6.9-quilt/fs/namespace.c 2004-10-22 17:17:48.437100584 -0400
@@ -1119,6 +1119,38 @@ static void bump_expiry_counter(struct v
parent->mnt_expiry_countdown = diff;
}
+/* TESTING PURPOSES ONLY: THIS IS NOT A REAL SYSCALL!! - IT WILL GO AWAY */
+asmlinkage int sys_mnt_expire(char __user *_path, int ticks)
+{
+ struct nameidata nd;
+ char *path;
+ int err;
+
+ path = getname(_path);
+ err = PTR_ERR(path);
+ if (IS_ERR(path))
+ goto out;
+
+ err = path_lookup(path, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
+ if (err)
+ goto out_name;
+
+ err = -EINVAL;
+ if (nd.mnt->mnt_root != nd.dentry)
+ goto out_nd;
+
+ err = -EBUSY;
+ if (!mnt_expire(nd.mnt, ticks))
+ err = 0;
+
+out_nd:
+ path_release(&nd);
+out_name:
+ putname(path);
+out:
+ return err;
+}
+
/*
* process a list of expirable mountpoints with the intent of discarding any
* mountpoints that aren't in use and haven't been touched since last we came
This patch allows one to walk the mountpoint tree given a mountfd. There are
two operations permitted:
MOUNTFD_IOC_GETFIRSTCHILD - Given a mountfd, return the first child mountpoint
as a mountfd.
MOUNTFD_IOC_GETNEXTCHILD - Given a mountfd, return the next mountpoint sibling
to it. (*)
(*) XXX: This should be modified to also take a parent mountfd so that you
can't walk out of a chroot.
We explicitly don't allow walks to the parent of a mountpoint as that would
allow for a user to easily walk out of a chroot.
Signed-off-by: Mike Waychison <[email protected]>
---
fs/mountfd.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/fs.h | 3 +++
2 files changed, 49 insertions(+)
Index: linux-2.6.9-quilt/include/linux/fs.h
===================================================================
--- linux-2.6.9-quilt.orig/include/linux/fs.h 2004-10-22 17:17:42.012077336 -0400
+++ linux-2.6.9-quilt/include/linux/fs.h 2004-10-22 17:17:42.625984008 -0400
@@ -219,6 +219,9 @@ extern int leases_enable, dir_notify_ena
#define MOUNTFD_IOC_DETACH _IO('p', 0xa2)
#define MOUNTFD_IOC_FORCEDUNMOUNT _IO('p', 0xa3)
#define MOUNTFD_IOC_ATTACH _IOW('p', 0xa4, int)
+#define MOUNTFD_IOC_GETFIRSTCHILD _IO('p', 0xa5)
+/* TODO: change this interface to require the parent mfd as well */
+#define MOUNTFD_IOC_GETNEXTCHILD _IO('p', 0xa6)
#ifdef __KERNEL__
Index: linux-2.6.9-quilt/fs/mountfd.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/mountfd.c 2004-10-22 17:17:42.011077488 -0400
+++ linux-2.6.9-quilt/fs/mountfd.c 2004-10-22 17:17:42.625984008 -0400
@@ -284,6 +284,48 @@ out:
return ret;
}
+static long mfd_firstchild(struct file *mountfilp)
+{
+ struct vfsmount *mnt, *childmnt = NULL;
+ int ret;
+
+ mnt = mntget(VFSMOUNT(mountfilp));
+
+ spin_lock(&vfsmount_lock);
+ if (!list_empty(&mnt->mnt_mounts))
+ childmnt = mntget(container_of(mnt->mnt_mounts.next, struct vfsmount, mnt_child));
+ spin_unlock(&vfsmount_lock);
+
+ ret = -ENOENT;
+ if (childmnt)
+ ret = open_mfd(childmnt);
+
+ mntput(childmnt);
+ mntput(mnt);
+ return ret;
+}
+
+static long mfd_nextchild(struct file *mountfilp)
+{
+ struct vfsmount *mnt, *nextmnt = NULL;
+ int ret;
+
+ mnt = mntget(VFSMOUNT(mountfilp));
+
+ spin_lock(&vfsmount_lock);
+ if (mnt->mnt_child.next != &mnt->mnt_parent->mnt_mounts)
+ nextmnt = mntget(container_of(mnt->mnt_child.next, struct vfsmount, mnt_child));
+ spin_unlock(&vfsmount_lock);
+
+ ret = -ENOENT;
+ if (nextmnt)
+ ret = open_mfd(nextmnt);
+
+ mntput(nextmnt);
+ mntput(mnt);
+ return ret;
+}
+
static int mfd_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -298,6 +340,10 @@ static int mfd_ioctl(struct inode *inode
return mfd_umount(filp, MNT_FORCE);
case MOUNTFD_IOC_ATTACH:
return mfd_attach(filp, arg);
+ case MOUNTFD_IOC_GETFIRSTCHILD:
+ return mfd_firstchild(filp);
+ case MOUNTFD_IOC_GETNEXTCHILD:
+ return mfd_nextchild(filp);
}
return -ENOTTY;
}
This patch adds support for letting userspcae set the expiry information on a
given mountpoint.
Signed-off-by: Mike Waychison <[email protected]>
---
fs/mountfd.c | 10 ++++++++++
include/linux/fs.h | 1 +
2 files changed, 11 insertions(+)
Index: linux-2.6.9-quilt/include/linux/fs.h
===================================================================
--- linux-2.6.9-quilt.orig/include/linux/fs.h 2004-10-22 17:17:43.232891744 -0400
+++ linux-2.6.9-quilt/include/linux/fs.h 2004-10-22 17:17:43.766810576 -0400
@@ -228,6 +228,7 @@ extern int leases_enable, dir_notify_ena
#define MOUNTFD_IOC_GETFSTYPE _IOR('p', 0xa8, char [MOUNTFD_READSIZE])
#define MOUNTFD_IOC_GETVFSOPTIONS _IOR('p', 0xa9, char [MOUNTFD_READSIZE])
#define MOUNTFD_IOC_GETFSOPTIONS _IOR('p', 0xaa, char [MOUNTFD_READSIZE])
+#define MOUNTFD_IOC_SETVFSEXPIRE _IOW('p', 0xab, int)
#ifdef __KERNEL__
Index: linux-2.6.9-quilt/fs/mountfd.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/mountfd.c 2004-10-22 17:17:43.230892048 -0400
+++ linux-2.6.9-quilt/fs/mountfd.c 2004-10-22 17:17:43.767810424 -0400
@@ -393,6 +393,14 @@ static long mfd_nextchild(struct file *m
return ret;
}
+static int mfd_vfsexpire(struct file *mountfilp, int arg)
+{
+ struct vfsmount *mnt;
+
+ mnt = VFSMOUNT(mountfilp);
+ return mnt_expire(mnt, arg);
+}
+
static int mfd_ioctl_reads(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -455,6 +463,8 @@ static int mfd_ioctl(struct inode *inode
return mfd_firstchild(filp);
case MOUNTFD_IOC_GETNEXTCHILD:
return mfd_nextchild(filp);
+ case MOUNTFD_IOC_SETVFSEXPIRE:
+ return mfd_vfsexpire(filp, (int)arg);
}
ret = mfd_ioctl_reads(inode, filp, cmd, arg);
return ret;
This patch allows userspace to query a mountpoint file descriptor for
information using the ioctl interface.
The properties exported in this patch are for _example only_ to demonstrate
what the interface might look like. This patch allows mountfds to show the
following information:
MOUNTFD_IOC_GETDEV - Get the associated block device (if any)
MOUNTFD_IOC_GETFSTYPE - Get the fstype of the mountpoint.
MOUNTFD_IOC_GETVFSOPTIONS - Get the vfs specific options of the
mountpoint/superblock
MOUNTFD_IOC_GETFSOPTIONS - Get the fstype-specific options (if any)
Signed-off-by: Mike Waychison <[email protected]>
---
fs/mountfd.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/fs.h | 6 ++
2 files changed, 119 insertions(+), 1 deletion(-)
Index: linux-2.6.9-quilt/fs/mountfd.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/mountfd.c 2004-10-22 17:17:42.625984008 -0400
+++ linux-2.6.9-quilt/fs/mountfd.c 2004-10-22 17:17:43.230892048 -0400
@@ -160,6 +160,72 @@ static struct dentry *get_mfd_dentry(str
return dget(dentry);
}
+static int mfd_read_fstype(struct vfsmount *mnt, char *buf)
+{
+ return scnprintf(buf, MOUNTFD_READSIZE-1, "%s", mnt->mnt_sb->s_type->name) + 1;
+}
+
+static int mfd_read_dev(struct vfsmount *mnt, char *buf)
+{
+ return scnprintf(buf, MOUNTFD_READSIZE-1, "%s", mnt->mnt_sb->s_id) + 1;
+}
+
+static int mfd_read_vfsoptions(struct vfsmount *mnt, char *buf)
+{
+ static struct vfs_info {
+ int flag;
+ char *str;
+ } vfs_info[] = {
+ { MS_RDONLY, "ro" },
+ { MS_DIRSYNC, "dirsync" },
+ { MS_MANDLOCK, "mand" },
+ { MS_NOATIME, "noatime" },
+ { MS_NODIRATIME, "nodiratime" },
+ { 0, NULL }
+ };
+ struct vfs_info *vfs_infop;
+ static struct mnt_info {
+ int flag;
+ char *str;
+ } mnt_info[] = {
+ { MNT_NOSUID, "nosuid" },
+ { MNT_NODEV, "nodev" },
+ { MNT_NOEXEC, "noexec" },
+ { 0, NULL }
+ };
+ struct mnt_info *mnt_infop;
+
+ char *p = buf;
+
+ int sb_flags = mnt->mnt_sb->s_flags;
+ int mnt_flags = mnt->mnt_flags;
+ int first = 0;
+
+ /*
+ * Note: we skip length checks below because we assume we can't overrun
+ * MOUNTFD_READSIZE.
+ */
+
+ for (vfs_infop = vfs_info; vfs_infop->flag; vfs_infop++) {
+ if (sb_flags & vfs_infop->flag) {
+ if (first++)
+ *p++ = ',';
+ strcpy(p, vfs_infop->str);
+ p += strlen(vfs_infop->str);
+ }
+ }
+
+ for (mnt_infop = mnt_info; mnt_infop->flag; mnt_infop++) {
+ if (mnt_flags & mnt_infop->flag) {
+ if (first++)
+ *p++ = ',';
+ strcpy(p, mnt_infop->str);
+ p += strlen(mnt_infop->str);
+ }
+ }
+ return p - buf + 1;
+}
+
static long open_mfd(struct vfsmount *mnt)
{
struct file *file;
@@ -176,6 +242,7 @@ static long open_mfd(struct vfsmount *mn
if (fd < 0)
goto out_putfilp;
+ error = -ENOMEM;
file->private_data = mnt;
file->f_dentry = get_mfd_dentry(mnt);
if (IS_ERR(file->f_dentry)) {
@@ -326,9 +393,53 @@ static long mfd_nextchild(struct file *m
return ret;
}
+static int mfd_ioctl_reads(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ char __user *user_buf = (char __user *)arg;
+ struct vfsmount *mnt;
+ char *buf;
+ int ret;
+
+ mnt = VFSMOUNT(filp);
+
+ buf = (char *)get_zeroed_page(GFP_KERNEL);
+ if (buf)
+ return -ENOMEM;
+ switch (cmd) {
+ /*
+ * The following calls are expected to return the total number of bytes to write out, including '\0'.
+ */
+ case MOUNTFD_IOC_GETDEV:
+ ret = mfd_read_dev(mnt, buf);
+ break;
+ case MOUNTFD_IOC_GETFSTYPE:
+ ret = mfd_read_fstype(mnt, buf);
+ break;
+ case MOUNTFD_IOC_GETVFSOPTIONS:
+ ret = mfd_read_vfsoptions(mnt, buf);
+ break;
+ case MOUNTFD_IOC_GETFSOPTIONS:
+ /* TODO: need super_block op that doesn't take a seq_file */
+ ret = -ENOSYS;
+ break;
+ default:
+ ret = -ENOTTY;
+ }
+
+ if (ret >= 0) {
+ if (copy_to_user(user_buf, buf, ret))
+ ret = -EFAULT;
+ }
+
+ free_page((unsigned long)buf);
+ return ret;
+}
+
static int mfd_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
+ int ret;
switch (cmd) {
case MOUNTFD_IOC_GETDIRFD:
return mfd_getdirfd(filp);
@@ -345,7 +456,8 @@ static int mfd_ioctl(struct inode *inode
case MOUNTFD_IOC_GETNEXTCHILD:
return mfd_nextchild(filp);
}
- return -ENOTTY;
+ ret = mfd_ioctl_reads(inode, filp, cmd, arg);
+ return ret;
}
asmlinkage long sys_mountfd(int dirfd)
Index: linux-2.6.9-quilt/include/linux/fs.h
===================================================================
--- linux-2.6.9-quilt.orig/include/linux/fs.h 2004-10-22 17:17:42.625984008 -0400
+++ linux-2.6.9-quilt/include/linux/fs.h 2004-10-22 17:17:43.232891744 -0400
@@ -223,6 +223,12 @@ extern int leases_enable, dir_notify_ena
/* TODO: change this interface to require the parent mfd as well */
#define MOUNTFD_IOC_GETNEXTCHILD _IO('p', 0xa6)
+#define MOUNTFD_READSIZE PAGE_SIZE
+#define MOUNTFD_IOC_GETDEV _IOR('p', 0xa7, char [MOUNTFD_READSIZE])
+#define MOUNTFD_IOC_GETFSTYPE _IOR('p', 0xa8, char [MOUNTFD_READSIZE])
+#define MOUNTFD_IOC_GETVFSOPTIONS _IOR('p', 0xa9, char [MOUNTFD_READSIZE])
+#define MOUNTFD_IOC_GETFSOPTIONS _IOR('p', 0xaa, char [MOUNTFD_READSIZE])
+
#ifdef __KERNEL__
#include <linux/list.h>
On Mon, Oct 25, 2004 at 10:52:12AM -0400, Mike Waychison wrote:
> This patch adds a temporary syscall (to x86 only) that allows for quick
> testing to make sure that mnt_expire works properly. Tests can be found in
> the autofsng userspace package.
> +/* TESTING PURPOSES ONLY: THIS IS NOT A REAL SYSCALL!! - IT WILL GO AWAY */
> +asmlinkage int sys_mnt_expire(char __user *_path, int ticks)
so don't submit it..
On Mon, Oct 25, 2004 at 10:46:09AM -0400, Mike Waychison wrote:
> This patch adds functionality to mountfd so that a user can perform the
> various types of umount (forced umount, not-busy umount, lazy-umount).
>
> Signed-off-by: Mike Waychison <[email protected]>
> ---
>
> fs/mountfd.c | 20 ++++++++++++++++++++
> fs/namespace.c | 2 +-
> include/linux/fs.h | 5 ++++-
> 3 files changed, 25 insertions(+), 2 deletions(-)
>
> Index: linux-2.6.9-quilt/fs/mountfd.c
> ===================================================================
> --- linux-2.6.9-quilt.orig/fs/mountfd.c 2004-10-22 17:17:40.736271288 -0400
> +++ linux-2.6.9-quilt/fs/mountfd.c 2004-10-22 17:17:41.367175376 -0400
> @@ -11,6 +11,8 @@
>
> #define VFSMOUNT(filp) ((struct vfsmount *)((filp)->private_data))
>
> +extern int do_umount(struct vfsmount *mnt, int flags);
> +
> static struct vfsmount *mfdfs_mnt;
>
> static void mfdfs_read_inode(struct inode *inode);
> @@ -72,6 +74,18 @@ static int mfd_release(struct inode *ino
> return 0;
> }
>
> +static long mfd_umount(struct file *mountfilp, int flags)
> +{
> + struct vfsmount *mnt;
> + int error;
> +
> + mnt = mntget(VFSMOUNT(mountfilp));
> +
> + error = do_umount(mnt, flags);
> +
> + return error;
> +}
> +
> static int mfd_ioctl(struct inode *inode, struct file *filp,
> unsigned int cmd, unsigned long arg);
> static struct file_operations mfd_file_ops = {
> @@ -243,6 +257,12 @@ static int mfd_ioctl(struct inode *inode
> switch (cmd) {
> case MOUNTFD_IOC_GETDIRFD:
> return mfd_getdirfd(filp);
> + case MOUNTFD_IOC_DETACH:
> + return mfd_umount(filp, MNT_DETACH);
> + case MOUNTFD_IOC_UNMOUNT:
> + return mfd_umount(filp, 0);
> + case MOUNTFD_IOC_FORCEDUNMOUNT:
> + return mfd_umount(filp, MNT_FORCE);
Urgg, you don't want to add gazillions of strange ioctls, do you?
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Christoph Hellwig wrote:
> On Mon, Oct 25, 2004 at 10:46:09AM -0400, Mike Waychison wrote:
>
>>This patch adds functionality to mountfd so that a user can perform the
>>various types of umount (forced umount, not-busy umount, lazy-umount).
>>
>>Signed-off-by: Mike Waychison <[email protected]>
>>---
>>
>> fs/mountfd.c | 20 ++++++++++++++++++++
>> fs/namespace.c | 2 +-
>> include/linux/fs.h | 5 ++++-
>> 3 files changed, 25 insertions(+), 2 deletions(-)
>>
>>Index: linux-2.6.9-quilt/fs/mountfd.c
>>===================================================================
>>--- linux-2.6.9-quilt.orig/fs/mountfd.c 2004-10-22 17:17:40.736271288 -0400
>>+++ linux-2.6.9-quilt/fs/mountfd.c 2004-10-22 17:17:41.367175376 -0400
>>@@ -11,6 +11,8 @@
>>
>> #define VFSMOUNT(filp) ((struct vfsmount *)((filp)->private_data))
>>
>>+extern int do_umount(struct vfsmount *mnt, int flags);
>>+
>> static struct vfsmount *mfdfs_mnt;
>>
>> static void mfdfs_read_inode(struct inode *inode);
>>@@ -72,6 +74,18 @@ static int mfd_release(struct inode *ino
>> return 0;
>> }
>>
>>+static long mfd_umount(struct file *mountfilp, int flags)
>>+{
>>+ struct vfsmount *mnt;
>>+ int error;
>>+
>>+ mnt = mntget(VFSMOUNT(mountfilp));
>>+
>>+ error = do_umount(mnt, flags);
>>+
>>+ return error;
>>+}
>>+
>> static int mfd_ioctl(struct inode *inode, struct file *filp,
>> unsigned int cmd, unsigned long arg);
>> static struct file_operations mfd_file_ops = {
>>@@ -243,6 +257,12 @@ static int mfd_ioctl(struct inode *inode
>> switch (cmd) {
>> case MOUNTFD_IOC_GETDIRFD:
>> return mfd_getdirfd(filp);
>>+ case MOUNTFD_IOC_DETACH:
>>+ return mfd_umount(filp, MNT_DETACH);
>>+ case MOUNTFD_IOC_UNMOUNT:
>>+ return mfd_umount(filp, 0);
>>+ case MOUNTFD_IOC_FORCEDUNMOUNT:
>>+ return mfd_umount(filp, MNT_FORCE);
>
>
> Urgg, you don't want to add gazillions of strange ioctls, do you?
>
Only a couple million ;)
I have toyed with different interfaces. I have older patches that would
allow you to read/write on the fd to perform ops, but the code is a mess
of parsing/data checks. I also toyed with a multiplexed syscall, but
realized real quick that it was an ioctl with a different name, that
only worked on mountfds.
ioctl ended up being the cleanest solution (I came up with) in the end.
Alternatives?
- --
Mike Waychison
Sun Microsystems, Inc.
1 (650) 352-5299 voice
1 (416) 202-8336 voice
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NOTICE: The opinions expressed in this email are held by me,
and may not represent the views of Sun Microsystems, Inc.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFBflxTdQs4kOxk3/MRAq0NAJ9leUcfelicGndvtqGXqGgMlNoREACfXmXe
XsmXEDdefmJi7L8XmuKrQSk=
=xWa5
-----END PGP SIGNATURE-----