Commit c862868bb455694704c255481369c40d7185eb25
Committed by
Al Viro
1 parent
b0b0382bb4
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
ceph: move encode_fh to new API
Use parent_inode has a flag for whether nfsd wants a connectable fh, but generate one opportunistically so that we can take advantage of the additional info in there. Signed-off-by: Sage Weil <sage@newdream.net> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 1 changed file with 21 additions and 13 deletions Side-by-side Diff
fs/ceph/export.c
... | ... | @@ -40,38 +40,49 @@ |
40 | 40 | u32 parent_name_hash; |
41 | 41 | } __attribute__ ((packed)); |
42 | 42 | |
43 | -static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, | |
44 | - int connectable) | |
43 | +/* | |
44 | + * The presence of @parent_inode here tells us whether NFS wants a | |
45 | + * connectable file handle. However, we want to make a connectionable | |
46 | + * file handle unconditionally so that the MDS gets as much of a hint | |
47 | + * as possible. That means we only use @parent_dentry to indicate | |
48 | + * whether nfsd wants a connectable fh, and whether we should indicate | |
49 | + * failure from a too-small @max_len. | |
50 | + */ | |
51 | +static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len, | |
52 | + struct inode *parent_inode) | |
45 | 53 | { |
46 | 54 | int type; |
47 | 55 | struct ceph_nfs_fh *fh = (void *)rawfh; |
48 | 56 | struct ceph_nfs_confh *cfh = (void *)rawfh; |
49 | - struct dentry *parent; | |
50 | - struct inode *inode = dentry->d_inode; | |
51 | 57 | int connected_handle_length = sizeof(*cfh)/4; |
52 | 58 | int handle_length = sizeof(*fh)/4; |
59 | + struct dentry *dentry = d_find_alias(inode); | |
60 | + struct dentry *parent; | |
53 | 61 | |
54 | 62 | /* don't re-export snaps */ |
55 | 63 | if (ceph_snap(inode) != CEPH_NOSNAP) |
56 | 64 | return -EINVAL; |
57 | 65 | |
58 | - spin_lock(&dentry->d_lock); | |
59 | - parent = dentry->d_parent; | |
60 | - if (*max_len >= connected_handle_length) { | |
66 | + /* if we found an alias, generate a connectable fh */ | |
67 | + if (*max_len >= connected_handle_length && dentry) { | |
61 | 68 | dout("encode_fh %p connectable\n", dentry); |
62 | - cfh->ino = ceph_ino(dentry->d_inode); | |
69 | + spin_lock(&dentry->d_lock); | |
70 | + parent = dentry->d_parent; | |
71 | + cfh->ino = ceph_ino(inode); | |
63 | 72 | cfh->parent_ino = ceph_ino(parent->d_inode); |
64 | 73 | cfh->parent_name_hash = ceph_dentry_hash(parent->d_inode, |
65 | 74 | dentry); |
66 | 75 | *max_len = connected_handle_length; |
67 | 76 | type = 2; |
77 | + spin_unlock(&dentry->d_lock); | |
68 | 78 | } else if (*max_len >= handle_length) { |
69 | - if (connectable) { | |
79 | + if (parent_inode) { | |
80 | + /* nfsd wants connectable */ | |
70 | 81 | *max_len = connected_handle_length; |
71 | 82 | type = 255; |
72 | 83 | } else { |
73 | 84 | dout("encode_fh %p\n", dentry); |
74 | - fh->ino = ceph_ino(dentry->d_inode); | |
85 | + fh->ino = ceph_ino(inode); | |
75 | 86 | *max_len = handle_length; |
76 | 87 | type = 1; |
77 | 88 | } |
... | ... | @@ -79,7 +90,6 @@ |
79 | 90 | *max_len = handle_length; |
80 | 91 | type = 255; |
81 | 92 | } |
82 | - spin_unlock(&dentry->d_lock); | |
83 | 93 | return type; |
84 | 94 | } |
85 | 95 | |
86 | 96 | |
... | ... | @@ -247,9 +257,7 @@ |
247 | 257 | } |
248 | 258 | |
249 | 259 | const struct export_operations ceph_export_ops = { |
250 | -#ifdef CEPH_BREAKAGE_FIXED | |
251 | 260 | .encode_fh = ceph_encode_fh, |
252 | -#endif | |
253 | 261 | .fh_to_dentry = ceph_fh_to_dentry, |
254 | 262 | .fh_to_parent = ceph_fh_to_parent, |
255 | 263 | }; |