// close root ino
ceph_assert(inode_map.size() <= 1 + root_parents.size());
if (root && inode_map.size() == 1 + root_parents.size()) {
- delete root;
- root = 0;
- root_ancestor = 0;
- while (!root_parents.empty())
- root_parents.erase(root_parents.begin());
- inode_map.clear();
- _reset_faked_inos();
+ root.reset();
}
ceph_assert(inode_map.empty());
{
std::scoped_lock l(client_lock);
root->ll_get();
- return root;
+ return root.get();
}
<< (disconnected ? "DISCONNECTED ":"")
<< "inode " << in->ino
<< " " << path
- << " ref " << in->get_num_ref()
+ << " ref " << in->get_nref()
<< " " << *in << dendl;
if (f) {
f->open_array_section("cache");
if (root)
- dump_inode(f, root, did, true);
+ dump_inode(f, root.get(), did, true);
// make a second pass to catch anything disconnected
for (ceph::unordered_map<vinodeno_t, Inode*>::iterator it = inode_map.begin();
_invalidate_kernel_dcache();
// hose root?
- if (lru.lru_get_size() == 0 && root && root->get_num_ref() == 0 && inode_map.size() == 1 + root_parents.size()) {
+ if (lru.lru_get_size() == 0 && root && root->get_nref() == 1 && inode_map.size() == 1 + root_parents.size()) {
ldout(cct, 15) << "trim_cache trimmed root " << root << dendl;
- delete root;
- root = 0;
- root_ancestor = 0;
- while (!root_parents.empty())
- root_parents.erase(root_parents.begin());
- inode_map.clear();
- _reset_faked_inos();
+ root.reset();
}
}
if (!root) {
root = in;
if (use_faked_inos())
- _assign_faked_root(root);
+ _assign_faked_root(root.get());
root_ancestor = in;
cwd = root;
} else if (is_mounting()) {
{
ldout(cct, 10) << __func__ << " on " << *in << " n = " << n << dendl;
- int left = in->_put(n);
- if (left == 0) {
+ int left = in->get_nref();
+ ceph_assert(left >= n + 1);
+ in->iput(n);
+ left -= n;
+ if (left == 1) { // the last one will be held by the inode_map
// release any caps
remove_all_caps(in);
if (use_faked_inos())
_release_faked_ino(in);
- if (in == root) {
- root = 0;
+ if (root == nullptr) {
root_ancestor = 0;
while (!root_parents.empty())
root_parents.erase(root_parents.begin());
}
- delete in;
+ in->iput();
}
}
if ((cap & CEPH_CAP_FILE_BUFFER) &&
in->cap_refs[CEPH_CAP_FILE_BUFFER] == 0) {
ldout(cct, 5) << __func__ << " got first FILE_BUFFER ref on " << *in << dendl;
- in->get();
+ in->iget();
}
if ((cap & CEPH_CAP_FILE_CACHE) &&
in->cap_refs[CEPH_CAP_FILE_CACHE] == 0) {
ldout(cct, 5) << __func__ << " got first FILE_CACHE ref on " << *in << dendl;
- in->get();
+ in->iget();
}
in->get_cap_ref(cap);
}
void Client::_try_to_trim_inode(Inode *in, bool sched_inval)
{
- int ref = in->get_num_ref();
+ int ref = in->get_nref();
ldout(cct, 5) << __func__ << " in " << *in <<dendl;
if (in->dir && !in->dir->dentries.empty()) {
}
}
- if (ref > 0 && (in->flags & I_SNAPDIR_OPEN)) {
+ if (ref > 1 && (in->flags & I_SNAPDIR_OPEN)) {
InodeRef snapdir = open_snapdir(in);
_try_to_trim_inode(snapdir.get(), false);
--ref;
}
- if (ref > 0) {
+ if (ref > 1) {
auto q = in->dentries.begin();
while (q != in->dentries.end()) {
Dentry *dn = *q;
}
ceph_assert(root);
- _ll_get(root);
+ _ll_get(root.get());
// trace?
if (!cct->_conf->client_trace.empty()) {
});
cwd.reset();
+ root.reset();
// clean up any unclosed files
while (!fd_map.empty()) {
ldout(cct, 10) << __func__ << " " << *cwd << dendl;
Inode *in = cwd.get();
- while (in != root) {
+ while (in != root.get()) {
ceph_assert(in->dentries.size() < 2); // dirs can't be hard-linked
// A cwd or ancester is unlinked
// quota but we can see a parent of it that does have a quota, we'll
// respect that one instead.
ceph_assert(root != nullptr);
- Inode *quota_root = root->quota.is_enable() ? root : get_quota_root(root, perms);
+ InodeRef quota_root = root->quota.is_enable() ? root : get_quota_root(root.get(), perms);
// get_quota_root should always give us something
// because client quotas are always enabled
void Client::_ll_get(Inode *in)
{
if (in->ll_ref == 0) {
- in->get();
+ in->iget();
if (in->is_dir() && !in->dentries.empty()) {
ceph_assert(in->dentries.size() == 1); // dirs can't be hard-linked
in->get_first_parent()->get(); // pin dentry
void intrusive_ptr_add_ref(Inode *in)
{
- in->get();
+ in->iget();
}
void intrusive_ptr_release(Inode *in)
{
out << in.vino() << "("
<< "faked_ino=" << in.faked_ino
- << " ref=" << in._ref
+ << " nref=" << in.get_nref()
<< " ll_ref=" << in.ll_ref
<< " cap_refs=" << in.cap_refs
<< " open=" << in.open_by_mode
ceph_assert(dentries.size() < 2); // dirs can't be hard-linked
if (!dentries.empty())
get_first_parent()->get(); // pin dentry
- get(); // pin inode
+ iget(); // pin inode
}
return dir;
}
return (mode & want) == want;
}
-void Inode::get() {
- _ref++;
- lsubdout(client->cct, client, 15) << "inode.get on " << this << " " << ino << '.' << snapid
- << " now " << _ref << dendl;
-}
-
-//private method to put a reference; see Client::put_inode()
-int Inode::_put(int n) {
- _ref -= n;
- lsubdout(client->cct, client, 15) << "inode.put on " << this << " " << ino << '.' << snapid
- << " now " << _ref << dendl;
- ceph_assert(_ref >= 0);
- return _ref;
-}
-
-
void Inode::dump(Formatter *f) const
{
f->dump_stream("ino") << ino;
if (requested_max_size != max_size)
f->dump_unsigned("requested_max_size", requested_max_size);
- f->dump_int("ref", _ref);
+ f->dump_int("nref", get_nref());
f->dump_int("ll_ref", ll_ref);
if (!dentries.empty()) {
lsubdout(client->cct, client, 10) << __func__ << " " << *this << " " << ccap_string(dirty_caps) << " -> "
<< ccap_string(dirty_caps | caps) << dendl;
if (caps && !caps_dirty())
- get();
+ iget();
dirty_caps |= caps;
client->get_dirty_list().push_back(&dirty_cap_item);
}
#define I_CAP_DROPPED (1 << 4)
#define I_ERROR_FILELOCK (1 << 5)
-struct Inode {
+struct Inode : RefCountedObject {
Client *client;
// -- the actual inode --
uint64_t wanted_max_size = 0;
uint64_t requested_max_size = 0;
- int _ref = 0; // ref count. 1 for each dentry, fh that links to me.
uint64_t ll_ref = 0; // separate ref count for ll client
xlist<Dentry *> dentries; // if i'm linked to a dentry.
string symlink; // symlink content, if it's a symlink
void make_short_path(filepath& p);
void make_nosnap_relative_path(filepath& p);
- void get();
- int _put(int n=1);
-
- int get_num_ref() {
- return _ref;
- }
+ // The ref count. 1 for each dentry, fh, inode_map,
+ // cwd that links to me.
+ void iget() { get(); }
+ void iput(int n=1) { ceph_assert(n >= 0); while (n--) put(); }
void ll_get() {
ll_ref++;