Skip to content

Commit

Permalink
ceph: add helper function that forcibly reconnects to ceph cluster.
Browse files Browse the repository at this point in the history
It closes mds sessions, drop all caps and invalidates page caches,
then use new entity address to reconnect to the cluster.

After reconnect, all dirty data/metadata are dropped, file locks
get lost sliently. Open files continue to work because client will
try renewing caps on later read/write.

Signed-off-by: "Yan, Zheng" <[email protected]>
Reviewed-by: Jeff Layton <[email protected]>
Signed-off-by: Ilya Dryomov <[email protected]>
  • Loading branch information
ukernel authored and idryomov committed Sep 16, 2019
1 parent 5e3ded1 commit d468e72
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 5 deletions.
15 changes: 12 additions & 3 deletions fs/ceph/mds_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1394,9 +1394,12 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
struct ceph_cap_flush *cf;
struct ceph_mds_client *mdsc = fsc->mdsc;

if (ci->i_wrbuffer_ref > 0 &&
READ_ONCE(fsc->mount_state) == CEPH_MOUNT_SHUTDOWN)
invalidate = true;
if (READ_ONCE(fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
if (inode->i_data.nrpages > 0)
invalidate = true;
if (ci->i_wrbuffer_ref > 0)
mapping_set_error(&inode->i_data, -EIO);
}

while (!list_empty(&ci->i_cap_flush_list)) {
cf = list_first_entry(&ci->i_cap_flush_list,
Expand Down Expand Up @@ -4369,7 +4372,12 @@ void ceph_mdsc_force_umount(struct ceph_mds_client *mdsc)
session = __ceph_lookup_mds_session(mdsc, mds);
if (!session)
continue;

if (session->s_state == CEPH_MDS_SESSION_REJECTED)
__unregister_session(mdsc, session);
__wake_requests(mdsc, &session->s_waiting);
mutex_unlock(&mdsc->mutex);

mutex_lock(&session->s_mutex);
__close_session(mdsc, session);
if (session->s_state == CEPH_MDS_SESSION_CLOSING) {
Expand All @@ -4378,6 +4386,7 @@ void ceph_mdsc_force_umount(struct ceph_mds_client *mdsc)
}
mutex_unlock(&session->s_mutex);
ceph_put_mds_session(session);

mutex_lock(&mdsc->mutex);
kick_requests(mdsc, mds);
}
Expand Down
26 changes: 25 additions & 1 deletion fs/ceph/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,6 @@ static void ceph_umount_begin(struct super_block *sb)
fsc->mount_state = CEPH_MOUNT_SHUTDOWN;
ceph_osdc_abort_requests(&fsc->client->osdc, -EIO);
ceph_mdsc_force_umount(fsc->mdsc);
return;
}

static int ceph_remount(struct super_block *sb, int *flags, char *data)
Expand Down Expand Up @@ -1152,6 +1151,31 @@ static struct file_system_type ceph_fs_type = {
};
MODULE_ALIAS_FS("ceph");

int ceph_force_reconnect(struct super_block *sb)
{
struct ceph_fs_client *fsc = ceph_sb_to_client(sb);
int err = 0;

ceph_umount_begin(sb);

/* Make sure all page caches get invalidated.
* see remove_session_caps_cb() */
flush_workqueue(fsc->inode_wq);

/* In case that we were blacklisted. This also reset
* all mon/osd connections */
ceph_reset_client_addr(fsc->client);

ceph_osdc_clear_abort_err(&fsc->client->osdc);
fsc->mount_state = CEPH_MOUNT_MOUNTED;

if (sb->s_root) {
err = __ceph_do_getattr(d_inode(sb->s_root), NULL,
CEPH_STAT_CAP_INODE, true);
}
return err;
}

static int __init init_ceph(void)
{
int ret = init_caches();
Expand Down
3 changes: 2 additions & 1 deletion fs/ceph/super.h
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,8 @@ static inline int default_congestion_kb(void)
}



/* super.c */
extern int ceph_force_reconnect(struct super_block *sb);
/* snap.c */
struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc,
u64 ino);
Expand Down

0 comments on commit d468e72

Please sign in to comment.