summaryrefslogtreecommitdiff
path: root/src/os/FileStore.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/os/FileStore.cc')
-rw-r--r--src/os/FileStore.cc240
1 files changed, 120 insertions, 120 deletions
diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc
index b32f2875f71..24f7f1eff08 100644
--- a/src/os/FileStore.cc
+++ b/src/os/FileStore.cc
@@ -196,10 +196,22 @@ int FileStore::lfn_stat(coll_t cid, const hobject_t& oid, struct stat *buf)
return r;
}
-int FileStore::lfn_open(coll_t cid, const hobject_t& oid, int flags, mode_t mode,
+int FileStore::lfn_open(coll_t cid,
+ const hobject_t& oid,
+ bool create,
+ FDRef *outfd,
IndexedPath *path,
Index *index)
{
+ assert(outfd);
+ int flags = O_RDWR;
+ if (create)
+ flags |= O_CREAT;
+ Mutex::Locker l(fdcache_lock);
+ *outfd = fdcache.lookup(oid);
+ if (*outfd) {
+ return 0;
+ }
Index index2;
IndexedPath path2;
if (!path)
@@ -224,16 +236,16 @@ int FileStore::lfn_open(coll_t cid, const hobject_t& oid, int flags, mode_t mode
goto fail;
}
- r = ::open((*path)->path(), flags, mode);
+ r = ::open((*path)->path(), flags, 0644);
if (r < 0) {
r = -errno;
dout(10) << "error opening file " << (*path)->path() << " with flags="
- << flags << " and mode=" << mode << ": " << cpp_strerror(-r) << dendl;
+ << flags << ": " << cpp_strerror(-r) << dendl;
goto fail;
}
fd = r;
- if ((flags & O_CREAT) && (!exist)) {
+ if (create && (!exist)) {
r = (*index)->created(oid, (*path)->path());
if (r < 0) {
TEMP_FAILURE_RETRY(::close(fd));
@@ -242,31 +254,16 @@ int FileStore::lfn_open(coll_t cid, const hobject_t& oid, int flags, mode_t mode
goto fail;
}
}
- return fd;
+ *outfd = fdcache.add(oid, fd);
+ return 0;
fail:
assert(!m_filestore_fail_eio || r != -EIO);
return r;
}
-int FileStore::lfn_open(coll_t cid, const hobject_t& oid, int flags, mode_t mode, IndexedPath *path)
-{
- return lfn_open(cid, oid, flags, mode, path, 0);
-}
-
-int FileStore::lfn_open(coll_t cid, const hobject_t& oid, int flags, mode_t mode)
-{
- return lfn_open(cid, oid, flags, mode, 0, 0);
-}
-
-int FileStore::lfn_open(coll_t cid, const hobject_t& oid, int flags)
+void FileStore::lfn_close(FDRef fd)
{
- return lfn_open(cid, oid, flags, 0);
-}
-
-void FileStore::lfn_close(int fd)
-{
- TEMP_FAILURE_RETRY(::close(fd));
}
int FileStore::lfn_link(coll_t c, coll_t cid, const hobject_t& o)
@@ -324,6 +321,7 @@ int FileStore::lfn_link(coll_t c, coll_t cid, const hobject_t& o)
int FileStore::lfn_unlink(coll_t cid, const hobject_t& o,
const SequencerPosition &spos)
{
+ Mutex::Locker l(fdcache_lock);
Index index;
int r = get_index(cid, &index);
if (r < 0)
@@ -355,6 +353,7 @@ int FileStore::lfn_unlink(coll_t cid, const hobject_t& o,
if (g_conf->filestore_debug_inject_read_err) {
debug_obj_on_delete(o);
}
+ fdcache.clear(o);
} else {
/* Ensure that replay of this op doesn't result in the object_map
* going away.
@@ -387,6 +386,8 @@ FileStore::FileStore(const std::string &base, const std::string &jdev, const cha
sync_entry_timeo_lock("sync_entry_timeo_lock"),
timer(g_ceph_context, sync_entry_timeo_lock),
stop(false), sync_thread(this),
+ fdcache_lock("fdcache_lock"),
+ fdcache(g_ceph_context),
default_osr("default"),
op_queue_len(0), op_queue_bytes(0),
op_throttle_lock("FileStore::op_throttle_lock"),
@@ -2263,12 +2264,13 @@ int FileStore::_check_replay_guard(coll_t cid, hobject_t oid, const SequencerPos
if (!replaying || btrfs_stable_commits)
return 1;
- int fd = lfn_open(cid, oid, 0);
- if (fd < 0) {
+ FDRef fd;
+ int r = lfn_open(cid, oid, false, &fd);
+ if (r < 0) {
dout(10) << "_check_replay_guard " << cid << " " << oid << " dne" << dendl;
return 1; // if file does not exist, there is no guard, and we can replay.
}
- int ret = _check_replay_guard(fd, spos);
+ int ret = _check_replay_guard(**fd, spos);
lfn_close(fd);
return ret;
}
@@ -2762,22 +2764,24 @@ int FileStore::read(
dout(15) << "read " << cid << "/" << oid << " " << offset << "~" << len << dendl;
- int fd = lfn_open(cid, oid, O_RDONLY);
- if (fd < 0) {
- dout(10) << "FileStore::read(" << cid << "/" << oid << ") open error: " << cpp_strerror(fd) << dendl;
- return fd;
+ FDRef fd;
+ int r = lfn_open(cid, oid, false, &fd);
+ if (r < 0) {
+ dout(10) << "FileStore::read(" << cid << "/" << oid << ") open error: "
+ << cpp_strerror(r) << dendl;
+ return r;
}
if (len == 0) {
struct stat st;
memset(&st, 0, sizeof(struct stat));
- int r = ::fstat(fd, &st);
+ int r = ::fstat(**fd, &st);
assert(r == 0);
len = st.st_size;
}
bufferptr bptr(len); // prealloc space for entire read
- got = safe_pread(fd, bptr.c_str(), len, offset);
+ got = safe_pread(**fd, bptr.c_str(), len, offset);
if (got < 0) {
dout(10) << "FileStore::read(" << cid << "/" << oid << ") pread error: " << cpp_strerror(got) << dendl;
lfn_close(fd);
@@ -2815,15 +2819,14 @@ int FileStore::fiemap(coll_t cid, const hobject_t& oid,
dout(15) << "fiemap " << cid << "/" << oid << " " << offset << "~" << len << dendl;
- int r;
- int fd = lfn_open(cid, oid, O_RDONLY);
- if (fd < 0) {
- r = fd;
+ FDRef fd;
+ int r = lfn_open(cid, oid, false, &fd);
+ if (r < 0) {
dout(10) << "read couldn't open " << cid << "/" << oid << ": " << cpp_strerror(r) << dendl;
} else {
uint64_t i;
- r = do_fiemap(fd, offset, len, &fiemap);
+ r = do_fiemap(**fd, offset, len, &fiemap);
if (r < 0)
goto done;
@@ -2865,10 +2868,10 @@ int FileStore::fiemap(coll_t cid, const hobject_t& oid,
}
done:
- if (fd >= 0)
+ if (r >= 0) {
lfn_close(fd);
- if (r >= 0)
::encode(exomap, bl);
+ }
dout(10) << "fiemap " << cid << "/" << oid << " " << offset << "~" << len << " = " << r << " num_extents=" << exomap.size() << " " << exomap << dendl;
free(fiemap);
@@ -2899,14 +2902,13 @@ int FileStore::_touch(coll_t cid, const hobject_t& oid)
{
dout(15) << "touch " << cid << "/" << oid << dendl;
- int flags = O_WRONLY|O_CREAT;
- int fd = lfn_open(cid, oid, flags, 0644);
- int r;
- if (fd >= 0) {
+ FDRef fd;
+ int r = lfn_open(cid, oid, true, &fd);
+ if (r < 0) {
+ return r;
+ } else {
lfn_close(fd);
- r = 0;
- } else
- r = fd;
+ }
dout(10) << "touch " << cid << "/" << oid << " = " << r << dendl;
return r;
}
@@ -2920,17 +2922,17 @@ int FileStore::_write(coll_t cid, const hobject_t& oid,
int64_t actual;
- int flags = O_WRONLY|O_CREAT;
- int fd = lfn_open(cid, oid, flags, 0644);
- if (fd < 0) {
- r = fd;
- dout(0) << "write couldn't open " << cid << "/" << oid << " flags " << flags << ": "
+ FDRef fd;
+ r = lfn_open(cid, oid, true, &fd);
+ if (r < 0) {
+ dout(0) << "write couldn't open " << cid << "/"
+ << oid << ": "
<< cpp_strerror(r) << dendl;
goto out;
}
// seek
- actual = ::lseek64(fd, offset, SEEK_SET);
+ actual = ::lseek64(**fd, offset, SEEK_SET);
if (actual < 0) {
r = -errno;
dout(0) << "write lseek64 to " << offset << " failed: " << cpp_strerror(r) << dendl;
@@ -2945,7 +2947,7 @@ int FileStore::_write(coll_t cid, const hobject_t& oid,
}
// write
- r = bl.write_fd(fd);
+ r = bl.write_fd(**fd);
if (r == 0)
r = bl.length();
@@ -2957,23 +2959,24 @@ int FileStore::_write(coll_t cid, const hobject_t& oid,
bool async_done = false;
if (!should_flush ||
!m_filestore_flusher ||
- !(async_done = queue_flusher(fd, offset, len, replica))) {
+ !(async_done = queue_flusher(**fd, offset, len, replica))) {
if (should_flush && m_filestore_sync_flush) {
- ::sync_file_range(fd, offset, len, SYNC_FILE_RANGE_WRITE);
+ ::sync_file_range(**fd, offset, len, SYNC_FILE_RANGE_WRITE);
local_flush = true;
}
}
+ // TODOSAM: this will be fixed in a subsequent patch
//Both lfn_close() and possible posix_fadvise() done by flusher
- if (async_done) fd = -1;
+ //if (async_done) fd = -1;
#else
// no sync_file_range; (maybe) flush inline and close.
if (should_flush && m_filestore_sync_flush) {
- ::fdatasync(fd);
+ ::fdatasync(**fd);
local_flush = true;
}
#endif
if (local_flush && replica && m_filestore_replica_fadvise) {
- int fa_r = posix_fadvise(fd, offset, len, POSIX_FADV_DONTNEED);
+ int fa_r = posix_fadvise(**fd, offset, len, POSIX_FADV_DONTNEED);
if (fa_r) {
dout(0) << "posic_fadvise failed: " << cpp_strerror(fa_r) << dendl;
} else {
@@ -2981,7 +2984,7 @@ int FileStore::_write(coll_t cid, const hobject_t& oid,
}
}
}
- if (fd >= 0) lfn_close(fd);
+ lfn_close(fd);
out:
dout(10) << "write " << cid << "/" << oid << " " << offset << "~" << len << " = " << r << dendl;
@@ -2996,14 +2999,14 @@ int FileStore::_zero(coll_t cid, const hobject_t& oid, uint64_t offset, size_t l
#ifdef CEPH_HAVE_FALLOCATE
# if !defined(DARWIN) && !defined(__FreeBSD__)
// first try to punch a hole.
- int fd = lfn_open(cid, oid, O_RDONLY);
- if (fd < 0) {
- ret = -errno;
+ FDRef fd;
+ ret = lfn_open(cid, oid, false, &fd);
+ if (ret < 0) {
goto out;
}
// first try fallocate
- ret = fallocate(fd, FALLOC_FL_PUNCH_HOLE, offset, len);
+ ret = fallocate(**fd, FALLOC_FL_PUNCH_HOLE, offset, len);
if (ret < 0)
ret = -errno;
lfn_close(fd);
@@ -3039,23 +3042,26 @@ int FileStore::_clone(coll_t cid, const hobject_t& oldoid, const hobject_t& newo
if (_check_replay_guard(cid, newoid, spos) < 0)
return 0;
- int o, n, r;
+ int r;
+ FDRef o, n;
{
Index index;
IndexedPath from, to;
- o = lfn_open(cid, oldoid, O_RDONLY, 0, &from, &index);
- if (o < 0) {
- r = o;
+ r = lfn_open(cid, oldoid, false, &o, &from, &index);
+ if (r < 0) {
goto out2;
}
- n = lfn_open(cid, newoid, O_CREAT|O_TRUNC|O_WRONLY, 0644, &to, &index);
- if (n < 0) {
- r = n;
+ r = lfn_open(cid, newoid, true, &n, &to, &index);
+ if (r < 0) {
+ goto out;
+ }
+ r = ::ftruncate(**n, 0);
+ if (r < 0) {
goto out;
}
struct stat st;
- ::fstat(o, &st);
- r = _do_clone_range(o, n, 0, st.st_size, 0);
+ ::fstat(**o, &st);
+ r = _do_clone_range(**o, **n, 0, st.st_size, 0);
if (r < 0) {
r = -errno;
goto out3;
@@ -3068,17 +3074,17 @@ int FileStore::_clone(coll_t cid, const hobject_t& oldoid, const hobject_t& newo
{
map<string, bufferptr> aset;
- r = _fgetattrs(o, aset, false);
+ r = _fgetattrs(**o, aset, false);
if (r < 0)
goto out3;
- r = _fsetattrs(n, aset);
+ r = _fsetattrs(**n, aset);
if (r < 0)
goto out3;
}
// clone is non-idempotent; record our work.
- _set_replay_guard(n, spos, &newoid);
+ _set_replay_guard(**n, spos, &newoid);
out3:
lfn_close(n);
@@ -3248,21 +3254,19 @@ int FileStore::_clone_range(coll_t cid, const hobject_t& oldoid, const hobject_t
return 0;
int r;
- int o, n;
- o = lfn_open(cid, oldoid, O_RDONLY);
- if (o < 0) {
- r = o;
+ FDRef o, n;
+ r = lfn_open(cid, oldoid, false, &o);
+ if (r < 0) {
goto out2;
}
- n = lfn_open(cid, newoid, O_CREAT|O_WRONLY, 0644);
- if (n < 0) {
- r = n;
+ r = lfn_open(cid, newoid, true, &n);
+ if (r < 0) {
goto out;
}
- r = _do_clone_range(o, n, srcoff, len, dstoff);
+ r = _do_clone_range(**o, **n, srcoff, len, dstoff);
// clone is non-idempotent; record our work.
- _set_replay_guard(n, spos, &newoid);
+ _set_replay_guard(**n, spos, &newoid);
lfn_close(n);
out:
@@ -3339,7 +3343,8 @@ void FileStore::flusher_entry()
} else
dout(10) << "flusher_entry JUST closing " << fd << " (stop=" << stop << ", ep=" << ep
<< ", sync_epoch=" << sync_epoch << ")" << dendl;
- lfn_close(fd);
+ // TODOSAM: this will be replaced in a subsequent patch
+ //lfn_close(fd);
}
lock.Lock();
flusher_queue_len -= num; // they're definitely closed, forget
@@ -3856,15 +3861,14 @@ bool FileStore::debug_mdata_eio(const hobject_t &oid) {
int FileStore::getattr(coll_t cid, const hobject_t& oid, const char *name, bufferptr &bp)
{
dout(15) << "getattr " << cid << "/" << oid << " '" << name << "'" << dendl;
- int r;
- int fd = lfn_open(cid, oid, 0);
- if (fd < 0) {
- r = -errno;
+ FDRef fd;
+ int r = lfn_open(cid, oid, false, &fd);
+ if (r < 0) {
goto out;
}
char n[CHAIN_XATTR_MAX_NAME_LEN];
get_attrname(name, n, CHAIN_XATTR_MAX_NAME_LEN);
- r = _fgetattr(fd, n, bp);
+ r = _fgetattr(**fd, n, bp);
lfn_close(fd);
if (r == -ENODATA && g_conf->filestore_xattr_use_omap) {
map<string, bufferlist> got;
@@ -3903,13 +3907,12 @@ int FileStore::getattr(coll_t cid, const hobject_t& oid, const char *name, buffe
int FileStore::getattrs(coll_t cid, const hobject_t& oid, map<string,bufferptr>& aset, bool user_only)
{
dout(15) << "getattrs " << cid << "/" << oid << dendl;
- int r;
- int fd = lfn_open(cid, oid, 0);
- if (fd < 0) {
- r = -errno;
+ FDRef fd;
+ int r = lfn_open(cid, oid, false, &fd);
+ if (r < 0) {
goto out;
}
- r = _fgetattrs(fd, aset, user_only);
+ r = _fgetattrs(**fd, aset, user_only);
lfn_close(fd);
if (g_conf->filestore_xattr_use_omap) {
set<string> omap_attrs;
@@ -3967,14 +3970,13 @@ int FileStore::_setattrs(coll_t cid, const hobject_t& oid, map<string,bufferptr>
set<string> omap_remove;
map<string, bufferptr> inline_set;
map<string, bufferptr> inline_to_set;
- int r = 0;
- int fd = lfn_open(cid, oid, 0);
- if (fd < 0) {
- r = -errno;
+ FDRef fd;
+ int r = lfn_open(cid, oid, false, &fd);
+ if (r < 0) {
goto out;
}
if (g_conf->filestore_xattr_use_omap) {
- r = _fgetattrs(fd, inline_set, false);
+ r = _fgetattrs(**fd, inline_set, false);
assert(!m_filestore_fail_eio || r != -EIO);
}
dout(15) << "setattrs " << cid << "/" << oid << dendl;
@@ -3988,7 +3990,7 @@ int FileStore::_setattrs(coll_t cid, const hobject_t& oid, map<string,bufferptr>
if (p->second.length() > g_conf->filestore_max_inline_xattr_size) {
if (inline_set.count(p->first)) {
inline_set.erase(p->first);
- r = chain_fremovexattr(fd, n);
+ r = chain_fremovexattr(**fd, n);
if (r < 0)
goto out_close;
}
@@ -4000,7 +4002,7 @@ int FileStore::_setattrs(coll_t cid, const hobject_t& oid, map<string,bufferptr>
inline_set.size() >= g_conf->filestore_max_inline_xattrs) {
if (inline_set.count(p->first)) {
inline_set.erase(p->first);
- r = chain_fremovexattr(fd, n);
+ r = chain_fremovexattr(**fd, n);
if (r < 0)
goto out_close;
}
@@ -4015,7 +4017,7 @@ int FileStore::_setattrs(coll_t cid, const hobject_t& oid, map<string,bufferptr>
}
- r = _fsetattrs(fd, inline_to_set);
+ r = _fsetattrs(**fd, inline_to_set);
if (r < 0)
goto out_close;
@@ -4050,15 +4052,14 @@ int FileStore::_rmattr(coll_t cid, const hobject_t& oid, const char *name,
const SequencerPosition &spos)
{
dout(15) << "rmattr " << cid << "/" << oid << " '" << name << "'" << dendl;
- int r = 0;
- int fd = lfn_open(cid, oid, 0);
- if (fd < 0) {
- r = -errno;
+ FDRef fd;
+ int r = lfn_open(cid, oid, false, &fd);
+ if (r < 0) {
goto out;
}
char n[CHAIN_XATTR_MAX_NAME_LEN];
get_attrname(name, n, CHAIN_XATTR_MAX_NAME_LEN);
- r = chain_fremovexattr(fd, n);
+ r = chain_fremovexattr(**fd, n);
if (r == -ENODATA && g_conf->filestore_xattr_use_omap) {
Index index;
r = get_index(cid, &index);
@@ -4088,18 +4089,17 @@ int FileStore::_rmattrs(coll_t cid, const hobject_t& oid,
dout(15) << "rmattrs " << cid << "/" << oid << dendl;
map<string,bufferptr> aset;
- int r = 0;
- int fd = lfn_open(cid, oid, 0);
- if (fd < 0) {
- r = -errno;
+ FDRef fd;
+ int r = lfn_open(cid, oid, false, &fd);
+ if (r < 0) {
goto out;
}
- r = _fgetattrs(fd, aset, false);
+ r = _fgetattrs(**fd, aset, false);
if (r >= 0) {
for (map<string,bufferptr>::iterator p = aset.begin(); p != aset.end(); ++p) {
char n[CHAIN_XATTR_MAX_NAME_LEN];
get_attrname(p->first.c_str(), n, CHAIN_XATTR_MAX_NAME_LEN);
- r = chain_fremovexattr(fd, n);
+ r = chain_fremovexattr(**fd, n);
if (r < 0)
break;
}
@@ -4687,21 +4687,21 @@ int FileStore::_collection_add(coll_t c, coll_t oldcid, const hobject_t& o,
// open guard on object so we don't any previous operations on the
// new name that will modify the source inode.
- int fd = lfn_open(oldcid, o, 0);
- if (fd < 0) {
+ FDRef fd;
+ int r = lfn_open(oldcid, o, 0, &fd);
+ if (r < 0) {
// the source collection/object does not exist. If we are replaying, we
// should be safe, so just return 0 and move on.
assert(replaying);
dout(10) << "collection_add " << c << "/" << o << " from "
- << oldcid << "/" << o << " (dne, continue replay) " << dendl;
+ << oldcid << "/" << o << " (dne, continue replay) " << dendl;
return 0;
}
- assert(fd >= 0);
if (dstcmp > 0) { // if dstcmp == 0 the guard already says "in-progress"
- _set_replay_guard(fd, spos, &o, true);
+ _set_replay_guard(**fd, spos, &o, true);
}
- int r = lfn_link(oldcid, c, o);
+ r = lfn_link(oldcid, c, o);
if (replaying && !btrfs_stable_commits &&
r == -EEXIST) // crashed between link() and set_replay_guard()
r = 0;
@@ -4710,7 +4710,7 @@ int FileStore::_collection_add(coll_t c, coll_t oldcid, const hobject_t& o,
// close guard on object so we don't do this again
if (r == 0) {
- _close_replay_guard(fd, spos);
+ _close_replay_guard(**fd, spos);
}
lfn_close(fd);