All of lore.kernel.org
 help / color / mirror / Atom feed
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,

  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 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.