rgw_file: dont deadlock in advance_mtime()

Fixes: https://tracker.ceph.com/issues/41173

Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
This commit is contained in:
Matt Benjamin 2019-08-08 16:21:24 -04:00
parent ad88d4dced
commit 0d3338c2d2
2 changed files with 16 additions and 9 deletions

View File

@ -589,7 +589,7 @@ namespace rgw {
/* save attrs */
rgw_fh->encode_attrs(ux_key, ux_attrs);
if (st)
rgw_fh->stat(st);
rgw_fh->stat(st, RGWFileHandle::FLAG_LOCKED);
get<0>(mkr) = rgw_fh;
} else {
get<1>(mkr) = -EIO;
@ -720,7 +720,7 @@ namespace rgw {
parent->set_ctime(real_clock::to_timespec(t));
}
if (st)
(void) rgw_fh->stat(st);
(void) rgw_fh->stat(st, RGWFileHandle::FLAG_LOCKED);
rgw_fh->set_etag(*(req.get_attr(RGW_ATTR_ETAG)));
rgw_fh->set_acls(*(req.get_attr(RGW_ATTR_ACL)));
@ -1264,8 +1264,11 @@ namespace rgw {
}
bool initial_off;
char* mk{nullptr};
if (likely(!! get<const char*>(&offset))) {
initial_off = ! get<const char*>(offset);
mk = const_cast<char*>(get<const char*>(offset));
initial_off = !mk;
} else {
initial_off = (*get<uint64_t*>(offset) == 0);
}
@ -1478,10 +1481,14 @@ namespace rgw {
}
}
void RGWFileHandle::advance_mtime() {
void RGWFileHandle::advance_mtime(uint32_t flags) {
/* intended for use on directories, fast-forward mtime so as to
* ensure a new, higher value for the change attribute */
lock_guard guard(mtx);
unique_lock uniq(mtx, std::defer_lock);
if (likely(! (flags & RGWFileHandle::FLAG_LOCKED))) {
uniq.lock();
}
/* advance mtime only if stored mtime is older than the
* configured namespace expiration */
auto now = real_clock::now();

View File

@ -238,7 +238,7 @@ namespace rgw {
};
void clear_state();
void advance_mtime();
void advance_mtime(uint32_t flags = FLAG_NONE);
boost::variant<file, directory> variant_type;
@ -436,7 +436,7 @@ namespace rgw {
state.ctime = st->st_ctim;
}
int stat(struct stat* st) {
int stat(struct stat* st, uint32_t flags = FLAG_NONE) {
/* partial Unix attrs */
memset(st, 0, sizeof(struct stat));
st->st_dev = state.dev;
@ -450,7 +450,7 @@ namespace rgw {
switch (fh.fh_type) {
case RGW_FS_TYPE_DIRECTORY:
/* virtual directories are always invalid */
advance_mtime();
advance_mtime(flags);
st->st_nlink = state.nlink;
break;
case RGW_FS_TYPE_FILE:
@ -1077,7 +1077,7 @@ namespace rgw {
fh_key fhk = parent->make_fhk(obj_name);
lsubdout(get_context(), rgw, 10)
<< __func__ << " lookup called on "
<< __func__ << " called on "
<< parent->object_name() << " for " << key_name
<< " (" << obj_name << ")"
<< " -> " << fhk