VFS: Export dquot_send_warning
[linux-2.6.git] / fs / quota / dquot.c
index 4a37b8e..9b6ad90 100644 (file)
 #include <linux/capability.h>
 #include <linux/quotaops.h>
 #include <linux/writeback.h> /* for inode_lock, oddly enough.. */
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-#include <net/netlink.h>
-#include <net/genetlink.h>
-#endif
 
 #include <asm/uaccess.h>
 
@@ -156,7 +152,9 @@ void unregister_quota_format(struct quota_format_type *fmt)
        struct quota_format_type **actqf;
 
        spin_lock(&dq_list_lock);
-       for (actqf = &quota_formats; *actqf && *actqf != fmt; actqf = &(*actqf)->qf_next);
+       for (actqf = &quota_formats; *actqf && *actqf != fmt;
+            actqf = &(*actqf)->qf_next)
+               ;
        if (*actqf)
                *actqf = (*actqf)->qf_next;
        spin_unlock(&dq_list_lock);
@@ -168,18 +166,25 @@ static struct quota_format_type *find_quota_format(int id)
        struct quota_format_type *actqf;
 
        spin_lock(&dq_list_lock);
-       for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next);
+       for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id;
+            actqf = actqf->qf_next)
+               ;
        if (!actqf || !try_module_get(actqf->qf_owner)) {
                int qm;
 
                spin_unlock(&dq_list_lock);
                
-               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))
+               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))
                        return NULL;
 
                spin_lock(&dq_list_lock);
-               for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next);
+               for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id;
+                    actqf = actqf->qf_next)
+                       ;
                if (actqf && !try_module_get(actqf->qf_owner))
                        actqf = NULL;
        }
@@ -234,7 +239,8 @@ hashfn(const struct super_block *sb, unsigned int id, int type)
  */
 static inline void insert_dquot_hash(struct dquot *dquot)
 {
-       struct hlist_head *head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
+       struct hlist_head *head;
+       head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
        hlist_add_head(&dquot->dq_hash, head);
 }
 
@@ -251,7 +257,8 @@ static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb,
 
        hlist_for_each (node, dquot_hash+hashent) {
                dquot = hlist_entry(node, struct dquot, dq_hash);
-               if (dquot->dq_sb == sb && dquot->dq_id == id && dquot->dq_type == type)
+               if (dquot->dq_sb == sb && dquot->dq_id == id &&
+                   dquot->dq_type == type)
                        return dquot;
        }
        return NULL;
@@ -351,8 +358,10 @@ int dquot_acquire(struct dquot *dquot)
        if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
                ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
                /* Write the info if needed */
-               if (info_dirty(&dqopt->info[dquot->dq_type]))
-                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
+               if (info_dirty(&dqopt->info[dquot->dq_type])) {
+                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(
+                                               dquot->dq_sb, dquot->dq_type);
+               }
                if (ret < 0)
                        goto out_iolock;
                if (ret2 < 0) {
@@ -387,8 +396,10 @@ int dquot_commit(struct dquot *dquot)
         * => we have better not writing it */
        if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
                ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
-               if (info_dirty(&dqopt->info[dquot->dq_type]))
-                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
+               if (info_dirty(&dqopt->info[dquot->dq_type])) {
+                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(
+                                               dquot->dq_sb, dquot->dq_type);
+               }
                if (ret >= 0)
                        ret = ret2;
        }
@@ -414,8 +425,10 @@ int dquot_release(struct dquot *dquot)
        if (dqopt->ops[dquot->dq_type]->release_dqblk) {
                ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);
                /* Write the info */
-               if (info_dirty(&dqopt->info[dquot->dq_type]))
-                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
+               if (info_dirty(&dqopt->info[dquot->dq_type])) {
+                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(
+                                               dquot->dq_sb, dquot->dq_type);
+               }
                if (ret >= 0)
                        ret = ret2;
        }
