/* * The presence of @parent_inode here tells us whether NFS wants a * connectable file handle. However, we want to make a connectionable * file handle unconditionally so that the MDS gets as much of a hint * as possible. That means we only use @parent_dentry to indicate * whether nfsd wants a connectable fh, and whether we should indicate * failure from a too-small @max_len. */ static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len, struct inode *parent_inode) { int type; struct ceph_nfs_fh *fh = (void *)rawfh; struct ceph_nfs_confh *cfh = (void *)rawfh; int connected_handle_length = sizeof(*cfh)/4; int handle_length = sizeof(*fh)/4; struct dentry *dentry = d_find_alias(inode); struct dentry *parent; /* don't re-export snaps */ if (ceph_snap(inode) != CEPH_NOSNAP) return -EINVAL; /* if we found an alias, generate a connectable fh */ if (*max_len >= connected_handle_length && dentry) { dout("encode_fh %p connectable\n", dentry); spin_lock(&dentry->d_lock); parent = dentry->d_parent; cfh->ino = ceph_ino(inode); cfh->parent_ino = ceph_ino(parent->d_inode); cfh->parent_name_hash = ceph_dentry_hash(parent->d_inode, dentry); *max_len = connected_handle_length; type = 2; spin_unlock(&dentry->d_lock); } else if (*max_len >= handle_length) { if (parent_inode) { /* nfsd wants connectable */ *max_len = connected_handle_length; type = 255; } else { dout("encode_fh %p\n", dentry); fh->ino = ceph_ino(inode); *max_len = handle_length; type = 1; } } else { *max_len = handle_length; type = 255; } if (dentry) dput(dentry); return type; }
static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, int connectable) { int type; struct ceph_nfs_fh *fh = (void *)rawfh; struct ceph_nfs_confh *cfh = (void *)rawfh; struct dentry *parent; struct inode *inode = dentry->d_inode; int connected_handle_length = sizeof(*cfh)/4; int handle_length = sizeof(*fh)/4; /* don't re-export snaps */ if (ceph_snap(inode) != CEPH_NOSNAP) return -EINVAL; spin_lock(&dentry->d_lock); parent = dentry->d_parent; if (*max_len >= connected_handle_length) { dout("encode_fh %p connectable\n", dentry); cfh->ino = ceph_ino(dentry->d_inode); cfh->parent_ino = ceph_ino(parent->d_inode); cfh->parent_name_hash = ceph_dentry_hash(parent->d_inode, dentry); *max_len = connected_handle_length; type = 2; } else if (*max_len >= handle_length) { if (connectable) { *max_len = connected_handle_length; type = 255; } else { dout("encode_fh %p\n", dentry); fh->ino = ceph_ino(dentry->d_inode); *max_len = handle_length; type = 1; } } else { *max_len = handle_length; type = 255; } spin_unlock(&dentry->d_lock); return type; }