From: "Aneesh Kumar K. V" <aneesh.kumar@linux.vnet.ibm.com>
To: Andreas Dilger <adilger@sun.com>
Cc: hch@infradead.org, viro@zeniv.linux.org.uk,
linux-fsdevel@vger.kernel.org, corbet@lwn.net
Subject: Re: [PATCH -V2] Generic name to handle and open by handle syscalls
Date: Fri, 19 Mar 2010 11:30:27 +0530 [thread overview]
Message-ID: <87eijgkg04.fsf@linux.vnet.ibm.com> (raw)
In-Reply-To: <77C63295-0772-4AAC-B5C2-502BD991FC6B@sun.com>
On Thu, 18 Mar 2010 16:26:42 -0600, Andreas Dilger <adilger@sun.com> wrote:
> On 2010-03-18, at 11:09, Aneesh Kumar K.V wrote:
> > Example program:
> > int main(int argc, char *argv[])
> > {
> > ret = syscall(338, argv[1], &fh);
> > if (ret) {
> > perror("Error:");
> > exit(1);
> > }
> > dirfd = open("/", O_RDONLY|O_DIRECTORY);
> > fd = syscall(339, dirfd, &fh, O_RDONLY);
>
>
> For your example program, it would be useful to include the
> system calls so it is easier to see what is going on, like:
>
> #ifndef HAVE_NAME_TO_HANDLE
> static inline int name_to_handle(const char *name, struct file_handle
> *fh)
> {
> return syscall(338, name, fh);
> }
>
> static inline int open_by_handle(int dirfd, struct file_handle *fh,
> int flags)
> {
> return syscall(339, dirfd, fh, flags);
> }
> #endif
>
> int main(...)
> {
> ret = name_to_handle(argv[1], &fh);
> :
>
> dirfd = open("/", O_RDONLY|O_DIRECTORY);
> fd = open_by_handle(dirfd, &fh, O_RDONLY);
> :
> :
> }
>
Updated the sample prg as below. I also needed an additonal kernel
patch. Adding the kernel patch also here.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
struct file_handle {
int handle_size;
int handle_type;
void *handle;
};
static int name_to_handle(const char *name, struct file_handle *fh)
{
return syscall(338, name, fh);
}
static int open_by_handle(int dirfd, struct file_handle *fh, int flags)
{
return syscall(339, dirfd, fh, flags);
}
int main(int argc, char *argv[])
{
int ret;
int fd, dirfd;
char buf[100];
struct file_handle fh;
fh.handle_size = 0;
again:
if (fh.handle_size)
fh.handle = malloc(fh.handle_size);
fh.handle_type = 0;
errno = 0;
ret = name_to_handle(argv[1], &fh);
if (ret) {
perror("Error:");
printf("Found the handle size needed to be %d\n", fh.handle_size);
printf("Trying again..\n");
goto again;
exit(1);
}
dirfd = open("/", O_RDONLY|O_DIRECTORY);
fd = open_by_handle(dirfd, &fh, O_RDONLY);
if (fd <= 0 ) {
perror("Error:");
exit(1);
}
memset(buf, 0 , 100);
while (read(fd, buf, 100) > 0) {
printf("%s", buf);
memset(buf, 0 , 100);
}
return 0;
}
commit 1a1fe3f95295857e8406fcc3943ba6ad4cc2792c
Author: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Date: Fri Mar 19 10:19:17 2010 +0530
exportfs: Return the minimum required handle size
The exportfs encode handle function should return the minimum required
handle size. This helps user to find out the handle size by passing 0
handle size in the first step and then redoing to the call again with
the returned handle size value.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index ba5c3fd..db22392 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -21,9 +21,13 @@ static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len,
int len = *max_len;
int type;
- if ((len < BTRFS_FID_SIZE_NON_CONNECTABLE) ||
- (connectable && len < BTRFS_FID_SIZE_CONNECTABLE))
+ if (connectable && (len < BTRFS_FID_SIZE_CONNECTABLE)) {
+ *max_len = BTRFS_FID_SIZE_CONNECTABLE;
return 255;
+ } else if (len < BTRFS_FID_SIZE_NON_CONNECTABLE) {
+ *max_len = BTRFS_FID_SIZE_NON_CONNECTABLE;
+ return 255;
+ }
len = BTRFS_FID_SIZE_NON_CONNECTABLE;
type = FILEID_BTRFS_WITHOUT_PARENT;
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index e9e1759..cfee0f0 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -319,9 +319,14 @@ static int export_encode_fh(struct dentry *dentry, struct fid *fid,
struct inode * inode = dentry->d_inode;
int len = *max_len;
int type = FILEID_INO32_GEN;
-
- if (len < 2 || (connectable && len < 4))
+
+ if (connectable && (len < 4)) {
+ *max_len = 4;
+ return 255;
+ } else if (len < 2) {
+ *max_len = 2;
return 255;
+ }
len = 2;
fid->i32.ino = inode->i_ino;
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index fbeecdc..b4c3839 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -738,8 +738,10 @@ fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
struct inode *inode = de->d_inode;
u32 ipos_h, ipos_m, ipos_l;
- if (len < 5)
+ if (len < 5) {
+ *lenp = 5;
return 255; /* no room */
+ }
ipos_h = MSDOS_I(inode)->i_pos >> 8;
ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 1a822ce..a0e90c3 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -638,8 +638,10 @@ static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len,
u64 nodeid;
u32 generation;
- if (*max_len < len)
+ if (*max_len < len) {
+ *max_len = len;
return 255;
+ }
nodeid = get_fuse_inode(inode)->nodeid;
generation = inode->i_generation;
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c
index d15876e..4a85b36 100644
--- a/fs/gfs2/export.c
+++ b/fs/gfs2/export.c
@@ -37,9 +37,13 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
struct super_block *sb = inode->i_sb;
struct gfs2_inode *ip = GFS2_I(inode);
- if (*len < GFS2_SMALL_FH_SIZE ||
- (connectable && *len < GFS2_LARGE_FH_SIZE))
+ if (connectable && (*len < GFS2_LARGE_FH_SIZE)) {
+ *len = GFS2_LARGE_FH_SIZE;
return 255;
+ } else if (*len < GFS2_SMALL_FH_SIZE) {
+ *len = GFS2_SMALL_FH_SIZE;
+ return 255;
+ }
fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32);
fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF);
diff --git a/fs/isofs/export.c b/fs/isofs/export.c
index ed752cb..dd4687f 100644
--- a/fs/isofs/export.c
+++ b/fs/isofs/export.c
@@ -124,9 +124,13 @@ isofs_export_encode_fh(struct dentry *dentry,
* offset of the inode and the upper 16 bits of fh32[1] to
* hold the offset of the parent.
*/
-
- if (len < 3 || (connectable && len < 5))
+ if (connectable && (len < 5)) {
+ *max_len = 5;
+ return 255;
+ } else if (len < 3) {
+ *max_len = 3;
return 255;
+ }
len = 3;
fh32[0] = ei->i_iget5_block;
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index 19ad145..250a347 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -201,8 +201,14 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len,
dentry->d_name.len, dentry->d_name.name,
fh, len, connectable);
- if (len < 3 || (connectable && len < 6)) {
+ if (connectable && (len < 6)) {
mlog(ML_ERROR, "fh buffer is too small for encoding\n");
+ *max_len = 6;
+ type = 255;
+ goto bail;
+ } else if (len < 3) {
+ mlog(ML_ERROR, "fh buffer is too small for encoding\n");
+ *max_len = 3;
type = 255;
goto bail;
}
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index d1da94b..fe1600c 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1587,8 +1587,13 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
struct inode *inode = dentry->d_inode;
int maxlen = *lenp;
- if (maxlen < 3)
+ if (need_parent && (maxlen < 5)) {
+ *lenp = 5;
return 255;
+ } else if (maxlen < 3) {
+ *lenp = 3;
+ return 255;
+ }
data[0] = inode->i_ino;
data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id);
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index db423ab..7f6fc85 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -1360,8 +1360,13 @@ static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp,
struct fid *fid = (struct fid *)fh;
int type = FILEID_UDF_WITHOUT_PARENT;
- if (len < 3 || (connectable && len < 5))
+ if (connectable && (len < 5)) {
+ *lenp = 5;
+ return 255;
+ } else if (len < 3) {
+ *lenp = 3;
return 255;
+ }
*lenp = 3;
fid->udf.block = location.logicalBlockNum;
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index 846b75a..82c0553 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -81,8 +81,10 @@ xfs_fs_encode_fh(
* seven combinations work. The real answer is "don't use v2".
*/
len = xfs_fileid_length(fileid_type);
- if (*max_len < len)
+ if (*max_len < len) {
+ *max_len = len
return 255;
+ }
*max_len = len;
switch (fileid_type) {
diff --git a/mm/shmem.c b/mm/shmem.c
index eef4ebe..bbeda1c 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2125,8 +2125,10 @@ static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
{
struct inode *inode = dentry->d_inode;
- if (*len < 3)
+ if (*len < 3) {
+ *len = 3;
return 255;
+ }
if (hlist_unhashed(&inode->i_hash)) {
/* Unfortunately insert_inode_hash is not idempotent,
next prev parent reply other threads:[~2010-03-19 6:00 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-18 17:09 [PATCH -V2] Generic name to handle and open by handle syscalls Aneesh Kumar K.V
2010-03-18 17:09 ` [PATCH -V2 1/3] vfs: Add name to file handle conversion support Aneesh Kumar K.V
2010-03-18 17:09 ` [PATCH -V2 2/3] vfs: Add open by file handle support Aneesh Kumar K.V
2010-03-18 17:09 ` [PATCH -V2 3/3] x86: Add new syscalls for x86_32 Aneesh Kumar K.V
2010-03-18 17:31 ` [PATCH -V2] Generic name to handle and open by handle syscalls Christoph Hellwig
2010-03-18 17:54 ` J. Bruce Fields
2010-03-29 7:12 ` Aneesh Kumar K. V
2010-03-30 19:36 ` Andreas Dilger
2010-03-18 22:26 ` Andreas Dilger
2010-03-19 6:00 ` Aneesh Kumar K. V [this message]
2010-03-26 0:42 ` Ben Hutchings
2010-03-26 6:43 ` Andreas Dilger
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=87eijgkg04.fsf@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=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).