diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2011-01-29 08:13:25 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-14 09:15:28 -0400 |
commit | 5fe0c2378884e68beb532f5890cc0e3539ac747b (patch) | |
tree | be25414052184e146049ea6466854366559d5528 | |
parent | c8b91accfa1059d5565443193d89572eca2f5dd6 (diff) |
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: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/btrfs/export.c | 8 | ||||
-rw-r--r-- | fs/exportfs/expfs.c | 9 | ||||
-rw-r--r-- | fs/fat/inode.c | 4 | ||||
-rw-r--r-- | fs/fuse/inode.c | 4 | ||||
-rw-r--r-- | fs/gfs2/export.c | 8 | ||||
-rw-r--r-- | fs/isofs/export.c | 8 | ||||
-rw-r--r-- | fs/ocfs2/export.c | 8 | ||||
-rw-r--r-- | fs/reiserfs/inode.c | 7 | ||||
-rw-r--r-- | fs/udf/namei.c | 7 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_export.c | 4 | ||||
-rw-r--r-- | include/linux/exportfs.h | 6 | ||||
-rw-r--r-- | mm/shmem.c | 4 |
12 files changed, 59 insertions, 18 deletions
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index ff27d7a477b2..b4ffad859adb 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, | |||
21 | int len = *max_len; | 21 | int len = *max_len; |
22 | int type; | 22 | int type; |
23 | 23 | ||
24 | if ((len < BTRFS_FID_SIZE_NON_CONNECTABLE) || | 24 | if (connectable && (len < BTRFS_FID_SIZE_CONNECTABLE)) { |
25 | (connectable && len < BTRFS_FID_SIZE_CONNECTABLE)) | 25 | *max_len = BTRFS_FID_SIZE_CONNECTABLE; |
26 | return 255; | 26 | return 255; |
27 | } else if (len < BTRFS_FID_SIZE_NON_CONNECTABLE) { | ||
28 | *max_len = BTRFS_FID_SIZE_NON_CONNECTABLE; | ||
29 | return 255; | ||
30 | } | ||
27 | 31 | ||
28 | len = BTRFS_FID_SIZE_NON_CONNECTABLE; | 32 | len = BTRFS_FID_SIZE_NON_CONNECTABLE; |
29 | type = FILEID_BTRFS_WITHOUT_PARENT; | 33 | type = FILEID_BTRFS_WITHOUT_PARENT; |
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 4b6825740dd5..cfe55731b6dc 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -320,9 +320,14 @@ static int export_encode_fh(struct dentry *dentry, struct fid *fid, | |||
320 | struct inode * inode = dentry->d_inode; | 320 | struct inode * inode = dentry->d_inode; |
321 | int len = *max_len; | 321 | int len = *max_len; |
322 | int type = FILEID_INO32_GEN; | 322 | int type = FILEID_INO32_GEN; |
323 | 323 | ||
324 | if (len < 2 || (connectable && len < 4)) | 324 | if (connectable && (len < 4)) { |
325 | *max_len = 4; | ||
326 | return 255; | ||
327 | } else if (len < 2) { | ||
328 | *max_len = 2; | ||
325 | return 255; | 329 | return 255; |
330 | } | ||
326 | 331 | ||
327 | len = 2; | 332 | len = 2; |
328 | fid->i32.ino = inode->i_ino; | 333 | fid->i32.ino = inode->i_ino; |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 86753fe10bd1..0e277ec4b612 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -757,8 +757,10 @@ fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable) | |||
757 | struct inode *inode = de->d_inode; | 757 | struct inode *inode = de->d_inode; |
758 | u32 ipos_h, ipos_m, ipos_l; | 758 | u32 ipos_h, ipos_m, ipos_l; |
759 | 759 | ||
760 | if (len < 5) | 760 | if (len < 5) { |
761 | *lenp = 5; | ||
761 | return 255; /* no room */ | 762 | return 255; /* no room */ |
763 | } | ||
762 | 764 | ||
763 | ipos_h = MSDOS_I(inode)->i_pos >> 8; | 765 | ipos_h = MSDOS_I(inode)->i_pos >> 8; |
764 | ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24; | 766 | ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24; |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 9e3f68cc1bd1..051b1a084528 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -637,8 +637,10 @@ static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, | |||
637 | u64 nodeid; | 637 | u64 nodeid; |
638 | u32 generation; | 638 | u32 generation; |
639 | 639 | ||
640 | if (*max_len < len) | 640 | if (*max_len < len) { |
641 | *max_len = len; | ||
641 | return 255; | 642 | return 255; |
643 | } | ||
642 | 644 | ||
643 | nodeid = get_fuse_inode(inode)->nodeid; | 645 | nodeid = get_fuse_inode(inode)->nodeid; |
644 | generation = inode->i_generation; | 646 | generation = inode->i_generation; |
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c index 9023db8184f9..b5a5e60df0d5 100644 --- a/fs/gfs2/export.c +++ b/fs/gfs2/export.c | |||
@@ -36,9 +36,13 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, | |||
36 | struct super_block *sb = inode->i_sb; | 36 | struct super_block *sb = inode->i_sb; |
37 | struct gfs2_inode *ip = GFS2_I(inode); | 37 | struct gfs2_inode *ip = GFS2_I(inode); |
38 | 38 | ||
39 | if (*len < GFS2_SMALL_FH_SIZE || | 39 | if (connectable && (*len < GFS2_LARGE_FH_SIZE)) { |
40 | (connectable && *len < GFS2_LARGE_FH_SIZE)) | 40 | *len = GFS2_LARGE_FH_SIZE; |
41 | return 255; | 41 | return 255; |
42 | } else if (*len < GFS2_SMALL_FH_SIZE) { | ||
43 | *len = GFS2_SMALL_FH_SIZE; | ||
44 | return 255; | ||
45 | } | ||
42 | 46 | ||
43 | fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32); | 47 | fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32); |
44 | fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); | 48 | fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); |
diff --git a/fs/isofs/export.c b/fs/isofs/export.c index ed752cb38474..dd4687ff30d0 100644 --- a/fs/isofs/export.c +++ b/fs/isofs/export.c | |||
@@ -124,9 +124,13 @@ isofs_export_encode_fh(struct dentry *dentry, | |||
124 | * offset of the inode and the upper 16 bits of fh32[1] to | 124 | * offset of the inode and the upper 16 bits of fh32[1] to |
125 | * hold the offset of the parent. | 125 | * hold the offset of the parent. |
126 | */ | 126 | */ |
127 | 127 | if (connectable && (len < 5)) { | |
128 | if (len < 3 || (connectable && len < 5)) | 128 | *max_len = 5; |
129 | return 255; | ||
130 | } else if (len < 3) { | ||
131 | *max_len = 3; | ||
129 | return 255; | 132 | return 255; |
133 | } | ||
130 | 134 | ||
131 | len = 3; | 135 | len = 3; |
132 | fh32[0] = ei->i_iget5_block; | 136 | fh32[0] = ei->i_iget5_block; |
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c index 5dbc3062b4fd..254652a9b542 100644 --- a/fs/ocfs2/export.c +++ b/fs/ocfs2/export.c | |||
@@ -197,8 +197,12 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, | |||
197 | dentry->d_name.len, dentry->d_name.name, | 197 | dentry->d_name.len, dentry->d_name.name, |
198 | fh, len, connectable); | 198 | fh, len, connectable); |
199 | 199 | ||
200 | if (len < 3 || (connectable && len < 6)) { | 200 | if (connectable && (len < 6)) { |
201 | mlog(ML_ERROR, "fh buffer is too small for encoding\n"); | 201 | *max_len = 6; |
202 | type = 255; | ||
203 | goto bail; | ||
204 | } else if (len < 3) { | ||
205 | *max_len = 3; | ||
202 | type = 255; | 206 | type = 255; |
203 | goto bail; | 207 | goto bail; |
204 | } | 208 | } |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 0bae036831e2..1bba24bad820 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -1593,8 +1593,13 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, | |||
1593 | struct inode *inode = dentry->d_inode; | 1593 | struct inode *inode = dentry->d_inode; |
1594 | int maxlen = *lenp; | 1594 | int maxlen = *lenp; |
1595 | 1595 | ||
1596 | if (maxlen < 3) | 1596 | if (need_parent && (maxlen < 5)) { |
1597 | *lenp = 5; | ||
1597 | return 255; | 1598 | return 255; |
1599 | } else if (maxlen < 3) { | ||
1600 | *lenp = 3; | ||
1601 | return 255; | ||
1602 | } | ||
1598 | 1603 | ||
1599 | data[0] = inode->i_ino; | 1604 | data[0] = inode->i_ino; |
1600 | data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); | 1605 | data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index b7c338d5e9df..f1dce848ef96 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -1286,8 +1286,13 @@ static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp, | |||
1286 | struct fid *fid = (struct fid *)fh; | 1286 | struct fid *fid = (struct fid *)fh; |
1287 | int type = FILEID_UDF_WITHOUT_PARENT; | 1287 | int type = FILEID_UDF_WITHOUT_PARENT; |
1288 | 1288 | ||
1289 | if (len < 3 || (connectable && len < 5)) | 1289 | if (connectable && (len < 5)) { |
1290 | *lenp = 5; | ||
1291 | return 255; | ||
1292 | } else if (len < 3) { | ||
1293 | *lenp = 3; | ||
1290 | return 255; | 1294 | return 255; |
1295 | } | ||
1291 | 1296 | ||
1292 | *lenp = 3; | 1297 | *lenp = 3; |
1293 | fid->udf.block = location.logicalBlockNum; | 1298 | 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 fc0114da7fdd..f4f878fc0083 100644 --- a/fs/xfs/linux-2.6/xfs_export.c +++ b/fs/xfs/linux-2.6/xfs_export.c | |||
@@ -89,8 +89,10 @@ xfs_fs_encode_fh( | |||
89 | * seven combinations work. The real answer is "don't use v2". | 89 | * seven combinations work. The real answer is "don't use v2". |
90 | */ | 90 | */ |
91 | len = xfs_fileid_length(fileid_type); | 91 | len = xfs_fileid_length(fileid_type); |
92 | if (*max_len < len) | 92 | if (*max_len < len) { |
93 | *max_len = len; | ||
93 | return 255; | 94 | return 255; |
95 | } | ||
94 | *max_len = len; | 96 | *max_len = len; |
95 | 97 | ||
96 | switch (fileid_type) { | 98 | switch (fileid_type) { |
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index 28028988c862..65afdfd31b7b 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h | |||
@@ -121,8 +121,10 @@ struct fid { | |||
121 | * set, the encode_fh() should store sufficient information so that a good | 121 | * set, the encode_fh() should store sufficient information so that a good |
122 | * attempt can be made to find not only the file but also it's place in the | 122 | * attempt can be made to find not only the file but also it's place in the |
123 | * filesystem. This typically means storing a reference to de->d_parent in | 123 | * filesystem. This typically means storing a reference to de->d_parent in |
124 | * the filehandle fragment. encode_fh() should return the number of bytes | 124 | * the filehandle fragment. encode_fh() should return the fileid_type on |
125 | * stored or a negative error code such as %-ENOSPC | 125 | * success and on error returns 255 (if the space needed to encode fh is |
126 | * greater than @max_len*4 bytes). On error @max_len contains the minimum | ||
127 | * size(in 4 byte unit) needed to encode the file handle. | ||
126 | * | 128 | * |
127 | * fh_to_dentry: | 129 | * fh_to_dentry: |
128 | * @fh_to_dentry is given a &struct super_block (@sb) and a file handle | 130 | * @fh_to_dentry is given a &struct super_block (@sb) and a file handle |
diff --git a/mm/shmem.c b/mm/shmem.c index 5ee67c990602..3437b65d6d6e 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -2144,8 +2144,10 @@ static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | |||
2144 | { | 2144 | { |
2145 | struct inode *inode = dentry->d_inode; | 2145 | struct inode *inode = dentry->d_inode; |
2146 | 2146 | ||
2147 | if (*len < 3) | 2147 | if (*len < 3) { |
2148 | *len = 3; | ||
2148 | return 255; | 2149 | return 255; |
2150 | } | ||
2149 | 2151 | ||
2150 | if (inode_unhashed(inode)) { | 2152 | if (inode_unhashed(inode)) { |
2151 | /* Unfortunately insert_inode_hash is not idempotent, | 2153 | /* Unfortunately insert_inode_hash is not idempotent, |