@@ -543,7 +556,8 @@ int vfs_quota_sync(struct super_block *sb, int type)
                spin_lock(&dq_list_lock);
                dirty = &dqopt->info[cnt].dqi_dirty_list;
                while (!list_empty(dirty)) {
-                       dquot = list_first_entry(dirty, struct dquot, dq_dirty);
+                       dquot = list_first_entry(dirty, struct dquot,
+                                                dq_dirty);
                        /* Dirty and inactive can be only bad dquot... */
                        if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
                                clear_dquot_dirty(dquot);
@@ -763,11 +777,12 @@ we_slept:
                dqstats.lookups++;
                spin_unlock(&dq_list_lock);
        }
-       /* Wait for dq_lock - after this we know that either dquot_release() is already
-        * finished or it will be canceled due to dq_count > 1 test */
+       /* Wait for dq_lock - after this we know that either dquot_release() is
+        * already finished or it will be canceled due to dq_count > 1 test */
        wait_on_dquot(dquot);
-       /* Read the dquot and instantiate it (everything done only if needed) */
-       if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) {
+       /* Read the dquot / allocate space in quota file */
+       if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) &&
+           sb->dq_op->acquire_dquot(dquot) < 0) {
                dqput(dquot);
                dquot = NULL;
                goto out;
@@ -804,12 +819,12 @@ static void add_dquot_ref(struct super_block *sb, int type)
 
        spin_lock(&inode_lock);
        list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
+               if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW))
+                       continue;
                if (!atomic_read(&inode->i_writecount))
                        continue;
                if (!dqinit_needed(inode, type))
                        continue;
-               if (inode->i_state & (I_FREEING|I_WILL_FREE))
-                       continue;
 
                __iget(inode);
                spin_unlock(&inode_lock);
@@ -828,7 +843,10 @@ static void add_dquot_ref(struct super_block *sb, int type)
        iput(old_inode);
 }
 
-/* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */
+/*
+ * Return 0 if dqput() won't block.
+ * (note that 1 doesn't necessarily mean blocking)
+ */
 static inline int dqput_blocks(struct dquot *dquot)
 {
        if (atomic_read(&dquot->dq_count) <= 1)
@@ -836,8 +854,11 @@ static inline int dqput_blocks(struct dquot *dquot)
        return 0;
 }
 
-/* Remove references to dquots from inode - add dquot to list for freeing if needed */
-/* We can't race with anybody because we hold dqptr_sem for writing... */
+/*
+ * Remove references to dquots from inode and add dquot to list for freeing
+ * if we have the last referece to dquot
+ * We can't race with anybody because we hold dqptr_sem for writing...
+ */
 static int remove_inode_dquot_ref(struct inode *inode, int type,
                                  struct list_head *tofree_head)
 {
@@ -851,7 +872,9 @@ static int remove_inode_dquot_ref(struct inode *inode, int type,
                                printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count));
 #endif
                        spin_lock(&dq_list_lock);
-                       list_add(&dquot->dq_free, tofree_head); /* As dquot must have currently users it can't be on the free list... */
+                       /* As dquot must have currently users it can't be on
+                        * the free list... */
+                       list_add(&dquot->dq_free, tofree_head);
                        spin_unlock(&dq_list_lock);
                        return 1;
                }
@@ -861,19 +884,22 @@ static int remove_inode_dquot_ref(struct inode *inode, int type,
        return 0;
 }
 
-/* Free list of dquots - called from inode.c */
-/* dquots are removed from inodes, no new references can be got so we are the only ones holding reference */
+/*
+ * Free list of dquots
+ * Dquots are removed from inodes and no new references can be got so we are
+ * the only ones holding reference
+ */
 static void put_dquot_list(struct list_head *tofree_head)
 {
        struct list_head *act_head;
        struct dquot *dquot;
 
        act_head = tofree_head->next;
-       /* So now we have dquots on the list... Just free them */
        while (act_head != tofree_head) {
                dquot = list_entry(act_head, struct dquot, dq_free);
                act_head = act_head->next;
-               list_del_init(&dquot->dq_free); /* Remove dquot from the list so we won't have problems... */
+               /* Remove dquot from the list so we won't have problems... */
+               list_del_init(&dquot->dq_free);
                dqput(dquot);
        }
 }
