Skip to content

Commit

Permalink
exportfs: Return the minimum required handle size
Browse files Browse the repository at this point in the history
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.

Acked-by: Serge Hallyn <[email protected]>
Signed-off-by: Aneesh Kumar K.V <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
kvaneesh authored and Al Viro committed Mar 14, 2011
1 parent c8b91ac commit 5fe0c23
Show file tree
Hide file tree
Showing 12 changed files with 59 additions and 18 deletions.
8 changes: 6 additions & 2 deletions fs/btrfs/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
9 changes: 7 additions & 2 deletions fs/exportfs/expfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,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;
Expand Down
4 changes: 3 additions & 1 deletion fs/fat/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,8 +757,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;
Expand Down
4 changes: 3 additions & 1 deletion fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,8 +637,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;
Expand Down
8 changes: 6 additions & 2 deletions fs/gfs2/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,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);
Expand Down
8 changes: 6 additions & 2 deletions fs/isofs/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions fs/ocfs2/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,12 @@ 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)) {
mlog(ML_ERROR, "fh buffer is too small for encoding\n");
if (connectable && (len < 6)) {
*max_len = 6;
type = 255;
goto bail;
} else if (len < 3) {
*max_len = 3;
type = 255;
goto bail;
}
Expand Down
7 changes: 6 additions & 1 deletion fs/reiserfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1593,8 +1593,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);
Expand Down
7 changes: 6 additions & 1 deletion fs/udf/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1286,8 +1286,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;
Expand Down
4 changes: 3 additions & 1 deletion fs/xfs/linux-2.6/xfs_export.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,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) {
Expand Down
6 changes: 4 additions & 2 deletions include/linux/exportfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,10 @@ struct fid {
* set, the encode_fh() should store sufficient information so that a good
* attempt can be made to find not only the file but also it's place in the
* filesystem. This typically means storing a reference to de->d_parent in
* the filehandle fragment. encode_fh() should return the number of bytes
* stored or a negative error code such as %-ENOSPC
* the filehandle fragment. encode_fh() should return the fileid_type on
* success and on error returns 255 (if the space needed to encode fh is
* greater than @max_len*4 bytes). On error @max_len contains the minimum
* size(in 4 byte unit) needed to encode the file handle.
*
* fh_to_dentry:
* @fh_to_dentry is given a &struct super_block (@sb) and a file handle
Expand Down
4 changes: 3 additions & 1 deletion mm/shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2144,8 +2144,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 (inode_unhashed(inode)) {
/* Unfortunately insert_inode_hash is not idempotent,
Expand Down

0 comments on commit 5fe0c23

Please sign in to comment.