diff options
Diffstat (limited to 'src/os/FileStore.cc')
-rw-r--r-- | src/os/FileStore.cc | 240 |
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); |