diff options
author | Jeff Layton <jlayton@kernel.org> | 2019-04-29 11:51:02 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2019-05-07 13:22:37 -0400 |
commit | 964fff7491e4923e18ff08f2a254c4b94e3f83d6 (patch) | |
tree | d9a103227b8586c155dd44ac8b566c151d8b6f19 /fs/ceph | |
parent | 69a10fb3f4b8769ffd44e4eaa662ab691fa61f4c (diff) |
ceph: use ceph_mdsc_build_path instead of clone_dentry_name
While it may be slightly more efficient, it's probably not worthwhile to
optimize for the case that clone_dentry_name handles. We can get the
same result by just calling ceph_mdsc_build_path when the parent isn't
locked, with less code duplication.
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/mds_client.c | 42 |
1 files changed, 3 insertions, 39 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index b01e2043b1b2..7af722834348 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -2172,56 +2172,20 @@ retry: | |||
2172 | return path; | 2172 | return path; |
2173 | } | 2173 | } |
2174 | 2174 | ||
2175 | /* Duplicate the dentry->d_name.name safely */ | ||
2176 | static int clone_dentry_name(struct dentry *dentry, const char **ppath, | ||
2177 | int *ppathlen) | ||
2178 | { | ||
2179 | u32 len; | ||
2180 | char *name; | ||
2181 | |||
2182 | retry: | ||
2183 | len = READ_ONCE(dentry->d_name.len); | ||
2184 | name = kmalloc(len + 1, GFP_NOFS); | ||
2185 | if (!name) | ||
2186 | return -ENOMEM; | ||
2187 | |||
2188 | spin_lock(&dentry->d_lock); | ||
2189 | if (dentry->d_name.len != len) { | ||
2190 | spin_unlock(&dentry->d_lock); | ||
2191 | kfree(name); | ||
2192 | goto retry; | ||
2193 | } | ||
2194 | memcpy(name, dentry->d_name.name, len); | ||
2195 | spin_unlock(&dentry->d_lock); | ||
2196 | |||
2197 | name[len] = '\0'; | ||
2198 | *ppath = name; | ||
2199 | *ppathlen = len; | ||
2200 | return 0; | ||
2201 | } | ||
2202 | |||
2203 | static int build_dentry_path(struct dentry *dentry, struct inode *dir, | 2175 | static int build_dentry_path(struct dentry *dentry, struct inode *dir, |
2204 | const char **ppath, int *ppathlen, u64 *pino, | 2176 | const char **ppath, int *ppathlen, u64 *pino, |
2205 | bool *pfreepath, bool parent_locked) | 2177 | bool *pfreepath, bool parent_locked) |
2206 | { | 2178 | { |
2207 | int ret; | ||
2208 | char *path; | 2179 | char *path; |
2209 | 2180 | ||
2210 | rcu_read_lock(); | 2181 | rcu_read_lock(); |
2211 | if (!dir) | 2182 | if (!dir) |
2212 | dir = d_inode_rcu(dentry->d_parent); | 2183 | dir = d_inode_rcu(dentry->d_parent); |
2213 | if (dir && ceph_snap(dir) == CEPH_NOSNAP) { | 2184 | if (dir && parent_locked && ceph_snap(dir) == CEPH_NOSNAP) { |
2214 | *pino = ceph_ino(dir); | 2185 | *pino = ceph_ino(dir); |
2215 | rcu_read_unlock(); | 2186 | rcu_read_unlock(); |
2216 | if (parent_locked) { | 2187 | *ppath = dentry->d_name.name; |
2217 | *ppath = dentry->d_name.name; | 2188 | *ppathlen = dentry->d_name.len; |
2218 | *ppathlen = dentry->d_name.len; | ||
2219 | } else { | ||
2220 | ret = clone_dentry_name(dentry, ppath, ppathlen); | ||
2221 | if (ret) | ||
2222 | return ret; | ||
2223 | *pfreepath = true; | ||
2224 | } | ||
2225 | return 0; | 2189 | return 0; |
2226 | } | 2190 | } |
2227 | rcu_read_unlock(); | 2191 | rcu_read_unlock(); |