From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
To: hch@infradead.org, viro@zeniv.linux.org.uk, adilger@sun.com,
corbet@lwn.net
Cc: linux-fsdevel@vger.kernel.org, sfrench@us.ibm.com,
"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Subject: [PATCH -V3 2/5] vfs: Add name to file handle conversion support
Date: Thu, 22 Apr 2010 23:45:30 +0530 [thread overview]
Message-ID: <1271960133-16414-3-git-send-email-aneesh.kumar@linux.vnet.ibm.com> (raw)
In-Reply-To: <1271960133-16414-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
fs/open.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/fs.h | 17 +++++++++
2 files changed, 112 insertions(+), 0 deletions(-)
diff --git a/fs/open.c b/fs/open.c
index 74e5cd9..2d9a92b 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -30,6 +30,8 @@
#include <linux/falloc.h>
#include <linux/fs_struct.h>
#include <linux/ima.h>
+#include <linux/exportfs.h>
+#include <linux/mnt_namespace.h>
#include "internal.h"
@@ -1206,3 +1208,96 @@ int nonseekable_open(struct inode *inode, struct file *filp)
}
EXPORT_SYMBOL(nonseekable_open);
+
+/* limit the handle size to some value */
+#define MAX_HANDLE_SZ 4096
+static int do_sys_name_to_handle(const char __user *name,
+ struct file_handle *fh)
+{
+ int retval;
+ int handle_size;
+ struct path path;
+ struct inode *inode;
+ void *handle = NULL;
+ struct super_block *sb;
+ struct uuid *this_fs_id;
+
+ if (fh->handle_size > MAX_HANDLE_SZ)
+ return -EINVAL;
+
+ retval = user_lpath(name, &path);
+ if (retval)
+ return retval;
+
+ inode = path.dentry->d_inode;
+ /*
+ * name to handle conversion only done for regular files
+ * directories and symbolic links
+ */
+ if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) &&
+ !S_ISLNK(inode->i_mode)) {
+ retval = -EINVAL;
+ goto err_out;
+ }
+ if (fh->handle_size > 0) {
+ handle = kmalloc(fh->handle_size, GFP_KERNEL);
+ if (!handle) {
+ retval = -ENOMEM;
+ goto err_out;
+ }
+
+ handle_size = fh->handle_size;
+ } else
+ handle_size = 0;
+ /* we ask for a non connected handle */
+ retval = exportfs_encode_fh(path.dentry, (struct fid *)handle,
+ &handle_size, 0);
+ /* convert handle size to bytes */
+ handle_size *= sizeof(u32);
+ fh->handle_type = retval;
+ if (handle_size <= fh->handle_size) {
+ if (copy_to_user(fh->f_handle, handle,
+ handle_size))
+ retval = -EFAULT;
+ else
+ retval = 0;
+ } else
+ retval = -EOVERFLOW;
+ fh->handle_size = handle_size;
+ sb = path.mnt->mnt_sb;
+ if (sb->s_op->get_fsid) {
+ this_fs_id = sb->s_op->get_fsid(sb);
+ memcpy(fh->fsid.uuid, this_fs_id->uuid, sizeof(fh->fsid.uuid));
+ } else
+ memset(fh->fsid.uuid, 0, sizeof(fh->fsid.uuid));
+ kfree(handle);
+
+err_out:
+ path_put(&path);
+ return retval;
+}
+
+SYSCALL_DEFINE2(name_to_handle, const char __user *, name,
+ struct file_handle __user *, handle)
+{
+ long ret;
+ struct file_handle f_handle;
+ if (copy_from_user(&f_handle, handle, sizeof(struct file_handle))) {
+ ret = -EFAULT;
+ goto err_out;
+ }
+ ret = do_sys_name_to_handle(name, &f_handle);
+ if (copy_to_user(&handle->handle_type,
+ &f_handle.handle_type, sizeof(f_handle.handle_type)) ||
+ copy_to_user(&handle->handle_size,
+ &f_handle.handle_size, sizeof(f_handle.handle_size)) ||
+ copy_to_user(handle->fsid.uuid,
+ f_handle.fsid.uuid, sizeof(f_handle.fsid.uuid))) {
+
+ ret = -EFAULT;
+ }
+err_out:
+ /* avoid REGPARM breakage on x86: */
+ asmlinkage_protect(2, ret, name, handle);
+ return ret;
+}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 39d57bc..f7b9557 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -948,6 +948,20 @@ struct file {
unsigned long f_mnt_write_state;
#endif
};
+
+struct uuid {
+ char uuid[16];
+};
+
+struct file_handle {
+ int handle_size;
+ int handle_type;
+ /* File system identifier */
+ struct uuid fsid;
+ /* file identifier */
+ void *f_handle;
+};
+
extern spinlock_t files_lock;
#define file_list_lock() spin_lock(&files_lock);
#define file_list_unlock() spin_unlock(&files_lock);
@@ -1580,6 +1594,7 @@ struct super_operations {
ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
#endif
int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
+ struct uuid *(*get_fsid)(struct super_block *);
};
/*
@@ -2328,6 +2343,8 @@ extern struct super_block *get_super(struct block_device *);
extern struct super_block *get_active_super(struct block_device *bdev);
extern struct super_block *user_get_super(dev_t);
extern void drop_super(struct super_block *sb);
+extern struct super_block *fs_get_sb(struct uuid *fsid);
+
extern int dcache_dir_open(struct inode *, struct file *);
extern int dcache_dir_close(struct inode *, struct file *);
--
1.7.0.4.360.g11766c
next prev parent reply other threads:[~2010-04-22 18:15 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-22 18:15 [PATCH -V3] Generic name to handle and open by handle syscalls Aneesh Kumar K.V
2010-04-22 18:15 ` [PATCH -V3 1/5] exportfs: Return the minimum required handle size Aneesh Kumar K.V
2010-04-22 18:15 ` Aneesh Kumar K.V [this message]
2010-04-22 18:15 ` [PATCH -V3 3/5] vfs: Add open by file handle support Aneesh Kumar K.V
2010-04-22 19:22 ` Andreas Dilger
2010-04-23 11:40 ` Aneesh Kumar K. V
2010-04-22 18:15 ` [PATCH -V3 4/5] x86: Add new syscalls for x86_32 Aneesh Kumar K.V
2010-04-22 18:15 ` [PATCH -V3 5/5] ext4: Add get_fsid callback Aneesh Kumar K.V
2010-04-22 19:07 ` [PATCH -V3] Generic name to handle and open by handle syscalls Andreas Dilger
2010-04-22 22:49 ` Serge E. Hallyn
2010-04-23 11:45 ` Aneesh Kumar K. V
2010-04-23 13:49 ` Serge E. Hallyn
2010-04-23 13:23 ` Theodore Tso
2010-04-24 0:19 ` Andreas Dilger
2010-04-24 1:08 ` Neil Brown
2010-04-25 18:21 ` Aneesh Kumar K. V
2010-04-26 9:56 ` Christoph Hellwig
2010-04-26 10:16 ` Neil Brown
2010-04-26 10:28 ` Christoph Hellwig
2010-04-26 11:16 ` Neil Brown
2010-04-26 14:53 ` Theodore Tso
2010-04-26 14:56 ` Christoph Hellwig
2010-04-25 18:07 ` Aneesh Kumar K. V
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1271960133-16414-3-git-send-email-aneesh.kumar@linux.vnet.ibm.com \
--to=aneesh.kumar@linux.vnet.ibm.com \
--cc=adilger@sun.com \
--cc=corbet@lwn.net \
--cc=hch@infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=sfrench@us.ibm.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.