@@ -83,7 +83,6 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc,
{
struct ceph_inode_info *ci = NULL;
struct ceph_snap_realm *realm, *next;
- struct ceph_vino vino;
struct inode *in;
bool has_quota;
@@ -96,14 +95,8 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc,
else
pr_err_ratelimited("get_quota_realm: ino (%llx.%llx) "
"null i_snap_realm\n", ceph_vinop(inode));
- while (realm) {
- vino.ino = realm->ino;
- vino.snap = CEPH_NOSNAP;
- in = ceph_find_inode(inode->i_sb, vino);
- if (!in) {
- pr_warn("Failed to find inode for %llu\n", vino.ino);
- break;
- }
+ while (realm && realm->inode) {
+ in = igrab(realm->inode);
ci = ceph_inode(in);
has_quota = ceph_has_quota(ci);
iput(in);
@@ -161,7 +154,6 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op,
struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
struct ceph_inode_info *ci;
struct ceph_snap_realm *realm, *next;
- struct ceph_vino vino;
struct inode *in;
u64 max, rvalue;
bool exceeded = false;
@@ -176,14 +168,8 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op,
else
pr_err_ratelimited("check_quota_exceeded: ino (%llx.%llx) "
"null i_snap_realm\n", ceph_vinop(inode));
- while (realm) {
- vino.ino = realm->ino;
- vino.snap = CEPH_NOSNAP;
- in = ceph_find_inode(inode->i_sb, vino);
- if (!in) {
- pr_warn("Failed to find inode for %llu\n", vino.ino);
- break;
- }
+ while (realm && realm->inode) {
+ in = igrab(realm->inode);
ci = ceph_inode(in);
spin_lock(&ci->i_ceph_lock);
if (op == QUOTA_CHECK_MAX_FILES_OP) {
@@ -110,6 +110,7 @@ static struct ceph_snap_realm *ceph_create_snap_realm(
u64 ino)
{
struct ceph_snap_realm *realm;
+ struct ceph_vino vino;
realm = kzalloc(sizeof(*realm), GFP_NOFS);
if (!realm)
@@ -117,6 +118,14 @@ static struct ceph_snap_realm *ceph_create_snap_realm(
atomic_set(&realm->nref, 1); /* for caller */
realm->ino = ino;
+
+ /* cache a pointer to inode */
+ vino.ino = realm->ino;
+ vino.snap = CEPH_NOSNAP;
+ realm->inode = ceph_find_inode(mdsc->fsc->sb, vino);
+ if (realm->inode)
+ /* drop ref */
+ iput(realm->inode);
INIT_LIST_HEAD(&realm->children);
INIT_LIST_HEAD(&realm->child_item);
INIT_LIST_HEAD(&realm->empty_item);
@@ -754,6 +754,7 @@ struct ceph_readdir_cache_control {
*/
struct ceph_snap_realm {
u64 ino;
+ struct inode *inode;
atomic_t nref;
struct rb_node node;
Keep a pointer to the inode in struct ceph_snap_realm. This allows to optimize functions that walk the realms hierarchy (e.g. in quotas). Signed-off-by: Luis Henriques <lhenriques@suse.com> --- fs/ceph/quota.c | 22 ++++------------------ fs/ceph/snap.c | 9 +++++++++ fs/ceph/super.h | 1 + 3 files changed, 14 insertions(+), 18 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html