diff options
Diffstat (limited to 'fs/udf')
-rw-r--r-- | fs/udf/balloc.c | 98 | ||||
-rw-r--r-- | fs/udf/dir.c | 4 | ||||
-rw-r--r-- | fs/udf/file.c | 29 | ||||
-rw-r--r-- | fs/udf/ialloc.c | 14 | ||||
-rw-r--r-- | fs/udf/inode.c | 72 | ||||
-rw-r--r-- | fs/udf/namei.c | 84 | ||||
-rw-r--r-- | fs/udf/partition.c | 1 | ||||
-rw-r--r-- | fs/udf/super.c | 32 | ||||
-rw-r--r-- | fs/udf/symlink.c | 11 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 5 | ||||
-rw-r--r-- | fs/udf/unicode.c | 1 |
11 files changed, 199 insertions, 152 deletions
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 1e068535b58b..9a9378b4eb5a 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -31,55 +31,8 @@ | |||
31 | #define udf_clear_bit(nr, addr) ext2_clear_bit(nr, addr) | 31 | #define udf_clear_bit(nr, addr) ext2_clear_bit(nr, addr) |
32 | #define udf_set_bit(nr, addr) ext2_set_bit(nr, addr) | 32 | #define udf_set_bit(nr, addr) ext2_set_bit(nr, addr) |
33 | #define udf_test_bit(nr, addr) ext2_test_bit(nr, addr) | 33 | #define udf_test_bit(nr, addr) ext2_test_bit(nr, addr) |
34 | #define udf_find_first_one_bit(addr, size) find_first_one_bit(addr, size) | ||
35 | #define udf_find_next_one_bit(addr, size, offset) \ | 34 | #define udf_find_next_one_bit(addr, size, offset) \ |
36 | find_next_one_bit(addr, size, offset) | 35 | ext2_find_next_bit(addr, size, offset) |
37 | |||
38 | #define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x) | ||
39 | #define leNUM_to_cpup(x, y) xleNUM_to_cpup(x, y) | ||
40 | #define xleNUM_to_cpup(x, y) (le ## x ## _to_cpup(y)) | ||
41 | #define uintBPL_t uint(BITS_PER_LONG) | ||
42 | #define uint(x) xuint(x) | ||
43 | #define xuint(x) __le ## x | ||
44 | |||
45 | static inline int find_next_one_bit(void *addr, int size, int offset) | ||
46 | { | ||
47 | uintBPL_t *p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG); | ||
48 | int result = offset & ~(BITS_PER_LONG - 1); | ||
49 | unsigned long tmp; | ||
50 | |||
51 | if (offset >= size) | ||
52 | return size; | ||
53 | size -= result; | ||
54 | offset &= (BITS_PER_LONG - 1); | ||
55 | if (offset) { | ||
56 | tmp = leBPL_to_cpup(p++); | ||
57 | tmp &= ~0UL << offset; | ||
58 | if (size < BITS_PER_LONG) | ||
59 | goto found_first; | ||
60 | if (tmp) | ||
61 | goto found_middle; | ||
62 | size -= BITS_PER_LONG; | ||
63 | result += BITS_PER_LONG; | ||
64 | } | ||
65 | while (size & ~(BITS_PER_LONG - 1)) { | ||
66 | tmp = leBPL_to_cpup(p++); | ||
67 | if (tmp) | ||
68 | goto found_middle; | ||
69 | result += BITS_PER_LONG; | ||
70 | size -= BITS_PER_LONG; | ||
71 | } | ||
72 | if (!size) | ||
73 | return result; | ||
74 | tmp = leBPL_to_cpup(p); | ||
75 | found_first: | ||
76 | tmp &= ~0UL >> (BITS_PER_LONG - size); | ||
77 | found_middle: | ||
78 | return result + ffz(~tmp); | ||
79 | } | ||
80 | |||
81 | #define find_first_one_bit(addr, size)\ | ||
82 | find_next_one_bit((addr), (size), 0) | ||
83 | 36 | ||
84 | static int read_block_bitmap(struct super_block *sb, | 37 | static int read_block_bitmap(struct super_block *sb, |
85 | struct udf_bitmap *bitmap, unsigned int block, | 38 | struct udf_bitmap *bitmap, unsigned int block, |
@@ -172,9 +125,8 @@ static void udf_bitmap_free_blocks(struct super_block *sb, | |||
172 | 125 | ||
173 | mutex_lock(&sbi->s_alloc_mutex); | 126 | mutex_lock(&sbi->s_alloc_mutex); |
174 | partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; | 127 | partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; |
175 | if (bloc->logicalBlockNum < 0 || | 128 | if (bloc->logicalBlockNum + count < count || |
176 | (bloc->logicalBlockNum + count) > | 129 | (bloc->logicalBlockNum + count) > partmap->s_partition_len) { |
177 | partmap->s_partition_len) { | ||
178 | udf_debug("%d < %d || %d + %d > %d\n", | 130 | udf_debug("%d < %d || %d + %d > %d\n", |
179 | bloc->logicalBlockNum, 0, bloc->logicalBlockNum, | 131 | bloc->logicalBlockNum, 0, bloc->logicalBlockNum, |
180 | count, partmap->s_partition_len); | 132 | count, partmap->s_partition_len); |
@@ -208,7 +160,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb, | |||
208 | ((char *)bh->b_data)[(bit + i) >> 3]); | 160 | ((char *)bh->b_data)[(bit + i) >> 3]); |
209 | } else { | 161 | } else { |
210 | if (inode) | 162 | if (inode) |
211 | vfs_dq_free_block(inode, 1); | 163 | dquot_free_block(inode, 1); |
212 | udf_add_free_space(sb, sbi->s_partition, 1); | 164 | udf_add_free_space(sb, sbi->s_partition, 1); |
213 | } | 165 | } |
214 | } | 166 | } |
@@ -260,11 +212,11 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb, | |||
260 | while (bit < (sb->s_blocksize << 3) && block_count > 0) { | 212 | while (bit < (sb->s_blocksize << 3) && block_count > 0) { |
261 | if (!udf_test_bit(bit, bh->b_data)) | 213 | if (!udf_test_bit(bit, bh->b_data)) |
262 | goto out; | 214 | goto out; |
263 | else if (vfs_dq_prealloc_block(inode, 1)) | 215 | else if (dquot_prealloc_block(inode, 1)) |
264 | goto out; | 216 | goto out; |
265 | else if (!udf_clear_bit(bit, bh->b_data)) { | 217 | else if (!udf_clear_bit(bit, bh->b_data)) { |
266 | udf_debug("bit already cleared for block %d\n", bit); | 218 | udf_debug("bit already cleared for block %d\n", bit); |
267 | vfs_dq_free_block(inode, 1); | 219 | dquot_free_block(inode, 1); |
268 | goto out; | 220 | goto out; |
269 | } | 221 | } |
270 | block_count--; | 222 | block_count--; |
@@ -390,10 +342,14 @@ got_block: | |||
390 | /* | 342 | /* |
391 | * Check quota for allocation of this block. | 343 | * Check quota for allocation of this block. |
392 | */ | 344 | */ |
393 | if (inode && vfs_dq_alloc_block(inode, 1)) { | 345 | if (inode) { |
394 | mutex_unlock(&sbi->s_alloc_mutex); | 346 | int ret = dquot_alloc_block(inode, 1); |
395 | *err = -EDQUOT; | 347 | |
396 | return 0; | 348 | if (ret) { |
349 | mutex_unlock(&sbi->s_alloc_mutex); | ||
350 | *err = ret; | ||
351 | return 0; | ||
352 | } | ||
397 | } | 353 | } |
398 | 354 | ||
399 | newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) - | 355 | newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) - |
@@ -436,11 +392,10 @@ static void udf_table_free_blocks(struct super_block *sb, | |||
436 | 392 | ||
437 | mutex_lock(&sbi->s_alloc_mutex); | 393 | mutex_lock(&sbi->s_alloc_mutex); |
438 | partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; | 394 | partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; |
439 | if (bloc->logicalBlockNum < 0 || | 395 | if (bloc->logicalBlockNum + count < count || |
440 | (bloc->logicalBlockNum + count) > | 396 | (bloc->logicalBlockNum + count) > partmap->s_partition_len) { |
441 | partmap->s_partition_len) { | ||
442 | udf_debug("%d < %d || %d + %d > %d\n", | 397 | udf_debug("%d < %d || %d + %d > %d\n", |
443 | bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count, | 398 | bloc->logicalBlockNum, 0, bloc->logicalBlockNum, count, |
444 | partmap->s_partition_len); | 399 | partmap->s_partition_len); |
445 | goto error_return; | 400 | goto error_return; |
446 | } | 401 | } |
@@ -449,7 +404,7 @@ static void udf_table_free_blocks(struct super_block *sb, | |||
449 | /* We do this up front - There are some error conditions that | 404 | /* We do this up front - There are some error conditions that |
450 | could occure, but.. oh well */ | 405 | could occure, but.. oh well */ |
451 | if (inode) | 406 | if (inode) |
452 | vfs_dq_free_block(inode, count); | 407 | dquot_free_block(inode, count); |
453 | udf_add_free_space(sb, sbi->s_partition, count); | 408 | udf_add_free_space(sb, sbi->s_partition, count); |
454 | 409 | ||
455 | start = bloc->logicalBlockNum + offset; | 410 | start = bloc->logicalBlockNum + offset; |
@@ -547,7 +502,7 @@ static void udf_table_free_blocks(struct super_block *sb, | |||
547 | } | 502 | } |
548 | 503 | ||
549 | if (epos.offset + (2 * adsize) > sb->s_blocksize) { | 504 | if (epos.offset + (2 * adsize) > sb->s_blocksize) { |
550 | char *sptr, *dptr; | 505 | unsigned char *sptr, *dptr; |
551 | int loffset; | 506 | int loffset; |
552 | 507 | ||
553 | brelse(oepos.bh); | 508 | brelse(oepos.bh); |
@@ -694,7 +649,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb, | |||
694 | epos.offset -= adsize; | 649 | epos.offset -= adsize; |
695 | 650 | ||
696 | alloc_count = (elen >> sb->s_blocksize_bits); | 651 | alloc_count = (elen >> sb->s_blocksize_bits); |
697 | if (inode && vfs_dq_prealloc_block(inode, | 652 | if (inode && dquot_prealloc_block(inode, |
698 | alloc_count > block_count ? block_count : alloc_count)) | 653 | alloc_count > block_count ? block_count : alloc_count)) |
699 | alloc_count = 0; | 654 | alloc_count = 0; |
700 | else if (alloc_count > block_count) { | 655 | else if (alloc_count > block_count) { |
@@ -797,12 +752,13 @@ static int udf_table_new_block(struct super_block *sb, | |||
797 | newblock = goal_eloc.logicalBlockNum; | 752 | newblock = goal_eloc.logicalBlockNum; |
798 | goal_eloc.logicalBlockNum++; | 753 | goal_eloc.logicalBlockNum++; |
799 | goal_elen -= sb->s_blocksize; | 754 | goal_elen -= sb->s_blocksize; |
800 | 755 | if (inode) { | |
801 | if (inode && vfs_dq_alloc_block(inode, 1)) { | 756 | *err = dquot_alloc_block(inode, 1); |
802 | brelse(goal_epos.bh); | 757 | if (*err) { |
803 | mutex_unlock(&sbi->s_alloc_mutex); | 758 | brelse(goal_epos.bh); |
804 | *err = -EDQUOT; | 759 | mutex_unlock(&sbi->s_alloc_mutex); |
805 | return 0; | 760 | return 0; |
761 | } | ||
806 | } | 762 | } |
807 | 763 | ||
808 | if (goal_elen) | 764 | if (goal_elen) |
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 61d9a76a3a69..f0f2a436251e 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -45,8 +45,8 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
45 | int block, iblock; | 45 | int block, iblock; |
46 | loff_t nf_pos = (filp->f_pos - 1) << 2; | 46 | loff_t nf_pos = (filp->f_pos - 1) << 2; |
47 | int flen; | 47 | int flen; |
48 | char *fname = NULL; | 48 | unsigned char *fname = NULL; |
49 | char *nameptr; | 49 | unsigned char *nameptr; |
50 | uint16_t liu; | 50 | uint16_t liu; |
51 | uint8_t lfi; | 51 | uint8_t lfi; |
52 | loff_t size = udf_ext0_offset(dir) + dir->i_size; | 52 | loff_t size = udf_ext0_offset(dir) + dir->i_size; |
diff --git a/fs/udf/file.c b/fs/udf/file.c index b80cbd78833c..4b6a46ccbf46 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
35 | #include <linux/smp_lock.h> | 35 | #include <linux/smp_lock.h> |
36 | #include <linux/pagemap.h> | 36 | #include <linux/pagemap.h> |
37 | #include <linux/quotaops.h> | ||
37 | #include <linux/buffer_head.h> | 38 | #include <linux/buffer_head.h> |
38 | #include <linux/aio.h> | 39 | #include <linux/aio.h> |
39 | 40 | ||
@@ -196,6 +197,7 @@ static int udf_release_file(struct inode *inode, struct file *filp) | |||
196 | mutex_lock(&inode->i_mutex); | 197 | mutex_lock(&inode->i_mutex); |
197 | lock_kernel(); | 198 | lock_kernel(); |
198 | udf_discard_prealloc(inode); | 199 | udf_discard_prealloc(inode); |
200 | udf_truncate_tail_extent(inode); | ||
199 | unlock_kernel(); | 201 | unlock_kernel(); |
200 | mutex_unlock(&inode->i_mutex); | 202 | mutex_unlock(&inode->i_mutex); |
201 | } | 203 | } |
@@ -206,7 +208,7 @@ const struct file_operations udf_file_operations = { | |||
206 | .read = do_sync_read, | 208 | .read = do_sync_read, |
207 | .aio_read = generic_file_aio_read, | 209 | .aio_read = generic_file_aio_read, |
208 | .ioctl = udf_ioctl, | 210 | .ioctl = udf_ioctl, |
209 | .open = generic_file_open, | 211 | .open = dquot_file_open, |
210 | .mmap = generic_file_mmap, | 212 | .mmap = generic_file_mmap, |
211 | .write = do_sync_write, | 213 | .write = do_sync_write, |
212 | .aio_write = udf_file_aio_write, | 214 | .aio_write = udf_file_aio_write, |
@@ -216,6 +218,29 @@ const struct file_operations udf_file_operations = { | |||
216 | .llseek = generic_file_llseek, | 218 | .llseek = generic_file_llseek, |
217 | }; | 219 | }; |
218 | 220 | ||
221 | int udf_setattr(struct dentry *dentry, struct iattr *iattr) | ||
222 | { | ||
223 | struct inode *inode = dentry->d_inode; | ||
224 | int error; | ||
225 | |||
226 | error = inode_change_ok(inode, iattr); | ||
227 | if (error) | ||
228 | return error; | ||
229 | |||
230 | if (iattr->ia_valid & ATTR_SIZE) | ||
231 | dquot_initialize(inode); | ||
232 | |||
233 | if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || | ||
234 | (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { | ||
235 | error = dquot_transfer(inode, iattr); | ||
236 | if (error) | ||
237 | return error; | ||
238 | } | ||
239 | |||
240 | return inode_setattr(inode, iattr); | ||
241 | } | ||
242 | |||
219 | const struct inode_operations udf_file_inode_operations = { | 243 | const struct inode_operations udf_file_inode_operations = { |
220 | .truncate = udf_truncate, | 244 | .truncate = udf_truncate, |
245 | .setattr = udf_setattr, | ||
221 | }; | 246 | }; |
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index c10fa39f97e2..fb68c9cd0c3e 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
@@ -36,8 +36,8 @@ void udf_free_inode(struct inode *inode) | |||
36 | * Note: we must free any quota before locking the superblock, | 36 | * Note: we must free any quota before locking the superblock, |
37 | * as writing the quota to disk may need the lock as well. | 37 | * as writing the quota to disk may need the lock as well. |
38 | */ | 38 | */ |
39 | vfs_dq_free_inode(inode); | 39 | dquot_free_inode(inode); |
40 | vfs_dq_drop(inode); | 40 | dquot_drop(inode); |
41 | 41 | ||
42 | clear_inode(inode); | 42 | clear_inode(inode); |
43 | 43 | ||
@@ -61,7 +61,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) | |||
61 | struct super_block *sb = dir->i_sb; | 61 | struct super_block *sb = dir->i_sb; |
62 | struct udf_sb_info *sbi = UDF_SB(sb); | 62 | struct udf_sb_info *sbi = UDF_SB(sb); |
63 | struct inode *inode; | 63 | struct inode *inode; |
64 | int block; | 64 | int block, ret; |
65 | uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; | 65 | uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; |
66 | struct udf_inode_info *iinfo; | 66 | struct udf_inode_info *iinfo; |
67 | struct udf_inode_info *dinfo = UDF_I(dir); | 67 | struct udf_inode_info *dinfo = UDF_I(dir); |
@@ -153,12 +153,14 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) | |||
153 | insert_inode_hash(inode); | 153 | insert_inode_hash(inode); |
154 | mark_inode_dirty(inode); | 154 | mark_inode_dirty(inode); |
155 | 155 | ||
156 | if (vfs_dq_alloc_inode(inode)) { | 156 | dquot_initialize(inode); |
157 | vfs_dq_drop(inode); | 157 | ret = dquot_alloc_inode(inode); |
158 | if (ret) { | ||
159 | dquot_drop(inode); | ||
158 | inode->i_flags |= S_NOQUOTA; | 160 | inode->i_flags |= S_NOQUOTA; |
159 | inode->i_nlink = 0; | 161 | inode->i_nlink = 0; |
160 | iput(inode); | 162 | iput(inode); |
161 | *err = -EDQUOT; | 163 | *err = ret; |
162 | return NULL; | 164 | return NULL; |
163 | } | 165 | } |
164 | 166 | ||
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 6d24c2c63f93..8a3fbd177cab 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/pagemap.h> | 36 | #include <linux/pagemap.h> |
37 | #include <linux/buffer_head.h> | 37 | #include <linux/buffer_head.h> |
38 | #include <linux/writeback.h> | 38 | #include <linux/writeback.h> |
39 | #include <linux/quotaops.h> | ||
39 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
40 | #include <linux/crc-itu-t.h> | 41 | #include <linux/crc-itu-t.h> |
41 | 42 | ||
@@ -70,6 +71,9 @@ static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); | |||
70 | 71 | ||
71 | void udf_delete_inode(struct inode *inode) | 72 | void udf_delete_inode(struct inode *inode) |
72 | { | 73 | { |
74 | if (!is_bad_inode(inode)) | ||
75 | dquot_initialize(inode); | ||
76 | |||
73 | truncate_inode_pages(&inode->i_data, 0); | 77 | truncate_inode_pages(&inode->i_data, 0); |
74 | 78 | ||
75 | if (is_bad_inode(inode)) | 79 | if (is_bad_inode(inode)) |
@@ -97,15 +101,19 @@ no_delete: | |||
97 | */ | 101 | */ |
98 | void udf_clear_inode(struct inode *inode) | 102 | void udf_clear_inode(struct inode *inode) |
99 | { | 103 | { |
100 | struct udf_inode_info *iinfo; | 104 | struct udf_inode_info *iinfo = UDF_I(inode); |
101 | if (!(inode->i_sb->s_flags & MS_RDONLY)) { | 105 | |
102 | lock_kernel(); | 106 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && |
103 | udf_truncate_tail_extent(inode); | 107 | inode->i_size != iinfo->i_lenExtents) { |
104 | unlock_kernel(); | 108 | printk(KERN_WARNING "UDF-fs (%s): Inode %lu (mode %o) has " |
105 | write_inode_now(inode, 0); | 109 | "inode size %llu different from extent length %llu. " |
106 | invalidate_inode_buffers(inode); | 110 | "Filesystem need not be standards compliant.\n", |
111 | inode->i_sb->s_id, inode->i_ino, inode->i_mode, | ||
112 | (unsigned long long)inode->i_size, | ||
113 | (unsigned long long)iinfo->i_lenExtents); | ||
107 | } | 114 | } |
108 | iinfo = UDF_I(inode); | 115 | |
116 | dquot_drop(inode); | ||
109 | kfree(iinfo->i_ext.i_data); | 117 | kfree(iinfo->i_ext.i_data); |
110 | iinfo->i_ext.i_data = NULL; | 118 | iinfo->i_ext.i_data = NULL; |
111 | } | 119 | } |
@@ -198,7 +206,6 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, | |||
198 | int newblock; | 206 | int newblock; |
199 | struct buffer_head *dbh = NULL; | 207 | struct buffer_head *dbh = NULL; |
200 | struct kernel_lb_addr eloc; | 208 | struct kernel_lb_addr eloc; |
201 | uint32_t elen; | ||
202 | uint8_t alloctype; | 209 | uint8_t alloctype; |
203 | struct extent_position epos; | 210 | struct extent_position epos; |
204 | 211 | ||
@@ -273,12 +280,11 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, | |||
273 | eloc.logicalBlockNum = *block; | 280 | eloc.logicalBlockNum = *block; |
274 | eloc.partitionReferenceNum = | 281 | eloc.partitionReferenceNum = |
275 | iinfo->i_location.partitionReferenceNum; | 282 | iinfo->i_location.partitionReferenceNum; |
276 | elen = inode->i_sb->s_blocksize; | 283 | iinfo->i_lenExtents = inode->i_size; |
277 | iinfo->i_lenExtents = elen; | ||
278 | epos.bh = NULL; | 284 | epos.bh = NULL; |
279 | epos.block = iinfo->i_location; | 285 | epos.block = iinfo->i_location; |
280 | epos.offset = udf_file_entry_alloc_offset(inode); | 286 | epos.offset = udf_file_entry_alloc_offset(inode); |
281 | udf_add_aext(inode, &epos, &eloc, elen, 0); | 287 | udf_add_aext(inode, &epos, &eloc, inode->i_size, 0); |
282 | /* UniqueID stuff */ | 288 | /* UniqueID stuff */ |
283 | 289 | ||
284 | brelse(epos.bh); | 290 | brelse(epos.bh); |
@@ -1308,7 +1314,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1308 | break; | 1314 | break; |
1309 | case ICBTAG_FILE_TYPE_SYMLINK: | 1315 | case ICBTAG_FILE_TYPE_SYMLINK: |
1310 | inode->i_data.a_ops = &udf_symlink_aops; | 1316 | inode->i_data.a_ops = &udf_symlink_aops; |
1311 | inode->i_op = &page_symlink_inode_operations; | 1317 | inode->i_op = &udf_symlink_inode_operations; |
1312 | inode->i_mode = S_IFLNK | S_IRWXUGO; | 1318 | inode->i_mode = S_IFLNK | S_IRWXUGO; |
1313 | break; | 1319 | break; |
1314 | case ICBTAG_FILE_TYPE_MAIN: | 1320 | case ICBTAG_FILE_TYPE_MAIN: |
@@ -1373,12 +1379,12 @@ static mode_t udf_convert_permissions(struct fileEntry *fe) | |||
1373 | return mode; | 1379 | return mode; |
1374 | } | 1380 | } |
1375 | 1381 | ||
1376 | int udf_write_inode(struct inode *inode, int sync) | 1382 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) |
1377 | { | 1383 | { |
1378 | int ret; | 1384 | int ret; |
1379 | 1385 | ||
1380 | lock_kernel(); | 1386 | lock_kernel(); |
1381 | ret = udf_update_inode(inode, sync); | 1387 | ret = udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); |
1382 | unlock_kernel(); | 1388 | unlock_kernel(); |
1383 | 1389 | ||
1384 | return ret; | 1390 | return ret; |
@@ -1402,20 +1408,19 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1402 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; | 1408 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; |
1403 | struct udf_inode_info *iinfo = UDF_I(inode); | 1409 | struct udf_inode_info *iinfo = UDF_I(inode); |
1404 | 1410 | ||
1405 | bh = udf_tread(inode->i_sb, | 1411 | bh = udf_tgetblk(inode->i_sb, |
1406 | udf_get_lb_pblock(inode->i_sb, | 1412 | udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0)); |
1407 | &iinfo->i_location, 0)); | ||
1408 | if (!bh) { | 1413 | if (!bh) { |
1409 | udf_debug("bread failure\n"); | 1414 | udf_debug("getblk failure\n"); |
1410 | return -EIO; | 1415 | return -ENOMEM; |
1411 | } | 1416 | } |
1412 | 1417 | ||
1413 | memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); | 1418 | lock_buffer(bh); |
1414 | 1419 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); | |
1415 | fe = (struct fileEntry *)bh->b_data; | 1420 | fe = (struct fileEntry *)bh->b_data; |
1416 | efe = (struct extendedFileEntry *)bh->b_data; | 1421 | efe = (struct extendedFileEntry *)bh->b_data; |
1417 | 1422 | ||
1418 | if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) { | 1423 | if (iinfo->i_use) { |
1419 | struct unallocSpaceEntry *use = | 1424 | struct unallocSpaceEntry *use = |
1420 | (struct unallocSpaceEntry *)bh->b_data; | 1425 | (struct unallocSpaceEntry *)bh->b_data; |
1421 | 1426 | ||
@@ -1423,20 +1428,18 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1423 | memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), | 1428 | memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), |
1424 | iinfo->i_ext.i_data, inode->i_sb->s_blocksize - | 1429 | iinfo->i_ext.i_data, inode->i_sb->s_blocksize - |
1425 | sizeof(struct unallocSpaceEntry)); | 1430 | sizeof(struct unallocSpaceEntry)); |
1431 | use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE); | ||
1432 | use->descTag.tagLocation = | ||
1433 | cpu_to_le32(iinfo->i_location.logicalBlockNum); | ||
1426 | crclen = sizeof(struct unallocSpaceEntry) + | 1434 | crclen = sizeof(struct unallocSpaceEntry) + |
1427 | iinfo->i_lenAlloc - sizeof(struct tag); | 1435 | iinfo->i_lenAlloc - sizeof(struct tag); |
1428 | use->descTag.tagLocation = cpu_to_le32( | ||
1429 | iinfo->i_location. | ||
1430 | logicalBlockNum); | ||
1431 | use->descTag.descCRCLength = cpu_to_le16(crclen); | 1436 | use->descTag.descCRCLength = cpu_to_le16(crclen); |
1432 | use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use + | 1437 | use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use + |
1433 | sizeof(struct tag), | 1438 | sizeof(struct tag), |
1434 | crclen)); | 1439 | crclen)); |
1435 | use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); | 1440 | use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); |
1436 | 1441 | ||
1437 | mark_buffer_dirty(bh); | 1442 | goto out; |
1438 | brelse(bh); | ||
1439 | return err; | ||
1440 | } | 1443 | } |
1441 | 1444 | ||
1442 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) | 1445 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) |
@@ -1591,18 +1594,21 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1591 | fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number); | 1594 | fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number); |
1592 | fe->descTag.tagLocation = cpu_to_le32( | 1595 | fe->descTag.tagLocation = cpu_to_le32( |
1593 | iinfo->i_location.logicalBlockNum); | 1596 | iinfo->i_location.logicalBlockNum); |
1594 | crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - | 1597 | crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - sizeof(struct tag); |
1595 | sizeof(struct tag); | ||
1596 | fe->descTag.descCRCLength = cpu_to_le16(crclen); | 1598 | fe->descTag.descCRCLength = cpu_to_le16(crclen); |
1597 | fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag), | 1599 | fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag), |
1598 | crclen)); | 1600 | crclen)); |
1599 | fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); | 1601 | fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); |
1600 | 1602 | ||
1603 | out: | ||
1604 | set_buffer_uptodate(bh); | ||
1605 | unlock_buffer(bh); | ||
1606 | |||
1601 | /* write the data blocks */ | 1607 | /* write the data blocks */ |
1602 | mark_buffer_dirty(bh); | 1608 | mark_buffer_dirty(bh); |
1603 | if (do_sync) { | 1609 | if (do_sync) { |
1604 | sync_dirty_buffer(bh); | 1610 | sync_dirty_buffer(bh); |
1605 | if (buffer_req(bh) && !buffer_uptodate(bh)) { | 1611 | if (buffer_write_io_error(bh)) { |
1606 | printk(KERN_WARNING "IO error syncing udf inode " | 1612 | printk(KERN_WARNING "IO error syncing udf inode " |
1607 | "[%s:%08lx]\n", inode->i_sb->s_id, | 1613 | "[%s:%08lx]\n", inode->i_sb->s_id, |
1608 | inode->i_ino); | 1614 | inode->i_ino); |
@@ -1672,7 +1678,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, | |||
1672 | return -1; | 1678 | return -1; |
1673 | 1679 | ||
1674 | if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) { | 1680 | if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) { |
1675 | char *sptr, *dptr; | 1681 | unsigned char *sptr, *dptr; |
1676 | struct buffer_head *nbh; | 1682 | struct buffer_head *nbh; |
1677 | int err, loffset; | 1683 | int err, loffset; |
1678 | struct kernel_lb_addr obloc = epos->block; | 1684 | struct kernel_lb_addr obloc = epos->block; |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 21dad8c608f9..75816025f95f 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -34,8 +34,8 @@ | |||
34 | #include <linux/crc-itu-t.h> | 34 | #include <linux/crc-itu-t.h> |
35 | #include <linux/exportfs.h> | 35 | #include <linux/exportfs.h> |
36 | 36 | ||
37 | static inline int udf_match(int len1, const char *name1, int len2, | 37 | static inline int udf_match(int len1, const unsigned char *name1, int len2, |
38 | const char *name2) | 38 | const unsigned char *name2) |
39 | { | 39 | { |
40 | if (len1 != len2) | 40 | if (len1 != len2) |
41 | return 0; | 41 | return 0; |
@@ -142,15 +142,15 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, | |||
142 | } | 142 | } |
143 | 143 | ||
144 | static struct fileIdentDesc *udf_find_entry(struct inode *dir, | 144 | static struct fileIdentDesc *udf_find_entry(struct inode *dir, |
145 | struct qstr *child, | 145 | const struct qstr *child, |
146 | struct udf_fileident_bh *fibh, | 146 | struct udf_fileident_bh *fibh, |
147 | struct fileIdentDesc *cfi) | 147 | struct fileIdentDesc *cfi) |
148 | { | 148 | { |
149 | struct fileIdentDesc *fi = NULL; | 149 | struct fileIdentDesc *fi = NULL; |
150 | loff_t f_pos; | 150 | loff_t f_pos; |
151 | int block, flen; | 151 | int block, flen; |
152 | char *fname = NULL; | 152 | unsigned char *fname = NULL; |
153 | char *nameptr; | 153 | unsigned char *nameptr; |
154 | uint8_t lfi; | 154 | uint8_t lfi; |
155 | uint16_t liu; | 155 | uint16_t liu; |
156 | loff_t size; | 156 | loff_t size; |
@@ -308,7 +308,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
308 | { | 308 | { |
309 | struct super_block *sb = dir->i_sb; | 309 | struct super_block *sb = dir->i_sb; |
310 | struct fileIdentDesc *fi = NULL; | 310 | struct fileIdentDesc *fi = NULL; |
311 | char *name = NULL; | 311 | unsigned char *name = NULL; |
312 | int namelen; | 312 | int namelen; |
313 | loff_t f_pos; | 313 | loff_t f_pos; |
314 | loff_t size = udf_ext0_offset(dir) + dir->i_size; | 314 | loff_t size = udf_ext0_offset(dir) + dir->i_size; |
@@ -408,15 +408,6 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
408 | } | 408 | } |
409 | 409 | ||
410 | add: | 410 | add: |
411 | /* Is there any extent whose size we need to round up? */ | ||
412 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && elen) { | ||
413 | elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1); | ||
414 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | ||
415 | epos.offset -= sizeof(struct short_ad); | ||
416 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | ||
417 | epos.offset -= sizeof(struct long_ad); | ||
418 | udf_write_aext(dir, &epos, &eloc, elen, 1); | ||
419 | } | ||
420 | f_pos += nfidlen; | 411 | f_pos += nfidlen; |
421 | 412 | ||
422 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && | 413 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && |
@@ -439,6 +430,7 @@ add: | |||
439 | udf_current_aext(dir, &epos, &eloc, &elen, 1); | 430 | udf_current_aext(dir, &epos, &eloc, &elen, 1); |
440 | } | 431 | } |
441 | 432 | ||
433 | /* Entry fits into current block? */ | ||
442 | if (sb->s_blocksize - fibh->eoffset >= nfidlen) { | 434 | if (sb->s_blocksize - fibh->eoffset >= nfidlen) { |
443 | fibh->soffset = fibh->eoffset; | 435 | fibh->soffset = fibh->eoffset; |
444 | fibh->eoffset += nfidlen; | 436 | fibh->eoffset += nfidlen; |
@@ -462,6 +454,16 @@ add: | |||
462 | (fibh->sbh->b_data + fibh->soffset); | 454 | (fibh->sbh->b_data + fibh->soffset); |
463 | } | 455 | } |
464 | } else { | 456 | } else { |
457 | /* Round up last extent in the file */ | ||
458 | elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1); | ||
459 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | ||
460 | epos.offset -= sizeof(struct short_ad); | ||
461 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | ||
462 | epos.offset -= sizeof(struct long_ad); | ||
463 | udf_write_aext(dir, &epos, &eloc, elen, 1); | ||
464 | dinfo->i_lenExtents = (dinfo->i_lenExtents + sb->s_blocksize | ||
465 | - 1) & ~(sb->s_blocksize - 1); | ||
466 | |||
465 | fibh->soffset = fibh->eoffset - sb->s_blocksize; | 467 | fibh->soffset = fibh->eoffset - sb->s_blocksize; |
466 | fibh->eoffset += nfidlen - sb->s_blocksize; | 468 | fibh->eoffset += nfidlen - sb->s_blocksize; |
467 | if (fibh->sbh != fibh->ebh) { | 469 | if (fibh->sbh != fibh->ebh) { |
@@ -508,6 +510,20 @@ add: | |||
508 | dir->i_size += nfidlen; | 510 | dir->i_size += nfidlen; |
509 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 511 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
510 | dinfo->i_lenAlloc += nfidlen; | 512 | dinfo->i_lenAlloc += nfidlen; |
513 | else { | ||
514 | /* Find the last extent and truncate it to proper size */ | ||
515 | while (udf_next_aext(dir, &epos, &eloc, &elen, 1) == | ||
516 | (EXT_RECORDED_ALLOCATED >> 30)) | ||
517 | ; | ||
518 | elen -= dinfo->i_lenExtents - dir->i_size; | ||
519 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | ||
520 | epos.offset -= sizeof(struct short_ad); | ||
521 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | ||
522 | epos.offset -= sizeof(struct long_ad); | ||
523 | udf_write_aext(dir, &epos, &eloc, elen, 1); | ||
524 | dinfo->i_lenExtents = dir->i_size; | ||
525 | } | ||
526 | |||
511 | mark_inode_dirty(dir); | 527 | mark_inode_dirty(dir); |
512 | goto out_ok; | 528 | goto out_ok; |
513 | } else { | 529 | } else { |
@@ -547,6 +563,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, | |||
547 | int err; | 563 | int err; |
548 | struct udf_inode_info *iinfo; | 564 | struct udf_inode_info *iinfo; |
549 | 565 | ||
566 | dquot_initialize(dir); | ||
567 | |||
550 | lock_kernel(); | 568 | lock_kernel(); |
551 | inode = udf_new_inode(dir, mode, &err); | 569 | inode = udf_new_inode(dir, mode, &err); |
552 | if (!inode) { | 570 | if (!inode) { |
@@ -600,6 +618,8 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
600 | if (!old_valid_dev(rdev)) | 618 | if (!old_valid_dev(rdev)) |
601 | return -EINVAL; | 619 | return -EINVAL; |
602 | 620 | ||
621 | dquot_initialize(dir); | ||
622 | |||
603 | lock_kernel(); | 623 | lock_kernel(); |
604 | err = -EIO; | 624 | err = -EIO; |
605 | inode = udf_new_inode(dir, mode, &err); | 625 | inode = udf_new_inode(dir, mode, &err); |
@@ -646,6 +666,8 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
646 | struct udf_inode_info *dinfo = UDF_I(dir); | 666 | struct udf_inode_info *dinfo = UDF_I(dir); |
647 | struct udf_inode_info *iinfo; | 667 | struct udf_inode_info *iinfo; |
648 | 668 | ||
669 | dquot_initialize(dir); | ||
670 | |||
649 | lock_kernel(); | 671 | lock_kernel(); |
650 | err = -EMLINK; | 672 | err = -EMLINK; |
651 | if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1) | 673 | if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1) |
@@ -783,6 +805,8 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) | |||
783 | struct fileIdentDesc *fi, cfi; | 805 | struct fileIdentDesc *fi, cfi; |
784 | struct kernel_lb_addr tloc; | 806 | struct kernel_lb_addr tloc; |
785 | 807 | ||
808 | dquot_initialize(dir); | ||
809 | |||
786 | retval = -ENOENT; | 810 | retval = -ENOENT; |
787 | lock_kernel(); | 811 | lock_kernel(); |
788 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 812 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
@@ -829,6 +853,8 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry) | |||
829 | struct fileIdentDesc cfi; | 853 | struct fileIdentDesc cfi; |
830 | struct kernel_lb_addr tloc; | 854 | struct kernel_lb_addr tloc; |
831 | 855 | ||
856 | dquot_initialize(dir); | ||
857 | |||
832 | retval = -ENOENT; | 858 | retval = -ENOENT; |
833 | lock_kernel(); | 859 | lock_kernel(); |
834 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 860 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
@@ -869,20 +895,22 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
869 | { | 895 | { |
870 | struct inode *inode; | 896 | struct inode *inode; |
871 | struct pathComponent *pc; | 897 | struct pathComponent *pc; |
872 | char *compstart; | 898 | const char *compstart; |
873 | struct udf_fileident_bh fibh; | 899 | struct udf_fileident_bh fibh; |
874 | struct extent_position epos = {}; | 900 | struct extent_position epos = {}; |
875 | int eoffset, elen = 0; | 901 | int eoffset, elen = 0; |
876 | struct fileIdentDesc *fi; | 902 | struct fileIdentDesc *fi; |
877 | struct fileIdentDesc cfi; | 903 | struct fileIdentDesc cfi; |
878 | char *ea; | 904 | uint8_t *ea; |
879 | int err; | 905 | int err; |
880 | int block; | 906 | int block; |
881 | char *name = NULL; | 907 | unsigned char *name = NULL; |
882 | int namelen; | 908 | int namelen; |
883 | struct buffer_head *bh; | 909 | struct buffer_head *bh; |
884 | struct udf_inode_info *iinfo; | 910 | struct udf_inode_info *iinfo; |
885 | 911 | ||
912 | dquot_initialize(dir); | ||
913 | |||
886 | lock_kernel(); | 914 | lock_kernel(); |
887 | inode = udf_new_inode(dir, S_IFLNK, &err); | 915 | inode = udf_new_inode(dir, S_IFLNK, &err); |
888 | if (!inode) | 916 | if (!inode) |
@@ -897,7 +925,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
897 | iinfo = UDF_I(inode); | 925 | iinfo = UDF_I(inode); |
898 | inode->i_mode = S_IFLNK | S_IRWXUGO; | 926 | inode->i_mode = S_IFLNK | S_IRWXUGO; |
899 | inode->i_data.a_ops = &udf_symlink_aops; | 927 | inode->i_data.a_ops = &udf_symlink_aops; |
900 | inode->i_op = &page_symlink_inode_operations; | 928 | inode->i_op = &udf_symlink_inode_operations; |
901 | 929 | ||
902 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 930 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
903 | struct kernel_lb_addr eloc; | 931 | struct kernel_lb_addr eloc; |
@@ -922,7 +950,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
922 | block = udf_get_pblock(inode->i_sb, block, | 950 | block = udf_get_pblock(inode->i_sb, block, |
923 | iinfo->i_location.partitionReferenceNum, | 951 | iinfo->i_location.partitionReferenceNum, |
924 | 0); | 952 | 0); |
925 | epos.bh = udf_tread(inode->i_sb, block); | 953 | epos.bh = udf_tgetblk(inode->i_sb, block); |
926 | lock_buffer(epos.bh); | 954 | lock_buffer(epos.bh); |
927 | memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); | 955 | memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); |
928 | set_buffer_uptodate(epos.bh); | 956 | set_buffer_uptodate(epos.bh); |
@@ -954,7 +982,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
954 | 982 | ||
955 | pc = (struct pathComponent *)(ea + elen); | 983 | pc = (struct pathComponent *)(ea + elen); |
956 | 984 | ||
957 | compstart = (char *)symname; | 985 | compstart = symname; |
958 | 986 | ||
959 | do { | 987 | do { |
960 | symname++; | 988 | symname++; |
@@ -999,6 +1027,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
999 | inode->i_size = elen; | 1027 | inode->i_size = elen; |
1000 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1028 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
1001 | iinfo->i_lenAlloc = inode->i_size; | 1029 | iinfo->i_lenAlloc = inode->i_size; |
1030 | else | ||
1031 | udf_truncate_tail_extent(inode); | ||
1002 | mark_inode_dirty(inode); | 1032 | mark_inode_dirty(inode); |
1003 | 1033 | ||
1004 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 1034 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
@@ -1051,6 +1081,8 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1051 | int err; | 1081 | int err; |
1052 | struct buffer_head *bh; | 1082 | struct buffer_head *bh; |
1053 | 1083 | ||
1084 | dquot_initialize(dir); | ||
1085 | |||
1054 | lock_kernel(); | 1086 | lock_kernel(); |
1055 | if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { | 1087 | if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { |
1056 | unlock_kernel(); | 1088 | unlock_kernel(); |
@@ -1113,6 +1145,9 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1113 | struct kernel_lb_addr tloc; | 1145 | struct kernel_lb_addr tloc; |
1114 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); | 1146 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); |
1115 | 1147 | ||
1148 | dquot_initialize(old_dir); | ||
1149 | dquot_initialize(new_dir); | ||
1150 | |||
1116 | lock_kernel(); | 1151 | lock_kernel(); |
1117 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); | 1152 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1118 | if (ofi) { | 1153 | if (ofi) { |
@@ -1358,6 +1393,7 @@ const struct export_operations udf_export_ops = { | |||
1358 | const struct inode_operations udf_dir_inode_operations = { | 1393 | const struct inode_operations udf_dir_inode_operations = { |
1359 | .lookup = udf_lookup, | 1394 | .lookup = udf_lookup, |
1360 | .create = udf_create, | 1395 | .create = udf_create, |
1396 | .setattr = udf_setattr, | ||
1361 | .link = udf_link, | 1397 | .link = udf_link, |
1362 | .unlink = udf_unlink, | 1398 | .unlink = udf_unlink, |
1363 | .symlink = udf_symlink, | 1399 | .symlink = udf_symlink, |
@@ -1366,3 +1402,9 @@ const struct inode_operations udf_dir_inode_operations = { | |||
1366 | .mknod = udf_mknod, | 1402 | .mknod = udf_mknod, |
1367 | .rename = udf_rename, | 1403 | .rename = udf_rename, |
1368 | }; | 1404 | }; |
1405 | const struct inode_operations udf_symlink_inode_operations = { | ||
1406 | .readlink = generic_readlink, | ||
1407 | .follow_link = page_follow_link_light, | ||
1408 | .put_link = page_put_link, | ||
1409 | .setattr = udf_setattr, | ||
1410 | }; | ||
diff --git a/fs/udf/partition.c b/fs/udf/partition.c index 4b540ee632d5..745eb209be0c 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/slab.h> | ||
28 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
29 | 28 | ||
30 | uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, | 29 | uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 9d1b8c2e6c45..1e4543cbcd27 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -1078,21 +1078,39 @@ static int udf_fill_partdesc_info(struct super_block *sb, | |||
1078 | return 0; | 1078 | return 0; |
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) | 1081 | static void udf_find_vat_block(struct super_block *sb, int p_index, |
1082 | int type1_index, sector_t start_block) | ||
1082 | { | 1083 | { |
1083 | struct udf_sb_info *sbi = UDF_SB(sb); | 1084 | struct udf_sb_info *sbi = UDF_SB(sb); |
1084 | struct udf_part_map *map = &sbi->s_partmaps[p_index]; | 1085 | struct udf_part_map *map = &sbi->s_partmaps[p_index]; |
1086 | sector_t vat_block; | ||
1085 | struct kernel_lb_addr ino; | 1087 | struct kernel_lb_addr ino; |
1088 | |||
1089 | /* | ||
1090 | * VAT file entry is in the last recorded block. Some broken disks have | ||
1091 | * it a few blocks before so try a bit harder... | ||
1092 | */ | ||
1093 | ino.partitionReferenceNum = type1_index; | ||
1094 | for (vat_block = start_block; | ||
1095 | vat_block >= map->s_partition_root && | ||
1096 | vat_block >= start_block - 3 && | ||
1097 | !sbi->s_vat_inode; vat_block--) { | ||
1098 | ino.logicalBlockNum = vat_block - map->s_partition_root; | ||
1099 | sbi->s_vat_inode = udf_iget(sb, &ino); | ||
1100 | } | ||
1101 | } | ||
1102 | |||
1103 | static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) | ||
1104 | { | ||
1105 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
1106 | struct udf_part_map *map = &sbi->s_partmaps[p_index]; | ||
1086 | struct buffer_head *bh = NULL; | 1107 | struct buffer_head *bh = NULL; |
1087 | struct udf_inode_info *vati; | 1108 | struct udf_inode_info *vati; |
1088 | uint32_t pos; | 1109 | uint32_t pos; |
1089 | struct virtualAllocationTable20 *vat20; | 1110 | struct virtualAllocationTable20 *vat20; |
1090 | sector_t blocks = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits; | 1111 | sector_t blocks = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits; |
1091 | 1112 | ||
1092 | /* VAT file entry is in the last recorded block */ | 1113 | udf_find_vat_block(sb, p_index, type1_index, sbi->s_last_block); |
1093 | ino.partitionReferenceNum = type1_index; | ||
1094 | ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root; | ||
1095 | sbi->s_vat_inode = udf_iget(sb, &ino); | ||
1096 | if (!sbi->s_vat_inode && | 1114 | if (!sbi->s_vat_inode && |
1097 | sbi->s_last_block != blocks - 1) { | 1115 | sbi->s_last_block != blocks - 1) { |
1098 | printk(KERN_NOTICE "UDF-fs: Failed to read VAT inode from the" | 1116 | printk(KERN_NOTICE "UDF-fs: Failed to read VAT inode from the" |
@@ -1100,9 +1118,7 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) | |||
1100 | "block of the device (%lu).\n", | 1118 | "block of the device (%lu).\n", |
1101 | (unsigned long)sbi->s_last_block, | 1119 | (unsigned long)sbi->s_last_block, |
1102 | (unsigned long)blocks - 1); | 1120 | (unsigned long)blocks - 1); |
1103 | ino.partitionReferenceNum = type1_index; | 1121 | udf_find_vat_block(sb, p_index, type1_index, blocks - 1); |
1104 | ino.logicalBlockNum = blocks - 1 - map->s_partition_root; | ||
1105 | sbi->s_vat_inode = udf_iget(sb, &ino); | ||
1106 | } | 1122 | } |
1107 | if (!sbi->s_vat_inode) | 1123 | if (!sbi->s_vat_inode) |
1108 | return 1; | 1124 | return 1; |
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index c3265e1385d4..16064787d2b7 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c | |||
@@ -26,18 +26,17 @@ | |||
26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/stat.h> | 28 | #include <linux/stat.h> |
29 | #include <linux/slab.h> | ||
30 | #include <linux/pagemap.h> | 29 | #include <linux/pagemap.h> |
31 | #include <linux/smp_lock.h> | 30 | #include <linux/smp_lock.h> |
32 | #include <linux/buffer_head.h> | 31 | #include <linux/buffer_head.h> |
33 | #include "udf_i.h" | 32 | #include "udf_i.h" |
34 | 33 | ||
35 | static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen, | 34 | static void udf_pc_to_char(struct super_block *sb, unsigned char *from, |
36 | char *to) | 35 | int fromlen, unsigned char *to) |
37 | { | 36 | { |
38 | struct pathComponent *pc; | 37 | struct pathComponent *pc; |
39 | int elen = 0; | 38 | int elen = 0; |
40 | char *p = to; | 39 | unsigned char *p = to; |
41 | 40 | ||
42 | while (elen < fromlen) { | 41 | while (elen < fromlen) { |
43 | pc = (struct pathComponent *)(from + elen); | 42 | pc = (struct pathComponent *)(from + elen); |
@@ -75,9 +74,9 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
75 | { | 74 | { |
76 | struct inode *inode = page->mapping->host; | 75 | struct inode *inode = page->mapping->host; |
77 | struct buffer_head *bh = NULL; | 76 | struct buffer_head *bh = NULL; |
78 | char *symlink; | 77 | unsigned char *symlink; |
79 | int err = -EIO; | 78 | int err = -EIO; |
80 | char *p = kmap(page); | 79 | unsigned char *p = kmap(page); |
81 | struct udf_inode_info *iinfo; | 80 | struct udf_inode_info *iinfo; |
82 | 81 | ||
83 | lock_kernel(); | 82 | lock_kernel(); |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 8d46f4294ee7..702a1148e702 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -76,6 +76,7 @@ extern const struct inode_operations udf_dir_inode_operations; | |||
76 | extern const struct file_operations udf_dir_operations; | 76 | extern const struct file_operations udf_dir_operations; |
77 | extern const struct inode_operations udf_file_inode_operations; | 77 | extern const struct inode_operations udf_file_inode_operations; |
78 | extern const struct file_operations udf_file_operations; | 78 | extern const struct file_operations udf_file_operations; |
79 | extern const struct inode_operations udf_symlink_inode_operations; | ||
79 | extern const struct address_space_operations udf_aops; | 80 | extern const struct address_space_operations udf_aops; |
80 | extern const struct address_space_operations udf_adinicb_aops; | 81 | extern const struct address_space_operations udf_adinicb_aops; |
81 | extern const struct address_space_operations udf_symlink_aops; | 82 | extern const struct address_space_operations udf_symlink_aops; |
@@ -131,7 +132,7 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, | |||
131 | /* file.c */ | 132 | /* file.c */ |
132 | extern int udf_ioctl(struct inode *, struct file *, unsigned int, | 133 | extern int udf_ioctl(struct inode *, struct file *, unsigned int, |
133 | unsigned long); | 134 | unsigned long); |
134 | 135 | extern int udf_setattr(struct dentry *dentry, struct iattr *iattr); | |
135 | /* inode.c */ | 136 | /* inode.c */ |
136 | extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); | 137 | extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); |
137 | extern int udf_sync_inode(struct inode *); | 138 | extern int udf_sync_inode(struct inode *); |
@@ -142,7 +143,7 @@ extern void udf_truncate(struct inode *); | |||
142 | extern void udf_read_inode(struct inode *); | 143 | extern void udf_read_inode(struct inode *); |
143 | extern void udf_delete_inode(struct inode *); | 144 | extern void udf_delete_inode(struct inode *); |
144 | extern void udf_clear_inode(struct inode *); | 145 | extern void udf_clear_inode(struct inode *); |
145 | extern int udf_write_inode(struct inode *, int); | 146 | extern int udf_write_inode(struct inode *, struct writeback_control *wbc); |
146 | extern long udf_block_map(struct inode *, sector_t); | 147 | extern long udf_block_map(struct inode *, sector_t); |
147 | extern int udf_extend_file(struct inode *, struct extent_position *, | 148 | extern int udf_extend_file(struct inode *, struct extent_position *, |
148 | struct kernel_long_ad *, sector_t); | 149 | struct kernel_long_ad *, sector_t); |
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index cefa8c8913e6..d03a90b6ad69 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/string.h> /* for memset */ | 24 | #include <linux/string.h> /* for memset */ |
25 | #include <linux/nls.h> | 25 | #include <linux/nls.h> |
26 | #include <linux/crc-itu-t.h> | 26 | #include <linux/crc-itu-t.h> |
27 | #include <linux/slab.h> | ||
27 | 28 | ||
28 | #include "udf_sb.h" | 29 | #include "udf_sb.h" |
29 | 30 | ||