Commit 5fe0c237 authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Al Viro

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.
Acked-by: default avatarSerge Hallyn <serue@us.ibm.com>
Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent c8b91acc
...@@ -21,9 +21,13 @@ static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, ...@@ -21,9 +21,13 @@ static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len,
int len = *max_len; int len = *max_len;
int type; int type;
if ((len < BTRFS_FID_SIZE_NON_CONNECTABLE) || if (connectable && (len < BTRFS_FID_SIZE_CONNECTABLE)) {
(connectable && len < BTRFS_FID_SIZE_CONNECTABLE)) *max_len = BTRFS_FID_SIZE_CONNECTABLE;
return 255; 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; len = BTRFS_FID_SIZE_NON_CONNECTABLE;
type = FILEID_BTRFS_WITHOUT_PARENT; type = FILEID_BTRFS_WITHOUT_PARENT;
......
...@@ -320,9 +320,14 @@ static int export_encode_fh(struct dentry *dentry, struct fid *fid, ...@@ -320,9 +320,14 @@ static int export_encode_fh(struct dentry *dentry, struct fid *fid,
struct inode * inode = dentry->d_inode; struct inode * inode = dentry->d_inode;
int len = *max_len; int len = *max_len;
int type = FILEID_INO32_GEN; 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; return 255;
}
len = 2; len = 2;
fid->i32.ino = inode->i_ino; fid->i32.ino = inode->i_ino;
......
...@@ -757,8 +757,10 @@ fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable) ...@@ -757,8 +757,10 @@ fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
struct inode *inode = de->d_inode; struct inode *inode = de->d_inode;
u32 ipos_h, ipos_m, ipos_l; u32 ipos_h, ipos_m, ipos_l;
if (len < 5) if (len < 5) {
*lenp = 5;
return 255; /* no room */ return 255; /* no room */
}
ipos_h = MSDOS_I(inode)->i_pos >> 8; ipos_h = MSDOS_I(inode)->i_pos >> 8;
ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24; ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24;
......
...@@ -637,8 +637,10 @@ static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, ...@@ -637,8 +637,10 @@ static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len,
u64 nodeid; u64 nodeid;
u32 generation; u32 generation;
if (*max_len < len) if (*max_len < len) {
*max_len = len;
return 255; return 255;
}
nodeid = get_fuse_inode(inode)->nodeid; nodeid = get_fuse_inode(inode)->nodeid;
generation = inode->i_generation; generation = inode->i_generation;
......
...@@ -36,9 +36,13 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, ...@@ -36,9 +36,13 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_inode *ip = GFS2_I(inode);
if (*len < GFS2_SMALL_FH_SIZE || if (connectable && (*len < GFS2_LARGE_FH_SIZE)) {
(connectable && *len < GFS2_LARGE_FH_SIZE)) *len = GFS2_LARGE_FH_SIZE;
return 255; 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[0] = cpu_to_be32(ip->i_no_formal_ino >> 32);
fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF);
......
...@@ -124,9 +124,13 @@ isofs_export_encode_fh(struct dentry *dentry, ...@@ -124,9 +124,13 @@ isofs_export_encode_fh(struct dentry *dentry,
* offset of the inode and the upper 16 bits of fh32[1] to * offset of the inode and the upper 16 bits of fh32[1] to
* hold the offset of the parent. * hold the offset of the parent.
*/ */
if (connectable && (len < 5)) {
if (len < 3 || (connectable && len < 5)) *max_len = 5;
return 255;
} else if (len < 3) {
*max_len = 3;
return 255; return 255;
}
len = 3; len = 3;
fh32[0] = ei->i_iget5_block; fh32[0] = ei->i_iget5_block;
......
...@@ -197,8 +197,12 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, ...@@ -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, dentry->d_name.len, dentry->d_name.name,
fh, len, connectable); 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) {
*max_len = 3;
type = 255; type = 255;
goto bail; goto bail;
} }
......
...@@ -1593,8 +1593,13 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, ...@@ -1593,8 +1593,13 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
int maxlen = *lenp; int maxlen = *lenp;
if (maxlen < 3) if (need_parent && (maxlen < 5)) {
*lenp = 5;
return 255; return 255;
} else if (maxlen < 3) {
*lenp = 3;
return 255;
}
data[0] = inode->i_ino; data[0] = inode->i_ino;
data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id);
......
...@@ -1286,8 +1286,13 @@ static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp, ...@@ -1286,8 +1286,13 @@ static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp,
struct fid *fid = (struct fid *)fh; struct fid *fid = (struct fid *)fh;
int type = FILEID_UDF_WITHOUT_PARENT; 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; return 255;
}
*lenp = 3; *lenp = 3;
fid->udf.block = location.logicalBlockNum; fid->udf.block = location.logicalBlockNum;
......
...@@ -89,8 +89,10 @@ xfs_fs_encode_fh( ...@@ -89,8 +89,10 @@ xfs_fs_encode_fh(
* seven combinations work. The real answer is "don't use v2". * seven combinations work. The real answer is "don't use v2".
*/ */
len = xfs_fileid_length(fileid_type); len = xfs_fileid_length(fileid_type);
if (*max_len < len) if (*max_len < len) {
*max_len = len;
return 255; return 255;
}
*max_len = len; *max_len = len;
switch (fileid_type) { switch (fileid_type) {
......
...@@ -121,8 +121,10 @@ struct fid { ...@@ -121,8 +121,10 @@ struct fid {
* set, the encode_fh() should store sufficient information so that a good * 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 * 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 * filesystem. This typically means storing a reference to de->d_parent in
* the filehandle fragment. encode_fh() should return the number of bytes * the filehandle fragment. encode_fh() should return the fileid_type on
* stored or a negative error code such as %-ENOSPC * 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:
* @fh_to_dentry is given a &struct super_block (@sb) and a file handle * @fh_to_dentry is given a &struct super_block (@sb) and a file handle
......
...@@ -2144,8 +2144,10 @@ static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len, ...@@ -2144,8 +2144,10 @@ static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
if (*len < 3) if (*len < 3) {
*len = 3;
return 255; return 255;
}
if (inode_unhashed(inode)) { if (inode_unhashed(inode)) {
/* Unfortunately insert_inode_hash is not idempotent, /* Unfortunately insert_inode_hash is not idempotent,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment