1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2013 Inktank Storage, Inc.
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #ifndef CEPH_FDCACHE_H
16 #define CEPH_FDCACHE_H
21 #include "common/config_obs.h"
22 #include "common/hobject.h"
23 #include "common/shared_cache.hpp"
24 #include "include/compat.h"
25 #include "include/intarith.h"
30 class FDCache
: public md_config_obs_t
{
35 * Wrapper for an fd. Destructor closes the fd.
40 explicit FD(int _fd
) : fd(_fd
) {
41 ceph_assert(_fd
>= 0);
43 int operator*() const {
47 VOID_TEMP_FAILURE_RETRY(::close(fd
));
53 const int registry_shards
;
54 SharedLRU
<ghobject_t
, FD
> *registry
;
57 explicit FDCache(CephContext
*cct
) : cct(cct
),
58 registry_shards(std::max
<int64_t>(cct
->_conf
->filestore_fd_cache_shards
, 1)) {
60 cct
->_conf
.add_observer(this);
61 registry
= new SharedLRU
<ghobject_t
, FD
>[registry_shards
];
62 for (int i
= 0; i
< registry_shards
; ++i
) {
63 registry
[i
].set_cct(cct
);
65 std::max
<int64_t>((cct
->_conf
->filestore_fd_cache_size
/ registry_shards
), 1));
69 cct
->_conf
.remove_observer(this);
72 typedef std::shared_ptr
<FD
> FDRef
;
74 FDRef
lookup(const ghobject_t
&hoid
) {
75 int registry_id
= hoid
.hobj
.get_hash() % registry_shards
;
76 return registry
[registry_id
].lookup(hoid
);
79 FDRef
add(const ghobject_t
&hoid
, int fd
, bool *existed
) {
80 int registry_id
= hoid
.hobj
.get_hash() % registry_shards
;
81 return registry
[registry_id
].add(hoid
, new FD(fd
), existed
);
84 /// clear cached fd for hoid, subsequent lookups will get an empty FD
85 void clear(const ghobject_t
&hoid
) {
86 int registry_id
= hoid
.hobj
.get_hash() % registry_shards
;
87 registry
[registry_id
].purge(hoid
);
91 const char** get_tracked_conf_keys() const override
{
92 static const char* KEYS
[] = {
93 "filestore_fd_cache_size",
98 void handle_conf_change(const ConfigProxy
& conf
,
99 const std::set
<std::string
> &changed
) override
{
100 if (changed
.count("filestore_fd_cache_size")) {
101 for (int i
= 0; i
< registry_shards
; ++i
)
102 registry
[i
].set_size(
103 std::max
<int64_t>((conf
->filestore_fd_cache_size
/ registry_shards
), 1));
108 typedef FDCache::FDRef FDRef
;