@@ -885,6 +911,12 @@ static void remove_dquot_ref(struct super_block *sb, int type,
 
        spin_lock(&inode_lock);
        list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
+               /*
+                *  We have to scan also I_NEW inodes because they can already
+                *  have quota pointer initialized. Luckily, we need to touch
+                *  only quota pointers and these have separate locking
+                *  (dqptr_sem).
+                */
                if (!IS_NOQUOTA(inode))
                        remove_inode_dquot_ref(inode, type, tofree_head);
        }
@@ -1035,76 +1067,6 @@ static void print_warning(struct dquot *dquot, const int warntype)
 }
 #endif
 
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-
-/* Netlink family structure for quota */
-static struct genl_family quota_genl_family = {
-       .id = GENL_ID_GENERATE,
-       .hdrsize = 0,
-       .name = "VFS_DQUOT",
-       .version = 1,
-       .maxattr = QUOTA_NL_A_MAX,
-};
-
-/* Send warning to userspace about user which exceeded quota */
-static void send_warning(const struct dquot *dquot, const char warntype)
-{
-       static atomic_t seq;
-       struct sk_buff *skb;
-       void *msg_head;
-       int ret;
-       int msg_size = 4 * nla_total_size(sizeof(u32)) +
-                      2 * nla_total_size(sizeof(u64));
-
-       /* We have to allocate using GFP_NOFS as we are called from a
-        * filesystem performing write and thus further recursion into
-        * the fs to free some data could cause deadlocks. */
-       skb = genlmsg_new(msg_size, GFP_NOFS);
-       if (!skb) {
-               printk(KERN_ERR
-                 "VFS: Not enough memory to send quota warning.\n");
-               return;
-       }
-       msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
-                       &quota_genl_family, 0, QUOTA_NL_C_WARNING);
-       if (!msg_head) {
-               printk(KERN_ERR
-                 "VFS: Cannot store netlink header in quota warning.\n");
-               goto err_out;
-       }
-       ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, dquot->dq_type);
-       if (ret)
-               goto attr_err_out;
-       ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, dquot->dq_id);
-       if (ret)
-               goto attr_err_out;
-       ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
-       if (ret)
-               goto attr_err_out;
-       ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MAJOR,
-               MAJOR(dquot->dq_sb->s_dev));
-       if (ret)
-               goto attr_err_out;
-       ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR,
-               MINOR(dquot->dq_sb->s_dev));
-       if (ret)
-               goto attr_err_out;
-       ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
-       if (ret)
-               goto attr_err_out;
-       genlmsg_end(skb, msg_head);
-
-       ret = genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS);
-       if (ret < 0 && ret != -ESRCH)
-               printk(KERN_ERR
-                       "VFS: Failed to send notification message: %d\n", ret);
-       return;
-attr_err_out:
-       printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
-err_out:
-       kfree_skb(skb);
-}
-#endif
 /*
  * Write warnings to the console and send warning messages over netlink.
  *
@@ -1112,18 +1074,20 @@ err_out:
  */
 static void flush_warnings(struct dquot *const *dquots, char *warntype)
 {
+       struct dquot *dq;
        int i;
 
-       for (i = 0; i < MAXQUOTAS; i++)
-               if (dquots[i] && warntype[i] != QUOTA_NL_NOWARN &&
-                   !warning_issued(dquots[i], warntype[i])) {
+       for (i = 0; i < MAXQUOTAS; i++) {
+               dq = dquots[i];
+               if (dq && warntype[i] != QUOTA_NL_NOWARN &&
+                   !warning_issued(dq, warntype[i])) {
 #ifdef CONFIG_PRINT_QUOTA_WARNING
-                       print_warning(dquots[i], warntype[i]);
-#endif
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-                       send_warning(dquots[i], warntype[i]);
+                       print_warning(dq, warntype[i]);
 #endif
+                       quota_send_warning(dq->dq_type, dq->dq_id,
+                                          dq->dq_sb->s_dev, warntype[i]);
                }
+       }
 }
 
 static int ignore_hardlimit(struct dquot *dquot)
@@ -1131,37 +1095,42 @@ static int ignore_hardlimit(struct dquot *dquot)
        struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
 
        return capable(CAP_SYS_RESOURCE) &&
-           (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || !(info->dqi_flags & V1_DQF_RSQUASH));
+              (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
+               !(info->dqi_flags & V1_DQF_RSQUASH));
 }
 
 /* needs dq_data_lock */
 static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
 {
+       qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes;
+
        *warntype = QUOTA_NL_NOWARN;
        if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) ||
            test_bit(DQ_FAKE_B, &dquot->dq_flags))
                return QUOTA_OK;
 
        if (dquot->dq_dqb.dqb_ihardlimit &&
-          (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_ihardlimit &&
+           newinodes > dquot->dq_dqb.dqb_ihardlimit &&
             !ignore_hardlimit(dquot)) {
                *warntype = QUOTA_NL_IHARDWARN;
                return NO_QUOTA;
        }
 
        if (dquot->dq_dqb.dqb_isoftlimit &&
-          (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
-           dquot->dq_dqb.dqb_itime && get_seconds() >= dquot->dq_dqb.dqb_itime &&
+           newinodes > dquot->dq_dqb.dqb_isoftlimit &&
+           dquot->dq_dqb.dqb_itime &&
+           get_seconds() >= dquot->dq_dqb.dqb_itime &&
             !ignore_hardlimit(dquot)) {
                *warntype = QUOTA_NL_ISOFTLONGWARN;
                return NO_QUOTA;
        }
 
        if (dquot->dq_dqb.dqb_isoftlimit &&
-          (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
+           newinodes > dquot->dq_dqb.dqb_isoftlimit &&
            dquot->dq_dqb.dqb_itime == 0) {
                *warntype = QUOTA_NL_ISOFTWARN;
-               dquot->dq_dqb.dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
+               dquot->dq_dqb.dqb_itime = get_seconds() +
+                   sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
        }
 
        return QUOTA_OK;
@@ -1171,9 +1140,10 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
 static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype)
 {
        qsize_t tspace;
+       struct super_block *sb = dquot->dq_sb;
 
        *warntype = QUOTA_NL_NOWARN;
-       if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) ||
+       if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) ||
            test_bit(DQ_FAKE_B, &dquot->dq_flags))
                return QUOTA_OK;
 
