Skip to content

Commit c37ad2b

Browse files
committed
client: calls to _ll_fh_exists() should hold client_lock
Credit to Brad Hubbard for grabbing the stack trace. Fixes: https://tracker.ceph.com/issues/67565 Signed-off-by: Venky Shankar <[email protected]>
1 parent 36924ef commit c37ad2b

File tree

1 file changed

+20
-16
lines changed

1 file changed

+20
-16
lines changed

src/client/Client.cc

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15842,6 +15842,10 @@ int Client::ll_read(Fh *fh, loff_t off, loff_t len, bufferlist *bl)
1584215842
return -CEPHFS_ENOTCONN;
1584315843
}
1584415844

15845+
/* We can't return bytes written larger than INT_MAX, clamp len to that */
15846+
len = std::min(len, (loff_t)INT_MAX);
15847+
15848+
std::scoped_lock lock(client_lock);
1584515849
if (fh == NULL || !_ll_fh_exists(fh)) {
1584615850
ldout(cct, 3) << "(fh)" << fh << " is invalid" << dendl;
1584715851
return -CEPHFS_EBADF;
@@ -15853,10 +15857,6 @@ int Client::ll_read(Fh *fh, loff_t off, loff_t len, bufferlist *bl)
1585315857
tout(cct) << off << std::endl;
1585415858
tout(cct) << len << std::endl;
1585515859

15856-
/* We can't return bytes written larger than INT_MAX, clamp len to that */
15857-
len = std::min(len, (loff_t)INT_MAX);
15858-
std::scoped_lock lock(client_lock);
15859-
1586015860
int r = _read(fh, off, len, bl);
1586115861
ldout(cct, 3) << "ll_read " << fh << " " << off << "~" << len << " = " << r
1586215862
<< dendl;
@@ -15987,6 +15987,10 @@ int Client::ll_write(Fh *fh, loff_t off, loff_t len, const char *data)
1598715987
return -CEPHFS_ENOTCONN;
1598815988
}
1598915989

15990+
/* We can't return bytes written larger than INT_MAX, clamp len to that */
15991+
len = std::min(len, (loff_t)INT_MAX);
15992+
15993+
std::scoped_lock lock(client_lock);
1599015994
if (fh == NULL || !_ll_fh_exists(fh)) {
1599115995
ldout(cct, 3) << "(fh)" << fh << " is invalid" << dendl;
1599215996
return -CEPHFS_EBADF;
@@ -15999,10 +16003,6 @@ int Client::ll_write(Fh *fh, loff_t off, loff_t len, const char *data)
1599916003
tout(cct) << off << std::endl;
1600016004
tout(cct) << len << std::endl;
1600116005

16002-
/* We can't return bytes written larger than INT_MAX, clamp len to that */
16003-
len = std::min(len, (loff_t)INT_MAX);
16004-
std::scoped_lock lock(client_lock);
16005-
1600616006
int r = _write(fh, off, len, data, NULL, 0);
1600716007
ldout(cct, 3) << "ll_write " << fh << " " << off << "~" << len << " = " << r
1600816008
<< dendl;
@@ -16016,12 +16016,11 @@ int64_t Client::ll_writev(struct Fh *fh, const struct iovec *iov, int iovcnt, in
1601616016
return -CEPHFS_ENOTCONN;
1601716017
}
1601816018

16019+
std::scoped_lock cl(client_lock);
1601916020
if (fh == NULL || !_ll_fh_exists(fh)) {
1602016021
ldout(cct, 3) << "(fh)" << fh << " is invalid" << dendl;
1602116022
return -CEPHFS_EBADF;
1602216023
}
16023-
16024-
std::scoped_lock cl(client_lock);
1602516024
return _preadv_pwritev_locked(fh, iov, iovcnt, off, true, false);
1602616025
}
1602716026

@@ -16032,12 +16031,11 @@ int64_t Client::ll_readv(struct Fh *fh, const struct iovec *iov, int iovcnt, int
1603216031
return -CEPHFS_ENOTCONN;
1603316032
}
1603416033

16034+
std::scoped_lock cl(client_lock);
1603516035
if (fh == NULL || !_ll_fh_exists(fh)) {
1603616036
ldout(cct, 3) << "(fh)" << fh << " is invalid" << dendl;
1603716037
return -CEPHFS_EBADF;
1603816038
}
16039-
16040-
std::scoped_lock cl(client_lock);
1604116039
return _preadv_pwritev_locked(fh, iov, iovcnt, off, false, false);
1604216040
}
1604316041

@@ -16060,18 +16058,24 @@ int64_t Client::ll_preadv_pwritev(struct Fh *fh, const struct iovec *iov,
1606016058
return retval;
1606116059
}
1606216060

16061+
retval = 0;
16062+
std::unique_lock cl(client_lock);
16063+
1606316064
if(fh == NULL || !_ll_fh_exists(fh)) {
1606416065
ldout(cct, 3) << "(fh)" << fh << " is invalid" << dendl;
1606516066
retval = -CEPHFS_EBADF;
16067+
}
16068+
16069+
if (retval != 0) {
1606616070
if (onfinish != nullptr) {
16071+
cl.unlock();
1606716072
onfinish->complete(retval);
16073+
cl.lock();
1606816074
retval = 0;
1606916075
}
1607016076
return retval;
1607116077
}
1607216078

16073-
std::scoped_lock cl(client_lock);
16074-
1607516079
retval = _preadv_pwritev_locked(fh, iov, iovcnt, offset, write, true,
1607616080
onfinish, bl, do_fsync, syncdataonly);
1607716081
/* There are two scenarios with each having two cases to handle here
@@ -16092,9 +16096,9 @@ int64_t Client::ll_preadv_pwritev(struct Fh *fh, const struct iovec *iov,
1609216096
if (retval < 0) {
1609316097
if (onfinish != nullptr) {
1609416098
//async io failed
16095-
client_lock.unlock();
16099+
cl.unlock();
1609616100
onfinish->complete(retval);
16097-
client_lock.lock();
16101+
cl.lock();
1609816102
/* async call should always return zero to caller and allow the
1609916103
caller to wait on callback for the actual errno/retval. */
1610016104
retval = 0;

0 commit comments

Comments
 (0)