X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fquota%2Flproc_quota.c;h=1f2584f4516cf260fc3591dfe875fb81f681422a;hb=623b315f6ddf8aa6ef435aa405e371ba93d0454a;hp=9c655262461dc3af4556a9ca1b92058d889c06a2;hpb=294aa9cb666c48e02da1057c222fe5f206ce38fc;p=fs%2Flustre-release.git diff --git a/lustre/quota/lproc_quota.c b/lustre/quota/lproc_quota.c index 9c65526..1f2584f 100644 --- a/lustre/quota/lproc_quota.c +++ b/lustre/quota/lproc_quota.c @@ -21,7 +21,7 @@ * GPL HEADER END */ /* - * Copyright (c) 2012 Intel, Inc. + * Copyright (c) 2011, 2015, Intel Corporation. * Use is subject to license terms. * * Author: Johann Lombardi @@ -34,17 +34,18 @@ #include #include #include -#include - #include "lquota_internal.h" -#ifdef LPROCFS +#ifdef CONFIG_PROC_FS /* structure allocated at seq_open time and release when seq_release is called. * It is passed to seq_start/stop/next/show which can thus use the same lu_env * to be used with the iterator API */ struct lquota_procfs { - struct dt_object *lqp_obj; - struct lu_env lqp_env; + struct dt_object *lqp_obj; + struct lu_env lqp_env; + struct dt_it *lqp_it; + __u64 lqp_cookie; + __u64 lqp_first_cookie; }; /* global shared environment */ @@ -60,27 +61,20 @@ static void *lprocfs_quota_seq_start(struct seq_file *p, loff_t *pos) if (offset == 0) return SEQ_START_TOKEN; - offset--; if (lqp->lqp_obj == NULL) /* accounting not enabled. */ return NULL; - /* initialize iterator */ - iops = &lqp->lqp_obj->do_index_ops->dio_it; - it = iops->init(&lqp->lqp_env, lqp->lqp_obj, 0, BYPASS_CAPA); - if (IS_ERR(it)) { - CERROR("%s: failed to initialize iterator: rc = %ld\n", - lqp->lqp_obj->do_lu.lo_dev->ld_obd->obd_name, - PTR_ERR(it)); + if (lqp->lqp_it == NULL) /* reach the end */ return NULL; - } - /* move on to the first valid record */ - rc = iops->load(&lqp->lqp_env, it, 0); - if (rc < 0) { /* Error */ - goto not_found; - } else if (rc == 0) { + offset--; + /* move on to the the last processed entry */ + iops = &lqp->lqp_obj->do_index_ops->dio_it; + it = lqp->lqp_it; + rc = iops->load(&lqp->lqp_env, it, lqp->lqp_cookie); + if (rc == 0 && offset == 0) { /* * Iterator didn't find record with exactly the key requested. * @@ -94,17 +88,25 @@ static void *lprocfs_quota_seq_start(struct seq_file *p, loff_t *pos) rc = iops->next(&lqp->lqp_env, it); if (rc != 0) goto not_found; + lqp->lqp_cookie = iops->store(&lqp->lqp_env, it); + } else if (rc <= 0) { + goto not_found; } - while (offset--) { - rc = iops->next(&lqp->lqp_env, it); - if (rc != 0) /* Error or reach the end */ - goto not_found; - } + + /* The id entry could be deleted while iteration, and above ->load() + * operation will reset cursor to the first cookie (ldiskfs), we + * need to break in such situation. */ + if (offset == 0) + lqp->lqp_first_cookie = lqp->lqp_cookie; + else if (lqp->lqp_cookie == lqp->lqp_first_cookie) + goto not_found; + return it; not_found: iops->put(&lqp->lqp_env, it); iops->fini(&lqp->lqp_env, it); + lqp->lqp_it = NULL; return NULL; } @@ -122,7 +124,6 @@ static void lprocfs_quota_seq_stop(struct seq_file *p, void *v) /* if something wrong happened during ->seq_show, we need to release * the iterator here */ iops->put(&lqp->lqp_env, it); - iops->fini(&lqp->lqp_env, it); } static void *lprocfs_quota_seq_next(struct seq_file *p, void *v, loff_t *pos) @@ -141,12 +142,17 @@ static void *lprocfs_quota_seq_next(struct seq_file *p, void *v, loff_t *pos) if (v == SEQ_START_TOKEN) return lprocfs_quota_seq_start(p, pos); + if (lqp->lqp_it == NULL) /* reach the end */ + return NULL; + iops = &lqp->lqp_obj->do_index_ops->dio_it; it = (struct dt_it *)v; rc = iops->next(&lqp->lqp_env, it); - if (rc == 0) + if (rc == 0) { + lqp->lqp_cookie = iops->store(&lqp->lqp_env, it); return it; + } if (rc < 0) CERROR("%s: seq_next failed: rc = %d\n", @@ -155,6 +161,7 @@ static void *lprocfs_quota_seq_next(struct seq_file *p, void *v, loff_t *pos) /* Reach the end or error */ iops->put(&lqp->lqp_env, it); iops->fini(&lqp->lqp_env, it); + lqp->lqp_it = NULL; return NULL; } @@ -201,6 +208,9 @@ static int lprocfs_quota_seq_show(struct seq_file *p, void *v) seq_printf(p, "global_pool%d_%s_%s\n", poolid, RES_NAME(rtype), QTYPE_NAME(qtype)); + } else if (fid_seq(fid) == FID_SEQ_LOCAL_NAME) { + /* global index copy object */ + seq_printf(p, "global_index_copy:\n"); } else { return -ENOTSUPP; } @@ -227,13 +237,12 @@ static int lprocfs_quota_seq_show(struct seq_file *p, void *v) seq_printf(p, "- %-8s %llu\n", "id:", *((__u64 *)key)); if (fid_is_acct(fid)) - seq_printf(p, " %-8s { inodes: %20"LPF64"u, kbytes: %20"LPF64 - "u }\n", "usage:", + seq_printf(p, " %-8s { inodes: %20llu, kbytes: %20llu }\n", "usage:", ((struct lquota_acct_rec *)rec)->ispace, toqb(((struct lquota_acct_rec *)rec)->bspace)); - else if (fid_seq(fid) == FID_SEQ_QUOTA_GLB) - seq_printf(p, " %-8s { hard: %20"LPF64"u, soft: %20"LPF64 - "u, granted: %20"LPF64"u, time: %20"LPF64"u }\n", + else if (fid_seq(fid) == FID_SEQ_QUOTA_GLB || + fid_seq(fid) == FID_SEQ_LOCAL_NAME) + seq_printf(p, " %-8s { hard: %20llu, soft: %20llu, granted: %20llu, time: %20llu }\n", "limits:", ((struct lquota_glb_rec *)rec)->qbr_hardlimit, ((struct lquota_glb_rec *)rec)->qbr_softlimit, @@ -251,10 +260,11 @@ struct seq_operations lprocfs_quota_seq_sops = { static int lprocfs_quota_seq_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *dp = PDE(inode); struct seq_file *seq; int rc; struct lquota_procfs *lqp; + const struct dt_it_ops *iops; + struct dt_it *it; /* Allocate quota procfs data. This structure will be passed to * seq_start/stop/next/show via seq->private */ @@ -263,31 +273,47 @@ static int lprocfs_quota_seq_open(struct inode *inode, struct file *file) return -ENOMEM; /* store pointer to object we would like to iterate over */ - lqp->lqp_obj = (struct dt_object *)dp->data; + lqp->lqp_obj = (struct dt_object *)PDE_DATA(inode); /* Initialize the common environment to be used in the seq operations */ rc = lu_env_init(&lqp->lqp_env, LCT_LOCAL); if (rc) { + char *obd_name = "quota"; + + if (lqp->lqp_obj != NULL) + obd_name = lqp->lqp_obj->do_lu.lo_dev->ld_obd->obd_name; + CERROR("%s: error initializing procfs quota env: rc = %d\n", - lqp->lqp_obj->do_lu.lo_dev->ld_obd->obd_name, rc); + obd_name, rc); goto out_lqp; } - if (LPROCFS_ENTRY_AND_CHECK(dp)) { - rc = -ENOENT; + rc = LPROCFS_ENTRY_CHECK(inode); + if (rc < 0) goto out_env; - } rc = seq_open(file, &lprocfs_quota_seq_sops); if (rc) - goto out_lprocfs; + goto out_env; + + /* initialize iterator */ + iops = &lqp->lqp_obj->do_index_ops->dio_it; + it = iops->init(&lqp->lqp_env, lqp->lqp_obj, 0); + if (IS_ERR(it)) { + rc = PTR_ERR(it); + CERROR("%s: failed to initialize iterator: rc = %ld\n", + lqp->lqp_obj->do_lu.lo_dev->ld_obd->obd_name, + PTR_ERR(it)); + seq_release(inode, file); + goto out_env; + } + lqp->lqp_it = it; + lqp->lqp_cookie = 0; seq = file->private_data; seq->private = lqp; return 0; -out_lprocfs: - LPROCFS_EXIT(); out_env: lu_env_fini(&lqp->lqp_env); out_lqp: @@ -299,10 +325,12 @@ static int lprocfs_quota_seq_release(struct inode *inode, struct file *file) { struct seq_file *seq = file->private_data; struct lquota_procfs *lqp = seq->private; - - LPROCFS_EXIT(); + const struct dt_it_ops *iops; LASSERT(lqp); + iops = &lqp->lqp_obj->do_index_ops->dio_it; + if (lqp->lqp_it != NULL) + iops->fini(&lqp->lqp_env, lqp->lqp_it); lu_env_fini(&lqp->lqp_env); OBD_FREE_PTR(lqp); @@ -316,4 +344,4 @@ struct file_operations lprocfs_quota_seq_fops = { .llseek = seq_lseek, .release = lprocfs_quota_seq_release, }; -#endif /* LPROCFS */ +#endif /* CONFIG_PROC_FS */