From 9bb2b5e75b34ec9ee6a7f198170d6e20c7b4746b Mon Sep 17 00:00:00 2001 From: Gui Hecheng Date: Thu, 29 Jun 2017 15:51:56 +0800 Subject: [PATCH] rgw_file: skip stat_leaf for ".." after readdir Signed-off-by: Gui Hecheng --- src/rgw/rgw_file.cc | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index ca8a5c4b4b8..e3a8625b7e0 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -1650,21 +1650,30 @@ int rgw_lookup(struct rgw_fs *rgw_fs, return -ENOENT; } } else { - /* lookup in a readdir callback */ - enum rgw_fh_type fh_type = fh_type_of(flags); - - uint32_t sl_flags = (flags & RGW_LOOKUP_FLAG_RCB) - ? RGWFileHandle::FLAG_NONE - : RGWFileHandle::FLAG_EXACT_MATCH; - - fhr = fs->stat_leaf(parent, path, fh_type, sl_flags); - if (! get<0>(fhr)) { - if (! (flags & RGW_LOOKUP_FLAG_CREATE)) - return -ENOENT; - else - fhr = fs->lookup_fh(parent, path, RGWFileHandle::FLAG_CREATE); + /* special: after readdir--note extra ref()! */ + if (unlikely((strcmp(path, "..") == 0))) { + rgw_fh = parent; + lsubdout(fs->get_context(), rgw, 17) + << __func__ << "BANG"<< *rgw_fh + << dendl; + fs->ref(rgw_fh); + } else { + /* lookup in a readdir callback */ + enum rgw_fh_type fh_type = fh_type_of(flags); + + uint32_t sl_flags = (flags & RGW_LOOKUP_FLAG_RCB) + ? RGWFileHandle::FLAG_NONE + : RGWFileHandle::FLAG_EXACT_MATCH; + + fhr = fs->stat_leaf(parent, path, fh_type, sl_flags); + if (! get<0>(fhr)) { + if (! (flags & RGW_LOOKUP_FLAG_CREATE)) + return -ENOENT; + else + fhr = fs->lookup_fh(parent, path, RGWFileHandle::FLAG_CREATE); + } + rgw_fh = get<0>(fhr); } - rgw_fh = get<0>(fhr); } /* !root */ struct rgw_file_handle *rfh = rgw_fh->get_fh(); -- 2.47.3