Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Al Viro b0b0382b 6d42e7e9

+93 -139
+4 -11
fs/btrfs/export.c
··· 13 13 parent_root_objectid) / 4) 14 14 #define BTRFS_FID_SIZE_CONNECTABLE_ROOT (sizeof(struct btrfs_fid) / 4) 15 15 16 - static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, 17 - int connectable) 16 + static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len, 17 + struct inode *parent) 18 18 { 19 19 struct btrfs_fid *fid = (struct btrfs_fid *)fh; 20 - struct inode *inode = dentry->d_inode; 21 20 int len = *max_len; 22 21 int type; 23 22 24 - if (connectable && (len < BTRFS_FID_SIZE_CONNECTABLE)) { 23 + if (parent && (len < BTRFS_FID_SIZE_CONNECTABLE)) { 25 24 *max_len = BTRFS_FID_SIZE_CONNECTABLE; 26 25 return 255; 27 26 } else if (len < BTRFS_FID_SIZE_NON_CONNECTABLE) { ··· 35 36 fid->root_objectid = BTRFS_I(inode)->root->objectid; 36 37 fid->gen = inode->i_generation; 37 38 38 - if (connectable && !S_ISDIR(inode->i_mode)) { 39 - struct inode *parent; 39 + if (parent) { 40 40 u64 parent_root_id; 41 41 42 - spin_lock(&dentry->d_lock); 43 - 44 - parent = dentry->d_parent->d_inode; 45 42 fid->parent_objectid = BTRFS_I(parent)->location.objectid; 46 43 fid->parent_gen = parent->i_generation; 47 44 parent_root_id = BTRFS_I(parent)->root->objectid; 48 - 49 - spin_unlock(&dentry->d_lock); 50 45 51 46 if (parent_root_id != fid->root_objectid) { 52 47 fid->parent_root_objectid = parent_root_id;
+2
fs/ceph/export.c
··· 247 247 } 248 248 249 249 const struct export_operations ceph_export_ops = { 250 + #ifdef CEPH_BREAKAGE_FIXED 250 251 .encode_fh = ceph_encode_fh, 252 + #endif 251 253 .fh_to_dentry = ceph_fh_to_dentry, 252 254 .fh_to_parent = ceph_fh_to_parent, 253 255 };
+19 -14
fs/exportfs/expfs.c
··· 304 304 305 305 /** 306 306 * export_encode_fh - default export_operations->encode_fh function 307 - * @dentry: the dentry to encode 307 + * @inode: the object to encode 308 308 * @fh: where to store the file handle fragment 309 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 312 * This default encode_fh function assumes that the 32 inode number 313 313 * is suitable for locating an inode, and that the generation number 314 314 * can be used to check that it is still valid. It places them in the 315 315 * filehandle fragment where export_decode_fh expects to find them. 316 316 */ 317 - static int export_encode_fh(struct dentry *dentry, struct fid *fid, 318 - int *max_len, int connectable) 317 + static int export_encode_fh(struct inode *inode, struct fid *fid, 318 + int *max_len, struct inode *parent) 319 319 { 320 - struct inode * inode = dentry->d_inode; 321 320 int len = *max_len; 322 321 int type = FILEID_INO32_GEN; 323 322 324 - if (connectable && (len < 4)) { 323 + if (parent && (len < 4)) { 325 324 *max_len = 4; 326 325 return 255; 327 326 } else if (len < 2) { ··· 331 332 len = 2; 332 333 fid->i32.ino = inode->i_ino; 333 334 fid->i32.gen = inode->i_generation; 334 - if (connectable && !S_ISDIR(inode->i_mode)) { 335 - struct inode *parent; 336 - 337 - spin_lock(&dentry->d_lock); 338 - parent = dentry->d_parent->d_inode; 335 + if (parent) { 339 336 fid->i32.parent_ino = parent->i_ino; 340 337 fid->i32.parent_gen = parent->i_generation; 341 - spin_unlock(&dentry->d_lock); 342 338 len = 4; 343 339 type = FILEID_INO32_GEN_PARENT; 344 340 } ··· 346 352 { 347 353 const struct export_operations *nop = dentry->d_sb->s_export_op; 348 354 int error; 355 + struct dentry *p = NULL; 356 + struct inode *inode = dentry->d_inode, *parent = NULL; 349 357 358 + if (connectable && !S_ISDIR(inode->i_mode)) { 359 + p = dget_parent(dentry); 360 + /* 361 + * note that while p might've ceased to be our parent already, 362 + * it's still pinned by and still positive. 363 + */ 364 + parent = p->d_inode; 365 + } 350 366 if (nop->encode_fh) 351 - error = nop->encode_fh(dentry, fid->raw, max_len, connectable); 367 + error = nop->encode_fh(inode, fid->raw, max_len, parent); 352 368 else 353 - error = export_encode_fh(dentry, fid, max_len, connectable); 369 + error = export_encode_fh(inode, fid, max_len, parent); 370 + dput(p); 354 371 355 372 return error; 356 373 }
+4 -5
fs/fat/inode.c
··· 752 752 } 753 753 754 754 static int 755 - fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable) 755 + fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent) 756 756 { 757 757 int len = *lenp; 758 - struct inode *inode = de->d_inode; 759 758 u32 ipos_h, ipos_m, ipos_l; 760 759 761 760 if (len < 5) { ··· 770 771 fh[1] = inode->i_generation; 771 772 fh[2] = ipos_h; 772 773 fh[3] = ipos_m | MSDOS_I(inode)->i_logstart; 773 - spin_lock(&de->d_lock); 774 - fh[4] = ipos_l | MSDOS_I(de->d_parent->d_inode)->i_logstart; 775 - spin_unlock(&de->d_lock); 774 + fh[4] = ipos_l; 775 + if (parent) 776 + fh[4] |= MSDOS_I(parent)->i_logstart; 776 777 return 3; 777 778 } 778 779
+5 -12
fs/fuse/inode.c
··· 627 627 return ERR_PTR(err); 628 628 } 629 629 630 - static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, 631 - int connectable) 630 + static int fuse_encode_fh(struct inode *inode, u32 *fh, int *max_len, 631 + struct inode *parent) 632 632 { 633 - struct inode *inode = dentry->d_inode; 634 - bool encode_parent = connectable && !S_ISDIR(inode->i_mode); 635 - int len = encode_parent ? 6 : 3; 633 + int len = parent ? 6 : 3; 636 634 u64 nodeid; 637 635 u32 generation; 638 636 ··· 646 648 fh[1] = (u32)(nodeid & 0xffffffff); 647 649 fh[2] = generation; 648 650 649 - if (encode_parent) { 650 - struct inode *parent; 651 - 652 - spin_lock(&dentry->d_lock); 653 - parent = dentry->d_parent->d_inode; 651 + if (parent) { 654 652 nodeid = get_fuse_inode(parent)->nodeid; 655 653 generation = parent->i_generation; 656 - spin_unlock(&dentry->d_lock); 657 654 658 655 fh[3] = (u32)(nodeid >> 32); 659 656 fh[4] = (u32)(nodeid & 0xffffffff); ··· 656 663 } 657 664 658 665 *max_len = len; 659 - return encode_parent ? 0x82 : 0x81; 666 + return parent ? 0x82 : 0x81; 660 667 } 661 668 662 669 static struct dentry *fuse_fh_to_dentry(struct super_block *sb,
+5 -12
fs/gfs2/export.c
··· 28 28 #define GFS2_LARGE_FH_SIZE 8 29 29 #define GFS2_OLD_FH_SIZE 10 30 30 31 - static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, 32 - int connectable) 31 + static int gfs2_encode_fh(struct inode *inode, __u32 *p, int *len, 32 + struct inode *parent) 33 33 { 34 34 __be32 *fh = (__force __be32 *)p; 35 - struct inode *inode = dentry->d_inode; 36 35 struct super_block *sb = inode->i_sb; 37 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 39 *len = GFS2_LARGE_FH_SIZE; 41 40 return 255; 42 41 } else if (*len < GFS2_SMALL_FH_SIZE) { ··· 49 50 fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); 50 51 *len = GFS2_SMALL_FH_SIZE; 51 52 52 - if (!connectable || inode == sb->s_root->d_inode) 53 + if (!parent || inode == sb->s_root->d_inode) 53 54 return *len; 54 55 55 - spin_lock(&dentry->d_lock); 56 - inode = dentry->d_parent->d_inode; 57 - ip = GFS2_I(inode); 58 - igrab(inode); 59 - spin_unlock(&dentry->d_lock); 56 + ip = GFS2_I(parent); 60 57 61 58 fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32); 62 59 fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); 63 60 fh[6] = cpu_to_be32(ip->i_no_addr >> 32); 64 61 fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); 65 62 *len = GFS2_LARGE_FH_SIZE; 66 - 67 - iput(inode); 68 63 69 64 return *len; 70 65 }
+4 -9
fs/isofs/export.c
··· 107 107 } 108 108 109 109 static int 110 - isofs_export_encode_fh(struct dentry *dentry, 110 + isofs_export_encode_fh(struct inode *inode, 111 111 __u32 *fh32, 112 112 int *max_len, 113 - int connectable) 113 + struct inode *parent) 114 114 { 115 - struct inode * inode = dentry->d_inode; 116 115 struct iso_inode_info * ei = ISOFS_I(inode); 117 116 int len = *max_len; 118 117 int type = 1; ··· 123 124 * offset of the inode and the upper 16 bits of fh32[1] to 124 125 * hold the offset of the parent. 125 126 */ 126 - if (connectable && (len < 5)) { 127 + if (parent && (len < 5)) { 127 128 *max_len = 5; 128 129 return 255; 129 130 } else if (len < 3) { ··· 135 136 fh32[0] = ei->i_iget5_block; 136 137 fh16[2] = (__u16)ei->i_iget5_offset; /* fh16 [sic] */ 137 138 fh32[2] = inode->i_generation; 138 - if (connectable && !S_ISDIR(inode->i_mode)) { 139 - struct inode *parent; 139 + if (parent) { 140 140 struct iso_inode_info *eparent; 141 - spin_lock(&dentry->d_lock); 142 - parent = dentry->d_parent->d_inode; 143 141 eparent = ISOFS_I(parent); 144 142 fh32[3] = eparent->i_iget5_block; 145 143 fh16[3] = (__u16)eparent->i_iget5_offset; /* fh16 [sic] */ 146 144 fh32[4] = parent->i_generation; 147 - spin_unlock(&dentry->d_lock); 148 145 len = 5; 149 146 type = 2; 150 147 }
+10 -12
fs/nilfs2/namei.c
··· 508 508 return nilfs_get_dentry(sb, fid->cno, fid->parent_ino, fid->parent_gen); 509 509 } 510 510 511 - static int nilfs_encode_fh(struct dentry *dentry, __u32 *fh, int *lenp, 512 - int connectable) 511 + static int nilfs_encode_fh(struct inode *inode, __u32 *fh, int *lenp, 512 + struct inode *parent) 513 513 { 514 514 struct nilfs_fid *fid = (struct nilfs_fid *)fh; 515 - struct inode *inode = dentry->d_inode; 516 515 struct nilfs_root *root = NILFS_I(inode)->i_root; 517 516 int type; 518 517 519 - if (*lenp < NILFS_FID_SIZE_NON_CONNECTABLE || 520 - (connectable && *lenp < NILFS_FID_SIZE_CONNECTABLE)) 518 + if (parent && *lenp < NILFS_FID_SIZE_CONNECTABLE) { 519 + *lenp = NILFS_FID_SIZE_CONNECTABLE; 521 520 return 255; 521 + } 522 + if (*lenp < NILFS_FID_SIZE_NON_CONNECTABLE) { 523 + *lenp = NILFS_FID_SIZE_NON_CONNECTABLE; 524 + return 255; 525 + } 522 526 523 527 fid->cno = root->cno; 524 528 fid->ino = inode->i_ino; 525 529 fid->gen = inode->i_generation; 526 530 527 - if (connectable && !S_ISDIR(inode->i_mode)) { 528 - struct inode *parent; 529 - 530 - spin_lock(&dentry->d_lock); 531 - parent = dentry->d_parent->d_inode; 531 + if (parent) { 532 532 fid->parent_ino = parent->i_ino; 533 533 fid->parent_gen = parent->i_generation; 534 - spin_unlock(&dentry->d_lock); 535 - 536 534 type = FILEID_NILFS_WITH_PARENT; 537 535 *lenp = NILFS_FID_SIZE_CONNECTABLE; 538 536 } else {
+7 -12
fs/ocfs2/export.c
··· 177 177 return parent; 178 178 } 179 179 180 - static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, 181 - int connectable) 180 + static int ocfs2_encode_fh(struct inode *inode, u32 *fh_in, int *max_len, 181 + struct inode *parent) 182 182 { 183 - struct inode *inode = dentry->d_inode; 184 183 int len = *max_len; 185 184 int type = 1; 186 185 u64 blkno; 187 186 u32 generation; 188 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 191 trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len, 191 192 dentry->d_name.name, 192 193 fh, len, connectable); 194 + #endif 193 195 194 - if (connectable && (len < 6)) { 196 + if (parent && (len < 6)) { 195 197 *max_len = 6; 196 198 type = 255; 197 199 goto bail; ··· 213 211 fh[1] = cpu_to_le32((u32)(blkno & 0xffffffff)); 214 212 fh[2] = cpu_to_le32(generation); 215 213 216 - if (connectable && !S_ISDIR(inode->i_mode)) { 217 - struct inode *parent; 218 - 219 - spin_lock(&dentry->d_lock); 220 - 221 - parent = dentry->d_parent->d_inode; 214 + if (parent) { 222 215 blkno = OCFS2_I(parent)->ip_blkno; 223 216 generation = parent->i_generation; 224 217 225 218 fh[3] = cpu_to_le32((u32)(blkno >> 32)); 226 219 fh[4] = cpu_to_le32((u32)(blkno & 0xffffffff)); 227 220 fh[5] = cpu_to_le32(generation); 228 - 229 - spin_unlock(&dentry->d_lock); 230 221 231 222 len = 6; 232 223 type = 2;
+11 -17
fs/reiserfs/inode.c
··· 1592 1592 (fh_type == 6) ? fid->raw[5] : 0); 1593 1593 } 1594 1594 1595 - int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, 1596 - int need_parent) 1595 + int reiserfs_encode_fh(struct inode *inode, __u32 * data, int *lenp, 1596 + struct inode *parent) 1597 1597 { 1598 - struct inode *inode = dentry->d_inode; 1599 1598 int maxlen = *lenp; 1600 1599 1601 - if (need_parent && (maxlen < 5)) { 1600 + if (parent && (maxlen < 5)) { 1602 1601 *lenp = 5; 1603 1602 return 255; 1604 1603 } else if (maxlen < 3) { ··· 1609 1610 data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); 1610 1611 data[2] = inode->i_generation; 1611 1612 *lenp = 3; 1612 - /* no room for directory info? return what we've stored so far */ 1613 - if (maxlen < 5 || !need_parent) 1614 - return 3; 1615 - 1616 - spin_lock(&dentry->d_lock); 1617 - inode = dentry->d_parent->d_inode; 1618 - data[3] = inode->i_ino; 1619 - data[4] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); 1620 - *lenp = 5; 1621 - if (maxlen >= 6) { 1622 - data[5] = inode->i_generation; 1623 - *lenp = 6; 1613 + if (parent) { 1614 + data[3] = parent->i_ino; 1615 + data[4] = le32_to_cpu(INODE_PKEY(parent)->k_dir_id); 1616 + *lenp = 5; 1617 + if (maxlen >= 6) { 1618 + data[5] = parent->i_generation; 1619 + *lenp = 6; 1620 + } 1624 1621 } 1625 - spin_unlock(&dentry->d_lock); 1626 1622 return *lenp; 1627 1623 } 1628 1624
+2 -2
fs/reiserfs/reiserfs.h
··· 2611 2611 int fh_len, int fh_type); 2612 2612 struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid, 2613 2613 int fh_len, int fh_type); 2614 - int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, 2615 - int connectable); 2614 + int reiserfs_encode_fh(struct inode *inode, __u32 * data, int *lenp, 2615 + struct inode *parent); 2616 2616 2617 2617 int reiserfs_truncate_file(struct inode *, int update_timestamps); 2618 2618 void make_cpu_key(struct cpu_key *cpu_key, struct inode *inode, loff_t offset,
+5 -9
fs/udf/namei.c
··· 1260 1260 fid->udf.parent_partref, 1261 1261 fid->udf.parent_generation); 1262 1262 } 1263 - static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp, 1264 - int connectable) 1263 + static int udf_encode_fh(struct inode *inode, __u32 *fh, int *lenp, 1264 + struct inode *parent) 1265 1265 { 1266 1266 int len = *lenp; 1267 - struct inode *inode = de->d_inode; 1268 1267 struct kernel_lb_addr location = UDF_I(inode)->i_location; 1269 1268 struct fid *fid = (struct fid *)fh; 1270 1269 int type = FILEID_UDF_WITHOUT_PARENT; 1271 1270 1272 - if (connectable && (len < 5)) { 1271 + if (parent && (len < 5)) { 1273 1272 *lenp = 5; 1274 1273 return 255; 1275 1274 } else if (len < 3) { ··· 1281 1282 fid->udf.partref = location.partitionReferenceNum; 1282 1283 fid->udf.generation = inode->i_generation; 1283 1284 1284 - if (connectable && !S_ISDIR(inode->i_mode)) { 1285 - spin_lock(&de->d_lock); 1286 - inode = de->d_parent->d_inode; 1287 - location = UDF_I(inode)->i_location; 1285 + if (parent) { 1286 + location = UDF_I(parent)->i_location; 1288 1287 fid->udf.parent_block = location.logicalBlockNum; 1289 1288 fid->udf.parent_partref = location.partitionReferenceNum; 1290 1289 fid->udf.parent_generation = inode->i_generation; 1291 - spin_unlock(&de->d_lock); 1292 1290 *lenp = 5; 1293 1291 type = FILEID_UDF_WITH_PARENT; 1294 1292 }
+9 -14
fs/xfs/xfs_export.c
··· 52 52 53 53 STATIC int 54 54 xfs_fs_encode_fh( 55 - struct dentry *dentry, 56 - __u32 *fh, 57 - int *max_len, 58 - int connectable) 55 + struct inode *inode, 56 + __u32 *fh, 57 + int *max_len, 58 + struct inode *parent) 59 59 { 60 60 struct fid *fid = (struct fid *)fh; 61 61 struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fh; 62 - struct inode *inode = dentry->d_inode; 63 62 int fileid_type; 64 63 int len; 65 64 66 65 /* Directories don't need their parent encoded, they have ".." */ 67 - if (S_ISDIR(inode->i_mode) || !connectable) 66 + if (!parent) 68 67 fileid_type = FILEID_INO32_GEN; 69 68 else 70 69 fileid_type = FILEID_INO32_GEN_PARENT; ··· 95 96 96 97 switch (fileid_type) { 97 98 case FILEID_INO32_GEN_PARENT: 98 - spin_lock(&dentry->d_lock); 99 - fid->i32.parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; 100 - fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation; 101 - spin_unlock(&dentry->d_lock); 99 + fid->i32.parent_ino = XFS_I(parent)->i_ino; 100 + fid->i32.parent_gen = parent->i_generation; 102 101 /*FALLTHRU*/ 103 102 case FILEID_INO32_GEN: 104 103 fid->i32.ino = XFS_I(inode)->i_ino; 105 104 fid->i32.gen = inode->i_generation; 106 105 break; 107 106 case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG: 108 - spin_lock(&dentry->d_lock); 109 - fid64->parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; 110 - fid64->parent_gen = dentry->d_parent->d_inode->i_generation; 111 - spin_unlock(&dentry->d_lock); 107 + fid64->parent_ino = XFS_I(parent)->i_ino; 108 + fid64->parent_gen = parent->i_generation; 112 109 /*FALLTHRU*/ 113 110 case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG: 114 111 fid64->ino = XFS_I(inode)->i_ino;
+2 -2
include/linux/exportfs.h
··· 165 165 */ 166 166 167 167 struct export_operations { 168 - int (*encode_fh)(struct dentry *de, __u32 *fh, int *max_len, 169 - int connectable); 168 + int (*encode_fh)(struct inode *inode, __u32 *fh, int *max_len, 169 + struct inode *parent); 170 170 struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid, 171 171 int fh_len, int fh_type); 172 172 struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid,
+2 -4
mm/cleancache.c
··· 80 80 static int cleancache_get_key(struct inode *inode, 81 81 struct cleancache_filekey *key) 82 82 { 83 - int (*fhfn)(struct dentry *, __u32 *fh, int *, int); 83 + int (*fhfn)(struct inode *, __u32 *fh, int *, struct inode *); 84 84 int len = 0, maxlen = CLEANCACHE_KEY_MAX; 85 85 struct super_block *sb = inode->i_sb; 86 86 ··· 88 88 if (sb->s_export_op != NULL) { 89 89 fhfn = sb->s_export_op->encode_fh; 90 90 if (fhfn) { 91 - struct dentry d; 92 - d.d_inode = inode; 93 - len = (*fhfn)(&d, &key->u.fh[0], &maxlen, 0); 91 + len = (*fhfn)(inode, &key->u.fh[0], &maxlen, NULL); 94 92 if (len <= 0 || len == 255) 95 93 return -1; 96 94 if (maxlen > CLEANCACHE_KEY_MAX)
+2 -4
mm/shmem.c
··· 2033 2033 return dentry; 2034 2034 } 2035 2035 2036 - static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len, 2037 - int connectable) 2036 + static int shmem_encode_fh(struct inode *inode, __u32 *fh, int *len, 2037 + struct inode *parent) 2038 2038 { 2039 - struct inode *inode = dentry->d_inode; 2040 - 2041 2039 if (*len < 3) { 2042 2040 *len = 3; 2043 2041 return 255;