diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/Kconfig | 85 | ||||
-rw-r--r-- | fs/ocfs2/alloc.c | 3 | ||||
-rw-r--r-- | fs/ocfs2/dcache.c | 42 | ||||
-rw-r--r-- | fs/ocfs2/dcache.h | 9 | ||||
-rw-r--r-- | fs/ocfs2/dlmglue.c | 4 | ||||
-rw-r--r-- | fs/ocfs2/ocfs2.h | 6 | ||||
-rw-r--r-- | fs/ocfs2/quota_global.c | 173 | ||||
-rw-r--r-- | fs/ocfs2/super.c | 3 | ||||
-rw-r--r-- | fs/ocfs2/xattr.c | 17 |
9 files changed, 161 insertions, 181 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/alloc.c b/fs/ocfs2/alloc.c index d861096c9d81..60fe74035db5 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -5390,6 +5390,9 @@ int ocfs2_remove_btree_range(struct inode *inode, | |||
5390 | goto out; | 5390 | goto out; |
5391 | } | 5391 | } |
5392 | 5392 | ||
5393 | vfs_dq_free_space_nodirty(inode, | ||
5394 | ocfs2_clusters_to_bytes(inode->i_sb, len)); | ||
5395 | |||
5393 | ret = ocfs2_remove_extent(inode, et, cpos, len, handle, meta_ac, | 5396 | ret = ocfs2_remove_extent(inode, et, cpos, len, handle, meta_ac, |
5394 | dealloc); | 5397 | dealloc); |
5395 | if (ret) { | 5398 | if (ret) { |
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c index b1cc7c381e88..e9d7c2038c0f 100644 --- a/fs/ocfs2/dcache.c +++ b/fs/ocfs2/dcache.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "dlmglue.h" | 38 | #include "dlmglue.h" |
39 | #include "file.h" | 39 | #include "file.h" |
40 | #include "inode.h" | 40 | #include "inode.h" |
41 | #include "super.h" | ||
41 | 42 | ||
42 | 43 | ||
43 | static int ocfs2_dentry_revalidate(struct dentry *dentry, | 44 | static int ocfs2_dentry_revalidate(struct dentry *dentry, |
@@ -294,6 +295,34 @@ out_attach: | |||
294 | return ret; | 295 | return ret; |
295 | } | 296 | } |
296 | 297 | ||
298 | static DEFINE_SPINLOCK(dentry_list_lock); | ||
299 | |||
300 | /* We limit the number of dentry locks to drop in one go. We have | ||
301 | * this limit so that we don't starve other users of ocfs2_wq. */ | ||
302 | #define DL_INODE_DROP_COUNT 64 | ||
303 | |||
304 | /* Drop inode references from dentry locks */ | ||
305 | void ocfs2_drop_dl_inodes(struct work_struct *work) | ||
306 | { | ||
307 | struct ocfs2_super *osb = container_of(work, struct ocfs2_super, | ||
308 | dentry_lock_work); | ||
309 | struct ocfs2_dentry_lock *dl; | ||
310 | int drop_count = DL_INODE_DROP_COUNT; | ||
311 | |||
312 | spin_lock(&dentry_list_lock); | ||
313 | while (osb->dentry_lock_list && drop_count--) { | ||
314 | dl = osb->dentry_lock_list; | ||
315 | osb->dentry_lock_list = dl->dl_next; | ||
316 | spin_unlock(&dentry_list_lock); | ||
317 | iput(dl->dl_inode); | ||
318 | kfree(dl); | ||
319 | spin_lock(&dentry_list_lock); | ||
320 | } | ||
321 | if (osb->dentry_lock_list) | ||
322 | queue_work(ocfs2_wq, &osb->dentry_lock_work); | ||
323 | spin_unlock(&dentry_list_lock); | ||
324 | } | ||
325 | |||
297 | /* | 326 | /* |
298 | * ocfs2_dentry_iput() and friends. | 327 | * ocfs2_dentry_iput() and friends. |
299 | * | 328 | * |
@@ -318,16 +347,23 @@ out_attach: | |||
318 | static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb, | 347 | static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb, |
319 | struct ocfs2_dentry_lock *dl) | 348 | struct ocfs2_dentry_lock *dl) |
320 | { | 349 | { |
321 | iput(dl->dl_inode); | ||
322 | ocfs2_simple_drop_lockres(osb, &dl->dl_lockres); | 350 | ocfs2_simple_drop_lockres(osb, &dl->dl_lockres); |
323 | ocfs2_lock_res_free(&dl->dl_lockres); | 351 | ocfs2_lock_res_free(&dl->dl_lockres); |
324 | kfree(dl); | 352 | |
353 | /* We leave dropping of inode reference to ocfs2_wq as that can | ||
354 | * possibly lead to inode deletion which gets tricky */ | ||
355 | spin_lock(&dentry_list_lock); | ||
356 | if (!osb->dentry_lock_list) | ||
357 | queue_work(ocfs2_wq, &osb->dentry_lock_work); | ||
358 | dl->dl_next = osb->dentry_lock_list; | ||
359 | osb->dentry_lock_list = dl; | ||
360 | spin_unlock(&dentry_list_lock); | ||
325 | } | 361 | } |
326 | 362 | ||
327 | void ocfs2_dentry_lock_put(struct ocfs2_super *osb, | 363 | void ocfs2_dentry_lock_put(struct ocfs2_super *osb, |
328 | struct ocfs2_dentry_lock *dl) | 364 | struct ocfs2_dentry_lock *dl) |
329 | { | 365 | { |
330 | int unlock = 0; | 366 | int unlock; |
331 | 367 | ||
332 | BUG_ON(dl->dl_count == 0); | 368 | BUG_ON(dl->dl_count == 0); |
333 | 369 | ||
diff --git a/fs/ocfs2/dcache.h b/fs/ocfs2/dcache.h index c091c34d9883..d06e16c06640 100644 --- a/fs/ocfs2/dcache.h +++ b/fs/ocfs2/dcache.h | |||
@@ -29,8 +29,13 @@ | |||
29 | extern struct dentry_operations ocfs2_dentry_ops; | 29 | extern struct dentry_operations ocfs2_dentry_ops; |
30 | 30 | ||
31 | struct ocfs2_dentry_lock { | 31 | struct ocfs2_dentry_lock { |
32 | /* Use count of dentry lock */ | ||
32 | unsigned int dl_count; | 33 | unsigned int dl_count; |
33 | u64 dl_parent_blkno; | 34 | union { |
35 | /* Linked list of dentry locks to release */ | ||
36 | struct ocfs2_dentry_lock *dl_next; | ||
37 | u64 dl_parent_blkno; | ||
38 | }; | ||
34 | 39 | ||
35 | /* | 40 | /* |
36 | * The ocfs2_dentry_lock keeps an inode reference until | 41 | * The ocfs2_dentry_lock keeps an inode reference until |
@@ -47,6 +52,8 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry, struct inode *inode, | |||
47 | void ocfs2_dentry_lock_put(struct ocfs2_super *osb, | 52 | void ocfs2_dentry_lock_put(struct ocfs2_super *osb, |
48 | struct ocfs2_dentry_lock *dl); | 53 | struct ocfs2_dentry_lock *dl); |
49 | 54 | ||
55 | void ocfs2_drop_dl_inodes(struct work_struct *work); | ||
56 | |||
50 | struct dentry *ocfs2_find_local_alias(struct inode *inode, u64 parent_blkno, | 57 | struct dentry *ocfs2_find_local_alias(struct inode *inode, u64 parent_blkno, |
51 | int skip_unhashed); | 58 | int skip_unhashed); |
52 | 59 | ||
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index b0c4cadd4c45..206a2370876a 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -2860,6 +2860,10 @@ static void ocfs2_unlock_ast(void *opaque, int error) | |||
2860 | case OCFS2_UNLOCK_CANCEL_CONVERT: | 2860 | case OCFS2_UNLOCK_CANCEL_CONVERT: |
2861 | mlog(0, "Cancel convert success for %s\n", lockres->l_name); | 2861 | mlog(0, "Cancel convert success for %s\n", lockres->l_name); |
2862 | lockres->l_action = OCFS2_AST_INVALID; | 2862 | lockres->l_action = OCFS2_AST_INVALID; |
2863 | /* Downconvert thread may have requeued this lock, we | ||
2864 | * need to wake it. */ | ||
2865 | if (lockres->l_flags & OCFS2_LOCK_BLOCKED) | ||
2866 | ocfs2_wake_downconvert_thread(ocfs2_get_lockres_osb(lockres)); | ||
2863 | break; | 2867 | break; |
2864 | case OCFS2_UNLOCK_DROP_LOCK: | 2868 | case OCFS2_UNLOCK_DROP_LOCK: |
2865 | lockres->l_level = DLM_LOCK_IV; | 2869 | lockres->l_level = DLM_LOCK_IV; |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index ad5c24a29edd..077384135f4e 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
@@ -210,6 +210,7 @@ struct ocfs2_journal; | |||
210 | struct ocfs2_slot_info; | 210 | struct ocfs2_slot_info; |
211 | struct ocfs2_recovery_map; | 211 | struct ocfs2_recovery_map; |
212 | struct ocfs2_quota_recovery; | 212 | struct ocfs2_quota_recovery; |
213 | struct ocfs2_dentry_lock; | ||
213 | struct ocfs2_super | 214 | struct ocfs2_super |
214 | { | 215 | { |
215 | struct task_struct *commit_task; | 216 | struct task_struct *commit_task; |
@@ -325,6 +326,11 @@ struct ocfs2_super | |||
325 | struct list_head blocked_lock_list; | 326 | struct list_head blocked_lock_list; |
326 | unsigned long blocked_lock_count; | 327 | unsigned long blocked_lock_count; |
327 | 328 | ||
329 | /* List of dentry locks to release. Anyone can add locks to | ||
330 | * the list, ocfs2_wq processes the list */ | ||
331 | struct ocfs2_dentry_lock *dentry_lock_list; | ||
332 | struct work_struct dentry_lock_work; | ||
333 | |||
328 | wait_queue_head_t osb_mount_event; | 334 | wait_queue_head_t osb_mount_event; |
329 | 335 | ||
330 | /* Truncate log info */ | 336 | /* Truncate log info */ |
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index 6aff8f2d3e49..1ed0f7c86869 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
@@ -754,7 +754,9 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) | |||
754 | if (dquot->dq_flags & mask) | 754 | if (dquot->dq_flags & mask) |
755 | sync = 1; | 755 | sync = 1; |
756 | spin_unlock(&dq_data_lock); | 756 | spin_unlock(&dq_data_lock); |
757 | if (!sync) { | 757 | /* This is a slight hack but we can't afford getting global quota |
758 | * lock if we already have a transaction started. */ | ||
759 | if (!sync || journal_current_handle()) { | ||
758 | status = ocfs2_write_dquot(dquot); | 760 | status = ocfs2_write_dquot(dquot); |
759 | goto out; | 761 | goto out; |
760 | } | 762 | } |
@@ -810,171 +812,6 @@ out: | |||
810 | return status; | 812 | return status; |
811 | } | 813 | } |
812 | 814 | ||
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) | 815 | static struct dquot *ocfs2_alloc_dquot(struct super_block *sb, int type) |
979 | { | 816 | { |
980 | struct ocfs2_dquot *dquot = | 817 | struct ocfs2_dquot *dquot = |
@@ -991,8 +828,8 @@ static void ocfs2_destroy_dquot(struct dquot *dquot) | |||
991 | } | 828 | } |
992 | 829 | ||
993 | struct dquot_operations ocfs2_quota_operations = { | 830 | struct dquot_operations ocfs2_quota_operations = { |
994 | .initialize = ocfs2_dquot_initialize, | 831 | .initialize = dquot_initialize, |
995 | .drop = ocfs2_dquot_drop, | 832 | .drop = dquot_drop, |
996 | .alloc_space = dquot_alloc_space, | 833 | .alloc_space = dquot_alloc_space, |
997 | .alloc_inode = dquot_alloc_inode, | 834 | .alloc_inode = dquot_alloc_inode, |
998 | .free_space = dquot_free_space, | 835 | .free_space = dquot_free_space, |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 43ed11345b59..b1cb38fbe807 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -1887,6 +1887,9 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1887 | INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery); | 1887 | INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery); |
1888 | journal->j_state = OCFS2_JOURNAL_FREE; | 1888 | journal->j_state = OCFS2_JOURNAL_FREE; |
1889 | 1889 | ||
1890 | INIT_WORK(&osb->dentry_lock_work, ocfs2_drop_dl_inodes); | ||
1891 | osb->dentry_lock_list = NULL; | ||
1892 | |||
1890 | /* get some pseudo constants for clustersize bits */ | 1893 | /* get some pseudo constants for clustersize bits */ |
1891 | osb->s_clustersize_bits = | 1894 | osb->s_clustersize_bits = |
1892 | le32_to_cpu(di->id2.i_super.s_clustersize_bits); | 1895 | le32_to_cpu(di->id2.i_super.s_clustersize_bits); |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index e1d638af6ac3..915039fffe6e 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -4729,13 +4729,6 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode, | |||
4729 | vb.vb_xv = (struct ocfs2_xattr_value_root *) | 4729 | vb.vb_xv = (struct ocfs2_xattr_value_root *) |
4730 | (vb.vb_bh->b_data + offset % blocksize); | 4730 | (vb.vb_bh->b_data + offset % blocksize); |
4731 | 4731 | ||
4732 | ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket, | ||
4733 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
4734 | if (ret) { | ||
4735 | mlog_errno(ret); | ||
4736 | goto out; | ||
4737 | } | ||
4738 | |||
4739 | /* | 4732 | /* |
4740 | * From here on out we have to dirty the bucket. The generic | 4733 | * From here on out we have to dirty the bucket. The generic |
4741 | * value calls only modify one of the bucket's bhs, but we need | 4734 | * value calls only modify one of the bucket's bhs, but we need |
@@ -4748,12 +4741,18 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode, | |||
4748 | ret = ocfs2_xattr_value_truncate(inode, &vb, len, ctxt); | 4741 | ret = ocfs2_xattr_value_truncate(inode, &vb, len, ctxt); |
4749 | if (ret) { | 4742 | if (ret) { |
4750 | mlog_errno(ret); | 4743 | mlog_errno(ret); |
4751 | goto out_dirty; | 4744 | goto out; |
4745 | } | ||
4746 | |||
4747 | ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket, | ||
4748 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
4749 | if (ret) { | ||
4750 | mlog_errno(ret); | ||
4751 | goto out; | ||
4752 | } | 4752 | } |
4753 | 4753 | ||
4754 | xe->xe_value_size = cpu_to_le64(len); | 4754 | xe->xe_value_size = cpu_to_le64(len); |
4755 | 4755 | ||
4756 | out_dirty: | ||
4757 | ocfs2_xattr_bucket_journal_dirty(ctxt->handle, bucket); | 4756 | ocfs2_xattr_bucket_journal_dirty(ctxt->handle, bucket); |
4758 | 4757 | ||
4759 | out: | 4758 | out: |