Whamcloud - gitweb
make lustre_get_qids() support 2.6.12
authorniu <niu>
Fri, 23 Dec 2005 03:51:45 +0000 (03:51 +0000)
committerniu <niu>
Fri, 23 Dec 2005 03:51:45 +0000 (03:51 +0000)
b: 9812

lustre/include/linux/lustre_fsfilt.h
lustre/include/linux/lustre_quota.h
lustre/ldiskfs/lustre_quota_fmt.c
lustre/ldiskfs/quotafmt_test.c
lustre/lvfs/fsfilt_ext3.c
lustre/quota/quota_context.c
lustre/quota/quota_master.c

index 2358b86..34840d3 100644 (file)
@@ -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;
 }
 
index 3c5f547..c597b7a 100644 (file)
@@ -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
 
index 82bd9a6..15739f1 100644 (file)
@@ -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);
index 3b769b9..9dcbdcd 100644 (file)
@@ -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);
index e8dd5e0..6e56cb3 100644 (file)
@@ -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
 };
index 6d4123f..2c93975 100644 (file)
@@ -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);
 
index 101410a..768ec46 100644 (file)
@@ -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)