Merge remote-tracking branch 'gh/next'

Conflicts:
	PendingReleaseNotes
This commit is contained in:
Sage Weil 2014-12-22 06:51:14 -08:00
commit 20a4c57c4b
5 changed files with 115 additions and 89 deletions

View File

@ -30,5 +30,10 @@ v0.91
a bogus value (for example, when rados_watch() returns an error and
handle is not defined).
* The structure of the formatted 'pg stat' command is changed for the
portion that counts states by name to avoid using the '+' character
(which appears in state names) as part of the XML token (it is not
legal).
v0.92
-----

View File

@ -159,16 +159,16 @@ Client::Client(Messenger *m, MonClient *mc)
logger(NULL),
m_command_hook(this),
timer(m->cct, client_lock),
callback_handle(NULL),
switch_interrupt_cb(NULL),
remount_cb(NULL),
ino_invalidate_cb(NULL),
ino_invalidate_cb_handle(NULL),
dentry_invalidate_cb(NULL),
dentry_invalidate_cb_handle(NULL),
getgroups_cb(NULL),
getgroups_cb_handle(NULL),
async_ino_invalidator(m->cct),
async_dentry_invalidator(m->cct),
interrupt_finisher(m->cct),
remount_finisher(m->cct),
objecter_finisher(m->cct),
tick_event(NULL),
monclient(mc), messenger(m), whoami(m->get_myname().num()),
@ -510,6 +510,12 @@ void Client::shutdown()
interrupt_finisher.stop();
}
if (remount_cb) {
ldout(cct, 10) << "shutdown stopping remount finisher" << dendl;
remount_finisher.wait_for_empty();
remount_finisher.stop();
}
objectcacher->stop(); // outside of client_lock! this does a join.
client_lock.Lock();
@ -596,7 +602,7 @@ void Client::trim_cache_for_reconnect(MetaSession *s)
<< " trimmed " << trimmed << " dentries" << dendl;
if (s->caps.size() > 0)
_invalidate_kernel_dcache(s);
_invalidate_kernel_dcache();
}
void Client::trim_dentry(Dentry *dn)
@ -3099,7 +3105,7 @@ public:
void Client::_async_invalidate(Inode *in, int64_t off, int64_t len, bool keep_caps)
{
ldout(cct, 10) << "_async_invalidate " << off << "~" << len << (keep_caps ? " keep_caps" : "") << dendl;
ino_invalidate_cb(ino_invalidate_cb_handle, in->vino(), off, len);
ino_invalidate_cb(callback_handle, in->vino(), off, len);
client_lock.Lock();
if (!keep_caps)
@ -3395,21 +3401,22 @@ void Client::remove_session_caps(MetaSession *s)
sync_cond.Signal();
}
void Client::_invalidate_kernel_dcache(MetaSession *s)
{
if (!dentry_invalidate_cb)
return;
for (xlist<Cap*>::iterator p = s->caps.begin(); !p.end(); ++p) {
Inode *in = (*p)->inode;
if (in->dn_set.empty())
continue;
for (set<Dentry*>::iterator q = in->dn_set.begin();
q != in->dn_set.end();
++q) {
_schedule_invalidate_dentry_callback(*q, false);
}
class C_Client_Remount : public Context {
private:
Client *client;
public:
C_Client_Remount(Client *c) : client(c) {}
void finish(int r) {
client->remount_cb(client->callback_handle);
}
};
void Client::_invalidate_kernel_dcache()
{
// Hacky:
// when remounting a file system, linux kernel trims all unused dentries in the file system
if (remount_cb)
remount_finisher.queue(new C_Client_Remount(this));
}
void Client::trim_caps(MetaSession *s, int max)
@ -3441,7 +3448,6 @@ void Client::trim_caps(MetaSession *s, int max)
while (q != in->dn_set.end()) {
Dentry *dn = *q++;
if (dn->lru_is_expireable()) {
_schedule_invalidate_dentry_callback(dn, false);
trim_dentry(dn);
} else {
ldout(cct, 20) << " not expirable: " << dn->name << dendl;
@ -3463,6 +3469,9 @@ void Client::trim_caps(MetaSession *s, int max)
}
}
s->s_cap_iterator = NULL;
if (s->caps.size() > max)
_invalidate_kernel_dcache();
}
void Client::force_session_readonly(MetaSession *s)
@ -4126,7 +4135,7 @@ void Client::_async_dentry_invalidate(vinodeno_t dirino, vinodeno_t ino, string&
{
ldout(cct, 10) << "_async_dentry_invalidate '" << name << "' ino " << ino
<< " in dir " << dirino << dendl;
dentry_invalidate_cb(dentry_invalidate_cb_handle, dirino, ino, name);
dentry_invalidate_cb(callback_handle, dirino, ino, name);
}
void Client::_schedule_invalidate_dentry_callback(Dentry *dn, bool del)
@ -4291,7 +4300,7 @@ int Client::check_permissions(Inode *in, int flags, int uid, int gid)
gid_t *sgids = NULL;
int sgid_count = 0;
if (getgroups_cb) {
sgid_count = getgroups_cb(getgroups_cb_handle, uid, &sgids);
sgid_count = getgroups_cb(callback_handle, uid, &sgids);
if (sgid_count < 0) {
ldout(cct, 3) << "getgroups failed!" << dendl;
return sgid_count;
@ -7823,43 +7832,36 @@ int Client::ll_statfs(Inode *in, struct statvfs *stbuf)
return statfs(0, stbuf);
}
void Client::ll_register_ino_invalidate_cb(client_ino_callback_t cb, void *handle)
void Client::ll_register_callbacks(struct client_callback_args *args)
{
Mutex::Locker l(client_lock);
ldout(cct, 10) << "ll_register_ino_invalidate_cb cb " << (void*)cb << " p " << (void*)handle << dendl;
if (cb == NULL)
if (!args)
return;
ino_invalidate_cb = cb;
ino_invalidate_cb_handle = handle;
async_ino_invalidator.start();
}
void Client::ll_register_dentry_invalidate_cb(client_dentry_callback_t cb, void *handle)
{
Mutex::Locker l(client_lock);
ldout(cct, 10) << "ll_register_dentry_invalidate_cb cb " << (void*)cb << " p " << (void*)handle << dendl;
if (cb == NULL)
return;
dentry_invalidate_cb = cb;
dentry_invalidate_cb_handle = handle;
async_dentry_invalidator.start();
}
void Client::ll_register_switch_interrupt_cb(client_switch_interrupt_callback_t cb)
{
Mutex::Locker l(client_lock);
ldout(cct, 10) << "ll_register_switch_interrupt_cb cb " << (void*)cb << dendl;
if (cb == NULL)
return;
switch_interrupt_cb = cb;
interrupt_finisher.start();
}
void Client::ll_register_getgroups_cb(client_getgroups_callback_t cb, void *handle)
{
Mutex::Locker l(client_lock);
getgroups_cb = cb;
getgroups_cb_handle = handle;
ldout(cct, 10) << "ll_register_callbacks cb " << args->handle
<< " invalidate_ino_cb " << args->ino_cb
<< " invalidate_dentry_cb " << args->dentry_cb
<< " getgroups_cb" << args->getgroups_cb
<< " switch_interrupt_cb " << args->switch_intr_cb
<< " remount_cb " << args->remount_cb
<< dendl;
callback_handle = args->handle;
if (args->ino_cb) {
ino_invalidate_cb = args->ino_cb;
async_ino_invalidator.start();
}
if (args->dentry_cb) {
dentry_invalidate_cb = args->dentry_cb;
async_dentry_invalidator.start();
}
if (args->switch_intr_cb) {
switch_interrupt_cb = args->switch_intr_cb;
interrupt_finisher.start();
}
if (args->remount_cb) {
remount_cb = args->remount_cb;
remount_finisher.start();
}
getgroups_cb = args->getgroups_cb;
}
int Client::_sync_fs()

View File

@ -136,10 +136,20 @@ typedef void (*client_ino_callback_t)(void *handle, vinodeno_t ino, int64_t off,
typedef void (*client_dentry_callback_t)(void *handle, vinodeno_t dirino,
vinodeno_t ino, string& name);
typedef void (*client_remount_callback_t)(void *handle);
typedef int (*client_getgroups_callback_t)(void *handle, uid_t uid, gid_t **sgids);
typedef void(*client_switch_interrupt_callback_t)(void *req, void *data);
struct client_callback_args {
void *handle;
client_ino_callback_t ino_cb;
client_dentry_callback_t dentry_cb;
client_switch_interrupt_callback_t switch_intr_cb;
client_remount_callback_t remount_cb;
client_getgroups_callback_t getgroups_cb;
};
// ========================================================
// client interface
@ -226,20 +236,17 @@ class Client : public Dispatcher {
SafeTimer timer;
void *callback_handle;
client_switch_interrupt_callback_t switch_interrupt_cb;
client_remount_callback_t remount_cb;
client_ino_callback_t ino_invalidate_cb;
void *ino_invalidate_cb_handle;
client_dentry_callback_t dentry_invalidate_cb;
void *dentry_invalidate_cb_handle;
client_getgroups_callback_t getgroups_cb;
void *getgroups_cb_handle;
Finisher async_ino_invalidator;
Finisher async_dentry_invalidator;
Finisher interrupt_finisher;
Finisher remount_finisher;
Finisher objecter_finisher;
Context *tick_event;
@ -434,7 +441,7 @@ protected:
void trim_cache_for_reconnect(MetaSession *s);
void trim_dentry(Dentry *dn);
void trim_caps(MetaSession *s, int max);
void _invalidate_kernel_dcache(MetaSession *s);
void _invalidate_kernel_dcache();
void dump_inode(Formatter *f, Inode *in, set<Inode*>& did, bool disconnected);
void dump_cache(Formatter *f); // debug
@ -946,10 +953,7 @@ public:
int ll_osdaddr(int osd, uint32_t *addr);
int ll_osdaddr(int osd, char* buf, size_t size);
void ll_register_ino_invalidate_cb(client_ino_callback_t cb, void *handle);
void ll_register_dentry_invalidate_cb(client_dentry_callback_t cb, void *handle);
void ll_register_getgroups_cb(client_getgroups_callback_t cb, void *handle);
void ll_register_switch_interrupt_cb(client_switch_interrupt_callback_t cb);
void ll_register_callbacks(struct client_callback_args *args);
};
#endif

View File

@ -757,6 +757,16 @@ static void dentry_invalidate_cb(void *handle, vinodeno_t dirino,
#endif
}
static void remount_cb(void *handle)
{
// used for trimming kernel dcache. when remounting a file system, linux kernel
// trims all unused dentries in the file system
char cmd[1024];
CephFuse::Handle *cfuse = (CephFuse::Handle *)handle;
snprintf(cmd, sizeof(cmd), "mount -i -o remount %s", cfuse->mountpoint);
system(cmd);
}
static void do_init(void *data, fuse_conn_info *bar)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)data;
@ -854,7 +864,7 @@ CephFuse::Handle::~Handle()
void CephFuse::Handle::finalize()
{
client->ll_register_ino_invalidate_cb(NULL, NULL);
client->ll_register_callbacks(NULL);
if (se)
fuse_remove_signal_handlers(se);
@ -940,25 +950,26 @@ int CephFuse::Handle::start()
fuse_session_add_chan(se, ch);
client->ll_register_switch_interrupt_cb(switch_interrupt_cb);
/*
* this is broken:
*
* - the cb needs the request handle to be useful; we should get the
* gids in the method here in fuse_ll.c and pass the gid list in,
* not use a callback.
* - the callback mallocs the list but it is not free()'d
*
* so disable it for now...
client->ll_register_getgroups_cb(getgroups_cb, this);
*/
client->ll_register_dentry_invalidate_cb(dentry_invalidate_cb, this);
if (client->cct->_conf->fuse_use_invalidate_cb)
client->ll_register_ino_invalidate_cb(ino_invalidate_cb, this);
struct client_callback_args args = {
handle: this,
ino_cb: client->cct->_conf->fuse_use_invalidate_cb ? ino_invalidate_cb : NULL,
dentry_cb: dentry_invalidate_cb,
switch_intr_cb: switch_interrupt_cb,
remount_cb: remount_cb,
/*
* this is broken:
*
* - the cb needs the request handle to be useful; we should get the
* gids in the method here in fuse_ll.c and pass the gid list in,
* not use a callback.
* - the callback mallocs the list but it is not free()'d
*
* so disable it for now...
getgroups_cb: getgroups_cb,
*/
};
client->ll_register_callbacks(&args);
return 0;
}

View File

@ -1280,12 +1280,16 @@ void PGMap::print_oneline_summary(Formatter *f, ostream *out) const
std::stringstream ss;
if (f)
f->open_object_section("num_pg_by_state");
f->open_array_section("num_pg_by_state");
for (ceph::unordered_map<int,int>::const_iterator p = num_pg_by_state.begin();
p != num_pg_by_state.end();
++p) {
if (f)
f->dump_unsigned(pg_state_string(p->first).c_str(), p->second);
if (f) {
f->open_object_section("state");
f->dump_string("name", pg_state_string(p->first));
f->dump_unsigned("num", p->second);
f->close_section();
}
if (p != num_pg_by_state.begin())
ss << ", ";
ss << p->second << " " << pg_state_string(p->first);