aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/super.c
diff options
context:
space:
mode:
authorMark Bellon <mbellon@mvista.com>2005-09-06 18:16:54 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 19:57:23 -0400
commit8fc2751beb0941966d3a97b26544e8585e428c08 (patch)
tree30a03f2e173f31d76fb436054ed2356542099999 /fs/ext3/super.c
parentc92371566ea505cf455c208cdfb89046b3db87de (diff)
[PATCH] disk quotas fail when /etc/mtab is symlinked to /proc/mounts
If /etc/mtab is a regular file all of the mount options (of a file system) are written to /etc/mtab by the mount command. The quota tools look there for the quota strings for their operation. If, however, /etc/mtab is a symlink to /proc/mounts (a "good thing" in some environments) the tools don't write anything - they assume the kernel will take care of things. While the quota options are sent down to the kernel via the mount system call and the file system codes handle them properly unfortunately there is no code to echo the quota strings into /proc/mounts and the quota tools fail in the symlink case. The attached patchs modify the EXT[2|3] and JFS codes to add the necessary hooks. The show_options function of each file system in these patches currently deal with only those things that seemed related to quotas; especially in the EXT3 case more can be done (later?). Jan Kara also noted the difficulty in moving these changes above the FS codes responding similarly to myself to Andrew's comment about possible VFS migration. Issue summary: - FS codes have to process the entire string of options anyway. - Only FS codes that use quotas must have a show_options function (for quotas to work properly) however quotas are only used in a small number of FS. - Since most of the quota using FS support other options these FS codes should have the a show_options function to show those options - and the quota echoing becomes virtually negligible. Based on feedback I have modified my patches from the original: JFS a missing patch has been restored to the posting EXT[2|3] and JFS always use the show_options function - Each FS has at least one FS specific option displayed - QUOTA output is under a CONFIG_QUOTA ifdef - a follow-on patch will add a multitude of options for each FS EXT[2|3] and JFS "quota" is treated as "usrquota" EXT3 journalled data check for journalled quota removed EXT[2|3] mount when quota specified but not compiled in - no changes from my original patch. I tested the patch and the codes warn but - still mount. With all due respection I believe the comments otherwise were a - misread of the patch. Please reread/test and comment. XFS patch removed - the XFS team already made the necessary changes EXT3 mixing old and new quotas are handled differently (not purely exclusive) - if old and new quotas for the same type are used together the old type is silently depricated for compatability (e.g. usrquota and usrjquota) - mixing of old and new quotas is an error (e.g. usrjquota and grpquota) Signed-off-by: Mark Bellon <mbellon@mvista.com> Acked-by: Dave Kleikamp <shaggy@austin.ibm.com> Cc: Jan Kara <jack@ucw.cz> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r--fs/ext3/super.c92
1 files changed, 81 insertions, 11 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 3c3c6e399fb3..a93c3609025d 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -35,6 +35,7 @@
35#include <linux/mount.h> 35#include <linux/mount.h>
36#include <linux/namei.h> 36#include <linux/namei.h>
37#include <linux/quotaops.h> 37#include <linux/quotaops.h>
38#include <linux/seq_file.h>
38#include <asm/uaccess.h> 39#include <asm/uaccess.h>
39#include "xattr.h" 40#include "xattr.h"
40#include "acl.h" 41#include "acl.h"
@@ -509,8 +510,41 @@ static void ext3_clear_inode(struct inode *inode)
509 kfree(rsv); 510 kfree(rsv);
510} 511}
511 512
512#ifdef CONFIG_QUOTA 513static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
514{
515 struct ext3_sb_info *sbi = EXT3_SB(vfs->mnt_sb);
516
517 if (sbi->s_mount_opt & EXT3_MOUNT_JOURNAL_DATA)
518 seq_puts(seq, ",data=journal");
519
520 if (sbi->s_mount_opt & EXT3_MOUNT_ORDERED_DATA)
521 seq_puts(seq, ",data=ordered");
522
523 if (sbi->s_mount_opt & EXT3_MOUNT_WRITEBACK_DATA)
524 seq_puts(seq, ",data=writeback");
525
526#if defined(CONFIG_QUOTA)
527 if (sbi->s_jquota_fmt)
528 seq_printf(seq, ",jqfmt=%s",
529 (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0");
530
531 if (sbi->s_qf_names[USRQUOTA])
532 seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
533
534 if (sbi->s_qf_names[GRPQUOTA])
535 seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
513 536
537 if (sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA)
538 seq_puts(seq, ",usrquota");
539
540 if (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)
541 seq_puts(seq, ",grpquota");
542#endif
543
544 return 0;
545}
546
547#ifdef CONFIG_QUOTA
514#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") 548#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
515#define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) 549#define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
516 550
@@ -569,6 +603,7 @@ static struct super_operations ext3_sops = {
569 .statfs = ext3_statfs, 603 .statfs = ext3_statfs,
570 .remount_fs = ext3_remount, 604 .remount_fs = ext3_remount,
571 .clear_inode = ext3_clear_inode, 605 .clear_inode = ext3_clear_inode,
606 .show_options = ext3_show_options,
572#ifdef CONFIG_QUOTA 607#ifdef CONFIG_QUOTA
573 .quota_read = ext3_quota_read, 608 .quota_read = ext3_quota_read,
574 .quota_write = ext3_quota_write, 609 .quota_write = ext3_quota_write,
@@ -590,7 +625,8 @@ enum {
590 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 625 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
591 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 626 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
592 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, 627 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
593 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, 628 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
629 Opt_grpquota
594}; 630};
595 631
596static match_table_t tokens = { 632static match_table_t tokens = {
@@ -634,10 +670,10 @@ static match_table_t tokens = {
634 {Opt_grpjquota, "grpjquota=%s"}, 670 {Opt_grpjquota, "grpjquota=%s"},
635 {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, 671 {Opt_jqfmt_vfsold, "jqfmt=vfsold"},
636 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, 672 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
637 {Opt_quota, "grpquota"}, 673 {Opt_grpquota, "grpquota"},
638 {Opt_noquota, "noquota"}, 674 {Opt_noquota, "noquota"},
639 {Opt_quota, "quota"}, 675 {Opt_quota, "quota"},
640 {Opt_quota, "usrquota"}, 676 {Opt_usrquota, "usrquota"},
641 {Opt_barrier, "barrier=%u"}, 677 {Opt_barrier, "barrier=%u"},
642 {Opt_err, NULL}, 678 {Opt_err, NULL},
643 {Opt_resize, "resize"}, 679 {Opt_resize, "resize"},
@@ -903,7 +939,13 @@ clear_qf_name:
903 sbi->s_jquota_fmt = QFMT_VFS_V0; 939 sbi->s_jquota_fmt = QFMT_VFS_V0;
904 break; 940 break;
905 case Opt_quota: 941 case Opt_quota:
942 case Opt_usrquota:
906 set_opt(sbi->s_mount_opt, QUOTA); 943 set_opt(sbi->s_mount_opt, QUOTA);
944 set_opt(sbi->s_mount_opt, USRQUOTA);
945 break;
946 case Opt_grpquota:
947 set_opt(sbi->s_mount_opt, QUOTA);
948 set_opt(sbi->s_mount_opt, GRPQUOTA);
907 break; 949 break;
908 case Opt_noquota: 950 case Opt_noquota:
909 if (sb_any_quota_enabled(sb)) { 951 if (sb_any_quota_enabled(sb)) {
@@ -912,8 +954,13 @@ clear_qf_name:
912 return 0; 954 return 0;
913 } 955 }
914 clear_opt(sbi->s_mount_opt, QUOTA); 956 clear_opt(sbi->s_mount_opt, QUOTA);
957 clear_opt(sbi->s_mount_opt, USRQUOTA);
958 clear_opt(sbi->s_mount_opt, GRPQUOTA);
915 break; 959 break;
916#else 960#else
961 case Opt_quota:
962 case Opt_usrquota:
963 case Opt_grpquota:
917 case Opt_usrjquota: 964 case Opt_usrjquota:
918 case Opt_grpjquota: 965 case Opt_grpjquota:
919 case Opt_offusrjquota: 966 case Opt_offusrjquota:
@@ -924,7 +971,6 @@ clear_qf_name:
924 "EXT3-fs: journalled quota options not " 971 "EXT3-fs: journalled quota options not "
925 "supported.\n"); 972 "supported.\n");
926 break; 973 break;
927 case Opt_quota:
928 case Opt_noquota: 974 case Opt_noquota:
929 break; 975 break;
930#endif 976#endif
@@ -962,14 +1008,38 @@ clear_qf_name:
962 } 1008 }
963 } 1009 }
964#ifdef CONFIG_QUOTA 1010#ifdef CONFIG_QUOTA
965 if (!sbi->s_jquota_fmt && (sbi->s_qf_names[USRQUOTA] || 1011 if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
966 sbi->s_qf_names[GRPQUOTA])) { 1012 if ((sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA) &&
967 printk(KERN_ERR 1013 sbi->s_qf_names[USRQUOTA])
968 "EXT3-fs: journalled quota format not specified.\n"); 1014 clear_opt(sbi->s_mount_opt, USRQUOTA);
969 return 0; 1015
1016 if ((sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA) &&
1017 sbi->s_qf_names[GRPQUOTA])
1018 clear_opt(sbi->s_mount_opt, GRPQUOTA);
1019
1020 if ((sbi->s_qf_names[USRQUOTA] &&
1021 (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)) ||
1022 (sbi->s_qf_names[GRPQUOTA] &&
1023 (sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA))) {
1024 printk(KERN_ERR "EXT3-fs: old and new quota "
1025 "format mixing.\n");
1026 return 0;
1027 }
1028
1029 if (!sbi->s_jquota_fmt) {
1030 printk(KERN_ERR "EXT3-fs: journalled quota format "
1031 "not specified.\n");
1032 return 0;
1033 }
1034 } else {
1035 if (sbi->s_jquota_fmt) {
1036 printk(KERN_ERR "EXT3-fs: journalled quota format "
1037 "specified with no journalling "
1038 "enabled.\n");
1039 return 0;
1040 }
970 } 1041 }
971#endif 1042#endif
972
973 return 1; 1043 return 1;
974} 1044}
975 1045