diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/Kconfig | 85 | ||||
-rw-r--r-- | fs/ocfs2/quota_global.c | 169 |
2 files changed, 87 insertions, 167 deletions
diff --git a/fs/ocfs2/Kconfig b/fs/ocfs2/Kconfig new file mode 100644 index 000000000000..701b7a3a872e --- /dev/null +++ b/fs/ocfs2/Kconfig | |||
@@ -0,0 +1,85 @@ | |||
1 | config OCFS2_FS | ||
2 | tristate "OCFS2 file system support" | ||
3 | depends on NET && SYSFS | ||
4 | select CONFIGFS_FS | ||
5 | select JBD2 | ||
6 | select CRC32 | ||
7 | select QUOTA | ||
8 | select QUOTA_TREE | ||
9 | help | ||
10 | OCFS2 is a general purpose extent based shared disk cluster file | ||
11 | system with many similarities to ext3. It supports 64 bit inode | ||
12 | numbers, and has automatically extending metadata groups which may | ||
13 | also make it attractive for non-clustered use. | ||
14 | |||
15 | You'll want to install the ocfs2-tools package in order to at least | ||
16 | get "mount.ocfs2". | ||
17 | |||
18 | Project web page: http://oss.oracle.com/projects/ocfs2 | ||
19 | Tools web page: http://oss.oracle.com/projects/ocfs2-tools | ||
20 | OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/ | ||
21 | |||
22 | For more information on OCFS2, see the file | ||
23 | <file:Documentation/filesystems/ocfs2.txt>. | ||
24 | |||
25 | config OCFS2_FS_O2CB | ||
26 | tristate "O2CB Kernelspace Clustering" | ||
27 | depends on OCFS2_FS | ||
28 | default y | ||
29 | help | ||
30 | OCFS2 includes a simple kernelspace clustering package, the OCFS2 | ||
31 | Cluster Base. It only requires a very small userspace component | ||
32 | to configure it. This comes with the standard ocfs2-tools package. | ||
33 | O2CB is limited to maintaining a cluster for OCFS2 file systems. | ||
34 | It cannot manage any other cluster applications. | ||
35 | |||
36 | It is always safe to say Y here, as the clustering method is | ||
37 | run-time selectable. | ||
38 | |||
39 | config OCFS2_FS_USERSPACE_CLUSTER | ||
40 | tristate "OCFS2 Userspace Clustering" | ||
41 | depends on OCFS2_FS && DLM | ||
42 | default y | ||
43 | help | ||
44 | This option will allow OCFS2 to use userspace clustering services | ||
45 | in conjunction with the DLM in fs/dlm. If you are using a | ||
46 | userspace cluster manager, say Y here. | ||
47 | |||
48 | It is safe to say Y, as the clustering method is run-time | ||
49 | selectable. | ||
50 | |||
51 | config OCFS2_FS_STATS | ||
52 | bool "OCFS2 statistics" | ||
53 | depends on OCFS2_FS | ||
54 | default y | ||
55 | help | ||
56 | This option allows some fs statistics to be captured. Enabling | ||
57 | this option may increase the memory consumption. | ||
58 | |||
59 | config OCFS2_DEBUG_MASKLOG | ||
60 | bool "OCFS2 logging support" | ||
61 | depends on OCFS2_FS | ||
62 | default y | ||
63 | help | ||
64 | The ocfs2 filesystem has an extensive logging system. The system | ||
65 | allows selection of events to log via files in /sys/o2cb/logmask/. | ||
66 | This option will enlarge your kernel, but it allows debugging of | ||
67 | ocfs2 filesystem issues. | ||
68 | |||
69 | config OCFS2_DEBUG_FS | ||
70 | bool "OCFS2 expensive checks" | ||
71 | depends on OCFS2_FS | ||
72 | default n | ||
73 | help | ||
74 | This option will enable expensive consistency checks. Enable | ||
75 | this option for debugging only as it is likely to decrease | ||
76 | performance of the filesystem. | ||
77 | |||
78 | config OCFS2_FS_POSIX_ACL | ||
79 | bool "OCFS2 POSIX Access Control Lists" | ||
80 | depends on OCFS2_FS | ||
81 | select FS_POSIX_ACL | ||
82 | default n | ||
83 | help | ||
84 | Posix Access Control Lists (ACLs) support permissions for users and | ||
85 | groups beyond the owner/group/world scheme. | ||
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index 6aff8f2d3e49..f4efa89baee5 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
@@ -810,171 +810,6 @@ out: | |||
810 | return status; | 810 | return status; |
811 | } | 811 | } |
812 | 812 | ||
813 | /* This is difficult. We have to lock quota inode and start transaction | ||
814 | * in this function but we don't want to take the penalty of exlusive | ||
815 | * quota file lock when we are just going to use cached structures. So | ||
816 | * we just take read lock check whether we have dquot cached and if so, | ||
817 | * we don't have to take the write lock... */ | ||
818 | static int ocfs2_dquot_initialize(struct inode *inode, int type) | ||
819 | { | ||
820 | handle_t *handle = NULL; | ||
821 | int status = 0; | ||
822 | struct super_block *sb = inode->i_sb; | ||
823 | struct ocfs2_mem_dqinfo *oinfo; | ||
824 | int exclusive = 0; | ||
825 | int cnt; | ||
826 | qid_t id; | ||
827 | |||
828 | mlog_entry_void(); | ||
829 | |||
830 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
831 | if (type != -1 && cnt != type) | ||
832 | continue; | ||
833 | if (!sb_has_quota_active(sb, cnt)) | ||
834 | continue; | ||
835 | oinfo = sb_dqinfo(sb, cnt)->dqi_priv; | ||
836 | status = ocfs2_lock_global_qf(oinfo, 0); | ||
837 | if (status < 0) | ||
838 | goto out; | ||
839 | /* This is just a performance optimization not a reliable test. | ||
840 | * Since we hold an inode lock, noone can actually release | ||
841 | * the structure until we are finished with initialization. */ | ||
842 | if (inode->i_dquot[cnt] != NODQUOT) { | ||
843 | ocfs2_unlock_global_qf(oinfo, 0); | ||
844 | continue; | ||
845 | } | ||
846 | /* When we have inode lock, we know that no dquot_release() can | ||
847 | * run and thus we can safely check whether we need to | ||
848 | * read+modify global file to get quota information or whether | ||
849 | * our node already has it. */ | ||
850 | if (cnt == USRQUOTA) | ||
851 | id = inode->i_uid; | ||
852 | else if (cnt == GRPQUOTA) | ||
853 | id = inode->i_gid; | ||
854 | else | ||
855 | BUG(); | ||
856 | /* Obtain exclusion from quota off... */ | ||
857 | down_write(&sb_dqopt(sb)->dqptr_sem); | ||
858 | exclusive = !dquot_is_cached(sb, id, cnt); | ||
859 | up_write(&sb_dqopt(sb)->dqptr_sem); | ||
860 | if (exclusive) { | ||
861 | status = ocfs2_lock_global_qf(oinfo, 1); | ||
862 | if (status < 0) { | ||
863 | exclusive = 0; | ||
864 | mlog_errno(status); | ||
865 | goto out_ilock; | ||
866 | } | ||
867 | handle = ocfs2_start_trans(OCFS2_SB(sb), | ||
868 | ocfs2_calc_qinit_credits(sb, cnt)); | ||
869 | if (IS_ERR(handle)) { | ||
870 | status = PTR_ERR(handle); | ||
871 | mlog_errno(status); | ||
872 | goto out_ilock; | ||
873 | } | ||
874 | } | ||
875 | dquot_initialize(inode, cnt); | ||
876 | if (exclusive) { | ||
877 | ocfs2_commit_trans(OCFS2_SB(sb), handle); | ||
878 | ocfs2_unlock_global_qf(oinfo, 1); | ||
879 | } | ||
880 | ocfs2_unlock_global_qf(oinfo, 0); | ||
881 | } | ||
882 | mlog_exit(0); | ||
883 | return 0; | ||
884 | out_ilock: | ||
885 | if (exclusive) | ||
886 | ocfs2_unlock_global_qf(oinfo, 1); | ||
887 | ocfs2_unlock_global_qf(oinfo, 0); | ||
888 | out: | ||
889 | mlog_exit(status); | ||
890 | return status; | ||
891 | } | ||
892 | |||
893 | static int ocfs2_dquot_drop_slow(struct inode *inode) | ||
894 | { | ||
895 | int status = 0; | ||
896 | int cnt; | ||
897 | int got_lock[MAXQUOTAS] = {0, 0}; | ||
898 | handle_t *handle; | ||
899 | struct super_block *sb = inode->i_sb; | ||
900 | struct ocfs2_mem_dqinfo *oinfo; | ||
901 | |||
902 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
903 | if (!sb_has_quota_active(sb, cnt)) | ||
904 | continue; | ||
905 | oinfo = sb_dqinfo(sb, cnt)->dqi_priv; | ||
906 | status = ocfs2_lock_global_qf(oinfo, 1); | ||
907 | if (status < 0) | ||
908 | goto out; | ||
909 | got_lock[cnt] = 1; | ||
910 | } | ||
911 | handle = ocfs2_start_trans(OCFS2_SB(sb), | ||
912 | ocfs2_calc_qinit_credits(sb, USRQUOTA) + | ||
913 | ocfs2_calc_qinit_credits(sb, GRPQUOTA)); | ||
914 | if (IS_ERR(handle)) { | ||
915 | status = PTR_ERR(handle); | ||
916 | mlog_errno(status); | ||
917 | goto out; | ||
918 | } | ||
919 | dquot_drop(inode); | ||
920 | ocfs2_commit_trans(OCFS2_SB(sb), handle); | ||
921 | out: | ||
922 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | ||
923 | if (got_lock[cnt]) { | ||
924 | oinfo = sb_dqinfo(sb, cnt)->dqi_priv; | ||
925 | ocfs2_unlock_global_qf(oinfo, 1); | ||
926 | } | ||
927 | return status; | ||
928 | } | ||
929 | |||
930 | /* See the comment before ocfs2_dquot_initialize. */ | ||
931 | static int ocfs2_dquot_drop(struct inode *inode) | ||
932 | { | ||
933 | int status = 0; | ||
934 | struct super_block *sb = inode->i_sb; | ||
935 | struct ocfs2_mem_dqinfo *oinfo; | ||
936 | int exclusive = 0; | ||
937 | int cnt; | ||
938 | int got_lock[MAXQUOTAS] = {0, 0}; | ||
939 | |||
940 | mlog_entry_void(); | ||
941 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
942 | if (!sb_has_quota_active(sb, cnt)) | ||
943 | continue; | ||
944 | oinfo = sb_dqinfo(sb, cnt)->dqi_priv; | ||
945 | status = ocfs2_lock_global_qf(oinfo, 0); | ||
946 | if (status < 0) | ||
947 | goto out; | ||
948 | got_lock[cnt] = 1; | ||
949 | } | ||
950 | /* Lock against anyone releasing references so that when when we check | ||
951 | * we know we are not going to be last ones to release dquot */ | ||
952 | down_write(&sb_dqopt(sb)->dqptr_sem); | ||
953 | /* Urgh, this is a terrible hack :( */ | ||
954 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
955 | if (inode->i_dquot[cnt] != NODQUOT && | ||
956 | atomic_read(&inode->i_dquot[cnt]->dq_count) > 1) { | ||
957 | exclusive = 1; | ||
958 | break; | ||
959 | } | ||
960 | } | ||
961 | if (!exclusive) | ||
962 | dquot_drop_locked(inode); | ||
963 | up_write(&sb_dqopt(sb)->dqptr_sem); | ||
964 | out: | ||
965 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | ||
966 | if (got_lock[cnt]) { | ||
967 | oinfo = sb_dqinfo(sb, cnt)->dqi_priv; | ||
968 | ocfs2_unlock_global_qf(oinfo, 0); | ||
969 | } | ||
970 | /* In case we bailed out because we had to do expensive locking | ||
971 | * do it now... */ | ||
972 | if (exclusive) | ||
973 | status = ocfs2_dquot_drop_slow(inode); | ||
974 | mlog_exit(status); | ||
975 | return status; | ||
976 | } | ||
977 | |||
978 | static struct dquot *ocfs2_alloc_dquot(struct super_block *sb, int type) | 813 | static struct dquot *ocfs2_alloc_dquot(struct super_block *sb, int type) |
979 | { | 814 | { |
980 | struct ocfs2_dquot *dquot = | 815 | struct ocfs2_dquot *dquot = |
@@ -991,8 +826,8 @@ static void ocfs2_destroy_dquot(struct dquot *dquot) | |||
991 | } | 826 | } |
992 | 827 | ||
993 | struct dquot_operations ocfs2_quota_operations = { | 828 | struct dquot_operations ocfs2_quota_operations = { |
994 | .initialize = ocfs2_dquot_initialize, | 829 | .initialize = dquot_initialize, |
995 | .drop = ocfs2_dquot_drop, | 830 | .drop = dquot_drop, |
996 | .alloc_space = dquot_alloc_space, | 831 | .alloc_space = dquot_alloc_space, |
997 | .alloc_inode = dquot_alloc_inode, | 832 | .alloc_inode = dquot_alloc_inode, |
998 | .free_space = dquot_free_space, | 833 | .free_space = dquot_free_space, |