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: Jeff Layton <jlayton@kernel.org> Reviewed-by: Luis Henriques <lhenriques@suse.de> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
Родитель
c80dc3aee9
Коммит
0ba92e1c5f
|
@ -704,23 +704,7 @@ void ceph_add_cap(struct inode *inode,
|
|||
struct ceph_snap_realm *realm = ceph_lookup_snap_realm(mdsc,
|
||||
realmino);
|
||||
if (realm) {
|
||||
struct ceph_snap_realm *oldrealm = ci->i_snap_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);
|
||||
ceph_change_snap_realm(inode, realm);
|
||||
} else {
|
||||
pr_err("ceph_add_cap: couldn't find snap realm %llx\n",
|
||||
realmino);
|
||||
|
@ -1112,20 +1096,6 @@ int ceph_is_any_caps(struct inode *inode)
|
|||
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.
|
||||
*
|
||||
|
@ -1201,7 +1171,7 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
|
|||
* keep 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);
|
||||
}
|
||||
|
@ -3084,7 +3054,7 @@ static void __ceph_put_cap_refs(struct ceph_inode_info *ci, int had,
|
|||
}
|
||||
/* see comment in __ceph_remove_cap() */
|
||||
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)) {
|
||||
|
|
|
@ -581,16 +581,9 @@ void ceph_evict_inode(struct inode *inode)
|
|||
*/
|
||||
if (ci->i_snap_realm) {
|
||||
if (ceph_snap(inode) == CEPH_NOSNAP) {
|
||||
struct ceph_snap_realm *realm = ci->i_snap_realm;
|
||||
dout(" dropping residual ref to snap realm %p\n",
|
||||
realm);
|
||||
spin_lock(&realm->inodes_with_caps_lock);
|
||||
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);
|
||||
ci->i_snap_realm);
|
||||
ceph_change_snap_realm(inode, NULL);
|
||||
} else {
|
||||
ceph_put_snapid_map(mdsc, ci->i_snapid_map);
|
||||
ci->i_snap_realm = NULL;
|
||||
|
|
|
@ -849,6 +849,43 @@ static void flush_snaps(struct ceph_mds_client *mdsc)
|
|||
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.
|
||||
|
@ -935,7 +972,6 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
|
|||
};
|
||||
struct inode *inode = ceph_find_inode(sb, vino);
|
||||
struct ceph_inode_info *ci;
|
||||
struct ceph_snap_realm *oldrealm;
|
||||
|
||||
if (!inode)
|
||||
continue;
|
||||
|
@ -960,27 +996,10 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
|
|||
}
|
||||
dout(" will move %p to split realm %llx %p\n",
|
||||
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_put_snap_realm(mdsc, oldrealm);
|
||||
|
||||
ceph_change_snap_realm(inode, realm);
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
iput(inode);
|
||||
continue;
|
||||
|
||||
|
|
|
@ -418,7 +418,6 @@ struct ceph_inode_info {
|
|||
struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */
|
||||
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_flush_item;
|
||||
struct timespec64 i_btime;
|
||||
|
@ -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,
|
||||
void *p, void *e, bool deletion,
|
||||
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,
|
||||
struct ceph_mds_session *session,
|
||||
struct ceph_msg *msg);
|
||||
|
|
Загрузка…
Ссылка в новой задаче