diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 17:45:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 17:45:52 -0500 |
commit | 7c955fca3e1d8132982148267d9efcafae849bb6 (patch) | |
tree | dd55cc5fd36e36d5c6150a0e34ec798d03b1327e /fs/udf | |
parent | e9688f6acad8cb1f2e8d7abb2de06a6a5c9cbcf2 (diff) | |
parent | a4264b3f4049ae7aeeb0017f8158119e22fa354f (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-udf-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-udf-2.6:
UDF: Close small mem leak in udf_find_entry()
udf: Fix directory corruption after extent merging
udf: Protect udf_file_aio_write from possible races
udf: Remove unnecessary bkl usages
udf: Use of s_alloc_mutex to serialize udf_relocate_blocks() execution
udf: Replace bkl with the UDF_I(inode)->i_data_sem for protect udf_inode_info struct
udf: Remove BKL from free space counting functions
udf: Call udf_add_free_space() for more blocks at once in udf_free_blocks()
udf: Remove BKL from udf_put_super() and udf_remount_fs()
udf: Protect default inode credentials by rwlock
udf: Protect all modifications of LVID with s_alloc_mutex
udf: Move handling of uniqueID into a helper function and protect it by a s_alloc_mutex
udf: Remove BKL from udf_update_inode
udf: Convert UDF_SB(sb)->s_flags to use bitops
fs/udf: Add printf format/argument verification
fs/udf: Use vzalloc
(Evil merge: this also removes the BKL dependency from the Kconfig file)
Diffstat (limited to 'fs/udf')
-rw-r--r-- | fs/udf/Kconfig | 1 | ||||
-rw-r--r-- | fs/udf/balloc.c | 3 | ||||
-rw-r--r-- | fs/udf/dir.c | 5 | ||||
-rw-r--r-- | fs/udf/file.c | 11 | ||||
-rw-r--r-- | fs/udf/ialloc.c | 21 | ||||
-rw-r--r-- | fs/udf/inode.c | 51 | ||||
-rw-r--r-- | fs/udf/namei.c | 107 | ||||
-rw-r--r-- | fs/udf/partition.c | 27 | ||||
-rw-r--r-- | fs/udf/super.c | 67 | ||||
-rw-r--r-- | fs/udf/symlink.c | 12 | ||||
-rw-r--r-- | fs/udf/udf_i.h | 13 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 22 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 4 |
13 files changed, 164 insertions, 180 deletions
diff --git a/fs/udf/Kconfig b/fs/udf/Kconfig index f8def3c8ea4c..0e0e99bd6bce 100644 --- a/fs/udf/Kconfig +++ b/fs/udf/Kconfig | |||
@@ -1,6 +1,5 @@ | |||
1 | config UDF_FS | 1 | config UDF_FS |
2 | tristate "UDF file system support" | 2 | tristate "UDF file system support" |
3 | depends on BKL # needs serious work to remove | ||
4 | select CRC_ITU_T | 3 | select CRC_ITU_T |
5 | help | 4 | help |
6 | This is the new file system used on some CD-ROMs and DVDs. Say Y if | 5 | This is the new file system used on some CD-ROMs and DVDs. Say Y if |
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index b608efaa4cee..306ee39ef2c3 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -157,10 +157,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb, | |||
157 | udf_debug("bit %ld already set\n", bit + i); | 157 | udf_debug("bit %ld already set\n", bit + i); |
158 | udf_debug("byte=%2x\n", | 158 | udf_debug("byte=%2x\n", |
159 | ((char *)bh->b_data)[(bit + i) >> 3]); | 159 | ((char *)bh->b_data)[(bit + i) >> 3]); |
160 | } else { | ||
161 | udf_add_free_space(sb, sbi->s_partition, 1); | ||
162 | } | 160 | } |
163 | } | 161 | } |
162 | udf_add_free_space(sb, sbi->s_partition, count); | ||
164 | mark_buffer_dirty(bh); | 163 | mark_buffer_dirty(bh); |
165 | if (overflow) { | 164 | if (overflow) { |
166 | block += count; | 165 | block += count; |
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 51552bf50225..eb8bfe2b89a5 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
31 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/buffer_head.h> | 33 | #include <linux/buffer_head.h> |
35 | 34 | ||
36 | #include "udf_i.h" | 35 | #include "udf_i.h" |
@@ -190,18 +189,14 @@ static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
190 | struct inode *dir = filp->f_path.dentry->d_inode; | 189 | struct inode *dir = filp->f_path.dentry->d_inode; |
191 | int result; | 190 | int result; |
192 | 191 | ||
193 | lock_kernel(); | ||
194 | |||
195 | if (filp->f_pos == 0) { | 192 | if (filp->f_pos == 0) { |
196 | if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) { | 193 | if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) { |
197 | unlock_kernel(); | ||
198 | return 0; | 194 | return 0; |
199 | } | 195 | } |
200 | filp->f_pos++; | 196 | filp->f_pos++; |
201 | } | 197 | } |
202 | 198 | ||
203 | result = do_udf_readdir(dir, filp, filldir, dirent); | 199 | result = do_udf_readdir(dir, filp, filldir, dirent); |
204 | unlock_kernel(); | ||
205 | return result; | 200 | return result; |
206 | } | 201 | } |
207 | 202 | ||
diff --git a/fs/udf/file.c b/fs/udf/file.c index 66b9e7e7e4c5..89c78486cbbe 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/string.h> /* memset */ | 32 | #include <linux/string.h> /* memset */ |
33 | #include <linux/capability.h> | 33 | #include <linux/capability.h> |
34 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
35 | #include <linux/smp_lock.h> | ||
36 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
37 | #include <linux/buffer_head.h> | 36 | #include <linux/buffer_head.h> |
38 | #include <linux/aio.h> | 37 | #include <linux/aio.h> |
@@ -114,6 +113,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
114 | size_t count = iocb->ki_left; | 113 | size_t count = iocb->ki_left; |
115 | struct udf_inode_info *iinfo = UDF_I(inode); | 114 | struct udf_inode_info *iinfo = UDF_I(inode); |
116 | 115 | ||
116 | down_write(&iinfo->i_data_sem); | ||
117 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 117 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
118 | if (file->f_flags & O_APPEND) | 118 | if (file->f_flags & O_APPEND) |
119 | pos = inode->i_size; | 119 | pos = inode->i_size; |
@@ -126,6 +126,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
126 | udf_expand_file_adinicb(inode, pos + count, &err); | 126 | udf_expand_file_adinicb(inode, pos + count, &err); |
127 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 127 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
128 | udf_debug("udf_expand_adinicb: err=%d\n", err); | 128 | udf_debug("udf_expand_adinicb: err=%d\n", err); |
129 | up_write(&iinfo->i_data_sem); | ||
129 | return err; | 130 | return err; |
130 | } | 131 | } |
131 | } else { | 132 | } else { |
@@ -135,6 +136,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
135 | iinfo->i_lenAlloc = inode->i_size; | 136 | iinfo->i_lenAlloc = inode->i_size; |
136 | } | 137 | } |
137 | } | 138 | } |
139 | up_write(&iinfo->i_data_sem); | ||
138 | 140 | ||
139 | retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); | 141 | retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); |
140 | if (retval > 0) | 142 | if (retval > 0) |
@@ -149,8 +151,6 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
149 | long old_block, new_block; | 151 | long old_block, new_block; |
150 | int result = -EINVAL; | 152 | int result = -EINVAL; |
151 | 153 | ||
152 | lock_kernel(); | ||
153 | |||
154 | if (file_permission(filp, MAY_READ) != 0) { | 154 | if (file_permission(filp, MAY_READ) != 0) { |
155 | udf_debug("no permission to access inode %lu\n", inode->i_ino); | 155 | udf_debug("no permission to access inode %lu\n", inode->i_ino); |
156 | result = -EPERM; | 156 | result = -EPERM; |
@@ -196,7 +196,6 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
196 | } | 196 | } |
197 | 197 | ||
198 | out: | 198 | out: |
199 | unlock_kernel(); | ||
200 | return result; | 199 | return result; |
201 | } | 200 | } |
202 | 201 | ||
@@ -204,10 +203,10 @@ static int udf_release_file(struct inode *inode, struct file *filp) | |||
204 | { | 203 | { |
205 | if (filp->f_mode & FMODE_WRITE) { | 204 | if (filp->f_mode & FMODE_WRITE) { |
206 | mutex_lock(&inode->i_mutex); | 205 | mutex_lock(&inode->i_mutex); |
207 | lock_kernel(); | 206 | down_write(&UDF_I(inode)->i_data_sem); |
208 | udf_discard_prealloc(inode); | 207 | udf_discard_prealloc(inode); |
209 | udf_truncate_tail_extent(inode); | 208 | udf_truncate_tail_extent(inode); |
210 | unlock_kernel(); | 209 | up_write(&UDF_I(inode)->i_data_sem); |
211 | mutex_unlock(&inode->i_mutex); | 210 | mutex_unlock(&inode->i_mutex); |
212 | } | 211 | } |
213 | return 0; | 212 | return 0; |
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 75d9304d0dc3..6fb7e0adcda0 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
@@ -92,28 +92,19 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) | |||
92 | return NULL; | 92 | return NULL; |
93 | } | 93 | } |
94 | 94 | ||
95 | mutex_lock(&sbi->s_alloc_mutex); | ||
96 | if (sbi->s_lvid_bh) { | 95 | if (sbi->s_lvid_bh) { |
97 | struct logicalVolIntegrityDesc *lvid = | 96 | struct logicalVolIntegrityDescImpUse *lvidiu; |
98 | (struct logicalVolIntegrityDesc *) | 97 | |
99 | sbi->s_lvid_bh->b_data; | 98 | iinfo->i_unique = lvid_get_unique_id(sb); |
100 | struct logicalVolIntegrityDescImpUse *lvidiu = | 99 | mutex_lock(&sbi->s_alloc_mutex); |
101 | udf_sb_lvidiu(sbi); | 100 | lvidiu = udf_sb_lvidiu(sbi); |
102 | struct logicalVolHeaderDesc *lvhd; | ||
103 | uint64_t uniqueID; | ||
104 | lvhd = (struct logicalVolHeaderDesc *) | ||
105 | (lvid->logicalVolContentsUse); | ||
106 | if (S_ISDIR(mode)) | 101 | if (S_ISDIR(mode)) |
107 | le32_add_cpu(&lvidiu->numDirs, 1); | 102 | le32_add_cpu(&lvidiu->numDirs, 1); |
108 | else | 103 | else |
109 | le32_add_cpu(&lvidiu->numFiles, 1); | 104 | le32_add_cpu(&lvidiu->numFiles, 1); |
110 | iinfo->i_unique = uniqueID = le64_to_cpu(lvhd->uniqueID); | ||
111 | if (!(++uniqueID & 0x00000000FFFFFFFFUL)) | ||
112 | uniqueID += 16; | ||
113 | lvhd->uniqueID = cpu_to_le64(uniqueID); | ||
114 | udf_updated_lvid(sb); | 105 | udf_updated_lvid(sb); |
106 | mutex_unlock(&sbi->s_alloc_mutex); | ||
115 | } | 107 | } |
116 | mutex_unlock(&sbi->s_alloc_mutex); | ||
117 | 108 | ||
118 | inode_init_owner(inode, dir, mode); | 109 | inode_init_owner(inode, dir, mode); |
119 | 110 | ||
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index fc48f37aa2dd..c6a2e782b97b 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -31,7 +31,6 @@ | |||
31 | 31 | ||
32 | #include "udfdecl.h" | 32 | #include "udfdecl.h" |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/smp_lock.h> | ||
35 | #include <linux/module.h> | 34 | #include <linux/module.h> |
36 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
37 | #include <linux/buffer_head.h> | 36 | #include <linux/buffer_head.h> |
@@ -51,6 +50,7 @@ MODULE_LICENSE("GPL"); | |||
51 | static mode_t udf_convert_permissions(struct fileEntry *); | 50 | static mode_t udf_convert_permissions(struct fileEntry *); |
52 | static int udf_update_inode(struct inode *, int); | 51 | static int udf_update_inode(struct inode *, int); |
53 | static void udf_fill_inode(struct inode *, struct buffer_head *); | 52 | static void udf_fill_inode(struct inode *, struct buffer_head *); |
53 | static int udf_sync_inode(struct inode *inode); | ||
54 | static int udf_alloc_i_data(struct inode *inode, size_t size); | 54 | static int udf_alloc_i_data(struct inode *inode, size_t size); |
55 | static struct buffer_head *inode_getblk(struct inode *, sector_t, int *, | 55 | static struct buffer_head *inode_getblk(struct inode *, sector_t, int *, |
56 | sector_t *, int *); | 56 | sector_t *, int *); |
@@ -79,9 +79,7 @@ void udf_evict_inode(struct inode *inode) | |||
79 | want_delete = 1; | 79 | want_delete = 1; |
80 | inode->i_size = 0; | 80 | inode->i_size = 0; |
81 | udf_truncate(inode); | 81 | udf_truncate(inode); |
82 | lock_kernel(); | ||
83 | udf_update_inode(inode, IS_SYNC(inode)); | 82 | udf_update_inode(inode, IS_SYNC(inode)); |
84 | unlock_kernel(); | ||
85 | } | 83 | } |
86 | invalidate_inode_buffers(inode); | 84 | invalidate_inode_buffers(inode); |
87 | end_writeback(inode); | 85 | end_writeback(inode); |
@@ -97,9 +95,7 @@ void udf_evict_inode(struct inode *inode) | |||
97 | kfree(iinfo->i_ext.i_data); | 95 | kfree(iinfo->i_ext.i_data); |
98 | iinfo->i_ext.i_data = NULL; | 96 | iinfo->i_ext.i_data = NULL; |
99 | if (want_delete) { | 97 | if (want_delete) { |
100 | lock_kernel(); | ||
101 | udf_free_inode(inode); | 98 | udf_free_inode(inode); |
102 | unlock_kernel(); | ||
103 | } | 99 | } |
104 | } | 100 | } |
105 | 101 | ||
@@ -302,10 +298,9 @@ static int udf_get_block(struct inode *inode, sector_t block, | |||
302 | err = -EIO; | 298 | err = -EIO; |
303 | new = 0; | 299 | new = 0; |
304 | bh = NULL; | 300 | bh = NULL; |
305 | |||
306 | lock_kernel(); | ||
307 | |||
308 | iinfo = UDF_I(inode); | 301 | iinfo = UDF_I(inode); |
302 | |||
303 | down_write(&iinfo->i_data_sem); | ||
309 | if (block == iinfo->i_next_alloc_block + 1) { | 304 | if (block == iinfo->i_next_alloc_block + 1) { |
310 | iinfo->i_next_alloc_block++; | 305 | iinfo->i_next_alloc_block++; |
311 | iinfo->i_next_alloc_goal++; | 306 | iinfo->i_next_alloc_goal++; |
@@ -324,7 +319,7 @@ static int udf_get_block(struct inode *inode, sector_t block, | |||
324 | map_bh(bh_result, inode->i_sb, phys); | 319 | map_bh(bh_result, inode->i_sb, phys); |
325 | 320 | ||
326 | abort: | 321 | abort: |
327 | unlock_kernel(); | 322 | up_write(&iinfo->i_data_sem); |
328 | return err; | 323 | return err; |
329 | } | 324 | } |
330 | 325 | ||
@@ -1022,16 +1017,16 @@ void udf_truncate(struct inode *inode) | |||
1022 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 1017 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
1023 | return; | 1018 | return; |
1024 | 1019 | ||
1025 | lock_kernel(); | ||
1026 | iinfo = UDF_I(inode); | 1020 | iinfo = UDF_I(inode); |
1027 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1021 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1022 | down_write(&iinfo->i_data_sem); | ||
1028 | if (inode->i_sb->s_blocksize < | 1023 | if (inode->i_sb->s_blocksize < |
1029 | (udf_file_entry_alloc_offset(inode) + | 1024 | (udf_file_entry_alloc_offset(inode) + |
1030 | inode->i_size)) { | 1025 | inode->i_size)) { |
1031 | udf_expand_file_adinicb(inode, inode->i_size, &err); | 1026 | udf_expand_file_adinicb(inode, inode->i_size, &err); |
1032 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1027 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1033 | inode->i_size = iinfo->i_lenAlloc; | 1028 | inode->i_size = iinfo->i_lenAlloc; |
1034 | unlock_kernel(); | 1029 | up_write(&iinfo->i_data_sem); |
1035 | return; | 1030 | return; |
1036 | } else | 1031 | } else |
1037 | udf_truncate_extents(inode); | 1032 | udf_truncate_extents(inode); |
@@ -1042,10 +1037,13 @@ void udf_truncate(struct inode *inode) | |||
1042 | offset - udf_file_entry_alloc_offset(inode)); | 1037 | offset - udf_file_entry_alloc_offset(inode)); |
1043 | iinfo->i_lenAlloc = inode->i_size; | 1038 | iinfo->i_lenAlloc = inode->i_size; |
1044 | } | 1039 | } |
1040 | up_write(&iinfo->i_data_sem); | ||
1045 | } else { | 1041 | } else { |
1046 | block_truncate_page(inode->i_mapping, inode->i_size, | 1042 | block_truncate_page(inode->i_mapping, inode->i_size, |
1047 | udf_get_block); | 1043 | udf_get_block); |
1044 | down_write(&iinfo->i_data_sem); | ||
1048 | udf_truncate_extents(inode); | 1045 | udf_truncate_extents(inode); |
1046 | up_write(&iinfo->i_data_sem); | ||
1049 | } | 1047 | } |
1050 | 1048 | ||
1051 | inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); | 1049 | inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); |
@@ -1053,7 +1051,6 @@ void udf_truncate(struct inode *inode) | |||
1053 | udf_sync_inode(inode); | 1051 | udf_sync_inode(inode); |
1054 | else | 1052 | else |
1055 | mark_inode_dirty(inode); | 1053 | mark_inode_dirty(inode); |
1056 | unlock_kernel(); | ||
1057 | } | 1054 | } |
1058 | 1055 | ||
1059 | static void __udf_read_inode(struct inode *inode) | 1056 | static void __udf_read_inode(struct inode *inode) |
@@ -1202,6 +1199,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1202 | return; | 1199 | return; |
1203 | } | 1200 | } |
1204 | 1201 | ||
1202 | read_lock(&sbi->s_cred_lock); | ||
1205 | inode->i_uid = le32_to_cpu(fe->uid); | 1203 | inode->i_uid = le32_to_cpu(fe->uid); |
1206 | if (inode->i_uid == -1 || | 1204 | if (inode->i_uid == -1 || |
1207 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) || | 1205 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) || |
@@ -1214,13 +1212,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1214 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) | 1212 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) |
1215 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; | 1213 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; |
1216 | 1214 | ||
1217 | inode->i_nlink = le16_to_cpu(fe->fileLinkCount); | ||
1218 | if (!inode->i_nlink) | ||
1219 | inode->i_nlink = 1; | ||
1220 | |||
1221 | inode->i_size = le64_to_cpu(fe->informationLength); | ||
1222 | iinfo->i_lenExtents = inode->i_size; | ||
1223 | |||
1224 | if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY && | 1215 | if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY && |
1225 | sbi->s_fmode != UDF_INVALID_MODE) | 1216 | sbi->s_fmode != UDF_INVALID_MODE) |
1226 | inode->i_mode = sbi->s_fmode; | 1217 | inode->i_mode = sbi->s_fmode; |
@@ -1230,6 +1221,14 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1230 | else | 1221 | else |
1231 | inode->i_mode = udf_convert_permissions(fe); | 1222 | inode->i_mode = udf_convert_permissions(fe); |
1232 | inode->i_mode &= ~sbi->s_umask; | 1223 | inode->i_mode &= ~sbi->s_umask; |
1224 | read_unlock(&sbi->s_cred_lock); | ||
1225 | |||
1226 | inode->i_nlink = le16_to_cpu(fe->fileLinkCount); | ||
1227 | if (!inode->i_nlink) | ||
1228 | inode->i_nlink = 1; | ||
1229 | |||
1230 | inode->i_size = le64_to_cpu(fe->informationLength); | ||
1231 | iinfo->i_lenExtents = inode->i_size; | ||
1233 | 1232 | ||
1234 | if (iinfo->i_efe == 0) { | 1233 | if (iinfo->i_efe == 0) { |
1235 | inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << | 1234 | inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << |
@@ -1373,16 +1372,10 @@ static mode_t udf_convert_permissions(struct fileEntry *fe) | |||
1373 | 1372 | ||
1374 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) | 1373 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) |
1375 | { | 1374 | { |
1376 | int ret; | 1375 | return udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); |
1377 | |||
1378 | lock_kernel(); | ||
1379 | ret = udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); | ||
1380 | unlock_kernel(); | ||
1381 | |||
1382 | return ret; | ||
1383 | } | 1376 | } |
1384 | 1377 | ||
1385 | int udf_sync_inode(struct inode *inode) | 1378 | static int udf_sync_inode(struct inode *inode) |
1386 | { | 1379 | { |
1387 | return udf_update_inode(inode, 1); | 1380 | return udf_update_inode(inode, 1); |
1388 | } | 1381 | } |
@@ -2048,7 +2041,7 @@ long udf_block_map(struct inode *inode, sector_t block) | |||
2048 | struct extent_position epos = {}; | 2041 | struct extent_position epos = {}; |
2049 | int ret; | 2042 | int ret; |
2050 | 2043 | ||
2051 | lock_kernel(); | 2044 | down_read(&UDF_I(inode)->i_data_sem); |
2052 | 2045 | ||
2053 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == | 2046 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == |
2054 | (EXT_RECORDED_ALLOCATED >> 30)) | 2047 | (EXT_RECORDED_ALLOCATED >> 30)) |
@@ -2056,7 +2049,7 @@ long udf_block_map(struct inode *inode, sector_t block) | |||
2056 | else | 2049 | else |
2057 | ret = 0; | 2050 | ret = 0; |
2058 | 2051 | ||
2059 | unlock_kernel(); | 2052 | up_read(&UDF_I(inode)->i_data_sem); |
2060 | brelse(epos.bh); | 2053 | brelse(epos.bh); |
2061 | 2054 | ||
2062 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) | 2055 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 6d8dc02baebb..2be0f9eb86d2 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/buffer_head.h> | 30 | #include <linux/buffer_head.h> |
32 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
33 | #include <linux/crc-itu-t.h> | 32 | #include <linux/crc-itu-t.h> |
@@ -228,10 +227,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
228 | } | 227 | } |
229 | 228 | ||
230 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) && | 229 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) && |
231 | isdotdot) { | 230 | isdotdot) |
232 | brelse(epos.bh); | 231 | goto out_ok; |
233 | return fi; | ||
234 | } | ||
235 | 232 | ||
236 | if (!lfi) | 233 | if (!lfi) |
237 | continue; | 234 | continue; |
@@ -263,7 +260,6 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | |||
263 | if (dentry->d_name.len > UDF_NAME_LEN - 2) | 260 | if (dentry->d_name.len > UDF_NAME_LEN - 2) |
264 | return ERR_PTR(-ENAMETOOLONG); | 261 | return ERR_PTR(-ENAMETOOLONG); |
265 | 262 | ||
266 | lock_kernel(); | ||
267 | #ifdef UDF_RECOVERY | 263 | #ifdef UDF_RECOVERY |
268 | /* temporary shorthand for specifying files by inode number */ | 264 | /* temporary shorthand for specifying files by inode number */ |
269 | if (!strncmp(dentry->d_name.name, ".B=", 3)) { | 265 | if (!strncmp(dentry->d_name.name, ".B=", 3)) { |
@@ -275,7 +271,6 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | |||
275 | }; | 271 | }; |
276 | inode = udf_iget(dir->i_sb, lb); | 272 | inode = udf_iget(dir->i_sb, lb); |
277 | if (!inode) { | 273 | if (!inode) { |
278 | unlock_kernel(); | ||
279 | return ERR_PTR(-EACCES); | 274 | return ERR_PTR(-EACCES); |
280 | } | 275 | } |
281 | } else | 276 | } else |
@@ -291,11 +286,9 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | |||
291 | loc = lelb_to_cpu(cfi.icb.extLocation); | 286 | loc = lelb_to_cpu(cfi.icb.extLocation); |
292 | inode = udf_iget(dir->i_sb, &loc); | 287 | inode = udf_iget(dir->i_sb, &loc); |
293 | if (!inode) { | 288 | if (!inode) { |
294 | unlock_kernel(); | ||
295 | return ERR_PTR(-EACCES); | 289 | return ERR_PTR(-EACCES); |
296 | } | 290 | } |
297 | } | 291 | } |
298 | unlock_kernel(); | ||
299 | 292 | ||
300 | return d_splice_alias(inode, dentry); | 293 | return d_splice_alias(inode, dentry); |
301 | } | 294 | } |
@@ -476,15 +469,19 @@ add: | |||
476 | f_pos >> dir->i_sb->s_blocksize_bits, 1, err); | 469 | f_pos >> dir->i_sb->s_blocksize_bits, 1, err); |
477 | if (!fibh->ebh) | 470 | if (!fibh->ebh) |
478 | goto out_err; | 471 | goto out_err; |
472 | /* Extents could have been merged, invalidate our position */ | ||
473 | brelse(epos.bh); | ||
474 | epos.bh = NULL; | ||
475 | epos.block = dinfo->i_location; | ||
476 | epos.offset = udf_file_entry_alloc_offset(dir); | ||
479 | 477 | ||
480 | if (!fibh->soffset) { | 478 | if (!fibh->soffset) { |
481 | if (udf_next_aext(dir, &epos, &eloc, &elen, 1) == | 479 | /* Find the freshly allocated block */ |
482 | (EXT_RECORDED_ALLOCATED >> 30)) { | 480 | while (udf_next_aext(dir, &epos, &eloc, &elen, 1) == |
483 | block = eloc.logicalBlockNum + ((elen - 1) >> | 481 | (EXT_RECORDED_ALLOCATED >> 30)) |
482 | ; | ||
483 | block = eloc.logicalBlockNum + ((elen - 1) >> | ||
484 | dir->i_sb->s_blocksize_bits); | 484 | dir->i_sb->s_blocksize_bits); |
485 | } else | ||
486 | block++; | ||
487 | |||
488 | brelse(fibh->sbh); | 485 | brelse(fibh->sbh); |
489 | fibh->sbh = fibh->ebh; | 486 | fibh->sbh = fibh->ebh; |
490 | fi = (struct fileIdentDesc *)(fibh->sbh->b_data); | 487 | fi = (struct fileIdentDesc *)(fibh->sbh->b_data); |
@@ -562,10 +559,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, | |||
562 | int err; | 559 | int err; |
563 | struct udf_inode_info *iinfo; | 560 | struct udf_inode_info *iinfo; |
564 | 561 | ||
565 | lock_kernel(); | ||
566 | inode = udf_new_inode(dir, mode, &err); | 562 | inode = udf_new_inode(dir, mode, &err); |
567 | if (!inode) { | 563 | if (!inode) { |
568 | unlock_kernel(); | ||
569 | return err; | 564 | return err; |
570 | } | 565 | } |
571 | 566 | ||
@@ -583,7 +578,6 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, | |||
583 | inode->i_nlink--; | 578 | inode->i_nlink--; |
584 | mark_inode_dirty(inode); | 579 | mark_inode_dirty(inode); |
585 | iput(inode); | 580 | iput(inode); |
586 | unlock_kernel(); | ||
587 | return err; | 581 | return err; |
588 | } | 582 | } |
589 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 583 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); |
@@ -596,7 +590,6 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, | |||
596 | if (fibh.sbh != fibh.ebh) | 590 | if (fibh.sbh != fibh.ebh) |
597 | brelse(fibh.ebh); | 591 | brelse(fibh.ebh); |
598 | brelse(fibh.sbh); | 592 | brelse(fibh.sbh); |
599 | unlock_kernel(); | ||
600 | d_instantiate(dentry, inode); | 593 | d_instantiate(dentry, inode); |
601 | 594 | ||
602 | return 0; | 595 | return 0; |
@@ -614,7 +607,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
614 | if (!old_valid_dev(rdev)) | 607 | if (!old_valid_dev(rdev)) |
615 | return -EINVAL; | 608 | return -EINVAL; |
616 | 609 | ||
617 | lock_kernel(); | ||
618 | err = -EIO; | 610 | err = -EIO; |
619 | inode = udf_new_inode(dir, mode, &err); | 611 | inode = udf_new_inode(dir, mode, &err); |
620 | if (!inode) | 612 | if (!inode) |
@@ -627,7 +619,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
627 | inode->i_nlink--; | 619 | inode->i_nlink--; |
628 | mark_inode_dirty(inode); | 620 | mark_inode_dirty(inode); |
629 | iput(inode); | 621 | iput(inode); |
630 | unlock_kernel(); | ||
631 | return err; | 622 | return err; |
632 | } | 623 | } |
633 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 624 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); |
@@ -646,7 +637,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
646 | err = 0; | 637 | err = 0; |
647 | 638 | ||
648 | out: | 639 | out: |
649 | unlock_kernel(); | ||
650 | return err; | 640 | return err; |
651 | } | 641 | } |
652 | 642 | ||
@@ -659,7 +649,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
659 | struct udf_inode_info *dinfo = UDF_I(dir); | 649 | struct udf_inode_info *dinfo = UDF_I(dir); |
660 | struct udf_inode_info *iinfo; | 650 | struct udf_inode_info *iinfo; |
661 | 651 | ||
662 | lock_kernel(); | ||
663 | err = -EMLINK; | 652 | err = -EMLINK; |
664 | if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1) | 653 | if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1) |
665 | goto out; | 654 | goto out; |
@@ -712,7 +701,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
712 | err = 0; | 701 | err = 0; |
713 | 702 | ||
714 | out: | 703 | out: |
715 | unlock_kernel(); | ||
716 | return err; | 704 | return err; |
717 | } | 705 | } |
718 | 706 | ||
@@ -794,7 +782,6 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) | |||
794 | struct kernel_lb_addr tloc; | 782 | struct kernel_lb_addr tloc; |
795 | 783 | ||
796 | retval = -ENOENT; | 784 | retval = -ENOENT; |
797 | lock_kernel(); | ||
798 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 785 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
799 | if (!fi) | 786 | if (!fi) |
800 | goto out; | 787 | goto out; |
@@ -826,7 +813,6 @@ end_rmdir: | |||
826 | brelse(fibh.sbh); | 813 | brelse(fibh.sbh); |
827 | 814 | ||
828 | out: | 815 | out: |
829 | unlock_kernel(); | ||
830 | return retval; | 816 | return retval; |
831 | } | 817 | } |
832 | 818 | ||
@@ -840,7 +826,6 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry) | |||
840 | struct kernel_lb_addr tloc; | 826 | struct kernel_lb_addr tloc; |
841 | 827 | ||
842 | retval = -ENOENT; | 828 | retval = -ENOENT; |
843 | lock_kernel(); | ||
844 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 829 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
845 | if (!fi) | 830 | if (!fi) |
846 | goto out; | 831 | goto out; |
@@ -870,7 +855,6 @@ end_unlink: | |||
870 | brelse(fibh.sbh); | 855 | brelse(fibh.sbh); |
871 | 856 | ||
872 | out: | 857 | out: |
873 | unlock_kernel(); | ||
874 | return retval; | 858 | return retval; |
875 | } | 859 | } |
876 | 860 | ||
@@ -890,21 +874,21 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
890 | int block; | 874 | int block; |
891 | unsigned char *name = NULL; | 875 | unsigned char *name = NULL; |
892 | int namelen; | 876 | int namelen; |
893 | struct buffer_head *bh; | ||
894 | struct udf_inode_info *iinfo; | 877 | struct udf_inode_info *iinfo; |
878 | struct super_block *sb = dir->i_sb; | ||
895 | 879 | ||
896 | lock_kernel(); | ||
897 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); | 880 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); |
898 | if (!inode) | 881 | if (!inode) |
899 | goto out; | 882 | goto out; |
900 | 883 | ||
884 | iinfo = UDF_I(inode); | ||
885 | down_write(&iinfo->i_data_sem); | ||
901 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); | 886 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); |
902 | if (!name) { | 887 | if (!name) { |
903 | err = -ENOMEM; | 888 | err = -ENOMEM; |
904 | goto out_no_entry; | 889 | goto out_no_entry; |
905 | } | 890 | } |
906 | 891 | ||
907 | iinfo = UDF_I(inode); | ||
908 | inode->i_data.a_ops = &udf_symlink_aops; | 892 | inode->i_data.a_ops = &udf_symlink_aops; |
909 | inode->i_op = &udf_symlink_inode_operations; | 893 | inode->i_op = &udf_symlink_inode_operations; |
910 | 894 | ||
@@ -912,7 +896,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
912 | struct kernel_lb_addr eloc; | 896 | struct kernel_lb_addr eloc; |
913 | uint32_t bsize; | 897 | uint32_t bsize; |
914 | 898 | ||
915 | block = udf_new_block(inode->i_sb, inode, | 899 | block = udf_new_block(sb, inode, |
916 | iinfo->i_location.partitionReferenceNum, | 900 | iinfo->i_location.partitionReferenceNum, |
917 | iinfo->i_location.logicalBlockNum, &err); | 901 | iinfo->i_location.logicalBlockNum, &err); |
918 | if (!block) | 902 | if (!block) |
@@ -923,17 +907,17 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
923 | eloc.logicalBlockNum = block; | 907 | eloc.logicalBlockNum = block; |
924 | eloc.partitionReferenceNum = | 908 | eloc.partitionReferenceNum = |
925 | iinfo->i_location.partitionReferenceNum; | 909 | iinfo->i_location.partitionReferenceNum; |
926 | bsize = inode->i_sb->s_blocksize; | 910 | bsize = sb->s_blocksize; |
927 | iinfo->i_lenExtents = bsize; | 911 | iinfo->i_lenExtents = bsize; |
928 | udf_add_aext(inode, &epos, &eloc, bsize, 0); | 912 | udf_add_aext(inode, &epos, &eloc, bsize, 0); |
929 | brelse(epos.bh); | 913 | brelse(epos.bh); |
930 | 914 | ||
931 | block = udf_get_pblock(inode->i_sb, block, | 915 | block = udf_get_pblock(sb, block, |
932 | iinfo->i_location.partitionReferenceNum, | 916 | iinfo->i_location.partitionReferenceNum, |
933 | 0); | 917 | 0); |
934 | epos.bh = udf_tgetblk(inode->i_sb, block); | 918 | epos.bh = udf_tgetblk(sb, block); |
935 | lock_buffer(epos.bh); | 919 | lock_buffer(epos.bh); |
936 | memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); | 920 | memset(epos.bh->b_data, 0x00, bsize); |
937 | set_buffer_uptodate(epos.bh); | 921 | set_buffer_uptodate(epos.bh); |
938 | unlock_buffer(epos.bh); | 922 | unlock_buffer(epos.bh); |
939 | mark_buffer_dirty_inode(epos.bh, inode); | 923 | mark_buffer_dirty_inode(epos.bh, inode); |
@@ -941,7 +925,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
941 | } else | 925 | } else |
942 | ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr; | 926 | ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr; |
943 | 927 | ||
944 | eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode); | 928 | eoffset = sb->s_blocksize - udf_ext0_offset(inode); |
945 | pc = (struct pathComponent *)ea; | 929 | pc = (struct pathComponent *)ea; |
946 | 930 | ||
947 | if (*symname == '/') { | 931 | if (*symname == '/') { |
@@ -981,7 +965,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
981 | } | 965 | } |
982 | 966 | ||
983 | if (pc->componentType == 5) { | 967 | if (pc->componentType == 5) { |
984 | namelen = udf_put_filename(inode->i_sb, compstart, name, | 968 | namelen = udf_put_filename(sb, compstart, name, |
985 | symname - compstart); | 969 | symname - compstart); |
986 | if (!namelen) | 970 | if (!namelen) |
987 | goto out_no_entry; | 971 | goto out_no_entry; |
@@ -1015,27 +999,16 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
1015 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 999 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
1016 | if (!fi) | 1000 | if (!fi) |
1017 | goto out_no_entry; | 1001 | goto out_no_entry; |
1018 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 1002 | cfi.icb.extLength = cpu_to_le32(sb->s_blocksize); |
1019 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); | 1003 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); |
1020 | bh = UDF_SB(inode->i_sb)->s_lvid_bh; | 1004 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { |
1021 | if (bh) { | ||
1022 | struct logicalVolIntegrityDesc *lvid = | ||
1023 | (struct logicalVolIntegrityDesc *)bh->b_data; | ||
1024 | struct logicalVolHeaderDesc *lvhd; | ||
1025 | uint64_t uniqueID; | ||
1026 | lvhd = (struct logicalVolHeaderDesc *) | ||
1027 | lvid->logicalVolContentsUse; | ||
1028 | uniqueID = le64_to_cpu(lvhd->uniqueID); | ||
1029 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | 1005 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = |
1030 | cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); | 1006 | cpu_to_le32(lvid_get_unique_id(sb)); |
1031 | if (!(++uniqueID & 0x00000000FFFFFFFFUL)) | ||
1032 | uniqueID += 16; | ||
1033 | lvhd->uniqueID = cpu_to_le64(uniqueID); | ||
1034 | mark_buffer_dirty(bh); | ||
1035 | } | 1007 | } |
1036 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 1008 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
1037 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1009 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
1038 | mark_inode_dirty(dir); | 1010 | mark_inode_dirty(dir); |
1011 | up_write(&iinfo->i_data_sem); | ||
1039 | if (fibh.sbh != fibh.ebh) | 1012 | if (fibh.sbh != fibh.ebh) |
1040 | brelse(fibh.ebh); | 1013 | brelse(fibh.ebh); |
1041 | brelse(fibh.sbh); | 1014 | brelse(fibh.sbh); |
@@ -1044,10 +1017,10 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
1044 | 1017 | ||
1045 | out: | 1018 | out: |
1046 | kfree(name); | 1019 | kfree(name); |
1047 | unlock_kernel(); | ||
1048 | return err; | 1020 | return err; |
1049 | 1021 | ||
1050 | out_no_entry: | 1022 | out_no_entry: |
1023 | up_write(&iinfo->i_data_sem); | ||
1051 | inode_dec_link_count(inode); | 1024 | inode_dec_link_count(inode); |
1052 | iput(inode); | 1025 | iput(inode); |
1053 | goto out; | 1026 | goto out; |
@@ -1060,36 +1033,20 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1060 | struct udf_fileident_bh fibh; | 1033 | struct udf_fileident_bh fibh; |
1061 | struct fileIdentDesc cfi, *fi; | 1034 | struct fileIdentDesc cfi, *fi; |
1062 | int err; | 1035 | int err; |
1063 | struct buffer_head *bh; | ||
1064 | 1036 | ||
1065 | lock_kernel(); | ||
1066 | if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { | 1037 | if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { |
1067 | unlock_kernel(); | ||
1068 | return -EMLINK; | 1038 | return -EMLINK; |
1069 | } | 1039 | } |
1070 | 1040 | ||
1071 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 1041 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
1072 | if (!fi) { | 1042 | if (!fi) { |
1073 | unlock_kernel(); | ||
1074 | return err; | 1043 | return err; |
1075 | } | 1044 | } |
1076 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 1045 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); |
1077 | cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location); | 1046 | cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location); |
1078 | bh = UDF_SB(inode->i_sb)->s_lvid_bh; | 1047 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { |
1079 | if (bh) { | ||
1080 | struct logicalVolIntegrityDesc *lvid = | ||
1081 | (struct logicalVolIntegrityDesc *)bh->b_data; | ||
1082 | struct logicalVolHeaderDesc *lvhd; | ||
1083 | uint64_t uniqueID; | ||
1084 | lvhd = (struct logicalVolHeaderDesc *) | ||
1085 | (lvid->logicalVolContentsUse); | ||
1086 | uniqueID = le64_to_cpu(lvhd->uniqueID); | ||
1087 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | 1048 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = |
1088 | cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); | 1049 | cpu_to_le32(lvid_get_unique_id(inode->i_sb)); |
1089 | if (!(++uniqueID & 0x00000000FFFFFFFFUL)) | ||
1090 | uniqueID += 16; | ||
1091 | lvhd->uniqueID = cpu_to_le64(uniqueID); | ||
1092 | mark_buffer_dirty(bh); | ||
1093 | } | 1050 | } |
1094 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 1051 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
1095 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1052 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
@@ -1103,7 +1060,6 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1103 | mark_inode_dirty(inode); | 1060 | mark_inode_dirty(inode); |
1104 | ihold(inode); | 1061 | ihold(inode); |
1105 | d_instantiate(dentry, inode); | 1062 | d_instantiate(dentry, inode); |
1106 | unlock_kernel(); | ||
1107 | 1063 | ||
1108 | return 0; | 1064 | return 0; |
1109 | } | 1065 | } |
@@ -1124,7 +1080,6 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1124 | struct kernel_lb_addr tloc; | 1080 | struct kernel_lb_addr tloc; |
1125 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); | 1081 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); |
1126 | 1082 | ||
1127 | lock_kernel(); | ||
1128 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); | 1083 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1129 | if (ofi) { | 1084 | if (ofi) { |
1130 | if (ofibh.sbh != ofibh.ebh) | 1085 | if (ofibh.sbh != ofibh.ebh) |
@@ -1248,7 +1203,6 @@ end_rename: | |||
1248 | brelse(nfibh.ebh); | 1203 | brelse(nfibh.ebh); |
1249 | brelse(nfibh.sbh); | 1204 | brelse(nfibh.sbh); |
1250 | } | 1205 | } |
1251 | unlock_kernel(); | ||
1252 | 1206 | ||
1253 | return retval; | 1207 | return retval; |
1254 | } | 1208 | } |
@@ -1261,7 +1215,6 @@ static struct dentry *udf_get_parent(struct dentry *child) | |||
1261 | struct fileIdentDesc cfi; | 1215 | struct fileIdentDesc cfi; |
1262 | struct udf_fileident_bh fibh; | 1216 | struct udf_fileident_bh fibh; |
1263 | 1217 | ||
1264 | lock_kernel(); | ||
1265 | if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) | 1218 | if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) |
1266 | goto out_unlock; | 1219 | goto out_unlock; |
1267 | 1220 | ||
@@ -1273,11 +1226,9 @@ static struct dentry *udf_get_parent(struct dentry *child) | |||
1273 | inode = udf_iget(child->d_inode->i_sb, &tloc); | 1226 | inode = udf_iget(child->d_inode->i_sb, &tloc); |
1274 | if (!inode) | 1227 | if (!inode) |
1275 | goto out_unlock; | 1228 | goto out_unlock; |
1276 | unlock_kernel(); | ||
1277 | 1229 | ||
1278 | return d_obtain_alias(inode); | 1230 | return d_obtain_alias(inode); |
1279 | out_unlock: | 1231 | out_unlock: |
1280 | unlock_kernel(); | ||
1281 | return ERR_PTR(-EACCES); | 1232 | return ERR_PTR(-EACCES); |
1282 | } | 1233 | } |
1283 | 1234 | ||
diff --git a/fs/udf/partition.c b/fs/udf/partition.c index 745eb209be0c..a71090ea0e07 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
28 | #include <linux/mutex.h> | ||
28 | 29 | ||
29 | uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, | 30 | uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, |
30 | uint16_t partition, uint32_t offset) | 31 | uint16_t partition, uint32_t offset) |
@@ -159,7 +160,9 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
159 | struct udf_sb_info *sbi = UDF_SB(sb); | 160 | struct udf_sb_info *sbi = UDF_SB(sb); |
160 | u16 reallocationTableLen; | 161 | u16 reallocationTableLen; |
161 | struct buffer_head *bh; | 162 | struct buffer_head *bh; |
163 | int ret = 0; | ||
162 | 164 | ||
165 | mutex_lock(&sbi->s_alloc_mutex); | ||
163 | for (i = 0; i < sbi->s_partitions; i++) { | 166 | for (i = 0; i < sbi->s_partitions; i++) { |
164 | struct udf_part_map *map = &sbi->s_partmaps[i]; | 167 | struct udf_part_map *map = &sbi->s_partmaps[i]; |
165 | if (old_block > map->s_partition_root && | 168 | if (old_block > map->s_partition_root && |
@@ -175,8 +178,10 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
175 | break; | 178 | break; |
176 | } | 179 | } |
177 | 180 | ||
178 | if (!st) | 181 | if (!st) { |
179 | return 1; | 182 | ret = 1; |
183 | goto out; | ||
184 | } | ||
180 | 185 | ||
181 | reallocationTableLen = | 186 | reallocationTableLen = |
182 | le16_to_cpu(st->reallocationTableLen); | 187 | le16_to_cpu(st->reallocationTableLen); |
@@ -207,14 +212,16 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
207 | ((old_block - | 212 | ((old_block - |
208 | map->s_partition_root) & | 213 | map->s_partition_root) & |
209 | (sdata->s_packet_len - 1)); | 214 | (sdata->s_packet_len - 1)); |
210 | return 0; | 215 | ret = 0; |
216 | goto out; | ||
211 | } else if (origLoc == packet) { | 217 | } else if (origLoc == packet) { |
212 | *new_block = le32_to_cpu( | 218 | *new_block = le32_to_cpu( |
213 | entry->mappedLocation) + | 219 | entry->mappedLocation) + |
214 | ((old_block - | 220 | ((old_block - |
215 | map->s_partition_root) & | 221 | map->s_partition_root) & |
216 | (sdata->s_packet_len - 1)); | 222 | (sdata->s_packet_len - 1)); |
217 | return 0; | 223 | ret = 0; |
224 | goto out; | ||
218 | } else if (origLoc > packet) | 225 | } else if (origLoc > packet) |
219 | break; | 226 | break; |
220 | } | 227 | } |
@@ -251,20 +258,24 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
251 | st->mapEntry[k].mappedLocation) + | 258 | st->mapEntry[k].mappedLocation) + |
252 | ((old_block - map->s_partition_root) & | 259 | ((old_block - map->s_partition_root) & |
253 | (sdata->s_packet_len - 1)); | 260 | (sdata->s_packet_len - 1)); |
254 | return 0; | 261 | ret = 0; |
262 | goto out; | ||
255 | } | 263 | } |
256 | 264 | ||
257 | return 1; | 265 | ret = 1; |
266 | goto out; | ||
258 | } /* if old_block */ | 267 | } /* if old_block */ |
259 | } | 268 | } |
260 | 269 | ||
261 | if (i == sbi->s_partitions) { | 270 | if (i == sbi->s_partitions) { |
262 | /* outside of partitions */ | 271 | /* outside of partitions */ |
263 | /* for now, fail =) */ | 272 | /* for now, fail =) */ |
264 | return 1; | 273 | ret = 1; |
265 | } | 274 | } |
266 | 275 | ||
267 | return 0; | 276 | out: |
277 | mutex_unlock(&sbi->s_alloc_mutex); | ||
278 | return ret; | ||
268 | } | 279 | } |
269 | 280 | ||
270 | static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block, | 281 | static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block, |
diff --git a/fs/udf/super.c b/fs/udf/super.c index b539d53320fb..7b27b063ff6d 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <linux/stat.h> | 48 | #include <linux/stat.h> |
49 | #include <linux/cdrom.h> | 49 | #include <linux/cdrom.h> |
50 | #include <linux/nls.h> | 50 | #include <linux/nls.h> |
51 | #include <linux/smp_lock.h> | ||
52 | #include <linux/buffer_head.h> | 51 | #include <linux/buffer_head.h> |
53 | #include <linux/vfs.h> | 52 | #include <linux/vfs.h> |
54 | #include <linux/vmalloc.h> | 53 | #include <linux/vmalloc.h> |
@@ -135,6 +134,7 @@ static struct inode *udf_alloc_inode(struct super_block *sb) | |||
135 | ei->i_next_alloc_block = 0; | 134 | ei->i_next_alloc_block = 0; |
136 | ei->i_next_alloc_goal = 0; | 135 | ei->i_next_alloc_goal = 0; |
137 | ei->i_strat4096 = 0; | 136 | ei->i_strat4096 = 0; |
137 | init_rwsem(&ei->i_data_sem); | ||
138 | 138 | ||
139 | return &ei->vfs_inode; | 139 | return &ei->vfs_inode; |
140 | } | 140 | } |
@@ -574,13 +574,14 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
574 | if (!udf_parse_options(options, &uopt, true)) | 574 | if (!udf_parse_options(options, &uopt, true)) |
575 | return -EINVAL; | 575 | return -EINVAL; |
576 | 576 | ||
577 | lock_kernel(); | 577 | write_lock(&sbi->s_cred_lock); |
578 | sbi->s_flags = uopt.flags; | 578 | sbi->s_flags = uopt.flags; |
579 | sbi->s_uid = uopt.uid; | 579 | sbi->s_uid = uopt.uid; |
580 | sbi->s_gid = uopt.gid; | 580 | sbi->s_gid = uopt.gid; |
581 | sbi->s_umask = uopt.umask; | 581 | sbi->s_umask = uopt.umask; |
582 | sbi->s_fmode = uopt.fmode; | 582 | sbi->s_fmode = uopt.fmode; |
583 | sbi->s_dmode = uopt.dmode; | 583 | sbi->s_dmode = uopt.dmode; |
584 | write_unlock(&sbi->s_cred_lock); | ||
584 | 585 | ||
585 | if (sbi->s_lvid_bh) { | 586 | if (sbi->s_lvid_bh) { |
586 | int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); | 587 | int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); |
@@ -597,7 +598,6 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
597 | udf_open_lvid(sb); | 598 | udf_open_lvid(sb); |
598 | 599 | ||
599 | out_unlock: | 600 | out_unlock: |
600 | unlock_kernel(); | ||
601 | return error; | 601 | return error; |
602 | } | 602 | } |
603 | 603 | ||
@@ -966,9 +966,9 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | |||
966 | (sizeof(struct buffer_head *) * nr_groups); | 966 | (sizeof(struct buffer_head *) * nr_groups); |
967 | 967 | ||
968 | if (size <= PAGE_SIZE) | 968 | if (size <= PAGE_SIZE) |
969 | bitmap = kmalloc(size, GFP_KERNEL); | 969 | bitmap = kzalloc(size, GFP_KERNEL); |
970 | else | 970 | else |
971 | bitmap = vmalloc(size); /* TODO: get rid of vmalloc */ | 971 | bitmap = vzalloc(size); /* TODO: get rid of vzalloc */ |
972 | 972 | ||
973 | if (bitmap == NULL) { | 973 | if (bitmap == NULL) { |
974 | udf_error(sb, __func__, | 974 | udf_error(sb, __func__, |
@@ -977,7 +977,6 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | |||
977 | return NULL; | 977 | return NULL; |
978 | } | 978 | } |
979 | 979 | ||
980 | memset(bitmap, 0x00, size); | ||
981 | bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1); | 980 | bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1); |
982 | bitmap->s_nr_groups = nr_groups; | 981 | bitmap->s_nr_groups = nr_groups; |
983 | return bitmap; | 982 | return bitmap; |
@@ -1781,6 +1780,8 @@ static void udf_open_lvid(struct super_block *sb) | |||
1781 | 1780 | ||
1782 | if (!bh) | 1781 | if (!bh) |
1783 | return; | 1782 | return; |
1783 | |||
1784 | mutex_lock(&sbi->s_alloc_mutex); | ||
1784 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1785 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
1785 | lvidiu = udf_sb_lvidiu(sbi); | 1786 | lvidiu = udf_sb_lvidiu(sbi); |
1786 | 1787 | ||
@@ -1797,6 +1798,7 @@ static void udf_open_lvid(struct super_block *sb) | |||
1797 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | 1798 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
1798 | mark_buffer_dirty(bh); | 1799 | mark_buffer_dirty(bh); |
1799 | sbi->s_lvid_dirty = 0; | 1800 | sbi->s_lvid_dirty = 0; |
1801 | mutex_unlock(&sbi->s_alloc_mutex); | ||
1800 | } | 1802 | } |
1801 | 1803 | ||
1802 | static void udf_close_lvid(struct super_block *sb) | 1804 | static void udf_close_lvid(struct super_block *sb) |
@@ -1809,6 +1811,7 @@ static void udf_close_lvid(struct super_block *sb) | |||
1809 | if (!bh) | 1811 | if (!bh) |
1810 | return; | 1812 | return; |
1811 | 1813 | ||
1814 | mutex_lock(&sbi->s_alloc_mutex); | ||
1812 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1815 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
1813 | lvidiu = udf_sb_lvidiu(sbi); | 1816 | lvidiu = udf_sb_lvidiu(sbi); |
1814 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1817 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
@@ -1829,6 +1832,34 @@ static void udf_close_lvid(struct super_block *sb) | |||
1829 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | 1832 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
1830 | mark_buffer_dirty(bh); | 1833 | mark_buffer_dirty(bh); |
1831 | sbi->s_lvid_dirty = 0; | 1834 | sbi->s_lvid_dirty = 0; |
1835 | mutex_unlock(&sbi->s_alloc_mutex); | ||
1836 | } | ||
1837 | |||
1838 | u64 lvid_get_unique_id(struct super_block *sb) | ||
1839 | { | ||
1840 | struct buffer_head *bh; | ||
1841 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
1842 | struct logicalVolIntegrityDesc *lvid; | ||
1843 | struct logicalVolHeaderDesc *lvhd; | ||
1844 | u64 uniqueID; | ||
1845 | u64 ret; | ||
1846 | |||
1847 | bh = sbi->s_lvid_bh; | ||
1848 | if (!bh) | ||
1849 | return 0; | ||
1850 | |||
1851 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | ||
1852 | lvhd = (struct logicalVolHeaderDesc *)lvid->logicalVolContentsUse; | ||
1853 | |||
1854 | mutex_lock(&sbi->s_alloc_mutex); | ||
1855 | ret = uniqueID = le64_to_cpu(lvhd->uniqueID); | ||
1856 | if (!(++uniqueID & 0xFFFFFFFF)) | ||
1857 | uniqueID += 16; | ||
1858 | lvhd->uniqueID = cpu_to_le64(uniqueID); | ||
1859 | mutex_unlock(&sbi->s_alloc_mutex); | ||
1860 | mark_buffer_dirty(bh); | ||
1861 | |||
1862 | return ret; | ||
1832 | } | 1863 | } |
1833 | 1864 | ||
1834 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | 1865 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) |
@@ -1886,8 +1917,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1886 | struct kernel_lb_addr rootdir, fileset; | 1917 | struct kernel_lb_addr rootdir, fileset; |
1887 | struct udf_sb_info *sbi; | 1918 | struct udf_sb_info *sbi; |
1888 | 1919 | ||
1889 | lock_kernel(); | ||
1890 | |||
1891 | uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); | 1920 | uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); |
1892 | uopt.uid = -1; | 1921 | uopt.uid = -1; |
1893 | uopt.gid = -1; | 1922 | uopt.gid = -1; |
@@ -1896,10 +1925,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1896 | uopt.dmode = UDF_INVALID_MODE; | 1925 | uopt.dmode = UDF_INVALID_MODE; |
1897 | 1926 | ||
1898 | sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL); | 1927 | sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL); |
1899 | if (!sbi) { | 1928 | if (!sbi) |
1900 | unlock_kernel(); | ||
1901 | return -ENOMEM; | 1929 | return -ENOMEM; |
1902 | } | ||
1903 | 1930 | ||
1904 | sb->s_fs_info = sbi; | 1931 | sb->s_fs_info = sbi; |
1905 | 1932 | ||
@@ -1936,6 +1963,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1936 | sbi->s_fmode = uopt.fmode; | 1963 | sbi->s_fmode = uopt.fmode; |
1937 | sbi->s_dmode = uopt.dmode; | 1964 | sbi->s_dmode = uopt.dmode; |
1938 | sbi->s_nls_map = uopt.nls_map; | 1965 | sbi->s_nls_map = uopt.nls_map; |
1966 | rwlock_init(&sbi->s_cred_lock); | ||
1939 | 1967 | ||
1940 | if (uopt.session == 0xFFFFFFFF) | 1968 | if (uopt.session == 0xFFFFFFFF) |
1941 | sbi->s_session = udf_get_last_session(sb); | 1969 | sbi->s_session = udf_get_last_session(sb); |
@@ -2045,7 +2073,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
2045 | goto error_out; | 2073 | goto error_out; |
2046 | } | 2074 | } |
2047 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 2075 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
2048 | unlock_kernel(); | ||
2049 | return 0; | 2076 | return 0; |
2050 | 2077 | ||
2051 | error_out: | 2078 | error_out: |
@@ -2066,7 +2093,6 @@ error_out: | |||
2066 | kfree(sbi); | 2093 | kfree(sbi); |
2067 | sb->s_fs_info = NULL; | 2094 | sb->s_fs_info = NULL; |
2068 | 2095 | ||
2069 | unlock_kernel(); | ||
2070 | return -EINVAL; | 2096 | return -EINVAL; |
2071 | } | 2097 | } |
2072 | 2098 | ||
@@ -2105,8 +2131,6 @@ static void udf_put_super(struct super_block *sb) | |||
2105 | 2131 | ||
2106 | sbi = UDF_SB(sb); | 2132 | sbi = UDF_SB(sb); |
2107 | 2133 | ||
2108 | lock_kernel(); | ||
2109 | |||
2110 | if (sbi->s_vat_inode) | 2134 | if (sbi->s_vat_inode) |
2111 | iput(sbi->s_vat_inode); | 2135 | iput(sbi->s_vat_inode); |
2112 | if (sbi->s_partitions) | 2136 | if (sbi->s_partitions) |
@@ -2122,8 +2146,6 @@ static void udf_put_super(struct super_block *sb) | |||
2122 | kfree(sbi->s_partmaps); | 2146 | kfree(sbi->s_partmaps); |
2123 | kfree(sb->s_fs_info); | 2147 | kfree(sb->s_fs_info); |
2124 | sb->s_fs_info = NULL; | 2148 | sb->s_fs_info = NULL; |
2125 | |||
2126 | unlock_kernel(); | ||
2127 | } | 2149 | } |
2128 | 2150 | ||
2129 | static int udf_sync_fs(struct super_block *sb, int wait) | 2151 | static int udf_sync_fs(struct super_block *sb, int wait) |
@@ -2186,8 +2208,6 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
2186 | uint16_t ident; | 2208 | uint16_t ident; |
2187 | struct spaceBitmapDesc *bm; | 2209 | struct spaceBitmapDesc *bm; |
2188 | 2210 | ||
2189 | lock_kernel(); | ||
2190 | |||
2191 | loc.logicalBlockNum = bitmap->s_extPosition; | 2211 | loc.logicalBlockNum = bitmap->s_extPosition; |
2192 | loc.partitionReferenceNum = UDF_SB(sb)->s_partition; | 2212 | loc.partitionReferenceNum = UDF_SB(sb)->s_partition; |
2193 | bh = udf_read_ptagged(sb, &loc, 0, &ident); | 2213 | bh = udf_read_ptagged(sb, &loc, 0, &ident); |
@@ -2224,10 +2244,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
2224 | } | 2244 | } |
2225 | } | 2245 | } |
2226 | brelse(bh); | 2246 | brelse(bh); |
2227 | |||
2228 | out: | 2247 | out: |
2229 | unlock_kernel(); | ||
2230 | |||
2231 | return accum; | 2248 | return accum; |
2232 | } | 2249 | } |
2233 | 2250 | ||
@@ -2240,8 +2257,7 @@ static unsigned int udf_count_free_table(struct super_block *sb, | |||
2240 | int8_t etype; | 2257 | int8_t etype; |
2241 | struct extent_position epos; | 2258 | struct extent_position epos; |
2242 | 2259 | ||
2243 | lock_kernel(); | 2260 | mutex_lock(&UDF_SB(sb)->s_alloc_mutex); |
2244 | |||
2245 | epos.block = UDF_I(table)->i_location; | 2261 | epos.block = UDF_I(table)->i_location; |
2246 | epos.offset = sizeof(struct unallocSpaceEntry); | 2262 | epos.offset = sizeof(struct unallocSpaceEntry); |
2247 | epos.bh = NULL; | 2263 | epos.bh = NULL; |
@@ -2250,8 +2266,7 @@ static unsigned int udf_count_free_table(struct super_block *sb, | |||
2250 | accum += (elen >> table->i_sb->s_blocksize_bits); | 2266 | accum += (elen >> table->i_sb->s_blocksize_bits); |
2251 | 2267 | ||
2252 | brelse(epos.bh); | 2268 | brelse(epos.bh); |
2253 | 2269 | mutex_unlock(&UDF_SB(sb)->s_alloc_mutex); | |
2254 | unlock_kernel(); | ||
2255 | 2270 | ||
2256 | return accum; | 2271 | return accum; |
2257 | } | 2272 | } |
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index 16064787d2b7..b1d4488b0f14 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/stat.h> | 28 | #include <linux/stat.h> |
29 | #include <linux/pagemap.h> | 29 | #include <linux/pagemap.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/buffer_head.h> | 30 | #include <linux/buffer_head.h> |
32 | #include "udf_i.h" | 31 | #include "udf_i.h" |
33 | 32 | ||
@@ -78,13 +77,16 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
78 | int err = -EIO; | 77 | int err = -EIO; |
79 | unsigned char *p = kmap(page); | 78 | unsigned char *p = kmap(page); |
80 | struct udf_inode_info *iinfo; | 79 | struct udf_inode_info *iinfo; |
80 | uint32_t pos; | ||
81 | 81 | ||
82 | lock_kernel(); | ||
83 | iinfo = UDF_I(inode); | 82 | iinfo = UDF_I(inode); |
83 | pos = udf_block_map(inode, 0); | ||
84 | |||
85 | down_read(&iinfo->i_data_sem); | ||
84 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 86 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
85 | symlink = iinfo->i_ext.i_data + iinfo->i_lenEAttr; | 87 | symlink = iinfo->i_ext.i_data + iinfo->i_lenEAttr; |
86 | } else { | 88 | } else { |
87 | bh = sb_bread(inode->i_sb, udf_block_map(inode, 0)); | 89 | bh = sb_bread(inode->i_sb, pos); |
88 | 90 | ||
89 | if (!bh) | 91 | if (!bh) |
90 | goto out; | 92 | goto out; |
@@ -95,14 +97,14 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
95 | udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); | 97 | udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); |
96 | brelse(bh); | 98 | brelse(bh); |
97 | 99 | ||
98 | unlock_kernel(); | 100 | up_read(&iinfo->i_data_sem); |
99 | SetPageUptodate(page); | 101 | SetPageUptodate(page); |
100 | kunmap(page); | 102 | kunmap(page); |
101 | unlock_page(page); | 103 | unlock_page(page); |
102 | return 0; | 104 | return 0; |
103 | 105 | ||
104 | out: | 106 | out: |
105 | unlock_kernel(); | 107 | up_read(&iinfo->i_data_sem); |
106 | SetPageError(page); | 108 | SetPageError(page); |
107 | kunmap(page); | 109 | kunmap(page); |
108 | unlock_page(page); | 110 | unlock_page(page); |
diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h index e58d1de41073..d1bd31ea724e 100644 --- a/fs/udf/udf_i.h +++ b/fs/udf/udf_i.h | |||
@@ -1,6 +1,18 @@ | |||
1 | #ifndef _UDF_I_H | 1 | #ifndef _UDF_I_H |
2 | #define _UDF_I_H | 2 | #define _UDF_I_H |
3 | 3 | ||
4 | /* | ||
5 | * The i_data_sem and i_mutex serve for protection of allocation information | ||
6 | * of a regular files and symlinks. This includes all extents belonging to | ||
7 | * the file/symlink, a fact whether data are in-inode or in external data | ||
8 | * blocks, preallocation, goal block information... When extents are read, | ||
9 | * i_mutex or i_data_sem must be held (for reading is enough in case of | ||
10 | * i_data_sem). When extents are changed, i_data_sem must be held for writing | ||
11 | * and also i_mutex must be held. | ||
12 | * | ||
13 | * For directories i_mutex is used for all the necessary protection. | ||
14 | */ | ||
15 | |||
4 | struct udf_inode_info { | 16 | struct udf_inode_info { |
5 | struct timespec i_crtime; | 17 | struct timespec i_crtime; |
6 | /* Physical address of inode */ | 18 | /* Physical address of inode */ |
@@ -21,6 +33,7 @@ struct udf_inode_info { | |||
21 | struct long_ad *i_lad; | 33 | struct long_ad *i_lad; |
22 | __u8 *i_data; | 34 | __u8 *i_data; |
23 | } i_ext; | 35 | } i_ext; |
36 | struct rw_semaphore i_data_sem; | ||
24 | struct inode vfs_inode; | 37 | struct inode vfs_inode; |
25 | }; | 38 | }; |
26 | 39 | ||
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index d113b72c2768..4858c191242b 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define __LINUX_UDF_SB_H | 2 | #define __LINUX_UDF_SB_H |
3 | 3 | ||
4 | #include <linux/mutex.h> | 4 | #include <linux/mutex.h> |
5 | #include <linux/bitops.h> | ||
5 | 6 | ||
6 | /* Since UDF 2.01 is ISO 13346 based... */ | 7 | /* Since UDF 2.01 is ISO 13346 based... */ |
7 | #define UDF_SUPER_MAGIC 0x15013346 | 8 | #define UDF_SUPER_MAGIC 0x15013346 |
@@ -128,6 +129,8 @@ struct udf_sb_info { | |||
128 | uid_t s_uid; | 129 | uid_t s_uid; |
129 | mode_t s_fmode; | 130 | mode_t s_fmode; |
130 | mode_t s_dmode; | 131 | mode_t s_dmode; |
132 | /* Lock protecting consistency of above permission settings */ | ||
133 | rwlock_t s_cred_lock; | ||
131 | 134 | ||
132 | /* Root Info */ | 135 | /* Root Info */ |
133 | struct timespec s_record_time; | 136 | struct timespec s_record_time; |
@@ -139,7 +142,7 @@ struct udf_sb_info { | |||
139 | __u16 s_udfrev; | 142 | __u16 s_udfrev; |
140 | 143 | ||
141 | /* Miscellaneous flags */ | 144 | /* Miscellaneous flags */ |
142 | __u32 s_flags; | 145 | unsigned long s_flags; |
143 | 146 | ||
144 | /* Encoding info */ | 147 | /* Encoding info */ |
145 | struct nls_table *s_nls_map; | 148 | struct nls_table *s_nls_map; |
@@ -161,8 +164,19 @@ struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi); | |||
161 | 164 | ||
162 | int udf_compute_nr_groups(struct super_block *sb, u32 partition); | 165 | int udf_compute_nr_groups(struct super_block *sb, u32 partition); |
163 | 166 | ||
164 | #define UDF_QUERY_FLAG(X,Y) ( UDF_SB(X)->s_flags & ( 1 << (Y) ) ) | 167 | static inline int UDF_QUERY_FLAG(struct super_block *sb, int flag) |
165 | #define UDF_SET_FLAG(X,Y) ( UDF_SB(X)->s_flags |= ( 1 << (Y) ) ) | 168 | { |
166 | #define UDF_CLEAR_FLAG(X,Y) ( UDF_SB(X)->s_flags &= ~( 1 << (Y) ) ) | 169 | return test_bit(flag, &UDF_SB(sb)->s_flags); |
170 | } | ||
171 | |||
172 | static inline void UDF_SET_FLAG(struct super_block *sb, int flag) | ||
173 | { | ||
174 | set_bit(flag, &UDF_SB(sb)->s_flags); | ||
175 | } | ||
176 | |||
177 | static inline void UDF_CLEAR_FLAG(struct super_block *sb, int flag) | ||
178 | { | ||
179 | clear_bit(flag, &UDF_SB(sb)->s_flags); | ||
180 | } | ||
167 | 181 | ||
168 | #endif /* __LINUX_UDF_SB_H */ | 182 | #endif /* __LINUX_UDF_SB_H */ |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 6995ab1f4305..eba48209f9f3 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -111,6 +111,8 @@ struct extent_position { | |||
111 | }; | 111 | }; |
112 | 112 | ||
113 | /* super.c */ | 113 | /* super.c */ |
114 | |||
115 | __attribute__((format(printf, 3, 4))) | ||
114 | extern void udf_warning(struct super_block *, const char *, const char *, ...); | 116 | extern void udf_warning(struct super_block *, const char *, const char *, ...); |
115 | static inline void udf_updated_lvid(struct super_block *sb) | 117 | static inline void udf_updated_lvid(struct super_block *sb) |
116 | { | 118 | { |
@@ -123,6 +125,7 @@ static inline void udf_updated_lvid(struct super_block *sb) | |||
123 | sb->s_dirt = 1; | 125 | sb->s_dirt = 1; |
124 | UDF_SB(sb)->s_lvid_dirty = 1; | 126 | UDF_SB(sb)->s_lvid_dirty = 1; |
125 | } | 127 | } |
128 | extern u64 lvid_get_unique_id(struct super_block *sb); | ||
126 | 129 | ||
127 | /* namei.c */ | 130 | /* namei.c */ |
128 | extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, | 131 | extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, |
@@ -133,7 +136,6 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, | |||
133 | extern long udf_ioctl(struct file *, unsigned int, unsigned long); | 136 | extern long udf_ioctl(struct file *, unsigned int, unsigned long); |
134 | /* inode.c */ | 137 | /* inode.c */ |
135 | extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); | 138 | extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); |
136 | extern int udf_sync_inode(struct inode *); | ||
137 | extern void udf_expand_file_adinicb(struct inode *, int, int *); | 139 | extern void udf_expand_file_adinicb(struct inode *, int, int *); |
138 | extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *); | 140 | extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *); |
139 | extern struct buffer_head *udf_bread(struct inode *, int, int, int *); | 141 | extern struct buffer_head *udf_bread(struct inode *, int, int, int *); |