@@ -1190,7 +1160,8 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
 
        if (dquot->dq_dqb.dqb_bsoftlimit &&
            tspace > dquot->dq_dqb.dqb_bsoftlimit &&
-           dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime &&
+           dquot->dq_dqb.dqb_btime &&
+           get_seconds() >= dquot->dq_dqb.dqb_btime &&
             !ignore_hardlimit(dquot)) {
                if (!prealloc)
                        *warntype = QUOTA_NL_BSOFTLONGWARN;
@@ -1202,7 +1173,8 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
            dquot->dq_dqb.dqb_btime == 0) {
                if (!prealloc) {
                        *warntype = QUOTA_NL_BSOFTWARN;
-                       dquot->dq_dqb.dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
+                       dquot->dq_dqb.dqb_btime = get_seconds() +
+                           sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace;
                }
                else
                        /*
@@ -1217,15 +1189,18 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
 
 static int info_idq_free(struct dquot *dquot, qsize_t inodes)
 {
+       qsize_t newinodes;
+
        if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
            dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit ||
            !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type))
                return QUOTA_NL_NOWARN;
 
-       if (dquot->dq_dqb.dqb_curinodes - inodes <= dquot->dq_dqb.dqb_isoftlimit)
+       newinodes = dquot->dq_dqb.dqb_curinodes - inodes;
+       if (newinodes <= dquot->dq_dqb.dqb_isoftlimit)
                return QUOTA_NL_ISOFTBELOW;
        if (dquot->dq_dqb.dqb_curinodes >= dquot->dq_dqb.dqb_ihardlimit &&
-           dquot->dq_dqb.dqb_curinodes - inodes < dquot->dq_dqb.dqb_ihardlimit)
+           newinodes < dquot->dq_dqb.dqb_ihardlimit)
                return QUOTA_NL_IHARDBELOW;
        return QUOTA_NL_NOWARN;
 }
@@ -1466,7 +1441,8 @@ int dquot_alloc_inode(const struct inode *inode, qsize_t number)
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
                if (!inode->i_dquot[cnt])
                        continue;
-               if (check_idq(inode->i_dquot[cnt], number, warntype+cnt) == NO_QUOTA)
+               if (check_idq(inode->i_dquot[cnt], number, warntype+cnt)
+                   == NO_QUOTA)
                        goto warn_put_all;
        }
 
@@ -1673,19 +1649,13 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
                transfer_from[cnt] = NULL;
                transfer_to[cnt] = NULL;
                warntype_to[cnt] = QUOTA_NL_NOWARN;
-               switch (cnt) {
-                       case USRQUOTA:
-                               if (!chuid)
-                                       continue;
-                               transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
-                               break;
-                       case GRPQUOTA:
-                               if (!chgid)
-                                       continue;
-                               transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
-                               break;
-               }
        }
+       if (chuid)
+               transfer_to[USRQUOTA] = dqget(inode->i_sb, iattr->ia_uid,
+                                             USRQUOTA);
+       if (chgid)
+               transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid,
+                                             GRPQUOTA);
 
        down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
        /* Now recheck reliably when holding dqptr_sem */
@@ -1800,7 +1770,7 @@ EXPORT_SYMBOL(dquot_commit_info);
 /*
  * Definitions of diskquota operations.
  */
-struct dquot_operations dquot_operations = {
+const struct dquot_operations dquot_operations = {
        .initialize     = dquot_initialize,
        .drop           = dquot_drop,
        .alloc_space    = dquot_alloc_space,
@@ -1881,8 +1851,8 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
                drop_dquot_ref(sb, cnt);
                invalidate_dquots(sb, cnt);
                /*
-                * Now all dquots should be invalidated, all writes done so we should be only
-                * users of the info. No locks needed.
+                * Now all dquots should be invalidated, all writes done so we
+                * should be only users of the info. No locks needed.
                 */
                if (info_dirty(&dqopt->info[cnt]))
                        sb->dq_op->write_info(sb, cnt);
@@ -1920,10 +1890,12 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
                        /* If quota was reenabled in the meantime, we have
                         * nothing to do */
                        if (!sb_has_quota_loaded(sb, cnt)) {
-                               mutex_lock_nested(&toputinode[cnt]->i_mutex, I_MUTEX_QUOTA);
+                               mutex_lock_nested(&toputinode[cnt]->i_mutex,
+                                                 I_MUTEX_QUOTA);
                                toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
                                  S_NOATIME | S_NOQUOTA);
-                               truncate_inode_pages(&toputinode[cnt]->i_data, 0);
+                               truncate_inode_pages(&toputinode[cnt]->i_data,
+                                                    0);
                                mutex_unlock(&toputinode[cnt]->i_mutex);
                                mark_inode_dirty(toputinode[cnt]);
                        }
@@ -2001,7 +1973,6 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
                 * changes */
                invalidate_bdev(sb->s_bdev);
        }
-       mutex_lock(&inode->i_mutex);
        mutex_lock(&dqopt->dqonoff_mutex);
        if (sb_has_quota_loaded(sb, type)) {
                error = -EBUSY;
@@ -2013,8 +1984,11 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
                 * possible) Also nobody should write to the file - we use
                 * special IO operations which ignore the immutable bit. */
                down_write(&dqopt->dqptr_sem);
-               oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA);
+               mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
+               oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE |
+                                            S_NOQUOTA);
                inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
