Skip to content

Commit

Permalink
rgw_file: dont deadlock in advance_mtime()
Browse files Browse the repository at this point in the history
Fixes: https://tracker.ceph.com/issues/41173

Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
  • Loading branch information
mattbenjamin committed Aug 8, 2019
1 parent ad88d4d commit 0d3338c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
17 changes: 12 additions & 5 deletions src/rgw/rgw_file.cc
Expand Up @@ -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;
Expand Down Expand Up @@ -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)));
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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();
Expand Down
8 changes: 4 additions & 4 deletions src/rgw/rgw_file.h
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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:
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 0d3338c

Please sign in to comment.