···304304305305/**306306 * export_encode_fh - default export_operations->encode_fh function307307- * @dentry: the dentry to encode307307+ * @inode: the object to encode308308 * @fh: where to store the file handle fragment309309 * @max_len: maximum length to store there310310- * @connectable: whether to store parent information310310+ * @parent: parent directory inode, if wanted311311 *312312 * This default encode_fh function assumes that the 32 inode number313313 * is suitable for locating an inode, and that the generation number314314 * can be used to check that it is still valid. It places them in the315315 * filehandle fragment where export_decode_fh expects to find them.316316 */317317-static int export_encode_fh(struct dentry *dentry, struct fid *fid,318318- int *max_len, int connectable)317317+static int export_encode_fh(struct inode *inode, struct fid *fid,318318+ int *max_len, struct inode *parent)319319{320320- struct inode * inode = dentry->d_inode;321320 int len = *max_len;322321 int type = FILEID_INO32_GEN;323322324324- if (connectable && (len < 4)) {323323+ if (parent && (len < 4)) {325324 *max_len = 4;326325 return 255;327326 } else if (len < 2) {···331332 len = 2;332333 fid->i32.ino = inode->i_ino;333334 fid->i32.gen = inode->i_generation;334334- if (connectable && !S_ISDIR(inode->i_mode)) {335335- struct inode *parent;336336-337337- spin_lock(&dentry->d_lock);338338- parent = dentry->d_parent->d_inode;335335+ if (parent) {339336 fid->i32.parent_ino = parent->i_ino;340337 fid->i32.parent_gen = parent->i_generation;341341- spin_unlock(&dentry->d_lock);342338 len = 4;343339 type = FILEID_INO32_GEN_PARENT;344340 }···346352{347353 const struct export_operations *nop = dentry->d_sb->s_export_op;348354 int error;355355+ struct dentry *p = NULL;356356+ struct inode *inode = dentry->d_inode, *parent = NULL;349357358358+ if (connectable && !S_ISDIR(inode->i_mode)) {359359+ p = dget_parent(dentry);360360+ /*361361+ * note that while p might've ceased to be our parent already,362362+ * it's still pinned by and still positive.363363+ */364364+ parent = p->d_inode;365365+ }350366 if (nop->encode_fh)351351- error = nop->encode_fh(dentry, fid->raw, max_len, connectable);367367+ error = nop->encode_fh(inode, fid->raw, max_len, parent);352368 else353353- error = export_encode_fh(dentry, fid, max_len, connectable);369369+ error = export_encode_fh(inode, fid, max_len, parent);370370+ dput(p);354371355372 return error;356373}
+4-5
fs/fat/inode.c
···752752}753753754754static int755755-fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)755755+fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent)756756{757757 int len = *lenp;758758- struct inode *inode = de->d_inode;759758 u32 ipos_h, ipos_m, ipos_l;760759761760 if (len < 5) {···770771 fh[1] = inode->i_generation;771772 fh[2] = ipos_h;772773 fh[3] = ipos_m | MSDOS_I(inode)->i_logstart;773773- spin_lock(&de->d_lock);774774- fh[4] = ipos_l | MSDOS_I(de->d_parent->d_inode)->i_logstart;775775- spin_unlock(&de->d_lock);774774+ fh[4] = ipos_l;775775+ if (parent)776776+ fh[4] |= MSDOS_I(parent)->i_logstart;776777 return 3;777778}778779