+               mutex_unlock(&inode->i_mutex);
                up_write(&dqopt->dqptr_sem);
                sb->dq_op->drop(inode);
        }
@@ -2032,12 +2006,12 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
        dqopt->info[type].dqi_fmt_id = format_id;
        INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
        mutex_lock(&dqopt->dqio_mutex);
-       if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) {
+       error = dqopt->ops[type]->read_file_info(sb, type);
+       if (error < 0) {
                mutex_unlock(&dqopt->dqio_mutex);
                goto out_file_init;
        }
        mutex_unlock(&dqopt->dqio_mutex);
-       mutex_unlock(&inode->i_mutex);
        spin_lock(&dq_state_lock);
        dqopt->flags |= dquot_state_flag(flags, type);
        spin_unlock(&dq_state_lock);
@@ -2051,16 +2025,17 @@ out_file_init:
        dqopt->files[type] = NULL;
        iput(inode);
 out_lock:
-       mutex_unlock(&dqopt->dqonoff_mutex);
        if (oldflags != -1) {
                down_write(&dqopt->dqptr_sem);
+               mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
                /* Set the flags back (in the case of accidental quotaon()
                 * on a wrong file we don't want to mess up the flags) */
                inode->i_flags &= ~(S_NOATIME | S_NOQUOTA | S_IMMUTABLE);
                inode->i_flags |= oldflags;
+               mutex_unlock(&inode->i_mutex);
                up_write(&dqopt->dqptr_sem);
        }
-       mutex_unlock(&inode->i_mutex);
+       mutex_unlock(&dqopt->dqonoff_mutex);
 out_fmt:
        put_quota_format(fmt);
 
@@ -2254,7 +2229,8 @@ static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
        spin_unlock(&dq_data_lock);
 }
 
-int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
+int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
+                 struct if_dqblk *di)
 {
        struct dquot *dquot;
 
@@ -2318,22 +2294,25 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
        }
 
        if (check_blim) {
-               if (!dm->dqb_bsoftlimit || dm->dqb_curspace < dm->dqb_bsoftlimit) {
+               if (!dm->dqb_bsoftlimit ||
+                   dm->dqb_curspace < dm->dqb_bsoftlimit) {
                        dm->dqb_btime = 0;
                        clear_bit(DQ_BLKS_B, &dquot->dq_flags);
-               }
-               else if (!(di->dqb_valid & QIF_BTIME))  /* Set grace only if user hasn't provided his own... */
+               } else if (!(di->dqb_valid & QIF_BTIME))
+                       /* Set grace only if user hasn't provided his own... */
                        dm->dqb_btime = get_seconds() + dqi->dqi_bgrace;
        }
        if (check_ilim) {
-               if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) {
+               if (!dm->dqb_isoftlimit ||
+                   dm->dqb_curinodes < dm->dqb_isoftlimit) {
                        dm->dqb_itime = 0;
                        clear_bit(DQ_INODES_B, &dquot->dq_flags);
-               }
-               else if (!(di->dqb_valid & QIF_ITIME))  /* Set grace only if user hasn't provided his own... */
+               } else if (!(di->dqb_valid & QIF_ITIME))
+                       /* Set grace only if user hasn't provided his own... */
                        dm->dqb_itime = get_seconds() + dqi->dqi_igrace;
        }
-       if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit)
+       if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit ||
+           dm->dqb_isoftlimit)
                clear_bit(DQ_FAKE_B, &dquot->dq_flags);
        else
                set_bit(DQ_FAKE_B, &dquot->dq_flags);
@@ -2343,7 +2322,8 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
        return 0;
 }
 
-int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
+int vfs_set_dqblk(struct super_block *sb, int type, qid_t id,
+                 struct if_dqblk *di)
 {
        struct dquot *dquot;
        int rc;
@@ -2400,7 +2380,8 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
        if (ii->dqi_valid & IIF_IGRACE)
                mi->dqi_igrace = ii->dqi_igrace;
        if (ii->dqi_valid & IIF_FLAGS)
-               mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK);
+               mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) |
+                               (ii->dqi_flags & DQF_MASK);
        spin_unlock(&dq_data_lock);
        mark_info_dirty(sb, type);
        /* Force write to disk */
@@ -2411,7 +2392,7 @@ out:
 }
 EXPORT_SYMBOL(vfs_set_dqinfo);
 
-struct quotactl_ops vfs_quotactl_ops = {
+const struct quotactl_ops vfs_quotactl_ops = {
        .quota_on       = vfs_quota_on,
        .quota_off      = vfs_quota_off,
        .quota_sync     = vfs_quota_sync,
@@ -2557,11 +2538,6 @@ static int __init dquot_init(void)
 
        register_shrinker(&dqcache_shrinker);
 
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-       if (genl_register_family(&quota_genl_family) != 0)
-               printk(KERN_ERR "VFS: Failed to create quota netlink interface.\n");
-#endif
-
        return 0;
 }
 module_init(dquot_init);