]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
tune2fs/quota: always create hidden quota files
authorAditya Kali <adityakali@google.com>
Fri, 13 Jul 2012 22:25:06 +0000 (15:25 -0700)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 16 Jul 2012 01:12:04 +0000 (21:12 -0400)
Currently 'tune2fs -O quota <dev>' will try to use existing
quota files and write their inode numbers in the superblock.
Next e2fsck run then converts these into hidden quota inodes
(ino #3 & #4). But this approach has problems:
1) Before e2fsck run, the inodes are visible to the user and
   might get corrupted or removed or replaced by the user.
2) Since these are user visible, we have to include
   their block usage in the quota accounting. But once
   these inodes are hidden, e2fsck will have to decrement
   their usage from the quota accounting (which e2fsck
   currently doesn't do and instead reports error).
   (the following used to give e2fsck error previously:
    # assume <dev> has aquota.user & aquota.group files
    $ tune2fs -O quota <dev> # stores ino# of quota files in
                             # ext4 superblock
    $ e2fsck -f <dev>  # hides quota files, but now quota
                       # usage is incorrect.
     << quota errors >>
Instead of making e2fsck complicated, this patch creates the
hidden quota inodes at 'tune2fs -O quota' time iteself. The
usage is computed freshly and limits are copied from the
aquota.user and aquota.group files as earlier.

Signed-off-by: Aditya Kali <adityakali@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/quota/mkquota.c
lib/quota/mkquota.h
misc/tune2fs.c

index c7869fd996f94f88127ca277c8b195b852f3e9e2..42af1f295d37c3d10e7f704c5edac47e40443241 100644 (file)
@@ -386,7 +386,9 @@ errcode_t quota_compute_usage(quota_ctx_t qctx)
                }
                if (ino == 0)
                        break;
-               if (inode.i_links_count) {
+               if (inode.i_links_count &&
+                   (ino == EXT2_ROOT_INO ||
+                    ino >= EXT2_FIRST_INODE(fs->super))) {
                        space = ext2fs_inode_i_blocks(fs, &inode) << 9;
                        quota_data_add(qctx, &inode, ino, space);
                        quota_data_inodes(qctx, &inode, ino, +1);
@@ -413,13 +415,15 @@ static int scan_dquots_callback(struct dquot *dquot, void *cb_data)
 
        dq = get_dq(quota_dict, dquot->dq_id);
        dq->dq_id = dquot->dq_id;
+       dq->dq_dqb.u.v2_mdqb.dqb_off = dquot->dq_dqb.u.v2_mdqb.dqb_off;
 
        /* Check if there is inconsistancy. */
        if (dq->dq_dqb.dqb_curspace != dquot->dq_dqb.dqb_curspace ||
            dq->dq_dqb.dqb_curinodes != dquot->dq_dqb.dqb_curinodes) {
                scan_data->usage_is_inconsistent = 1;
-               log_err("Usage inconsistent for ID %d: (%llu, %llu) != "
-                       "(%llu, %llu)", dq->dq_id, dq->dq_dqb.dqb_curspace,
+               fprintf(stderr, "[QUOTA WARNING] Usage inconsistent for ID %d:"
+                       "actual (%llu, %llu) != expected (%llu, %llu)\n",
+                       dq->dq_id, dq->dq_dqb.dqb_curspace,
                        dq->dq_dqb.dqb_curinodes, dquot->dq_dqb.dqb_curspace,
                        dquot->dq_dqb.dqb_curinodes);
        }
@@ -473,9 +477,9 @@ static errcode_t quota_write_all_dquots(struct quota_handle *qh,
 }
 
 /*
- * Update usage of in quota file, limits keep unchaged
+ * Updates the in-memory quota limits from the given quota inode.
  */
-errcode_t quota_update_inode(quota_ctx_t qctx, ext2_ino_t qf_ino, int type)
+errcode_t quota_update_limits(quota_ctx_t qctx, ext2_ino_t qf_ino, int type)
 {
        struct quota_handle *qh;
        errcode_t err;
@@ -489,14 +493,13 @@ errcode_t quota_update_inode(quota_ctx_t qctx, ext2_ino_t qf_ino, int type)
                return err;
        }
 
-       err = quota_file_open(qh, qctx->fs, qf_ino, type, -1, EXT2_FILE_WRITE);
+       err = quota_file_open(qh, qctx->fs, qf_ino, type, -1, 0);
        if (err) {
                log_err("Open quota file failed", "");
                goto out;
        }
 
        quota_read_all_dquots(qh, qctx, 1);
-       quota_write_all_dquots(qh, qctx);
 
        err = quota_file_close(qh);
        if (err) {
index a0c603f3870d0d1e6061f9057da2bf32e36c7462..ee1507193950bd07d7d8ee5fa85f9c01dc9ffd88 100644 (file)
@@ -51,7 +51,7 @@ void quota_data_add(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,
 void quota_data_sub(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,
                qsize_t space);
 errcode_t quota_write_inode(quota_ctx_t qctx, int qtype);
-errcode_t quota_update_inode(quota_ctx_t qctx, ext2_ino_t qf_ino, int type);
+errcode_t quota_update_limits(quota_ctx_t qctx, ext2_ino_t qf_ino, int type);
 errcode_t quota_compute_usage(quota_ctx_t qctx);
 void quota_release_context(quota_ctx_t *qctx);
 
index f1f0bcf06e11e7f5c1d585e8642f2327ebe6f187..73bc10c0a5cf6fae825542198cdb5159517c2a88 100644 (file)
@@ -713,28 +713,18 @@ void handle_quota_options(ext2_filsys fs)
 
        if (usrquota == QOPT_ENABLE && !fs->super->s_usr_quota_inum) {
                if ((qf_ino = quota_file_exists(fs, USRQUOTA,
-                                               QFMT_VFS_V1)) > 0) {
-                       if (quota_update_inode(qctx, qf_ino, USRQUOTA) == 0)
-                               quota_set_sb_inum(fs, qf_ino, USRQUOTA);
-                       else
-                               quota_write_inode(qctx, USRQUOTA);
-               } else {
-                       quota_write_inode(qctx, USRQUOTA);
-               }
+                                               QFMT_VFS_V1)) > 0)
+                       quota_update_limits(qctx, qf_ino, USRQUOTA);
+               quota_write_inode(qctx, USRQUOTA);
        } else if (usrquota == QOPT_DISABLE) {
                quota_remove_inode(fs, USRQUOTA);
        }
 
        if (grpquota == QOPT_ENABLE && !fs->super->s_grp_quota_inum) {
                if ((qf_ino = quota_file_exists(fs, GRPQUOTA,
-                                               QFMT_VFS_V1)) > 0) {
-                       if (quota_update_inode(qctx, qf_ino, GRPQUOTA) == 0)
-                               quota_set_sb_inum(fs, qf_ino, GRPQUOTA);
-                       else
-                               quota_write_inode(qctx, GRPQUOTA);
-               } else {
-                       quota_write_inode(qctx, GRPQUOTA);
-               }
+                                               QFMT_VFS_V1)) > 0)
+                       quota_update_limits(qctx, qf_ino, GRPQUOTA);
+               quota_write_inode(qctx, GRPQUOTA);
        } else if (grpquota == QOPT_DISABLE) {
                quota_remove_inode(fs, GRPQUOTA);
        }