aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-04-02 14:34:06 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-05-29 23:28:33 -0400
commitb0b0382bb4904965a9e9fca77ad87514dfda0d1c (patch)
treedc46873fa74e0d194e4a2571b16f0767e1919ae8 /fs
parent6d42e7e9f6d86ed4dfacde75a6cf515068f9749c (diff)
->encode_fh() API change
pass inode + parent's inode or NULL instead of dentry + bool saying whether we want the parent or not. NOTE: that needs ceph fix folded in. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/export.c15
-rw-r--r--fs/ceph/export.c2
-rw-r--r--fs/exportfs/expfs.c33
-rw-r--r--fs/fat/inode.c9
-rw-r--r--fs/fuse/inode.c17
-rw-r--r--fs/gfs2/export.c17
-rw-r--r--fs/isofs/export.c13
-rw-r--r--fs/nilfs2/namei.c22
-rw-r--r--fs/ocfs2/export.c19
-rw-r--r--fs/reiserfs/inode.c30
-rw-r--r--fs/reiserfs/reiserfs.h4
-rw-r--r--fs/udf/namei.c14
-rw-r--r--fs/xfs/xfs_export.c23
13 files changed, 88 insertions, 130 deletions
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index e887ee62b6d4..614f34a899c2 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -13,15 +13,14 @@
13 parent_root_objectid) / 4) 13 parent_root_objectid) / 4)
14#define BTRFS_FID_SIZE_CONNECTABLE_ROOT (sizeof(struct btrfs_fid) / 4) 14#define BTRFS_FID_SIZE_CONNECTABLE_ROOT (sizeof(struct btrfs_fid) / 4)
15 15
16static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, 16static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
17 int connectable) 17 struct inode *parent)
18{ 18{
19 struct btrfs_fid *fid = (struct btrfs_fid *)fh; 19 struct btrfs_fid *fid = (struct btrfs_fid *)fh;
20 struct inode *inode = dentry->d_inode;
21 int len = *max_len; 20 int len = *max_len;
22 int type; 21 int type;
23 22
24 if (connectable && (len < BTRFS_FID_SIZE_CONNECTABLE)) { 23 if (parent && (len < BTRFS_FID_SIZE_CONNECTABLE)) {
25 *max_len = BTRFS_FID_SIZE_CONNECTABLE; 24 *max_len = BTRFS_FID_SIZE_CONNECTABLE;
26 return 255; 25 return 255;
27 } else if (len < BTRFS_FID_SIZE_NON_CONNECTABLE) { 26 } else if (len < BTRFS_FID_SIZE_NON_CONNECTABLE) {
@@ -36,19 +35,13 @@ static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len,
36 fid->root_objectid = BTRFS_I(inode)->root->objectid; 35 fid->root_objectid = BTRFS_I(inode)->root->objectid;
37 fid->gen = inode->i_generation; 36 fid->gen = inode->i_generation;
38 37
39 if (connectable && !S_ISDIR(inode->i_mode)) { 38 if (parent) {
40 struct inode *parent;
41 u64 parent_root_id; 39 u64 parent_root_id;
42 40
43 spin_lock(&dentry->d_lock);
44
45 parent = dentry->d_parent->d_inode;
46 fid->parent_objectid = BTRFS_I(parent)->location.objectid; 41 fid->parent_objectid = BTRFS_I(parent)->location.objectid;
47 fid->parent_gen = parent->i_generation; 42 fid->parent_gen = parent->i_generation;
48 parent_root_id = BTRFS_I(parent)->root->objectid; 43 parent_root_id = BTRFS_I(parent)->root->objectid;
49 44
50 spin_unlock(&dentry->d_lock);
51
52 if (parent_root_id != fid->root_objectid) { 45 if (parent_root_id != fid->root_objectid) {
53 fid->parent_root_objectid = parent_root_id; 46 fid->parent_root_objectid = parent_root_id;
54 len = BTRFS_FID_SIZE_CONNECTABLE_ROOT; 47 len = BTRFS_FID_SIZE_CONNECTABLE_ROOT;
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index fbb2a643ef10..4f9234c6da61 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -247,7 +247,9 @@ static struct dentry *ceph_fh_to_parent(struct super_block *sb,
247} 247}
248 248
249const struct export_operations ceph_export_ops = { 249const struct export_operations ceph_export_ops = {
250#ifdef CEPH_BREAKAGE_FIXED
250 .encode_fh = ceph_encode_fh, 251 .encode_fh = ceph_encode_fh,
252#endif
251 .fh_to_dentry = ceph_fh_to_dentry, 253 .fh_to_dentry = ceph_fh_to_dentry,
252 .fh_to_parent = ceph_fh_to_parent, 254 .fh_to_parent = ceph_fh_to_parent,
253}; 255};
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index b05acb796135..b0201ca6e9c6 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -304,24 +304,23 @@ out:
304 304
305/** 305/**
306 * export_encode_fh - default export_operations->encode_fh function 306 * export_encode_fh - default export_operations->encode_fh function
307 * @dentry: the dentry to encode 307 * @inode: the object to encode
308 * @fh: where to store the file handle fragment 308 * @fh: where to store the file handle fragment
309 * @max_len: maximum length to store there 309 * @max_len: maximum length to store there
310 * @connectable: whether to store parent information 310 * @parent: parent directory inode, if wanted
311 * 311 *
312 * This default encode_fh function assumes that the 32 inode number 312 * This default encode_fh function assumes that the 32 inode number
313 * is suitable for locating an inode, and that the generation number 313 * is suitable for locating an inode, and that the generation number
314 * can be used to check that it is still valid. It places them in the 314 * can be used to check that it is still valid. It places them in the
315 * filehandle fragment where export_decode_fh expects to find them. 315 * filehandle fragment where export_decode_fh expects to find them.
316 */ 316 */
317static int export_encode_fh(struct dentry *dentry, struct fid *fid, 317static int export_encode_fh(struct inode *inode, struct fid *fid,
318 int *max_len, int connectable) 318 int *max_len, struct inode *parent)
319{ 319{
320 struct inode * inode = dentry->d_inode;
321 int len = *max_len; 320 int len = *max_len;
322 int type = FILEID_INO32_GEN; 321 int type = FILEID_INO32_GEN;
323 322
324 if (connectable && (len < 4)) { 323 if (parent && (len < 4)) {
325 *max_len = 4; 324 *max_len = 4;
326 return 255; 325 return 255;
327 } else if (len < 2) { 326 } else if (len < 2) {
@@ -332,14 +331,9 @@ static int export_encode_fh(struct dentry *dentry, struct fid *fid,
332 len = 2; 331 len = 2;
333 fid->i32.ino = inode->i_ino; 332 fid->i32.ino = inode->i_ino;
334 fid->i32.gen = inode->i_generation; 333 fid->i32.gen = inode->i_generation;
335 if (connectable && !S_ISDIR(inode->i_mode)) { 334 if (parent) {
336 struct inode *parent;
337
338 spin_lock(&dentry->d_lock);
339 parent = dentry->d_parent->d_inode;
340 fid->i32.parent_ino = parent->i_ino; 335 fid->i32.parent_ino = parent->i_ino;
341 fid->i32.parent_gen = parent->i_generation; 336 fid->i32.parent_gen = parent->i_generation;
342 spin_unlock(&dentry->d_lock);
343 len = 4; 337 len = 4;
344 type = FILEID_INO32_GEN_PARENT; 338 type = FILEID_INO32_GEN_PARENT;
345 } 339 }
@@ -352,11 +346,22 @@ int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len,
352{ 346{
353 const struct export_operations *nop = dentry->d_sb->s_export_op; 347 const struct export_operations *nop = dentry->d_sb->s_export_op;
354 int error; 348 int error;
349 struct dentry *p = NULL;
350 struct inode *inode = dentry->d_inode, *parent = NULL;
355 351
352 if (connectable && !S_ISDIR(inode->i_mode)) {
353 p = dget_parent(dentry);
354 /*
355 * note that while p might've ceased to be our parent already,
356 * it's still pinned by and still positive.
357 */
358 parent = p->d_inode;
359 }
356 if (nop->encode_fh) 360 if (nop->encode_fh)
357 error = nop->encode_fh(dentry, fid->raw, max_len, connectable); 361 error = nop->encode_fh(inode, fid->raw, max_len, parent);
358 else 362 else
359 error = export_encode_fh(dentry, fid, max_len, connectable); 363 error = export_encode_fh(inode, fid, max_len, parent);
364 dput(p);
360 365
361 return error; 366 return error;
362} 367}
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index b3d290c1b513..7edfaadc0787 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -752,10 +752,9 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb,
752} 752}
753 753
754static int 754static int
755fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable) 755fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent)
756{ 756{
757 int len = *lenp; 757 int len = *lenp;
758 struct inode *inode = de->d_inode;
759 u32 ipos_h, ipos_m, ipos_l; 758 u32 ipos_h, ipos_m, ipos_l;
760 759
761 if (len < 5) { 760 if (len < 5) {
@@ -771,9 +770,9 @@ fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
771 fh[1] = inode->i_generation; 770 fh[1] = inode->i_generation;
772 fh[2] = ipos_h; 771 fh[2] = ipos_h;
773 fh[3] = ipos_m | MSDOS_I(inode)->i_logstart; 772 fh[3] = ipos_m | MSDOS_I(inode)->i_logstart;
774 spin_lock(&de->d_lock); 773 fh[4] = ipos_l;
775 fh[4] = ipos_l | MSDOS_I(de->d_parent->d_inode)->i_logstart; 774 if (parent)
776 spin_unlock(&de->d_lock); 775 fh[4] |= MSDOS_I(parent)->i_logstart;
777 return 3; 776 return 3;
778} 777}
779 778
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 56f6dcf30768..42678a33b7bb 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -627,12 +627,10 @@ static struct dentry *fuse_get_dentry(struct super_block *sb,
627 return ERR_PTR(err); 627 return ERR_PTR(err);
628} 628}
629 629
630static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, 630static int fuse_encode_fh(struct inode *inode, u32 *fh, int *max_len,
631 int connectable) 631 struct inode *parent)
632{ 632{
633 struct inode *inode = dentry->d_inode; 633 int len = parent ? 6 : 3;
634 bool encode_parent = connectable && !S_ISDIR(inode->i_mode);
635 int len = encode_parent ? 6 : 3;
636 u64 nodeid; 634 u64 nodeid;
637 u32 generation; 635 u32 generation;
638 636
@@ -648,14 +646,9 @@ static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len,
648 fh[1] = (u32)(nodeid & 0xffffffff); 646 fh[1] = (u32)(nodeid & 0xffffffff);
649 fh[2] = generation; 647 fh[2] = generation;
650 648
651 if (encode_parent) { 649 if (parent) {
652 struct inode *parent;
653
654 spin_lock(&dentry->d_lock);
655 parent = dentry->d_parent->d_inode;
656 nodeid = get_fuse_inode(parent)->nodeid; 650 nodeid = get_fuse_inode(parent)->nodeid;
657 generation = parent->i_generation; 651 generation = parent->i_generation;
658 spin_unlock(&dentry->d_lock);
659 652
660 fh[3] = (u32)(nodeid >> 32); 653 fh[3] = (u32)(nodeid >> 32);
661 fh[4] = (u32)(nodeid & 0xffffffff); 654 fh[4] = (u32)(nodeid & 0xffffffff);
@@ -663,7 +656,7 @@ static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len,
663 } 656 }
664 657
665 *max_len = len; 658 *max_len = len;
666 return encode_parent ? 0x82 : 0x81; 659 return parent ? 0x82 : 0x81;
667} 660}
668 661
669static struct dentry *fuse_fh_to_dentry(struct super_block *sb, 662static struct dentry *fuse_fh_to_dentry(struct super_block *sb,
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c
index 70ba891654f8..e8ed6d4a6181 100644
--- a/fs/gfs2/export.c
+++ b/fs/gfs2/export.c
@@ -28,15 +28,14 @@
28#define GFS2_LARGE_FH_SIZE 8 28#define GFS2_LARGE_FH_SIZE 8
29#define GFS2_OLD_FH_SIZE 10 29#define GFS2_OLD_FH_SIZE 10
30 30
31static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, 31static int gfs2_encode_fh(struct inode *inode, __u32 *p, int *len,
32 int connectable) 32 struct inode *parent)
33{ 33{
34 __be32 *fh = (__force __be32 *)p; 34 __be32 *fh = (__force __be32 *)p;
35 struct inode *inode = dentry->d_inode;
36 struct super_block *sb = inode->i_sb; 35 struct super_block *sb = inode->i_sb;
37 struct gfs2_inode *ip = GFS2_I(inode); 36 struct gfs2_inode *ip = GFS2_I(inode);
38 37
39 if (connectable && (*len < GFS2_LARGE_FH_SIZE)) { 38 if (parent && (*len < GFS2_LARGE_FH_SIZE)) {
40 *len = GFS2_LARGE_FH_SIZE; 39 *len = GFS2_LARGE_FH_SIZE;
41 return 255; 40 return 255;
42 } else if (*len < GFS2_SMALL_FH_SIZE) { 41 } else if (*len < GFS2_SMALL_FH_SIZE) {
@@ -50,14 +49,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
50 fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); 49 fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF);
51 *len = GFS2_SMALL_FH_SIZE; 50 *len = GFS2_SMALL_FH_SIZE;
52 51
53 if (!connectable || inode == sb->s_root->d_inode) 52 if (!parent || inode == sb->s_root->d_inode)
54 return *len; 53 return *len;
55 54
56 spin_lock(&dentry->d_lock); 55 ip = GFS2_I(parent);
57 inode = dentry->d_parent->d_inode;
58 ip = GFS2_I(inode);
59 igrab(inode);
60 spin_unlock(&dentry->d_lock);
61 56
62 fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32); 57 fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32);
63 fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); 58 fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF);
@@ -65,8 +60,6 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
65 fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); 60 fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF);
66 *len = GFS2_LARGE_FH_SIZE; 61 *len = GFS2_LARGE_FH_SIZE;
67 62
68 iput(inode);
69
70 return *len; 63 return *len;
71} 64}
72 65
diff --git a/fs/isofs/export.c b/fs/isofs/export.c
index dd4687ff30d0..aa4356d09eee 100644
--- a/fs/isofs/export.c
+++ b/fs/isofs/export.c
@@ -107,12 +107,11 @@ static struct dentry *isofs_export_get_parent(struct dentry *child)
107} 107}
108 108
109static int 109static int
110isofs_export_encode_fh(struct dentry *dentry, 110isofs_export_encode_fh(struct inode *inode,
111 __u32 *fh32, 111 __u32 *fh32,
112 int *max_len, 112 int *max_len,
113 int connectable) 113 struct inode *parent)
114{ 114{
115 struct inode * inode = dentry->d_inode;
116 struct iso_inode_info * ei = ISOFS_I(inode); 115 struct iso_inode_info * ei = ISOFS_I(inode);
117 int len = *max_len; 116 int len = *max_len;
118 int type = 1; 117 int type = 1;
@@ -124,7 +123,7 @@ isofs_export_encode_fh(struct dentry *dentry,
124 * offset of the inode and the upper 16 bits of fh32[1] to 123 * offset of the inode and the upper 16 bits of fh32[1] to
125 * hold the offset of the parent. 124 * hold the offset of the parent.
126 */ 125 */
127 if (connectable && (len < 5)) { 126 if (parent && (len < 5)) {
128 *max_len = 5; 127 *max_len = 5;
129 return 255; 128 return 255;
130 } else if (len < 3) { 129 } else if (len < 3) {
@@ -136,16 +135,12 @@ isofs_export_encode_fh(struct dentry *dentry,
136 fh32[0] = ei->i_iget5_block; 135 fh32[0] = ei->i_iget5_block;
137 fh16[2] = (__u16)ei->i_iget5_offset; /* fh16 [sic] */ 136 fh16[2] = (__u16)ei->i_iget5_offset; /* fh16 [sic] */
138 fh32[2] = inode->i_generation; 137 fh32[2] = inode->i_generation;
139 if (connectable && !S_ISDIR(inode->i_mode)) { 138 if (parent) {
140 struct inode *parent;
141 struct iso_inode_info *eparent; 139 struct iso_inode_info *eparent;
142 spin_lock(&dentry->d_lock);
143 parent = dentry->d_parent->d_inode;
144 eparent = ISOFS_I(parent); 140 eparent = ISOFS_I(parent);
145 fh32[3] = eparent->i_iget5_block; 141 fh32[3] = eparent->i_iget5_block;
146 fh16[3] = (__u16)eparent->i_iget5_offset; /* fh16 [sic] */ 142 fh16[3] = (__u16)eparent->i_iget5_offset; /* fh16 [sic] */
147 fh32[4] = parent->i_generation; 143 fh32[4] = parent->i_generation;
148 spin_unlock(&dentry->d_lock);
149 len = 5; 144 len = 5;
150 type = 2; 145 type = 2;
151 } 146 }
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 0bb2c2010b95..b72847988b78 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -508,31 +508,29 @@ static struct dentry *nilfs_fh_to_parent(struct super_block *sb, struct fid *fh,
508 return nilfs_get_dentry(sb, fid->cno, fid->parent_ino, fid->parent_gen); 508 return nilfs_get_dentry(sb, fid->cno, fid->parent_ino, fid->parent_gen);
509} 509}
510 510
511static int nilfs_encode_fh(struct dentry *dentry, __u32 *fh, int *lenp, 511static int nilfs_encode_fh(struct inode *inode, __u32 *fh, int *lenp,
512 int connectable) 512 struct inode *parent)
513{ 513{
514 struct nilfs_fid *fid = (struct nilfs_fid *)fh; 514 struct nilfs_fid *fid = (struct nilfs_fid *)fh;
515 struct inode *inode = dentry->d_inode;
516 struct nilfs_root *root = NILFS_I(inode)->i_root; 515 struct nilfs_root *root = NILFS_I(inode)->i_root;
517 int type; 516 int type;
518 517
519 if (*lenp < NILFS_FID_SIZE_NON_CONNECTABLE || 518 if (parent && *lenp < NILFS_FID_SIZE_CONNECTABLE) {
520 (connectable && *lenp < NILFS_FID_SIZE_CONNECTABLE)) 519 *lenp = NILFS_FID_SIZE_CONNECTABLE;
520 return 255;
521 }
522 if (*lenp < NILFS_FID_SIZE_NON_CONNECTABLE) {
523 *lenp = NILFS_FID_SIZE_NON_CONNECTABLE;
521 return 255; 524 return 255;
525 }
522 526
523 fid->cno = root->cno; 527 fid->cno = root->cno;
524 fid->ino = inode->i_ino; 528 fid->ino = inode->i_ino;
525 fid->gen = inode->i_generation; 529 fid->gen = inode->i_generation;
526 530
527 if (connectable && !S_ISDIR(inode->i_mode)) { 531 if (parent) {
528 struct inode *parent;
529
530 spin_lock(&dentry->d_lock);
531 parent = dentry->d_parent->d_inode;
532 fid->parent_ino = parent->i_ino; 532 fid->parent_ino = parent->i_ino;
533 fid->parent_gen = parent->i_generation; 533 fid->parent_gen = parent->i_generation;
534 spin_unlock(&dentry->d_lock);
535
536 type = FILEID_NILFS_WITH_PARENT; 534 type = FILEID_NILFS_WITH_PARENT;
537 *lenp = NILFS_FID_SIZE_CONNECTABLE; 535 *lenp = NILFS_FID_SIZE_CONNECTABLE;
538 } else { 536 } else {
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index 745db42528d5..322216a5f0dd 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -177,21 +177,23 @@ bail:
177 return parent; 177 return parent;
178} 178}
179 179
180static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, 180static int ocfs2_encode_fh(struct inode *inode, u32 *fh_in, int *max_len,
181 int connectable) 181 struct inode *parent)
182{ 182{
183 struct inode *inode = dentry->d_inode;
184 int len = *max_len; 183 int len = *max_len;
185 int type = 1; 184 int type = 1;
186 u64 blkno; 185 u64 blkno;
187 u32 generation; 186 u32 generation;
188 __le32 *fh = (__force __le32 *) fh_in; 187 __le32 *fh = (__force __le32 *) fh_in;
189 188
189#ifdef TRACE_HOOKS_ARE_NOT_BRAINDEAD_IN_YOUR_OPINION
190#error "You go ahead and fix that mess, then. Somehow"
190 trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len, 191 trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len,
191 dentry->d_name.name, 192 dentry->d_name.name,
192 fh, len, connectable); 193 fh, len, connectable);
194#endif
193 195
194 if (connectable && (len < 6)) { 196 if (parent && (len < 6)) {
195 *max_len = 6; 197 *max_len = 6;
196 type = 255; 198 type = 255;
197 goto bail; 199 goto bail;
@@ -211,12 +213,7 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len,
211 fh[1] = cpu_to_le32((u32)(blkno & 0xffffffff)); 213 fh[1] = cpu_to_le32((u32)(blkno & 0xffffffff));
212 fh[2] = cpu_to_le32(generation); 214 fh[2] = cpu_to_le32(generation);
213 215
214 if (connectable && !S_ISDIR(inode->i_mode)) { 216 if (parent) {
215 struct inode *parent;
216
217 spin_lock(&dentry->d_lock);
218
219 parent = dentry->d_parent->d_inode;
220 blkno = OCFS2_I(parent)->ip_blkno; 217 blkno = OCFS2_I(parent)->ip_blkno;
221 generation = parent->i_generation; 218 generation = parent->i_generation;
222 219
@@ -224,8 +221,6 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len,
224 fh[4] = cpu_to_le32((u32)(blkno & 0xffffffff)); 221 fh[4] = cpu_to_le32((u32)(blkno & 0xffffffff));
225 fh[5] = cpu_to_le32(generation); 222 fh[5] = cpu_to_le32(generation);
226 223
227 spin_unlock(&dentry->d_lock);
228
229 len = 6; 224 len = 6;
230 type = 2; 225 type = 2;
231 226
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 59d06871a850..a6d4268fb6c1 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1592,13 +1592,12 @@ struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
1592 (fh_type == 6) ? fid->raw[5] : 0); 1592 (fh_type == 6) ? fid->raw[5] : 0);
1593} 1593}
1594 1594
1595int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, 1595int reiserfs_encode_fh(struct inode *inode, __u32 * data, int *lenp,
1596 int need_parent) 1596 struct inode *parent)
1597{ 1597{
1598 struct inode *inode = dentry->d_inode;
1599 int maxlen = *lenp; 1598 int maxlen = *lenp;
1600 1599
1601 if (need_parent && (maxlen < 5)) { 1600 if (parent && (maxlen < 5)) {
1602 *lenp = 5; 1601 *lenp = 5;
1603 return 255; 1602 return 255;
1604 } else if (maxlen < 3) { 1603 } else if (maxlen < 3) {
@@ -1610,20 +1609,15 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
1610 data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); 1609 data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id);
1611 data[2] = inode->i_generation; 1610 data[2] = inode->i_generation;
1612 *lenp = 3; 1611 *lenp = 3;
1613 /* no room for directory info? return what we've stored so far */ 1612 if (parent) {
1614 if (maxlen < 5 || !need_parent) 1613 data[3] = parent->i_ino;
1615 return 3; 1614 data[4] = le32_to_cpu(INODE_PKEY(parent)->k_dir_id);
1616 1615 *lenp = 5;
1617 spin_lock(&dentry->d_lock); 1616 if (maxlen >= 6) {
1618 inode = dentry->d_parent->d_inode; 1617 data[5] = parent->i_generation;
1619 data[3] = inode->i_ino; 1618 *lenp = 6;
1620 data[4] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); 1619 }
1621 *lenp = 5; 1620 }
1622 if (maxlen >= 6) {
1623 data[5] = inode->i_generation;
1624 *lenp = 6;
1625 }
1626 spin_unlock(&dentry->d_lock);
1627 return *lenp; 1621 return *lenp;
1628} 1622}
1629 1623
diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h
index a59d27126338..14a4f9dfb171 100644
--- a/fs/reiserfs/reiserfs.h
+++ b/fs/reiserfs/reiserfs.h
@@ -2611,8 +2611,8 @@ struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
2611 int fh_len, int fh_type); 2611 int fh_len, int fh_type);
2612struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid, 2612struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
2613 int fh_len, int fh_type); 2613 int fh_len, int fh_type);
2614int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, 2614int reiserfs_encode_fh(struct inode *inode, __u32 * data, int *lenp,
2615 int connectable); 2615 struct inode *parent);
2616 2616
2617int reiserfs_truncate_file(struct inode *, int update_timestamps); 2617int reiserfs_truncate_file(struct inode *, int update_timestamps);
2618void make_cpu_key(struct cpu_key *cpu_key, struct inode *inode, loff_t offset, 2618void make_cpu_key(struct cpu_key *cpu_key, struct inode *inode, loff_t offset,
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index a165c66e3eef..18024178ac4c 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -1260,16 +1260,15 @@ static struct dentry *udf_fh_to_parent(struct super_block *sb,
1260 fid->udf.parent_partref, 1260 fid->udf.parent_partref,
1261 fid->udf.parent_generation); 1261 fid->udf.parent_generation);
1262} 1262}
1263static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp, 1263static int udf_encode_fh(struct inode *inode, __u32 *fh, int *lenp,
1264 int connectable) 1264 struct inode *parent)
1265{ 1265{
1266 int len = *lenp; 1266 int len = *lenp;
1267 struct inode *inode = de->d_inode;
1268 struct kernel_lb_addr location = UDF_I(inode)->i_location; 1267 struct kernel_lb_addr location = UDF_I(inode)->i_location;
1269 struct fid *fid = (struct fid *)fh; 1268 struct fid *fid = (struct fid *)fh;
1270 int type = FILEID_UDF_WITHOUT_PARENT; 1269 int type = FILEID_UDF_WITHOUT_PARENT;
1271 1270
1272 if (connectable && (len < 5)) { 1271 if (parent && (len < 5)) {
1273 *lenp = 5; 1272 *lenp = 5;
1274 return 255; 1273 return 255;
1275 } else if (len < 3) { 1274 } else if (len < 3) {
@@ -1282,14 +1281,11 @@ static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp,
1282 fid->udf.partref = location.partitionReferenceNum; 1281 fid->udf.partref = location.partitionReferenceNum;
1283 fid->udf.generation = inode->i_generation; 1282 fid->udf.generation = inode->i_generation;
1284 1283
1285 if (connectable && !S_ISDIR(inode->i_mode)) { 1284 if (parent) {
1286 spin_lock(&de->d_lock); 1285 location = UDF_I(parent)->i_location;
1287 inode = de->d_parent->d_inode;
1288 location = UDF_I(inode)->i_location;
1289 fid->udf.parent_block = location.logicalBlockNum; 1286 fid->udf.parent_block = location.logicalBlockNum;
1290 fid->udf.parent_partref = location.partitionReferenceNum; 1287 fid->udf.parent_partref = location.partitionReferenceNum;
1291 fid->udf.parent_generation = inode->i_generation; 1288 fid->udf.parent_generation = inode->i_generation;
1292 spin_unlock(&de->d_lock);
1293 *lenp = 5; 1289 *lenp = 5;
1294 type = FILEID_UDF_WITH_PARENT; 1290 type = FILEID_UDF_WITH_PARENT;
1295 } 1291 }
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
index 2d25d19c4ea1..42679223a0fd 100644
--- a/fs/xfs/xfs_export.c
+++ b/fs/xfs/xfs_export.c
@@ -52,19 +52,18 @@ static int xfs_fileid_length(int fileid_type)
52 52
53STATIC int 53STATIC int
54xfs_fs_encode_fh( 54xfs_fs_encode_fh(
55 struct dentry *dentry, 55 struct inode *inode,
56 __u32 *fh, 56 __u32 *fh,
57 int *max_len, 57 int *max_len,
58 int connectable) 58 struct inode *parent)
59{ 59{
60 struct fid *fid = (struct fid *)fh; 60 struct fid *fid = (struct fid *)fh;
61 struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fh; 61 struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fh;
62 struct inode *inode = dentry->d_inode;
63 int fileid_type; 62 int fileid_type;
64 int len; 63 int len;
65 64
66 /* Directories don't need their parent encoded, they have ".." */ 65 /* Directories don't need their parent encoded, they have ".." */
67 if (S_ISDIR(inode->i_mode) || !connectable) 66 if (!parent)
68 fileid_type = FILEID_INO32_GEN; 67 fileid_type = FILEID_INO32_GEN;
69 else 68 else
70 fileid_type = FILEID_INO32_GEN_PARENT; 69 fileid_type = FILEID_INO32_GEN_PARENT;
@@ -96,20 +95,16 @@ xfs_fs_encode_fh(
96 95
97 switch (fileid_type) { 96 switch (fileid_type) {
98 case FILEID_INO32_GEN_PARENT: 97 case FILEID_INO32_GEN_PARENT:
99 spin_lock(&dentry->d_lock); 98 fid->i32.parent_ino = XFS_I(parent)->i_ino;
100 fid->i32.parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; 99 fid->i32.parent_gen = parent->i_generation;
101 fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation;
102 spin_unlock(&dentry->d_lock);
103 /*FALLTHRU*/ 100 /*FALLTHRU*/
104 case FILEID_INO32_GEN: 101 case FILEID_INO32_GEN:
105 fid->i32.ino = XFS_I(inode)->i_ino; 102 fid->i32.ino = XFS_I(inode)->i_ino;
106 fid->i32.gen = inode->i_generation; 103 fid->i32.gen = inode->i_generation;
107 break; 104 break;
108 case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG: 105 case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
109 spin_lock(&dentry->d_lock); 106 fid64->parent_ino = XFS_I(parent)->i_ino;
110 fid64->parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; 107 fid64->parent_gen = parent->i_generation;
111 fid64->parent_gen = dentry->d_parent->d_inode->i_generation;
112 spin_unlock(&dentry->d_lock);
113 /*FALLTHRU*/ 108 /*FALLTHRU*/
114 case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG: 109 case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
115 fid64->ino = XFS_I(inode)->i_ino; 110 fid64->ino = XFS_I(inode)->i_ino;