Commit 0ba92e1c authored by Jeff Layton's avatar Jeff Layton Committed by Ilya Dryomov

ceph: add ceph_change_snap_realm() helper

Consolidate some fiddly code for changing an inode's snap_realm
into a new helper function, and change the callers to use it.

While we're in here, nothing uses the i_snap_realm_counter field, so
remove that from the inode.
Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
Reviewed-by: default avatarLuis Henriques <lhenriques@suse.de>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent c80dc3ae
...@@ -704,23 +704,7 @@ void ceph_add_cap(struct inode *inode, ...@@ -704,23 +704,7 @@ void ceph_add_cap(struct inode *inode,
struct ceph_snap_realm *realm = ceph_lookup_snap_realm(mdsc, struct ceph_snap_realm *realm = ceph_lookup_snap_realm(mdsc,
realmino); realmino);
if (realm) { if (realm) {
struct ceph_snap_realm *oldrealm = ci->i_snap_realm; ceph_change_snap_realm(inode, realm);
if (oldrealm) {
spin_lock(&oldrealm->inodes_with_caps_lock);
list_del_init(&ci->i_snap_realm_item);
spin_unlock(&oldrealm->inodes_with_caps_lock);
}
spin_lock(&realm->inodes_with_caps_lock);
list_add(&ci->i_snap_realm_item,
&realm->inodes_with_caps);
ci->i_snap_realm = realm;
if (realm->ino == ci->i_vino.ino)
realm->inode = inode;
spin_unlock(&realm->inodes_with_caps_lock);
if (oldrealm)
ceph_put_snap_realm(mdsc, oldrealm);
} else { } else {
pr_err("ceph_add_cap: couldn't find snap realm %llx\n", pr_err("ceph_add_cap: couldn't find snap realm %llx\n",
realmino); realmino);
...@@ -1112,20 +1096,6 @@ int ceph_is_any_caps(struct inode *inode) ...@@ -1112,20 +1096,6 @@ int ceph_is_any_caps(struct inode *inode)
return ret; return ret;
} }
static void drop_inode_snap_realm(struct ceph_inode_info *ci)
{
struct ceph_snap_realm *realm = ci->i_snap_realm;
spin_lock(&realm->inodes_with_caps_lock);
list_del_init(&ci->i_snap_realm_item);
ci->i_snap_realm_counter++;
ci->i_snap_realm = NULL;
if (realm->ino == ci->i_vino.ino)
realm->inode = NULL;
spin_unlock(&realm->inodes_with_caps_lock);
ceph_put_snap_realm(ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc,
realm);
}
/* /*
* Remove a cap. Take steps to deal with a racing iterate_session_caps. * Remove a cap. Take steps to deal with a racing iterate_session_caps.
* *
...@@ -1201,7 +1171,7 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release) ...@@ -1201,7 +1171,7 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
* keep i_snap_realm. * keep i_snap_realm.
*/ */
if (ci->i_wr_ref == 0 && ci->i_snap_realm) if (ci->i_wr_ref == 0 && ci->i_snap_realm)
drop_inode_snap_realm(ci); ceph_change_snap_realm(&ci->vfs_inode, NULL);
__cap_delay_cancel(mdsc, ci); __cap_delay_cancel(mdsc, ci);
} }
...@@ -3084,7 +3054,7 @@ static void __ceph_put_cap_refs(struct ceph_inode_info *ci, int had, ...@@ -3084,7 +3054,7 @@ static void __ceph_put_cap_refs(struct ceph_inode_info *ci, int had,
} }
/* see comment in __ceph_remove_cap() */ /* see comment in __ceph_remove_cap() */
if (!__ceph_is_any_real_caps(ci) && ci->i_snap_realm) if (!__ceph_is_any_real_caps(ci) && ci->i_snap_realm)
drop_inode_snap_realm(ci); ceph_change_snap_realm(inode, NULL);
} }
} }
if (check_flushsnaps && __ceph_have_pending_cap_snap(ci)) { if (check_flushsnaps && __ceph_have_pending_cap_snap(ci)) {
......
...@@ -581,16 +581,9 @@ void ceph_evict_inode(struct inode *inode) ...@@ -581,16 +581,9 @@ void ceph_evict_inode(struct inode *inode)
*/ */
if (ci->i_snap_realm) { if (ci->i_snap_realm) {
if (ceph_snap(inode) == CEPH_NOSNAP) { if (ceph_snap(inode) == CEPH_NOSNAP) {
struct ceph_snap_realm *realm = ci->i_snap_realm;
dout(" dropping residual ref to snap realm %p\n", dout(" dropping residual ref to snap realm %p\n",
realm); ci->i_snap_realm);
spin_lock(&realm->inodes_with_caps_lock); ceph_change_snap_realm(inode, NULL);
list_del_init(&ci->i_snap_realm_item);
ci->i_snap_realm = NULL;
if (realm->ino == ci->i_vino.ino)
realm->inode = NULL;
spin_unlock(&realm->inodes_with_caps_lock);
ceph_put_snap_realm(mdsc, realm);
} else { } else {
ceph_put_snapid_map(mdsc, ci->i_snapid_map); ceph_put_snapid_map(mdsc, ci->i_snapid_map);
ci->i_snap_realm = NULL; ci->i_snap_realm = NULL;
......
...@@ -849,6 +849,43 @@ static void flush_snaps(struct ceph_mds_client *mdsc) ...@@ -849,6 +849,43 @@ static void flush_snaps(struct ceph_mds_client *mdsc)
dout("flush_snaps done\n"); dout("flush_snaps done\n");
} }
/**
* ceph_change_snap_realm - change the snap_realm for an inode
* @inode: inode to move to new snap realm
* @realm: new realm to move inode into (may be NULL)
*
* Detach an inode from its old snaprealm (if any) and attach it to
* the new snaprealm (if any). The old snap realm reference held by
* the inode is put. If realm is non-NULL, then the caller's reference
* to it is taken over by the inode.
*/
void ceph_change_snap_realm(struct inode *inode, struct ceph_snap_realm *realm)
{
struct ceph_inode_info *ci = ceph_inode(inode);
struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
struct ceph_snap_realm *oldrealm = ci->i_snap_realm;
lockdep_assert_held(&ci->i_ceph_lock);
if (oldrealm) {
spin_lock(&oldrealm->inodes_with_caps_lock);
list_del_init(&ci->i_snap_realm_item);
if (oldrealm->ino == ci->i_vino.ino)
oldrealm->inode = NULL;
spin_unlock(&oldrealm->inodes_with_caps_lock);
ceph_put_snap_realm(mdsc, oldrealm);
}
ci->i_snap_realm = realm;
if (realm) {
spin_lock(&realm->inodes_with_caps_lock);
list_add(&ci->i_snap_realm_item, &realm->inodes_with_caps);
if (realm->ino == ci->i_vino.ino)
realm->inode = inode;
spin_unlock(&realm->inodes_with_caps_lock);
}
}
/* /*
* Handle a snap notification from the MDS. * Handle a snap notification from the MDS.
...@@ -935,7 +972,6 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, ...@@ -935,7 +972,6 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
}; };
struct inode *inode = ceph_find_inode(sb, vino); struct inode *inode = ceph_find_inode(sb, vino);
struct ceph_inode_info *ci; struct ceph_inode_info *ci;
struct ceph_snap_realm *oldrealm;
if (!inode) if (!inode)
continue; continue;
...@@ -960,27 +996,10 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, ...@@ -960,27 +996,10 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
} }
dout(" will move %p to split realm %llx %p\n", dout(" will move %p to split realm %llx %p\n",
inode, realm->ino, realm); inode, realm->ino, realm);
/*
* Move the inode to the new realm
*/
oldrealm = ci->i_snap_realm;
spin_lock(&oldrealm->inodes_with_caps_lock);
list_del_init(&ci->i_snap_realm_item);
spin_unlock(&oldrealm->inodes_with_caps_lock);
spin_lock(&realm->inodes_with_caps_lock);
list_add(&ci->i_snap_realm_item,
&realm->inodes_with_caps);
ci->i_snap_realm = realm;
if (realm->ino == ci->i_vino.ino)
realm->inode = inode;
spin_unlock(&realm->inodes_with_caps_lock);
spin_unlock(&ci->i_ceph_lock);
ceph_get_snap_realm(mdsc, realm); ceph_get_snap_realm(mdsc, realm);
ceph_put_snap_realm(mdsc, oldrealm); ceph_change_snap_realm(inode, realm);
spin_unlock(&ci->i_ceph_lock);
iput(inode); iput(inode);
continue; continue;
......
...@@ -418,7 +418,6 @@ struct ceph_inode_info { ...@@ -418,7 +418,6 @@ struct ceph_inode_info {
struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */ struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */
struct ceph_snapid_map *i_snapid_map; /* snapid -> dev_t */ struct ceph_snapid_map *i_snapid_map; /* snapid -> dev_t */
}; };
int i_snap_realm_counter; /* snap realm (if caps) */
struct list_head i_snap_realm_item; struct list_head i_snap_realm_item;
struct list_head i_snap_flush_item; struct list_head i_snap_flush_item;
struct timespec64 i_btime; struct timespec64 i_btime;
...@@ -929,6 +928,7 @@ extern void ceph_put_snap_realm(struct ceph_mds_client *mdsc, ...@@ -929,6 +928,7 @@ extern void ceph_put_snap_realm(struct ceph_mds_client *mdsc,
extern int ceph_update_snap_trace(struct ceph_mds_client *m, extern int ceph_update_snap_trace(struct ceph_mds_client *m,
void *p, void *e, bool deletion, void *p, void *e, bool deletion,
struct ceph_snap_realm **realm_ret); struct ceph_snap_realm **realm_ret);
void ceph_change_snap_realm(struct inode *inode, struct ceph_snap_realm *realm);
extern void ceph_handle_snap(struct ceph_mds_client *mdsc, extern void ceph_handle_snap(struct ceph_mds_client *mdsc,
struct ceph_mds_session *session, struct ceph_mds_session *session,
struct ceph_msg *msg); struct ceph_msg *msg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment