Whamcloud - gitweb
LU-891 test: waiting import state for next step.
[fs/lustre-release.git] / lustre / lvfs / lustre_quota_fmt_convert.c
index 70350ed..560d52b 100644 (file)
@@ -1,10 +1,42 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- * convert quota format.
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
  *
- *  from
- *  linux/fs/quota_v2.c
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/lvfs/lustre_quota_fmt_convert.c
+ *
+ * convert quota format.
+ * from linux/fs/quota_v2.c
  */
 
 #ifndef EXPORT_SYMTAB
@@ -18,7 +50,9 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/quotaio_v1.h>
+#ifdef HAVE_QUOTAIO_V1_H
+# include <linux/quotaio_v1.h>
+#endif
 
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
@@ -27,6 +61,8 @@
 #include <obd_support.h>
 #include "lustre_quota_fmt.h"
 
+#ifdef HAVE_QUOTA_SUPPORT
+
 static int admin_convert_dqinfo(struct file *fp_v1, struct file *fp_v2,
                                 struct lustre_quota_info *lqi, int type)
 {
@@ -51,7 +87,7 @@ static int admin_convert_dqinfo(struct file *fp_v1, struct file *fp_v2,
         return rc;
 }
 
-static int admin_convert_v1_to_v2(struct file *fp_v1, struct file *fp_v2,
+static int quota_convert_v1_to_v2(struct file *fp_v1, struct file *fp_v2,
                                   struct lustre_quota_info *lqi, int type)
 {
         struct list_head blk_list;
@@ -95,7 +131,9 @@ static int admin_convert_v1_to_v2(struct file *fp_v1, struct file *fp_v2,
                 struct lustre_disk_dqblk fakedquot;
 
                 memset(buf, 0, LUSTRE_DQBLKSIZE);
-                if ((ret = quota_read(fp_v1, NULL, type, blk_item->blk, buf))<0) {
+
+                if ((ret = lustre_read_quota(fp_v1, NULL, type, buf, LUSTRE_DQBLKSIZE,
+                                 blk_item->blk << LUSTRE_DQBLKSIZE_BITS)) < 0) {
                         CERROR("VFS: Can't read quota tree block %u.\n",
                                blk_item->blk);
                         GOTO(out_free, rc = ret);
@@ -158,7 +196,7 @@ int lustre_quota_convert(struct lustre_quota_info *lqi, int type)
         f_v1 = filp_open(name, O_RDONLY, 0);
         if (!IS_ERR(f_v1)) {
                 if (!check_quota_file(f_v1, NULL, type, LUSTRE_QUOTA_V1)) {
-                        rc = admin_convert_v1_to_v2(f_v1, f_v2, lqi, type);
+                        rc = quota_convert_v1_to_v2(f_v1, f_v2, lqi, type);
                         if (rc)
                                 CERROR("failed to convert v1 quota file"
                                        " to v2 quota file.\n");
@@ -181,5 +219,92 @@ int lustre_quota_convert(struct lustre_quota_info *lqi, int type)
 
         RETURN(rc);
 }
-
 EXPORT_SYMBOL(lustre_quota_convert);
+
+#ifdef HAVE_QUOTA64
+/*
+ * convert operational quota files to the requested version 
+ * returns: -ESTALE if upgrading to qfmt version is not supported
+ *          -ENOMEM if memory was not allocated for conv. structures
+ *
+ *          other error codes can be returned by VFS and have the
+ *          appropriate meaning
+ */
+int lustre_slave_quota_convert(lustre_quota_version_t qfmt, int type)
+{
+        struct lustre_quota_info *lqi;
+        struct file *f_v1, *f_v2;
+        const char *name[][MAXQUOTAS] = LUSTRE_OPQFILES_NAMES;
+        int rc;
+
+        ENTRY;
+
+        /* we convert only to v2 version */
+        if (qfmt != LUSTRE_QUOTA_V2)
+                GOTO(out, rc = -ESTALE);
+
+        OBD_ALLOC_PTR(lqi);
+        if (lqi == NULL)
+                GOTO(out, rc = -ENOMEM);
+
+        /* now that we support only v1 and v2 formats,
+         * only upgrade from v1 is possible,
+         * let's check if v1 file exists so that we convert it to v2 */
+        f_v1 = filp_open(name[LUSTRE_QUOTA_V1][type], O_RDONLY, 0);
+        if (IS_ERR(f_v1))
+                GOTO(out_free, rc = PTR_ERR(f_v1));
+
+        /* make sure it is really a v1 file */
+        if (check_quota_file(f_v1, NULL, type, LUSTRE_QUOTA_V1))
+                GOTO(out_f_v1, rc = -EINVAL);
+
+        /* create new quota file for v2 version, follow the same rationale as
+         * mds_admin_quota_on: if the file already exists, then do not try to
+         * overwrite it, user has to fix the quotaon issue manually,
+         * e.g. through running quotacheck                                  */
+        f_v2 = filp_open(name[LUSTRE_QUOTA_V2][type],
+                         O_CREAT | O_EXCL | O_TRUNC | O_RDWR, 0644);
+        if (IS_ERR(f_v2))
+                GOTO(out_f_v1, rc = PTR_ERR(f_v2));
+
+        lqi->qi_version = LUSTRE_QUOTA_V2;
+        lqi->qi_files[type] = f_v2;
+
+        /* initialize quota file with defaults, marking it invalid,
+         * this will help us not to get confused with partially converted
+         * operational quota files if we crash during conversion   */
+        rc = lustre_init_quota_info_generic(lqi, type, 1);
+        if (rc)
+                GOTO(out_f_v2, rc);
+
+        rc = quota_convert_v1_to_v2(f_v1, f_v2, lqi, type);
+        if (!rc) {
+                /* we dont want good magic to store before the quota data,
+                 * just to be safe if ldiskfs is running in writeback mode */
+                LOCK_INODE_MUTEX(f_v2->f_dentry->d_inode);
+                rc = lustre_fsync(f_v2);
+                if (rc)
+                        CERROR("error from fsync, rc=%d\n", rc);
+                UNLOCK_INODE_MUTEX(f_v2->f_dentry->d_inode);
+
+                /* now that conversion successfully finished we mark
+                 * this operational quota file with the correct magic,
+                 * since this moment quotaon will treat it as a correct
+                 * quota file */
+                rc = lustre_init_quota_header(lqi, type, 0);
+        }
+
+        EXIT;
+
+out_f_v2:
+        filp_close(f_v2, 0);
+out_f_v1:
+        filp_close(f_v1, 0);
+out_free:
+        OBD_FREE_PTR(lqi);
+out:
+        return rc;
+}
+EXPORT_SYMBOL(lustre_slave_quota_convert);
+#endif /* HAVE_QUOTA64 */
+#endif /* HAVE_QUOTA_SUPPORT */