From: niu Date: Fri, 23 Dec 2005 03:51:45 +0000 (+0000) Subject: make lustre_get_qids() support 2.6.12 X-Git-Tag: v1_7_100~1^103~4^2~140 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=6c90f1fa716dcf135cc71a3d22dcbb513245b72e;p=fs%2Flustre-release.git make lustre_get_qids() support 2.6.12 b: 9812 --- diff --git a/lustre/include/linux/lustre_fsfilt.h b/lustre/include/linux/lustre_fsfilt.h index 2358b86..34840d3 100644 --- a/lustre/include/linux/lustre_fsfilt.h +++ b/lustre/include/linux/lustre_fsfilt.h @@ -97,7 +97,9 @@ struct fsfilt_operations { int (* fs_quotactl)(struct super_block *sb, struct obd_quotactl *oqctl); int (* fs_quotainfo)(struct lustre_quota_info *lqi, int type, - int cmd, struct list_head *list); + int cmd); + int (* fs_qids)(struct file *file, struct inode *inode, int type, + struct list_head *list); int (* fs_dquot)(struct lustre_dquot *dquot, int cmd); }; @@ -350,10 +352,19 @@ static inline int fsfilt_quotactl(struct obd_device *obd, static inline int fsfilt_quotainfo(struct obd_device *obd, struct lustre_quota_info *lqi, - int type, int cmd, struct list_head *list) + int type, int cmd) { if (obd->obd_fsops->fs_quotainfo) - return obd->obd_fsops->fs_quotainfo(lqi, type, cmd, list); + return obd->obd_fsops->fs_quotainfo(lqi, type, cmd); + return -ENOTSUPP; +} + +static inline int fsfilt_qids(struct obd_device *obd, struct file *file, + struct inode *inode, int type, + struct list_head *list) +{ + if (obd->obd_fsops->fs_qids) + return obd->obd_fsops->fs_qids(file, inode, type, list); return -ENOTSUPP; } diff --git a/lustre/include/linux/lustre_quota.h b/lustre/include/linux/lustre_quota.h index 3c5f5473..c597b7a 100644 --- a/lustre/include/linux/lustre_quota.h +++ b/lustre/include/linux/lustre_quota.h @@ -71,9 +71,8 @@ struct dquot_id { #define QFILE_RD_INFO 2 #define QFILE_WR_INFO 3 #define QFILE_INIT_INFO 4 -#define QFILE_GET_QIDS 5 -#define QFILE_RD_DQUOT 6 -#define QFILE_WR_DQUOT 7 +#define QFILE_RD_DQUOT 5 +#define QFILE_WR_DQUOT 6 /* admin quotafile operations */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) @@ -83,7 +82,7 @@ int lustre_write_quota_info(struct lustre_quota_info *lqi, int type); int lustre_read_dquot(struct lustre_dquot *dquot); int lustre_commit_dquot(struct lustre_dquot *dquot); int lustre_init_quota_info(struct lustre_quota_info *lqi, int type); -int lustre_get_qids(struct lustre_quota_info *lqi, int type, +int lustre_get_qids(struct file *file, struct inode *inode, int type, struct list_head *list); #else diff --git a/lustre/ldiskfs/lustre_quota_fmt.c b/lustre/ldiskfs/lustre_quota_fmt.c index 82bd9a6..15739f1 100644 --- a/lustre/ldiskfs/lustre_quota_fmt.c +++ b/lustre/ldiskfs/lustre_quota_fmt.c @@ -31,7 +31,7 @@ typedef char *dqbuf_t; #define GETIDINDEX(id, depth) (((id) >> ((LUSTRE_DQTREEDEPTH-(depth)-1)*8)) & 0xff) #define GETENTRIES(buf) ((struct lustre_disk_dqblk *)(((char *)buf)+sizeof(struct lustre_disk_dqdbheader))) -static int check_quota_file(struct file *f, int type) +static int check_quota_file(struct file *f, struct inode *inode, int type) { struct lustre_disk_dqheader dqhead; mm_segment_t fs; @@ -40,11 +40,22 @@ static int check_quota_file(struct file *f, int type) static const uint quota_magics[] = LUSTRE_INITQMAGICS; static const uint quota_versions[] = LUSTRE_INITQVERSIONS; - fs = get_fs(); - set_fs(KERNEL_DS); - size = f->f_op->read(f, (char *)&dqhead, - sizeof(struct lustre_disk_dqheader), &offset); - set_fs(fs); + if (f) { + fs = get_fs(); + set_fs(KERNEL_DS); + size = f->f_op->read(f, (char *)&dqhead, + sizeof(struct lustre_disk_dqheader), + &offset); + set_fs(fs); + } else { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) + size = 0; +#else + struct super_block *sb = inode->i_sb; + size = sb->s_op->quota_read(sb, type, (char *)&dqhead, + sizeof(struct lustre_disk_dqheader), 0); +#endif + } if (size != sizeof(struct lustre_disk_dqheader)) return 0; if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] || @@ -57,7 +68,7 @@ static int check_quota_file(struct file *f, int type) int lustre_check_quota_file(struct lustre_quota_info *lqi, int type) { struct file *f = lqi->qi_files[type]; - return check_quota_file(f, type); + return check_quota_file(f, NULL, type); } /* Read information header from quota file */ @@ -801,8 +812,26 @@ struct dqblk { uint blk; }; -static int walk_block_dqentry(struct file *filp, uint blk, - struct list_head *list) +static ssize_t quota_read(struct file *file, struct inode *inode, int type, + uint blk, dqbuf_t buf) +{ + if (file) { + return read_blk(file, blk, buf); + } else { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) + return -ENOTSUPP; +#else + struct super_block *sb = inode->i_sb; + memset(buf, 0, LUSTRE_DQBLKSIZE); + return sb->s_op->quota_read(sb, type, (char *)buf, + LUSTRE_DQBLKSIZE, + blk << LUSTRE_DQBLKSIZE_BITS); +#endif + } +} + +static int walk_block_dqentry(struct file *filp, struct inode *inode, int type, + uint blk, struct list_head *list) { dqbuf_t buf = getdqbuf(); loff_t ret = 0; @@ -814,7 +843,7 @@ static int walk_block_dqentry(struct file *filp, uint blk, if (!buf) return -ENOMEM; - if ((ret = read_blk(filp, blk, buf)) < 0) { + if ((ret = quota_read(filp, inode, type, blk, buf)) < 0) { printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); goto out_buf; } @@ -852,8 +881,8 @@ out_buf: return ret; } -static int walk_tree_dqentry(struct file *filp, uint blk, int depth, - struct list_head *list) +static int walk_tree_dqentry(struct file *filp, struct inode *inode, int type, + uint blk, int depth, struct list_head *list) { dqbuf_t buf = getdqbuf(); loff_t ret = 0; @@ -862,7 +891,7 @@ static int walk_tree_dqentry(struct file *filp, uint blk, int depth, if (!buf) return -ENOMEM; - if ((ret = read_blk(filp, blk, buf)) < 0) { + if ((ret = quota_read(filp, inode, type, blk, buf)) < 0) { printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); goto out_buf; } @@ -874,9 +903,10 @@ static int walk_tree_dqentry(struct file *filp, uint blk, int depth, continue; if (depth < LUSTRE_DQTREEDEPTH - 1) - ret = walk_tree_dqentry(filp, blk, depth + 1, list); + ret = walk_tree_dqentry(filp, inode, type, blk, + depth + 1, list); else - ret = walk_block_dqentry(filp, blk, list); + ret = walk_block_dqentry(filp, inode, type, blk, list); } out_buf: freedqbuf(buf); @@ -884,17 +914,16 @@ out_buf: } /* Walk through the quota file (v2 format) to get all ids with quota limit */ -int lustre_get_qids(struct lustre_quota_info *lqi, int type, +int lustre_get_qids(struct file *fp, struct inode *inode, int type, struct list_head *list) { - struct file *fp = lqi->qi_files[type]; struct list_head blk_list; struct dqblk *blk_item, *tmp; dqbuf_t buf = NULL; struct lustre_disk_dqblk *ddquot; int rc; - if (!check_quota_file(fp, type)) { + if (!check_quota_file(fp, inode, type)) { printk(KERN_ERR "unknown quota file format!\n"); return -EINVAL; } @@ -904,7 +933,7 @@ int lustre_get_qids(struct lustre_quota_info *lqi, int type, } INIT_LIST_HEAD(&blk_list); - rc = walk_tree_dqentry(fp, LUSTRE_DQTREEOFF, 0, &blk_list); + rc = walk_tree_dqentry(fp, inode, type, LUSTRE_DQTREEOFF, 0, &blk_list); if (rc) { printk(KERN_ERR "walk through quota file failed!(%d)\n", rc); goto out_free; @@ -923,7 +952,7 @@ int lustre_get_qids(struct lustre_quota_info *lqi, int type, struct lustre_disk_dqblk fakedquot; memset(buf, 0, LUSTRE_DQBLKSIZE); - if ((ret = read_blk(fp, blk_item->blk, buf)) < 0) { + if ((ret = quota_read(fp, inode, type, blk_item->blk, buf))<0) { printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk_item->blk); diff --git a/lustre/ldiskfs/quotafmt_test.c b/lustre/ldiskfs/quotafmt_test.c index 3b769b9..9dcbdcd 100644 --- a/lustre/ldiskfs/quotafmt_test.c +++ b/lustre/ldiskfs/quotafmt_test.c @@ -344,6 +344,7 @@ static int quotfmt_test_4(struct lustre_quota_info *lqi) static int quotfmt_test_5(struct lustre_quota_info *lqi) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) int i, rc = 0; for (i = USRQUOTA; i < MAXQUOTAS && !rc; i++) { @@ -351,7 +352,7 @@ static int quotfmt_test_5(struct lustre_quota_info *lqi) struct dquot_id *dqid, *tmp; INIT_LIST_HEAD(&list); - rc = lustre_get_qids(lqi, i, &list); + rc = lustre_get_qids(lqi->qi_files[i], NULL, i, &list); if (rc) { CERROR("%s get all %ss (rc:%d):\n", rc ? "error" : "success", @@ -366,6 +367,10 @@ static int quotfmt_test_5(struct lustre_quota_info *lqi) printk("\n"); } return rc; +#else + CWARN("kernel version >= 2.6.12, test skipped\n"); + return 0; +#endif } static int quotfmt_run_tests(struct obd_device *obd, struct obd_device *tgt) @@ -420,6 +425,7 @@ static int quotfmt_run_tests(struct obd_device *obd, struct obd_device *tgt) CERROR("walk through quota file failed\n"); GOTO(out, rc); } + out: CWARN("=== Finalize quotafile test\n"); rc = quotfmt_finalize(lqi, tgt, &saved); diff --git a/lustre/lvfs/fsfilt_ext3.c b/lustre/lvfs/fsfilt_ext3.c index e8dd5e0..6e56cb3 100644 --- a/lustre/lvfs/fsfilt_ext3.c +++ b/lustre/lvfs/fsfilt_ext3.c @@ -1731,7 +1731,6 @@ static int fsfilt_ext3_quotacheck(struct super_block *sb, struct ext3_sb_info *sbi = EXT3_SB(sb); int i, group; struct qchk_ctxt *qctxt; - struct lustre_quota_info *dummy = NULL; struct quota_info *dqopt = sb_dqopt(sb); struct buffer_head *bitmap_bh = NULL; unsigned long ino; @@ -1794,11 +1793,6 @@ static int fsfilt_ext3_quotacheck(struct super_block *sb, /* read old quota limits from old quota file. (only for the user * has limits but hasn't file) */ #ifdef HAVE_QUOTA_SUPPORT - OBD_ALLOC_PTR(dummy); - if (!dummy) { - CERROR("Not enough memory\n"); - GOTO(out, rc = -ENOMEM); - } for (i = 0; i < MAXQUOTAS; i++) { struct list_head id_list; struct dquot_id *dqid, *tmp; @@ -1808,21 +1802,24 @@ static int fsfilt_ext3_quotacheck(struct super_block *sb, if (qctxt->qckt_first_check[i]) continue; - - dummy->qi_files[i] = dqopt->files[i]; - LASSERT(dummy->qi_files[i] != NULL); + + LASSERT(dqopt->files[i] != NULL); INIT_LIST_HEAD(&id_list); - - rc = lustre_get_qids(dummy, i, &id_list); - if (rc) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) + rc = lustre_get_qids(dqopt->files[i], NULL, i, &id_list); +#else + rc = lustre_get_qids(NULL, dqopt->files[i], i, &id_list); +#endif + if (rc) CERROR("read old limits failed. (rc:%d)\n", rc); - break; - } + list_for_each_entry_safe(dqid, tmp, &id_list, di_link) { list_del_init(&dqid->di_link); - - cqget(sb, qctxt->qckt_hash, &qctxt->qckt_list, - dqid->di_id, i, qctxt->qckt_first_check[i]); + + if (!rc) + cqget(sb, qctxt->qckt_hash, &qctxt->qckt_list, + dqid->di_id, i, + qctxt->qckt_first_check[i]); kfree(dqid); } } @@ -1840,8 +1837,6 @@ out: /* dump and free chk_dqblk */ rc = prune_chkquots(sb, qctxt, rc); OBD_FREE_PTR(qctxt); - if (dummy) - OBD_FREE_PTR(dummy); /* turn off quota, `lfs quotacheck` will turn on when all * nodes quotacheck finish. */ @@ -1856,7 +1851,7 @@ out: #ifdef HAVE_QUOTA_SUPPORT static int fsfilt_ext3_quotainfo(struct lustre_quota_info *lqi, int type, - int cmd, struct list_head *list) + int cmd) { int rc = 0; ENTRY; @@ -1879,9 +1874,6 @@ static int fsfilt_ext3_quotainfo(struct lustre_quota_info *lqi, int type, case QFILE_INIT_INFO: rc = lustre_init_quota_info(lqi, type); break; - case QFILE_GET_QIDS: - rc = lustre_get_qids(lqi, type, list); - break; default: CERROR("Unsupported admin quota file cmd %d\n", cmd); LBUG(); @@ -1890,6 +1882,12 @@ static int fsfilt_ext3_quotainfo(struct lustre_quota_info *lqi, int type, RETURN(rc); } +static int fsfilt_ext3_qids(struct file *file, struct inode *inode, int type, + struct list_head *list) +{ + return lustre_get_qids(file, inode, type, list); +} + static int fsfilt_ext3_dquot(struct lustre_dquot *dquot, int cmd) { int rc = 0; @@ -1955,6 +1953,7 @@ static struct fsfilt_operations fsfilt_ext3_ops = { .fs_quotacheck = fsfilt_ext3_quotacheck, #ifdef HAVE_QUOTA_SUPPORT .fs_quotainfo = fsfilt_ext3_quotainfo, + .fs_qids = fsfilt_ext3_qids, .fs_dquot = fsfilt_ext3_dquot, #endif }; diff --git a/lustre/quota/quota_context.c b/lustre/quota/quota_context.c index 6d4123f..2c93975 100644 --- a/lustre/quota/quota_context.c +++ b/lustre/quota/quota_context.c @@ -709,32 +709,24 @@ static int qslave_recovery_main(void *arg) for (type = USRQUOTA; type < MAXQUOTAS; type++) { struct qunit_data qdata; struct quota_info *dqopt = sb_dqopt(qctxt->lqc_sb); - struct lustre_quota_info *dummy; struct list_head id_list; struct dquot_id *dqid, *tmp; int ret; - OBD_ALLOC_PTR(dummy); - if (!dummy) { - CERROR("Not enough memory\n"); - rc = -ENOMEM; - break; - } - down(&dqopt->dqonoff_sem); if (!sb_has_quota_enabled(qctxt->lqc_sb, type)) { up(&dqopt->dqonoff_sem); - OBD_FREE_PTR(dummy); break; } - dummy->qi_files[type] = dqopt->files[type]; - LASSERT(dummy->qi_files[type] != NULL); - INIT_LIST_HEAD(&id_list); - rc = fsfilt_quotainfo(obd, dummy, type, QFILE_GET_QIDS, &id_list); + LASSERT(dqopt->files[type] != NULL); + INIT_LIST_HEAD(&id_list); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) + rc = fsfilt_qids(obd, dqopt->files[type], NULL, type, &id_list); +#else + rc = fsfilt_qids(obd, NULL, dqopt->files[type], type, &id_list); +#endif up(&dqopt->dqonoff_sem); - - OBD_FREE_PTR(dummy); if (rc) CERROR("Get ids from quota file failed. (rc:%d)\n", rc); diff --git a/lustre/quota/quota_master.c b/lustre/quota/quota_master.c index 101410a..768ec46 100644 --- a/lustre/quota/quota_master.c +++ b/lustre/quota/quota_master.c @@ -430,7 +430,7 @@ int init_admin_quotafiles(struct obd_device *obd, struct obd_quotactl *oqctl) } qinfo->qi_files[i] = fp; - rc = fsfilt_quotainfo(obd, qinfo, i, QFILE_INIT_INFO, NULL); + rc = fsfilt_quotainfo(obd, qinfo, i, QFILE_INIT_INFO); filp_close(fp, 0); qinfo->qi_files[i] = NULL; @@ -500,7 +500,7 @@ int mds_admin_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl) } qinfo->qi_files[i] = fp; - rc = fsfilt_quotainfo(obd, qinfo, i, QFILE_RD_INFO, NULL); + rc = fsfilt_quotainfo(obd, qinfo, i, QFILE_RD_INFO); if (rc) { CERROR("error read quotainfo of %s! (rc:%d)\n", name, rc); @@ -589,7 +589,7 @@ int mds_set_dqinfo(struct obd_device *obd, struct obd_quotactl *oqctl) qinfo->qi_info[oqctl->qc_type].dqi_igrace = dqinfo->dqi_igrace; qinfo->qi_info[oqctl->qc_type].dqi_flags = dqinfo->dqi_flags; - rc = fsfilt_quotainfo(obd, qinfo, oqctl->qc_type, QFILE_WR_INFO, NULL); + rc = fsfilt_quotainfo(obd, qinfo, oqctl->qc_type, QFILE_WR_INFO); out: up(&mds->mds_qonoff_sem); @@ -1042,8 +1042,8 @@ static int qmaster_recovery_main(void *arg) continue; } INIT_LIST_HEAD(&id_list); - rc = fsfilt_quotainfo(obd, qinfo, type, QFILE_GET_QIDS, - &id_list); + rc = fsfilt_qids(obd, qinfo->qi_files[type], NULL, type, + &id_list); up(&mds->mds_qonoff_sem); if (rc)