Commit 97461518610fb1679f67333bb699bb81136e49fe
Committed by
Linus Torvalds
1 parent
7bf6d78dd9
Exists in
master
and in
20 other branches
[PATCH] convert ext3's truncate_sem to a mutex
ext3's truncate_sem is always released in the same function it's taken and it otherwise is a mutex as well.. Signed-off-by: Arjan van de Ven <arjan@infradead.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 5 changed files with 16 additions and 15 deletions Side-by-side Diff
fs/ext3/file.c
... | ... | @@ -37,9 +37,9 @@ |
37 | 37 | if ((filp->f_mode & FMODE_WRITE) && |
38 | 38 | (atomic_read(&inode->i_writecount) == 1)) |
39 | 39 | { |
40 | - down(&EXT3_I(inode)->truncate_sem); | |
40 | + mutex_lock(&EXT3_I(inode)->truncate_mutex); | |
41 | 41 | ext3_discard_reservation(inode); |
42 | - up(&EXT3_I(inode)->truncate_sem); | |
42 | + mutex_unlock(&EXT3_I(inode)->truncate_mutex); | |
43 | 43 | } |
44 | 44 | if (is_dx(inode) && filp->private_data) |
45 | 45 | ext3_htree_free_dir_info(filp->private_data); |
fs/ext3/inode.c
... | ... | @@ -702,7 +702,7 @@ |
702 | 702 | if (!create || err == -EIO) |
703 | 703 | goto cleanup; |
704 | 704 | |
705 | - down(&ei->truncate_sem); | |
705 | + mutex_lock(&ei->truncate_mutex); | |
706 | 706 | |
707 | 707 | /* |
708 | 708 | * If the indirect block is missing while we are reading |
... | ... | @@ -723,7 +723,7 @@ |
723 | 723 | } |
724 | 724 | partial = ext3_get_branch(inode, depth, offsets, chain, &err); |
725 | 725 | if (!partial) { |
726 | - up(&ei->truncate_sem); | |
726 | + mutex_unlock(&ei->truncate_mutex); | |
727 | 727 | if (err) |
728 | 728 | goto cleanup; |
729 | 729 | clear_buffer_new(bh_result); |
730 | 730 | |
... | ... | @@ -759,13 +759,13 @@ |
759 | 759 | err = ext3_splice_branch(handle, inode, iblock, chain, |
760 | 760 | partial, left); |
761 | 761 | /* |
762 | - * i_disksize growing is protected by truncate_sem. Don't forget to | |
762 | + * i_disksize growing is protected by truncate_mutex. Don't forget to | |
763 | 763 | * protect it if you're about to implement concurrent |
764 | 764 | * ext3_get_block() -bzzz |
765 | 765 | */ |
766 | 766 | if (!err && extend_disksize && inode->i_size > ei->i_disksize) |
767 | 767 | ei->i_disksize = inode->i_size; |
768 | - up(&ei->truncate_sem); | |
768 | + mutex_unlock(&ei->truncate_mutex); | |
769 | 769 | if (err) |
770 | 770 | goto cleanup; |
771 | 771 | |
... | ... | @@ -1227,7 +1227,7 @@ |
1227 | 1227 | * ext3_file_write() -> generic_file_write() -> __alloc_pages() -> ... |
1228 | 1228 | * |
1229 | 1229 | * Same applies to ext3_get_block(). We will deadlock on various things like |
1230 | - * lock_journal and i_truncate_sem. | |
1230 | + * lock_journal and i_truncate_mutex. | |
1231 | 1231 | * |
1232 | 1232 | * Setting PF_MEMALLOC here doesn't work - too many internal memory |
1233 | 1233 | * allocations fail. |
... | ... | @@ -2161,7 +2161,7 @@ |
2161 | 2161 | * From here we block out all ext3_get_block() callers who want to |
2162 | 2162 | * modify the block allocation tree. |
2163 | 2163 | */ |
2164 | - down(&ei->truncate_sem); | |
2164 | + mutex_lock(&ei->truncate_mutex); | |
2165 | 2165 | |
2166 | 2166 | if (n == 1) { /* direct blocks */ |
2167 | 2167 | ext3_free_data(handle, inode, NULL, i_data+offsets[0], |
... | ... | @@ -2228,7 +2228,7 @@ |
2228 | 2228 | |
2229 | 2229 | ext3_discard_reservation(inode); |
2230 | 2230 | |
2231 | - up(&ei->truncate_sem); | |
2231 | + mutex_unlock(&ei->truncate_mutex); | |
2232 | 2232 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; |
2233 | 2233 | ext3_mark_inode_dirty(handle, inode); |
2234 | 2234 |
fs/ext3/ioctl.c
... | ... | @@ -182,7 +182,7 @@ |
182 | 182 | * need to allocate reservation structure for this inode |
183 | 183 | * before set the window size |
184 | 184 | */ |
185 | - down(&ei->truncate_sem); | |
185 | + mutex_lock(&ei->truncate_mutex); | |
186 | 186 | if (!ei->i_block_alloc_info) |
187 | 187 | ext3_init_block_alloc_info(inode); |
188 | 188 | |
... | ... | @@ -190,7 +190,7 @@ |
190 | 190 | struct ext3_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node; |
191 | 191 | rsv->rsv_goal_size = rsv_window_size; |
192 | 192 | } |
193 | - up(&ei->truncate_sem); | |
193 | + mutex_unlock(&ei->truncate_mutex); | |
194 | 194 | return 0; |
195 | 195 | } |
196 | 196 | case EXT3_IOC_GROUP_EXTEND: { |
fs/ext3/super.c
include/linux/ext3_fs_i.h
... | ... | @@ -19,6 +19,7 @@ |
19 | 19 | #include <linux/rwsem.h> |
20 | 20 | #include <linux/rbtree.h> |
21 | 21 | #include <linux/seqlock.h> |
22 | +#include <linux/mutex.h> | |
22 | 23 | |
23 | 24 | struct ext3_reserve_window { |
24 | 25 | __u32 _rsv_start; /* First byte reserved */ |
25 | 26 | |
26 | 27 | |
... | ... | @@ -122,16 +123,16 @@ |
122 | 123 | __u16 i_extra_isize; |
123 | 124 | |
124 | 125 | /* |
125 | - * truncate_sem is for serialising ext3_truncate() against | |
126 | + * truncate_mutex is for serialising ext3_truncate() against | |
126 | 127 | * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's |
127 | 128 | * data tree are chopped off during truncate. We can't do that in |
128 | 129 | * ext3 because whenever we perform intermediate commits during |
129 | 130 | * truncate, the inode and all the metadata blocks *must* be in a |
130 | 131 | * consistent state which allows truncation of the orphans to restart |
131 | 132 | * during recovery. Hence we must fix the get_block-vs-truncate race |
132 | - * by other means, so we have truncate_sem. | |
133 | + * by other means, so we have truncate_mutex. | |
133 | 134 | */ |
134 | - struct semaphore truncate_sem; | |
135 | + struct mutex truncate_mutex; | |
135 | 136 | struct inode vfs_inode; |
136 | 137 | }; |
137 | 138 |