
From: Jan Kara <jack@suse.cz>


I'm sending you a patch which implements autoloading of quota modules.  The
patch should apply well against all recent kernels.



 fs/dquot.c            |   17 +++++++++++++++--
 include/linux/quota.h |   10 ++++++++++
 2 files changed, 25 insertions(+), 2 deletions(-)

diff -puN fs/dquot.c~quota-autoloading fs/dquot.c
--- 25/fs/dquot.c~quota-autoloading	2003-07-04 19:29:30.000000000 -0700
+++ 25-akpm/fs/dquot.c	2003-07-04 19:29:30.000000000 -0700
@@ -74,6 +74,7 @@
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/security.h>
+#include <linux/kmod.h>
 
 #include <asm/uaccess.h>
 
@@ -96,6 +97,7 @@ spinlock_t dq_data_lock = SPIN_LOCK_UNLO
 
 static char *quotatypes[] = INITQFNAMES;
 static struct quota_format_type *quota_formats;	/* List of registered formats */
+static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES;
 
 int register_quota_format(struct quota_format_type *fmt)
 {
@@ -123,8 +125,19 @@ static struct quota_format_type *find_qu
 
 	spin_lock(&dq_list_lock);
 	for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next);
-	if (actqf && !try_module_get(actqf->qf_owner))
-		actqf = NULL;
+	if (!actqf || !try_module_get(actqf->qf_owner)) {
+		int qm;
+
+		for (qm = 0; module_names[qm].qm_fmt_id && module_names[qm].qm_fmt_id != id; qm++);
+		if (!module_names[qm].qm_fmt_id || request_module(module_names[qm].qm_mod_name)) {
+			actqf = NULL;
+			goto out;
+		}
+		for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next);
+		if (actqf && !try_module_get(actqf->qf_owner))
+			actqf = NULL;
+	}
+out:
 	spin_unlock(&dq_list_lock);
 	return actqf;
 }
diff -puN include/linux/quota.h~quota-autoloading include/linux/quota.h
--- 25/include/linux/quota.h~quota-autoloading	2003-07-04 19:29:30.000000000 -0700
+++ 25-akpm/include/linux/quota.h	2003-07-04 19:29:30.000000000 -0700
@@ -306,6 +306,16 @@ int register_quota_format(struct quota_f
 void unregister_quota_format(struct quota_format_type *fmt);
 void init_dquot_operations(struct dquot_operations *fsdqops);
 
+struct quota_module_name {
+	int qm_fmt_id;
+	char *qm_mod_name;
+};
+
+#define INIT_QUOTA_MODULE_NAMES {\
+	{QFMT_VFS_OLD, "quota_v1"},\
+	{QFMT_VFS_V0, "quota_v2"},\
+	{0, NULL}}
+
 #else
 
 # /* nodep */ include <sys/cdefs.h>

_
