diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/udf | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'fs/udf')
-rw-r--r-- | fs/udf/balloc.c | 14 | ||||
-rw-r--r-- | fs/udf/dir.c | 5 | ||||
-rw-r--r-- | fs/udf/file.c | 19 | ||||
-rw-r--r-- | fs/udf/ialloc.c | 21 | ||||
-rw-r--r-- | fs/udf/inode.c | 289 | ||||
-rw-r--r-- | fs/udf/namei.c | 127 | ||||
-rw-r--r-- | fs/udf/partition.c | 27 | ||||
-rw-r--r-- | fs/udf/super.c | 77 | ||||
-rw-r--r-- | fs/udf/symlink.c | 12 | ||||
-rw-r--r-- | fs/udf/truncate.c | 146 | ||||
-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 | 16 |
13 files changed, 425 insertions, 363 deletions
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index b608efaa4cee..95518a9f589e 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -27,11 +27,10 @@ | |||
27 | #include "udf_i.h" | 27 | #include "udf_i.h" |
28 | #include "udf_sb.h" | 28 | #include "udf_sb.h" |
29 | 29 | ||
30 | #define udf_clear_bit(nr, addr) ext2_clear_bit(nr, addr) | 30 | #define udf_clear_bit __test_and_clear_bit_le |
31 | #define udf_set_bit(nr, addr) ext2_set_bit(nr, addr) | 31 | #define udf_set_bit __test_and_set_bit_le |
32 | #define udf_test_bit(nr, addr) ext2_test_bit(nr, addr) | 32 | #define udf_test_bit test_bit_le |
33 | #define udf_find_next_one_bit(addr, size, offset) \ | 33 | #define udf_find_next_one_bit find_next_bit_le |
34 | ext2_find_next_bit(addr, size, offset) | ||
35 | 34 | ||
36 | static int read_block_bitmap(struct super_block *sb, | 35 | static int read_block_bitmap(struct super_block *sb, |
37 | struct udf_bitmap *bitmap, unsigned int block, | 36 | struct udf_bitmap *bitmap, unsigned int block, |
@@ -157,10 +156,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb, | |||
157 | udf_debug("bit %ld already set\n", bit + i); | 156 | udf_debug("bit %ld already set\n", bit + i); |
158 | udf_debug("byte=%2x\n", | 157 | udf_debug("byte=%2x\n", |
159 | ((char *)bh->b_data)[(bit + i) >> 3]); | 158 | ((char *)bh->b_data)[(bit + i) >> 3]); |
160 | } else { | ||
161 | udf_add_free_space(sb, sbi->s_partition, 1); | ||
162 | } | 159 | } |
163 | } | 160 | } |
161 | udf_add_free_space(sb, sbi->s_partition, count); | ||
164 | mark_buffer_dirty(bh); | 162 | mark_buffer_dirty(bh); |
165 | if (overflow) { | 163 | if (overflow) { |
166 | block += count; | 164 | block += count; |
@@ -298,7 +296,7 @@ repeat: | |||
298 | break; | 296 | break; |
299 | } | 297 | } |
300 | } else { | 298 | } else { |
301 | bit = udf_find_next_one_bit((char *)bh->b_data, | 299 | bit = udf_find_next_one_bit(bh->b_data, |
302 | sb->s_blocksize << 3, | 300 | sb->s_blocksize << 3, |
303 | group_start << 3); | 301 | group_start << 3); |
304 | if (bit < sb->s_blocksize << 3) | 302 | if (bit < sb->s_blocksize << 3) |
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..2a346bb1d9f5 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> |
@@ -99,7 +98,6 @@ static int udf_adinicb_write_end(struct file *file, | |||
99 | const struct address_space_operations udf_adinicb_aops = { | 98 | const struct address_space_operations udf_adinicb_aops = { |
100 | .readpage = udf_adinicb_readpage, | 99 | .readpage = udf_adinicb_readpage, |
101 | .writepage = udf_adinicb_writepage, | 100 | .writepage = udf_adinicb_writepage, |
102 | .sync_page = block_sync_page, | ||
103 | .write_begin = simple_write_begin, | 101 | .write_begin = simple_write_begin, |
104 | .write_end = udf_adinicb_write_end, | 102 | .write_end = udf_adinicb_write_end, |
105 | }; | 103 | }; |
@@ -114,6 +112,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
114 | size_t count = iocb->ki_left; | 112 | size_t count = iocb->ki_left; |
115 | struct udf_inode_info *iinfo = UDF_I(inode); | 113 | struct udf_inode_info *iinfo = UDF_I(inode); |
116 | 114 | ||
115 | down_write(&iinfo->i_data_sem); | ||
117 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 116 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
118 | if (file->f_flags & O_APPEND) | 117 | if (file->f_flags & O_APPEND) |
119 | pos = inode->i_size; | 118 | pos = inode->i_size; |
@@ -123,9 +122,10 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
123 | if (inode->i_sb->s_blocksize < | 122 | if (inode->i_sb->s_blocksize < |
124 | (udf_file_entry_alloc_offset(inode) + | 123 | (udf_file_entry_alloc_offset(inode) + |
125 | pos + count)) { | 124 | pos + count)) { |
126 | udf_expand_file_adinicb(inode, pos + count, &err); | 125 | err = udf_expand_file_adinicb(inode); |
127 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 126 | if (err) { |
128 | udf_debug("udf_expand_adinicb: err=%d\n", err); | 127 | udf_debug("udf_expand_adinicb: err=%d\n", err); |
128 | up_write(&iinfo->i_data_sem); | ||
129 | return err; | 129 | return err; |
130 | } | 130 | } |
131 | } else { | 131 | } else { |
@@ -135,6 +135,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
135 | iinfo->i_lenAlloc = inode->i_size; | 135 | iinfo->i_lenAlloc = inode->i_size; |
136 | } | 136 | } |
137 | } | 137 | } |
138 | up_write(&iinfo->i_data_sem); | ||
138 | 139 | ||
139 | retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); | 140 | retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); |
140 | if (retval > 0) | 141 | if (retval > 0) |
@@ -149,8 +150,6 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
149 | long old_block, new_block; | 150 | long old_block, new_block; |
150 | int result = -EINVAL; | 151 | int result = -EINVAL; |
151 | 152 | ||
152 | lock_kernel(); | ||
153 | |||
154 | if (file_permission(filp, MAY_READ) != 0) { | 153 | if (file_permission(filp, MAY_READ) != 0) { |
155 | udf_debug("no permission to access inode %lu\n", inode->i_ino); | 154 | udf_debug("no permission to access inode %lu\n", inode->i_ino); |
156 | result = -EPERM; | 155 | result = -EPERM; |
@@ -196,7 +195,6 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
196 | } | 195 | } |
197 | 196 | ||
198 | out: | 197 | out: |
199 | unlock_kernel(); | ||
200 | return result; | 198 | return result; |
201 | } | 199 | } |
202 | 200 | ||
@@ -204,10 +202,10 @@ static int udf_release_file(struct inode *inode, struct file *filp) | |||
204 | { | 202 | { |
205 | if (filp->f_mode & FMODE_WRITE) { | 203 | if (filp->f_mode & FMODE_WRITE) { |
206 | mutex_lock(&inode->i_mutex); | 204 | mutex_lock(&inode->i_mutex); |
207 | lock_kernel(); | 205 | down_write(&UDF_I(inode)->i_data_sem); |
208 | udf_discard_prealloc(inode); | 206 | udf_discard_prealloc(inode); |
209 | udf_truncate_tail_extent(inode); | 207 | udf_truncate_tail_extent(inode); |
210 | unlock_kernel(); | 208 | up_write(&UDF_I(inode)->i_data_sem); |
211 | mutex_unlock(&inode->i_mutex); | 209 | mutex_unlock(&inode->i_mutex); |
212 | } | 210 | } |
213 | return 0; | 211 | return 0; |
@@ -238,7 +236,7 @@ static int udf_setattr(struct dentry *dentry, struct iattr *attr) | |||
238 | 236 | ||
239 | if ((attr->ia_valid & ATTR_SIZE) && | 237 | if ((attr->ia_valid & ATTR_SIZE) && |
240 | attr->ia_size != i_size_read(inode)) { | 238 | attr->ia_size != i_size_read(inode)) { |
241 | error = vmtruncate(inode, attr->ia_size); | 239 | error = udf_setsize(inode, attr->ia_size); |
242 | if (error) | 240 | if (error) |
243 | return error; | 241 | return error; |
244 | } | 242 | } |
@@ -250,5 +248,4 @@ static int udf_setattr(struct dentry *dentry, struct iattr *attr) | |||
250 | 248 | ||
251 | const struct inode_operations udf_file_inode_operations = { | 249 | const struct inode_operations udf_file_inode_operations = { |
252 | .setattr = udf_setattr, | 250 | .setattr = udf_setattr, |
253 | .truncate = udf_truncate, | ||
254 | }; | 251 | }; |
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..1d1358ed80c1 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 *); |
@@ -73,16 +73,12 @@ void udf_evict_inode(struct inode *inode) | |||
73 | struct udf_inode_info *iinfo = UDF_I(inode); | 73 | struct udf_inode_info *iinfo = UDF_I(inode); |
74 | int want_delete = 0; | 74 | int want_delete = 0; |
75 | 75 | ||
76 | truncate_inode_pages(&inode->i_data, 0); | ||
77 | |||
78 | if (!inode->i_nlink && !is_bad_inode(inode)) { | 76 | if (!inode->i_nlink && !is_bad_inode(inode)) { |
79 | want_delete = 1; | 77 | want_delete = 1; |
80 | inode->i_size = 0; | 78 | udf_setsize(inode, 0); |
81 | udf_truncate(inode); | ||
82 | lock_kernel(); | ||
83 | udf_update_inode(inode, IS_SYNC(inode)); | 79 | udf_update_inode(inode, IS_SYNC(inode)); |
84 | unlock_kernel(); | 80 | } else |
85 | } | 81 | truncate_inode_pages(&inode->i_data, 0); |
86 | invalidate_inode_buffers(inode); | 82 | invalidate_inode_buffers(inode); |
87 | end_writeback(inode); | 83 | end_writeback(inode); |
88 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && | 84 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && |
@@ -97,9 +93,7 @@ void udf_evict_inode(struct inode *inode) | |||
97 | kfree(iinfo->i_ext.i_data); | 93 | kfree(iinfo->i_ext.i_data); |
98 | iinfo->i_ext.i_data = NULL; | 94 | iinfo->i_ext.i_data = NULL; |
99 | if (want_delete) { | 95 | if (want_delete) { |
100 | lock_kernel(); | ||
101 | udf_free_inode(inode); | 96 | udf_free_inode(inode); |
102 | unlock_kernel(); | ||
103 | } | 97 | } |
104 | } | 98 | } |
105 | 99 | ||
@@ -121,9 +115,18 @@ static int udf_write_begin(struct file *file, struct address_space *mapping, | |||
121 | 115 | ||
122 | ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block); | 116 | ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block); |
123 | if (unlikely(ret)) { | 117 | if (unlikely(ret)) { |
124 | loff_t isize = mapping->host->i_size; | 118 | struct inode *inode = mapping->host; |
125 | if (pos + len > isize) | 119 | struct udf_inode_info *iinfo = UDF_I(inode); |
126 | vmtruncate(mapping->host, isize); | 120 | loff_t isize = inode->i_size; |
121 | |||
122 | if (pos + len > isize) { | ||
123 | truncate_pagecache(inode, pos + len, isize); | ||
124 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | ||
125 | down_write(&iinfo->i_data_sem); | ||
126 | udf_truncate_extents(inode); | ||
127 | up_write(&iinfo->i_data_sem); | ||
128 | } | ||
129 | } | ||
127 | } | 130 | } |
128 | 131 | ||
129 | return ret; | 132 | return ret; |
@@ -137,36 +140,36 @@ static sector_t udf_bmap(struct address_space *mapping, sector_t block) | |||
137 | const struct address_space_operations udf_aops = { | 140 | const struct address_space_operations udf_aops = { |
138 | .readpage = udf_readpage, | 141 | .readpage = udf_readpage, |
139 | .writepage = udf_writepage, | 142 | .writepage = udf_writepage, |
140 | .sync_page = block_sync_page, | ||
141 | .write_begin = udf_write_begin, | 143 | .write_begin = udf_write_begin, |
142 | .write_end = generic_write_end, | 144 | .write_end = generic_write_end, |
143 | .bmap = udf_bmap, | 145 | .bmap = udf_bmap, |
144 | }; | 146 | }; |
145 | 147 | ||
146 | void udf_expand_file_adinicb(struct inode *inode, int newsize, int *err) | 148 | int udf_expand_file_adinicb(struct inode *inode) |
147 | { | 149 | { |
148 | struct page *page; | 150 | struct page *page; |
149 | char *kaddr; | 151 | char *kaddr; |
150 | struct udf_inode_info *iinfo = UDF_I(inode); | 152 | struct udf_inode_info *iinfo = UDF_I(inode); |
153 | int err; | ||
151 | struct writeback_control udf_wbc = { | 154 | struct writeback_control udf_wbc = { |
152 | .sync_mode = WB_SYNC_NONE, | 155 | .sync_mode = WB_SYNC_NONE, |
153 | .nr_to_write = 1, | 156 | .nr_to_write = 1, |
154 | }; | 157 | }; |
155 | 158 | ||
156 | /* from now on we have normal address_space methods */ | ||
157 | inode->i_data.a_ops = &udf_aops; | ||
158 | |||
159 | if (!iinfo->i_lenAlloc) { | 159 | if (!iinfo->i_lenAlloc) { |
160 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) | 160 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) |
161 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; | 161 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; |
162 | else | 162 | else |
163 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; | 163 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; |
164 | /* from now on we have normal address_space methods */ | ||
165 | inode->i_data.a_ops = &udf_aops; | ||
164 | mark_inode_dirty(inode); | 166 | mark_inode_dirty(inode); |
165 | return; | 167 | return 0; |
166 | } | 168 | } |
167 | 169 | ||
168 | page = grab_cache_page(inode->i_mapping, 0); | 170 | page = find_or_create_page(inode->i_mapping, 0, GFP_NOFS); |
169 | BUG_ON(!PageLocked(page)); | 171 | if (!page) |
172 | return -ENOMEM; | ||
170 | 173 | ||
171 | if (!PageUptodate(page)) { | 174 | if (!PageUptodate(page)) { |
172 | kaddr = kmap(page); | 175 | kaddr = kmap(page); |
@@ -185,11 +188,24 @@ void udf_expand_file_adinicb(struct inode *inode, int newsize, int *err) | |||
185 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; | 188 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; |
186 | else | 189 | else |
187 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; | 190 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; |
188 | 191 | /* from now on we have normal address_space methods */ | |
189 | inode->i_data.a_ops->writepage(page, &udf_wbc); | 192 | inode->i_data.a_ops = &udf_aops; |
193 | err = inode->i_data.a_ops->writepage(page, &udf_wbc); | ||
194 | if (err) { | ||
195 | /* Restore everything back so that we don't lose data... */ | ||
196 | lock_page(page); | ||
197 | kaddr = kmap(page); | ||
198 | memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr, | ||
199 | inode->i_size); | ||
200 | kunmap(page); | ||
201 | unlock_page(page); | ||
202 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; | ||
203 | inode->i_data.a_ops = &udf_adinicb_aops; | ||
204 | } | ||
190 | page_cache_release(page); | 205 | page_cache_release(page); |
191 | |||
192 | mark_inode_dirty(inode); | 206 | mark_inode_dirty(inode); |
207 | |||
208 | return err; | ||
193 | } | 209 | } |
194 | 210 | ||
195 | struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, | 211 | struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, |
@@ -302,10 +318,9 @@ static int udf_get_block(struct inode *inode, sector_t block, | |||
302 | err = -EIO; | 318 | err = -EIO; |
303 | new = 0; | 319 | new = 0; |
304 | bh = NULL; | 320 | bh = NULL; |
305 | |||
306 | lock_kernel(); | ||
307 | |||
308 | iinfo = UDF_I(inode); | 321 | iinfo = UDF_I(inode); |
322 | |||
323 | down_write(&iinfo->i_data_sem); | ||
309 | if (block == iinfo->i_next_alloc_block + 1) { | 324 | if (block == iinfo->i_next_alloc_block + 1) { |
310 | iinfo->i_next_alloc_block++; | 325 | iinfo->i_next_alloc_block++; |
311 | iinfo->i_next_alloc_goal++; | 326 | iinfo->i_next_alloc_goal++; |
@@ -324,7 +339,7 @@ static int udf_get_block(struct inode *inode, sector_t block, | |||
324 | map_bh(bh_result, inode->i_sb, phys); | 339 | map_bh(bh_result, inode->i_sb, phys); |
325 | 340 | ||
326 | abort: | 341 | abort: |
327 | unlock_kernel(); | 342 | up_write(&iinfo->i_data_sem); |
328 | return err; | 343 | return err; |
329 | } | 344 | } |
330 | 345 | ||
@@ -353,8 +368,10 @@ static struct buffer_head *udf_getblk(struct inode *inode, long block, | |||
353 | } | 368 | } |
354 | 369 | ||
355 | /* Extend the file by 'blocks' blocks, return the number of extents added */ | 370 | /* Extend the file by 'blocks' blocks, return the number of extents added */ |
356 | int udf_extend_file(struct inode *inode, struct extent_position *last_pos, | 371 | static int udf_do_extend_file(struct inode *inode, |
357 | struct kernel_long_ad *last_ext, sector_t blocks) | 372 | struct extent_position *last_pos, |
373 | struct kernel_long_ad *last_ext, | ||
374 | sector_t blocks) | ||
358 | { | 375 | { |
359 | sector_t add; | 376 | sector_t add; |
360 | int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); | 377 | int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); |
@@ -362,6 +379,7 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos, | |||
362 | struct kernel_lb_addr prealloc_loc = {}; | 379 | struct kernel_lb_addr prealloc_loc = {}; |
363 | int prealloc_len = 0; | 380 | int prealloc_len = 0; |
364 | struct udf_inode_info *iinfo; | 381 | struct udf_inode_info *iinfo; |
382 | int err; | ||
365 | 383 | ||
366 | /* The previous extent is fake and we should not extend by anything | 384 | /* The previous extent is fake and we should not extend by anything |
367 | * - there's nothing to do... */ | 385 | * - there's nothing to do... */ |
@@ -427,26 +445,29 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos, | |||
427 | /* Create enough extents to cover the whole hole */ | 445 | /* Create enough extents to cover the whole hole */ |
428 | while (blocks > add) { | 446 | while (blocks > add) { |
429 | blocks -= add; | 447 | blocks -= add; |
430 | if (udf_add_aext(inode, last_pos, &last_ext->extLocation, | 448 | err = udf_add_aext(inode, last_pos, &last_ext->extLocation, |
431 | last_ext->extLength, 1) == -1) | 449 | last_ext->extLength, 1); |
432 | return -1; | 450 | if (err) |
451 | return err; | ||
433 | count++; | 452 | count++; |
434 | } | 453 | } |
435 | if (blocks) { | 454 | if (blocks) { |
436 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | 455 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
437 | (blocks << sb->s_blocksize_bits); | 456 | (blocks << sb->s_blocksize_bits); |
438 | if (udf_add_aext(inode, last_pos, &last_ext->extLocation, | 457 | err = udf_add_aext(inode, last_pos, &last_ext->extLocation, |
439 | last_ext->extLength, 1) == -1) | 458 | last_ext->extLength, 1); |
440 | return -1; | 459 | if (err) |
460 | return err; | ||
441 | count++; | 461 | count++; |
442 | } | 462 | } |
443 | 463 | ||
444 | out: | 464 | out: |
445 | /* Do we have some preallocated blocks saved? */ | 465 | /* Do we have some preallocated blocks saved? */ |
446 | if (prealloc_len) { | 466 | if (prealloc_len) { |
447 | if (udf_add_aext(inode, last_pos, &prealloc_loc, | 467 | err = udf_add_aext(inode, last_pos, &prealloc_loc, |
448 | prealloc_len, 1) == -1) | 468 | prealloc_len, 1); |
449 | return -1; | 469 | if (err) |
470 | return err; | ||
450 | last_ext->extLocation = prealloc_loc; | 471 | last_ext->extLocation = prealloc_loc; |
451 | last_ext->extLength = prealloc_len; | 472 | last_ext->extLength = prealloc_len; |
452 | count++; | 473 | count++; |
@@ -458,11 +479,68 @@ out: | |||
458 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 479 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
459 | last_pos->offset -= sizeof(struct long_ad); | 480 | last_pos->offset -= sizeof(struct long_ad); |
460 | else | 481 | else |
461 | return -1; | 482 | return -EIO; |
462 | 483 | ||
463 | return count; | 484 | return count; |
464 | } | 485 | } |
465 | 486 | ||
487 | static int udf_extend_file(struct inode *inode, loff_t newsize) | ||
488 | { | ||
489 | |||
490 | struct extent_position epos; | ||
491 | struct kernel_lb_addr eloc; | ||
492 | uint32_t elen; | ||
493 | int8_t etype; | ||
494 | struct super_block *sb = inode->i_sb; | ||
495 | sector_t first_block = newsize >> sb->s_blocksize_bits, offset; | ||
496 | int adsize; | ||
497 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
498 | struct kernel_long_ad extent; | ||
499 | int err; | ||
500 | |||
501 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | ||
502 | adsize = sizeof(struct short_ad); | ||
503 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | ||
504 | adsize = sizeof(struct long_ad); | ||
505 | else | ||
506 | BUG(); | ||
507 | |||
508 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); | ||
509 | |||
510 | /* File has extent covering the new size (could happen when extending | ||
511 | * inside a block)? */ | ||
512 | if (etype != -1) | ||
513 | return 0; | ||
514 | if (newsize & (sb->s_blocksize - 1)) | ||
515 | offset++; | ||
516 | /* Extended file just to the boundary of the last file block? */ | ||
517 | if (offset == 0) | ||
518 | return 0; | ||
519 | |||
520 | /* Truncate is extending the file by 'offset' blocks */ | ||
521 | if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || | ||
522 | (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { | ||
523 | /* File has no extents at all or has empty last | ||
524 | * indirect extent! Create a fake extent... */ | ||
525 | extent.extLocation.logicalBlockNum = 0; | ||
526 | extent.extLocation.partitionReferenceNum = 0; | ||
527 | extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; | ||
528 | } else { | ||
529 | epos.offset -= adsize; | ||
530 | etype = udf_next_aext(inode, &epos, &extent.extLocation, | ||
531 | &extent.extLength, 0); | ||
532 | extent.extLength |= etype << 30; | ||
533 | } | ||
534 | err = udf_do_extend_file(inode, &epos, &extent, offset); | ||
535 | if (err < 0) | ||
536 | goto out; | ||
537 | err = 0; | ||
538 | iinfo->i_lenExtents = newsize; | ||
539 | out: | ||
540 | brelse(epos.bh); | ||
541 | return err; | ||
542 | } | ||
543 | |||
466 | static struct buffer_head *inode_getblk(struct inode *inode, sector_t block, | 544 | static struct buffer_head *inode_getblk(struct inode *inode, sector_t block, |
467 | int *err, sector_t *phys, int *new) | 545 | int *err, sector_t *phys, int *new) |
468 | { | 546 | { |
@@ -545,7 +623,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block, | |||
545 | elen = EXT_RECORDED_ALLOCATED | | 623 | elen = EXT_RECORDED_ALLOCATED | |
546 | ((elen + inode->i_sb->s_blocksize - 1) & | 624 | ((elen + inode->i_sb->s_blocksize - 1) & |
547 | ~(inode->i_sb->s_blocksize - 1)); | 625 | ~(inode->i_sb->s_blocksize - 1)); |
548 | etype = udf_write_aext(inode, &cur_epos, &eloc, elen, 1); | 626 | udf_write_aext(inode, &cur_epos, &eloc, elen, 1); |
549 | } | 627 | } |
550 | brelse(prev_epos.bh); | 628 | brelse(prev_epos.bh); |
551 | brelse(cur_epos.bh); | 629 | brelse(cur_epos.bh); |
@@ -569,19 +647,17 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block, | |||
569 | memset(&laarr[0].extLocation, 0x00, | 647 | memset(&laarr[0].extLocation, 0x00, |
570 | sizeof(struct kernel_lb_addr)); | 648 | sizeof(struct kernel_lb_addr)); |
571 | laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; | 649 | laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; |
572 | /* Will udf_extend_file() create real extent from | 650 | /* Will udf_do_extend_file() create real extent from |
573 | a fake one? */ | 651 | a fake one? */ |
574 | startnum = (offset > 0); | 652 | startnum = (offset > 0); |
575 | } | 653 | } |
576 | /* Create extents for the hole between EOF and offset */ | 654 | /* Create extents for the hole between EOF and offset */ |
577 | ret = udf_extend_file(inode, &prev_epos, laarr, offset); | 655 | ret = udf_do_extend_file(inode, &prev_epos, laarr, offset); |
578 | if (ret == -1) { | 656 | if (ret < 0) { |
579 | brelse(prev_epos.bh); | 657 | brelse(prev_epos.bh); |
580 | brelse(cur_epos.bh); | 658 | brelse(cur_epos.bh); |
581 | brelse(next_epos.bh); | 659 | brelse(next_epos.bh); |
582 | /* We don't really know the error here so we just make | 660 | *err = ret; |
583 | * something up */ | ||
584 | *err = -ENOSPC; | ||
585 | return NULL; | 661 | return NULL; |
586 | } | 662 | } |
587 | c = 0; | 663 | c = 0; |
@@ -1010,50 +1086,66 @@ struct buffer_head *udf_bread(struct inode *inode, int block, | |||
1010 | return NULL; | 1086 | return NULL; |
1011 | } | 1087 | } |
1012 | 1088 | ||
1013 | void udf_truncate(struct inode *inode) | 1089 | int udf_setsize(struct inode *inode, loff_t newsize) |
1014 | { | 1090 | { |
1015 | int offset; | ||
1016 | int err; | 1091 | int err; |
1017 | struct udf_inode_info *iinfo; | 1092 | struct udf_inode_info *iinfo; |
1093 | int bsize = 1 << inode->i_blkbits; | ||
1018 | 1094 | ||
1019 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 1095 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
1020 | S_ISLNK(inode->i_mode))) | 1096 | S_ISLNK(inode->i_mode))) |
1021 | return; | 1097 | return -EINVAL; |
1022 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 1098 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
1023 | return; | 1099 | return -EPERM; |
1024 | 1100 | ||
1025 | lock_kernel(); | ||
1026 | iinfo = UDF_I(inode); | 1101 | iinfo = UDF_I(inode); |
1027 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1102 | if (newsize > inode->i_size) { |
1028 | if (inode->i_sb->s_blocksize < | 1103 | down_write(&iinfo->i_data_sem); |
1029 | (udf_file_entry_alloc_offset(inode) + | 1104 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1030 | inode->i_size)) { | 1105 | if (bsize < |
1031 | udf_expand_file_adinicb(inode, inode->i_size, &err); | 1106 | (udf_file_entry_alloc_offset(inode) + newsize)) { |
1032 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1107 | err = udf_expand_file_adinicb(inode); |
1033 | inode->i_size = iinfo->i_lenAlloc; | 1108 | if (err) { |
1034 | unlock_kernel(); | 1109 | up_write(&iinfo->i_data_sem); |
1035 | return; | 1110 | return err; |
1111 | } | ||
1036 | } else | 1112 | } else |
1037 | udf_truncate_extents(inode); | 1113 | iinfo->i_lenAlloc = newsize; |
1038 | } else { | ||
1039 | offset = inode->i_size & (inode->i_sb->s_blocksize - 1); | ||
1040 | memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + offset, | ||
1041 | 0x00, inode->i_sb->s_blocksize - | ||
1042 | offset - udf_file_entry_alloc_offset(inode)); | ||
1043 | iinfo->i_lenAlloc = inode->i_size; | ||
1044 | } | 1114 | } |
1115 | err = udf_extend_file(inode, newsize); | ||
1116 | if (err) { | ||
1117 | up_write(&iinfo->i_data_sem); | ||
1118 | return err; | ||
1119 | } | ||
1120 | truncate_setsize(inode, newsize); | ||
1121 | up_write(&iinfo->i_data_sem); | ||
1045 | } else { | 1122 | } else { |
1046 | block_truncate_page(inode->i_mapping, inode->i_size, | 1123 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1047 | udf_get_block); | 1124 | down_write(&iinfo->i_data_sem); |
1125 | memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + newsize, | ||
1126 | 0x00, bsize - newsize - | ||
1127 | udf_file_entry_alloc_offset(inode)); | ||
1128 | iinfo->i_lenAlloc = newsize; | ||
1129 | truncate_setsize(inode, newsize); | ||
1130 | up_write(&iinfo->i_data_sem); | ||
1131 | goto update_time; | ||
1132 | } | ||
1133 | err = block_truncate_page(inode->i_mapping, newsize, | ||
1134 | udf_get_block); | ||
1135 | if (err) | ||
1136 | return err; | ||
1137 | down_write(&iinfo->i_data_sem); | ||
1138 | truncate_setsize(inode, newsize); | ||
1048 | udf_truncate_extents(inode); | 1139 | udf_truncate_extents(inode); |
1140 | up_write(&iinfo->i_data_sem); | ||
1049 | } | 1141 | } |
1050 | 1142 | update_time: | |
1051 | inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); | 1143 | inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); |
1052 | if (IS_SYNC(inode)) | 1144 | if (IS_SYNC(inode)) |
1053 | udf_sync_inode(inode); | 1145 | udf_sync_inode(inode); |
1054 | else | 1146 | else |
1055 | mark_inode_dirty(inode); | 1147 | mark_inode_dirty(inode); |
1056 | unlock_kernel(); | 1148 | return 0; |
1057 | } | 1149 | } |
1058 | 1150 | ||
1059 | static void __udf_read_inode(struct inode *inode) | 1151 | static void __udf_read_inode(struct inode *inode) |
@@ -1202,6 +1294,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1202 | return; | 1294 | return; |
1203 | } | 1295 | } |
1204 | 1296 | ||
1297 | read_lock(&sbi->s_cred_lock); | ||
1205 | inode->i_uid = le32_to_cpu(fe->uid); | 1298 | inode->i_uid = le32_to_cpu(fe->uid); |
1206 | if (inode->i_uid == -1 || | 1299 | if (inode->i_uid == -1 || |
1207 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) || | 1300 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) || |
@@ -1214,13 +1307,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1214 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) | 1307 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) |
1215 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; | 1308 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; |
1216 | 1309 | ||
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 && | 1310 | if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY && |
1225 | sbi->s_fmode != UDF_INVALID_MODE) | 1311 | sbi->s_fmode != UDF_INVALID_MODE) |
1226 | inode->i_mode = sbi->s_fmode; | 1312 | inode->i_mode = sbi->s_fmode; |
@@ -1230,6 +1316,14 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1230 | else | 1316 | else |
1231 | inode->i_mode = udf_convert_permissions(fe); | 1317 | inode->i_mode = udf_convert_permissions(fe); |
1232 | inode->i_mode &= ~sbi->s_umask; | 1318 | inode->i_mode &= ~sbi->s_umask; |
1319 | read_unlock(&sbi->s_cred_lock); | ||
1320 | |||
1321 | inode->i_nlink = le16_to_cpu(fe->fileLinkCount); | ||
1322 | if (!inode->i_nlink) | ||
1323 | inode->i_nlink = 1; | ||
1324 | |||
1325 | inode->i_size = le64_to_cpu(fe->informationLength); | ||
1326 | iinfo->i_lenExtents = inode->i_size; | ||
1233 | 1327 | ||
1234 | if (iinfo->i_efe == 0) { | 1328 | if (iinfo->i_efe == 0) { |
1235 | inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << | 1329 | inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << |
@@ -1373,16 +1467,10 @@ static mode_t udf_convert_permissions(struct fileEntry *fe) | |||
1373 | 1467 | ||
1374 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) | 1468 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) |
1375 | { | 1469 | { |
1376 | int ret; | 1470 | 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 | } | 1471 | } |
1384 | 1472 | ||
1385 | int udf_sync_inode(struct inode *inode) | 1473 | static int udf_sync_inode(struct inode *inode) |
1386 | { | 1474 | { |
1387 | return udf_update_inode(inode, 1); | 1475 | return udf_update_inode(inode, 1); |
1388 | } | 1476 | } |
@@ -1644,14 +1732,13 @@ struct inode *udf_iget(struct super_block *sb, struct kernel_lb_addr *ino) | |||
1644 | return NULL; | 1732 | return NULL; |
1645 | } | 1733 | } |
1646 | 1734 | ||
1647 | int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, | 1735 | int udf_add_aext(struct inode *inode, struct extent_position *epos, |
1648 | struct kernel_lb_addr *eloc, uint32_t elen, int inc) | 1736 | struct kernel_lb_addr *eloc, uint32_t elen, int inc) |
1649 | { | 1737 | { |
1650 | int adsize; | 1738 | int adsize; |
1651 | struct short_ad *sad = NULL; | 1739 | struct short_ad *sad = NULL; |
1652 | struct long_ad *lad = NULL; | 1740 | struct long_ad *lad = NULL; |
1653 | struct allocExtDesc *aed; | 1741 | struct allocExtDesc *aed; |
1654 | int8_t etype; | ||
1655 | uint8_t *ptr; | 1742 | uint8_t *ptr; |
1656 | struct udf_inode_info *iinfo = UDF_I(inode); | 1743 | struct udf_inode_info *iinfo = UDF_I(inode); |
1657 | 1744 | ||
@@ -1667,7 +1754,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, | |||
1667 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 1754 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
1668 | adsize = sizeof(struct long_ad); | 1755 | adsize = sizeof(struct long_ad); |
1669 | else | 1756 | else |
1670 | return -1; | 1757 | return -EIO; |
1671 | 1758 | ||
1672 | if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) { | 1759 | if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) { |
1673 | unsigned char *sptr, *dptr; | 1760 | unsigned char *sptr, *dptr; |
@@ -1679,12 +1766,12 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, | |||
1679 | obloc.partitionReferenceNum, | 1766 | obloc.partitionReferenceNum, |
1680 | obloc.logicalBlockNum, &err); | 1767 | obloc.logicalBlockNum, &err); |
1681 | if (!epos->block.logicalBlockNum) | 1768 | if (!epos->block.logicalBlockNum) |
1682 | return -1; | 1769 | return -ENOSPC; |
1683 | nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, | 1770 | nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, |
1684 | &epos->block, | 1771 | &epos->block, |
1685 | 0)); | 1772 | 0)); |
1686 | if (!nbh) | 1773 | if (!nbh) |
1687 | return -1; | 1774 | return -EIO; |
1688 | lock_buffer(nbh); | 1775 | lock_buffer(nbh); |
1689 | memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize); | 1776 | memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize); |
1690 | set_buffer_uptodate(nbh); | 1777 | set_buffer_uptodate(nbh); |
@@ -1753,7 +1840,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, | |||
1753 | epos->bh = nbh; | 1840 | epos->bh = nbh; |
1754 | } | 1841 | } |
1755 | 1842 | ||
1756 | etype = udf_write_aext(inode, epos, eloc, elen, inc); | 1843 | udf_write_aext(inode, epos, eloc, elen, inc); |
1757 | 1844 | ||
1758 | if (!epos->bh) { | 1845 | if (!epos->bh) { |
1759 | iinfo->i_lenAlloc += adsize; | 1846 | iinfo->i_lenAlloc += adsize; |
@@ -1771,11 +1858,11 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, | |||
1771 | mark_buffer_dirty_inode(epos->bh, inode); | 1858 | mark_buffer_dirty_inode(epos->bh, inode); |
1772 | } | 1859 | } |
1773 | 1860 | ||
1774 | return etype; | 1861 | return 0; |
1775 | } | 1862 | } |
1776 | 1863 | ||
1777 | int8_t udf_write_aext(struct inode *inode, struct extent_position *epos, | 1864 | void udf_write_aext(struct inode *inode, struct extent_position *epos, |
1778 | struct kernel_lb_addr *eloc, uint32_t elen, int inc) | 1865 | struct kernel_lb_addr *eloc, uint32_t elen, int inc) |
1779 | { | 1866 | { |
1780 | int adsize; | 1867 | int adsize; |
1781 | uint8_t *ptr; | 1868 | uint8_t *ptr; |
@@ -1805,7 +1892,7 @@ int8_t udf_write_aext(struct inode *inode, struct extent_position *epos, | |||
1805 | adsize = sizeof(struct long_ad); | 1892 | adsize = sizeof(struct long_ad); |
1806 | break; | 1893 | break; |
1807 | default: | 1894 | default: |
1808 | return -1; | 1895 | return; |
1809 | } | 1896 | } |
1810 | 1897 | ||
1811 | if (epos->bh) { | 1898 | if (epos->bh) { |
@@ -1824,8 +1911,6 @@ int8_t udf_write_aext(struct inode *inode, struct extent_position *epos, | |||
1824 | 1911 | ||
1825 | if (inc) | 1912 | if (inc) |
1826 | epos->offset += adsize; | 1913 | epos->offset += adsize; |
1827 | |||
1828 | return (elen >> 30); | ||
1829 | } | 1914 | } |
1830 | 1915 | ||
1831 | int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, | 1916 | int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, |
@@ -2048,7 +2133,7 @@ long udf_block_map(struct inode *inode, sector_t block) | |||
2048 | struct extent_position epos = {}; | 2133 | struct extent_position epos = {}; |
2049 | int ret; | 2134 | int ret; |
2050 | 2135 | ||
2051 | lock_kernel(); | 2136 | down_read(&UDF_I(inode)->i_data_sem); |
2052 | 2137 | ||
2053 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == | 2138 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == |
2054 | (EXT_RECORDED_ALLOCATED >> 30)) | 2139 | (EXT_RECORDED_ALLOCATED >> 30)) |
@@ -2056,7 +2141,7 @@ long udf_block_map(struct inode *inode, sector_t block) | |||
2056 | else | 2141 | else |
2057 | ret = 0; | 2142 | ret = 0; |
2058 | 2143 | ||
2059 | unlock_kernel(); | 2144 | up_read(&UDF_I(inode)->i_data_sem); |
2060 | brelse(epos.bh); | 2145 | brelse(epos.bh); |
2061 | 2146 | ||
2062 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) | 2147 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index bf5fc674193c..f1dce848ef96 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -27,12 +27,13 @@ | |||
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> |
34 | #include <linux/exportfs.h> | 33 | #include <linux/exportfs.h> |
35 | 34 | ||
35 | enum { UDF_MAX_LINKS = 0xffff }; | ||
36 | |||
36 | static inline int udf_match(int len1, const unsigned char *name1, int len2, | 37 | static inline int udf_match(int len1, const unsigned char *name1, int len2, |
37 | const unsigned char *name2) | 38 | const unsigned char *name2) |
38 | { | 39 | { |
@@ -228,10 +229,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
228 | } | 229 | } |
229 | 230 | ||
230 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) && | 231 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) && |
231 | isdotdot) { | 232 | isdotdot) |
232 | brelse(epos.bh); | 233 | goto out_ok; |
233 | return fi; | ||
234 | } | ||
235 | 234 | ||
236 | if (!lfi) | 235 | if (!lfi) |
237 | continue; | 236 | continue; |
@@ -263,7 +262,6 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | |||
263 | if (dentry->d_name.len > UDF_NAME_LEN - 2) | 262 | if (dentry->d_name.len > UDF_NAME_LEN - 2) |
264 | return ERR_PTR(-ENAMETOOLONG); | 263 | return ERR_PTR(-ENAMETOOLONG); |
265 | 264 | ||
266 | lock_kernel(); | ||
267 | #ifdef UDF_RECOVERY | 265 | #ifdef UDF_RECOVERY |
268 | /* temporary shorthand for specifying files by inode number */ | 266 | /* temporary shorthand for specifying files by inode number */ |
269 | if (!strncmp(dentry->d_name.name, ".B=", 3)) { | 267 | if (!strncmp(dentry->d_name.name, ".B=", 3)) { |
@@ -275,7 +273,6 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | |||
275 | }; | 273 | }; |
276 | inode = udf_iget(dir->i_sb, lb); | 274 | inode = udf_iget(dir->i_sb, lb); |
277 | if (!inode) { | 275 | if (!inode) { |
278 | unlock_kernel(); | ||
279 | return ERR_PTR(-EACCES); | 276 | return ERR_PTR(-EACCES); |
280 | } | 277 | } |
281 | } else | 278 | } else |
@@ -291,11 +288,9 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | |||
291 | loc = lelb_to_cpu(cfi.icb.extLocation); | 288 | loc = lelb_to_cpu(cfi.icb.extLocation); |
292 | inode = udf_iget(dir->i_sb, &loc); | 289 | inode = udf_iget(dir->i_sb, &loc); |
293 | if (!inode) { | 290 | if (!inode) { |
294 | unlock_kernel(); | ||
295 | return ERR_PTR(-EACCES); | 291 | return ERR_PTR(-EACCES); |
296 | } | 292 | } |
297 | } | 293 | } |
298 | unlock_kernel(); | ||
299 | 294 | ||
300 | return d_splice_alias(inode, dentry); | 295 | return d_splice_alias(inode, dentry); |
301 | } | 296 | } |
@@ -476,15 +471,19 @@ add: | |||
476 | f_pos >> dir->i_sb->s_blocksize_bits, 1, err); | 471 | f_pos >> dir->i_sb->s_blocksize_bits, 1, err); |
477 | if (!fibh->ebh) | 472 | if (!fibh->ebh) |
478 | goto out_err; | 473 | goto out_err; |
474 | /* Extents could have been merged, invalidate our position */ | ||
475 | brelse(epos.bh); | ||
476 | epos.bh = NULL; | ||
477 | epos.block = dinfo->i_location; | ||
478 | epos.offset = udf_file_entry_alloc_offset(dir); | ||
479 | 479 | ||
480 | if (!fibh->soffset) { | 480 | if (!fibh->soffset) { |
481 | if (udf_next_aext(dir, &epos, &eloc, &elen, 1) == | 481 | /* Find the freshly allocated block */ |
482 | (EXT_RECORDED_ALLOCATED >> 30)) { | 482 | while (udf_next_aext(dir, &epos, &eloc, &elen, 1) == |
483 | block = eloc.logicalBlockNum + ((elen - 1) >> | 483 | (EXT_RECORDED_ALLOCATED >> 30)) |
484 | ; | ||
485 | block = eloc.logicalBlockNum + ((elen - 1) >> | ||
484 | dir->i_sb->s_blocksize_bits); | 486 | dir->i_sb->s_blocksize_bits); |
485 | } else | ||
486 | block++; | ||
487 | |||
488 | brelse(fibh->sbh); | 487 | brelse(fibh->sbh); |
489 | fibh->sbh = fibh->ebh; | 488 | fibh->sbh = fibh->ebh; |
490 | fi = (struct fileIdentDesc *)(fibh->sbh->b_data); | 489 | fi = (struct fileIdentDesc *)(fibh->sbh->b_data); |
@@ -562,10 +561,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, | |||
562 | int err; | 561 | int err; |
563 | struct udf_inode_info *iinfo; | 562 | struct udf_inode_info *iinfo; |
564 | 563 | ||
565 | lock_kernel(); | ||
566 | inode = udf_new_inode(dir, mode, &err); | 564 | inode = udf_new_inode(dir, mode, &err); |
567 | if (!inode) { | 565 | if (!inode) { |
568 | unlock_kernel(); | ||
569 | return err; | 566 | return err; |
570 | } | 567 | } |
571 | 568 | ||
@@ -583,7 +580,6 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, | |||
583 | inode->i_nlink--; | 580 | inode->i_nlink--; |
584 | mark_inode_dirty(inode); | 581 | mark_inode_dirty(inode); |
585 | iput(inode); | 582 | iput(inode); |
586 | unlock_kernel(); | ||
587 | return err; | 583 | return err; |
588 | } | 584 | } |
589 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 585 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); |
@@ -596,7 +592,6 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, | |||
596 | if (fibh.sbh != fibh.ebh) | 592 | if (fibh.sbh != fibh.ebh) |
597 | brelse(fibh.ebh); | 593 | brelse(fibh.ebh); |
598 | brelse(fibh.sbh); | 594 | brelse(fibh.sbh); |
599 | unlock_kernel(); | ||
600 | d_instantiate(dentry, inode); | 595 | d_instantiate(dentry, inode); |
601 | 596 | ||
602 | return 0; | 597 | return 0; |
@@ -614,7 +609,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
614 | if (!old_valid_dev(rdev)) | 609 | if (!old_valid_dev(rdev)) |
615 | return -EINVAL; | 610 | return -EINVAL; |
616 | 611 | ||
617 | lock_kernel(); | ||
618 | err = -EIO; | 612 | err = -EIO; |
619 | inode = udf_new_inode(dir, mode, &err); | 613 | inode = udf_new_inode(dir, mode, &err); |
620 | if (!inode) | 614 | if (!inode) |
@@ -627,7 +621,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
627 | inode->i_nlink--; | 621 | inode->i_nlink--; |
628 | mark_inode_dirty(inode); | 622 | mark_inode_dirty(inode); |
629 | iput(inode); | 623 | iput(inode); |
630 | unlock_kernel(); | ||
631 | return err; | 624 | return err; |
632 | } | 625 | } |
633 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 626 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); |
@@ -646,7 +639,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
646 | err = 0; | 639 | err = 0; |
647 | 640 | ||
648 | out: | 641 | out: |
649 | unlock_kernel(); | ||
650 | return err; | 642 | return err; |
651 | } | 643 | } |
652 | 644 | ||
@@ -659,9 +651,8 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
659 | struct udf_inode_info *dinfo = UDF_I(dir); | 651 | struct udf_inode_info *dinfo = UDF_I(dir); |
660 | struct udf_inode_info *iinfo; | 652 | struct udf_inode_info *iinfo; |
661 | 653 | ||
662 | lock_kernel(); | ||
663 | err = -EMLINK; | 654 | err = -EMLINK; |
664 | if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1) | 655 | if (dir->i_nlink >= UDF_MAX_LINKS) |
665 | goto out; | 656 | goto out; |
666 | 657 | ||
667 | err = -EIO; | 658 | err = -EIO; |
@@ -712,7 +703,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
712 | err = 0; | 703 | err = 0; |
713 | 704 | ||
714 | out: | 705 | out: |
715 | unlock_kernel(); | ||
716 | return err; | 706 | return err; |
717 | } | 707 | } |
718 | 708 | ||
@@ -794,7 +784,6 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) | |||
794 | struct kernel_lb_addr tloc; | 784 | struct kernel_lb_addr tloc; |
795 | 785 | ||
796 | retval = -ENOENT; | 786 | retval = -ENOENT; |
797 | lock_kernel(); | ||
798 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 787 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
799 | if (!fi) | 788 | if (!fi) |
800 | goto out; | 789 | goto out; |
@@ -826,7 +815,6 @@ end_rmdir: | |||
826 | brelse(fibh.sbh); | 815 | brelse(fibh.sbh); |
827 | 816 | ||
828 | out: | 817 | out: |
829 | unlock_kernel(); | ||
830 | return retval; | 818 | return retval; |
831 | } | 819 | } |
832 | 820 | ||
@@ -840,7 +828,6 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry) | |||
840 | struct kernel_lb_addr tloc; | 828 | struct kernel_lb_addr tloc; |
841 | 829 | ||
842 | retval = -ENOENT; | 830 | retval = -ENOENT; |
843 | lock_kernel(); | ||
844 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 831 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
845 | if (!fi) | 832 | if (!fi) |
846 | goto out; | 833 | goto out; |
@@ -870,7 +857,6 @@ end_unlink: | |||
870 | brelse(fibh.sbh); | 857 | brelse(fibh.sbh); |
871 | 858 | ||
872 | out: | 859 | out: |
873 | unlock_kernel(); | ||
874 | return retval; | 860 | return retval; |
875 | } | 861 | } |
876 | 862 | ||
@@ -890,21 +876,21 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
890 | int block; | 876 | int block; |
891 | unsigned char *name = NULL; | 877 | unsigned char *name = NULL; |
892 | int namelen; | 878 | int namelen; |
893 | struct buffer_head *bh; | ||
894 | struct udf_inode_info *iinfo; | 879 | struct udf_inode_info *iinfo; |
880 | struct super_block *sb = dir->i_sb; | ||
895 | 881 | ||
896 | lock_kernel(); | ||
897 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); | 882 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); |
898 | if (!inode) | 883 | if (!inode) |
899 | goto out; | 884 | goto out; |
900 | 885 | ||
886 | iinfo = UDF_I(inode); | ||
887 | down_write(&iinfo->i_data_sem); | ||
901 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); | 888 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); |
902 | if (!name) { | 889 | if (!name) { |
903 | err = -ENOMEM; | 890 | err = -ENOMEM; |
904 | goto out_no_entry; | 891 | goto out_no_entry; |
905 | } | 892 | } |
906 | 893 | ||
907 | iinfo = UDF_I(inode); | ||
908 | inode->i_data.a_ops = &udf_symlink_aops; | 894 | inode->i_data.a_ops = &udf_symlink_aops; |
909 | inode->i_op = &udf_symlink_inode_operations; | 895 | inode->i_op = &udf_symlink_inode_operations; |
910 | 896 | ||
@@ -912,7 +898,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
912 | struct kernel_lb_addr eloc; | 898 | struct kernel_lb_addr eloc; |
913 | uint32_t bsize; | 899 | uint32_t bsize; |
914 | 900 | ||
915 | block = udf_new_block(inode->i_sb, inode, | 901 | block = udf_new_block(sb, inode, |
916 | iinfo->i_location.partitionReferenceNum, | 902 | iinfo->i_location.partitionReferenceNum, |
917 | iinfo->i_location.logicalBlockNum, &err); | 903 | iinfo->i_location.logicalBlockNum, &err); |
918 | if (!block) | 904 | if (!block) |
@@ -923,17 +909,17 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
923 | eloc.logicalBlockNum = block; | 909 | eloc.logicalBlockNum = block; |
924 | eloc.partitionReferenceNum = | 910 | eloc.partitionReferenceNum = |
925 | iinfo->i_location.partitionReferenceNum; | 911 | iinfo->i_location.partitionReferenceNum; |
926 | bsize = inode->i_sb->s_blocksize; | 912 | bsize = sb->s_blocksize; |
927 | iinfo->i_lenExtents = bsize; | 913 | iinfo->i_lenExtents = bsize; |
928 | udf_add_aext(inode, &epos, &eloc, bsize, 0); | 914 | udf_add_aext(inode, &epos, &eloc, bsize, 0); |
929 | brelse(epos.bh); | 915 | brelse(epos.bh); |
930 | 916 | ||
931 | block = udf_get_pblock(inode->i_sb, block, | 917 | block = udf_get_pblock(sb, block, |
932 | iinfo->i_location.partitionReferenceNum, | 918 | iinfo->i_location.partitionReferenceNum, |
933 | 0); | 919 | 0); |
934 | epos.bh = udf_tgetblk(inode->i_sb, block); | 920 | epos.bh = udf_tgetblk(sb, block); |
935 | lock_buffer(epos.bh); | 921 | lock_buffer(epos.bh); |
936 | memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); | 922 | memset(epos.bh->b_data, 0x00, bsize); |
937 | set_buffer_uptodate(epos.bh); | 923 | set_buffer_uptodate(epos.bh); |
938 | unlock_buffer(epos.bh); | 924 | unlock_buffer(epos.bh); |
939 | mark_buffer_dirty_inode(epos.bh, inode); | 925 | mark_buffer_dirty_inode(epos.bh, inode); |
@@ -941,7 +927,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
941 | } else | 927 | } else |
942 | ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr; | 928 | ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr; |
943 | 929 | ||
944 | eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode); | 930 | eoffset = sb->s_blocksize - udf_ext0_offset(inode); |
945 | pc = (struct pathComponent *)ea; | 931 | pc = (struct pathComponent *)ea; |
946 | 932 | ||
947 | if (*symname == '/') { | 933 | if (*symname == '/') { |
@@ -981,7 +967,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
981 | } | 967 | } |
982 | 968 | ||
983 | if (pc->componentType == 5) { | 969 | if (pc->componentType == 5) { |
984 | namelen = udf_put_filename(inode->i_sb, compstart, name, | 970 | namelen = udf_put_filename(sb, compstart, name, |
985 | symname - compstart); | 971 | symname - compstart); |
986 | if (!namelen) | 972 | if (!namelen) |
987 | goto out_no_entry; | 973 | goto out_no_entry; |
@@ -1015,27 +1001,16 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
1015 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 1001 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
1016 | if (!fi) | 1002 | if (!fi) |
1017 | goto out_no_entry; | 1003 | goto out_no_entry; |
1018 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 1004 | cfi.icb.extLength = cpu_to_le32(sb->s_blocksize); |
1019 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); | 1005 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); |
1020 | bh = UDF_SB(inode->i_sb)->s_lvid_bh; | 1006 | 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 = | 1007 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = |
1030 | cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); | 1008 | 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 | } | 1009 | } |
1036 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 1010 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
1037 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1011 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
1038 | mark_inode_dirty(dir); | 1012 | mark_inode_dirty(dir); |
1013 | up_write(&iinfo->i_data_sem); | ||
1039 | if (fibh.sbh != fibh.ebh) | 1014 | if (fibh.sbh != fibh.ebh) |
1040 | brelse(fibh.ebh); | 1015 | brelse(fibh.ebh); |
1041 | brelse(fibh.sbh); | 1016 | brelse(fibh.sbh); |
@@ -1044,10 +1019,10 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
1044 | 1019 | ||
1045 | out: | 1020 | out: |
1046 | kfree(name); | 1021 | kfree(name); |
1047 | unlock_kernel(); | ||
1048 | return err; | 1022 | return err; |
1049 | 1023 | ||
1050 | out_no_entry: | 1024 | out_no_entry: |
1025 | up_write(&iinfo->i_data_sem); | ||
1051 | inode_dec_link_count(inode); | 1026 | inode_dec_link_count(inode); |
1052 | iput(inode); | 1027 | iput(inode); |
1053 | goto out; | 1028 | goto out; |
@@ -1060,36 +1035,19 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1060 | struct udf_fileident_bh fibh; | 1035 | struct udf_fileident_bh fibh; |
1061 | struct fileIdentDesc cfi, *fi; | 1036 | struct fileIdentDesc cfi, *fi; |
1062 | int err; | 1037 | int err; |
1063 | struct buffer_head *bh; | ||
1064 | 1038 | ||
1065 | lock_kernel(); | 1039 | if (inode->i_nlink >= UDF_MAX_LINKS) |
1066 | if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { | ||
1067 | unlock_kernel(); | ||
1068 | return -EMLINK; | 1040 | return -EMLINK; |
1069 | } | ||
1070 | 1041 | ||
1071 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 1042 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
1072 | if (!fi) { | 1043 | if (!fi) { |
1073 | unlock_kernel(); | ||
1074 | return err; | 1044 | return err; |
1075 | } | 1045 | } |
1076 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 1046 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); |
1077 | cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location); | 1047 | cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location); |
1078 | bh = UDF_SB(inode->i_sb)->s_lvid_bh; | 1048 | 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 = | 1049 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = |
1088 | cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); | 1050 | 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 | } | 1051 | } |
1094 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 1052 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
1095 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1053 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
@@ -1101,9 +1059,8 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1101 | inc_nlink(inode); | 1059 | inc_nlink(inode); |
1102 | inode->i_ctime = current_fs_time(inode->i_sb); | 1060 | inode->i_ctime = current_fs_time(inode->i_sb); |
1103 | mark_inode_dirty(inode); | 1061 | mark_inode_dirty(inode); |
1104 | atomic_inc(&inode->i_count); | 1062 | ihold(inode); |
1105 | d_instantiate(dentry, inode); | 1063 | d_instantiate(dentry, inode); |
1106 | unlock_kernel(); | ||
1107 | 1064 | ||
1108 | return 0; | 1065 | return 0; |
1109 | } | 1066 | } |
@@ -1124,7 +1081,6 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1124 | struct kernel_lb_addr tloc; | 1081 | struct kernel_lb_addr tloc; |
1125 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); | 1082 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); |
1126 | 1083 | ||
1127 | lock_kernel(); | ||
1128 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); | 1084 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1129 | if (ofi) { | 1085 | if (ofi) { |
1130 | if (ofibh.sbh != ofibh.ebh) | 1086 | if (ofibh.sbh != ofibh.ebh) |
@@ -1176,9 +1132,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1176 | goto end_rename; | 1132 | goto end_rename; |
1177 | 1133 | ||
1178 | retval = -EMLINK; | 1134 | retval = -EMLINK; |
1179 | if (!new_inode && | 1135 | if (!new_inode && new_dir->i_nlink >= UDF_MAX_LINKS) |
1180 | new_dir->i_nlink >= | ||
1181 | (256 << sizeof(new_dir->i_nlink)) - 1) | ||
1182 | goto end_rename; | 1136 | goto end_rename; |
1183 | } | 1137 | } |
1184 | if (!nfi) { | 1138 | if (!nfi) { |
@@ -1248,7 +1202,6 @@ end_rename: | |||
1248 | brelse(nfibh.ebh); | 1202 | brelse(nfibh.ebh); |
1249 | brelse(nfibh.sbh); | 1203 | brelse(nfibh.sbh); |
1250 | } | 1204 | } |
1251 | unlock_kernel(); | ||
1252 | 1205 | ||
1253 | return retval; | 1206 | return retval; |
1254 | } | 1207 | } |
@@ -1261,7 +1214,6 @@ static struct dentry *udf_get_parent(struct dentry *child) | |||
1261 | struct fileIdentDesc cfi; | 1214 | struct fileIdentDesc cfi; |
1262 | struct udf_fileident_bh fibh; | 1215 | struct udf_fileident_bh fibh; |
1263 | 1216 | ||
1264 | lock_kernel(); | ||
1265 | if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) | 1217 | if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) |
1266 | goto out_unlock; | 1218 | goto out_unlock; |
1267 | 1219 | ||
@@ -1273,11 +1225,9 @@ static struct dentry *udf_get_parent(struct dentry *child) | |||
1273 | inode = udf_iget(child->d_inode->i_sb, &tloc); | 1225 | inode = udf_iget(child->d_inode->i_sb, &tloc); |
1274 | if (!inode) | 1226 | if (!inode) |
1275 | goto out_unlock; | 1227 | goto out_unlock; |
1276 | unlock_kernel(); | ||
1277 | 1228 | ||
1278 | return d_obtain_alias(inode); | 1229 | return d_obtain_alias(inode); |
1279 | out_unlock: | 1230 | out_unlock: |
1280 | unlock_kernel(); | ||
1281 | return ERR_PTR(-EACCES); | 1231 | return ERR_PTR(-EACCES); |
1282 | } | 1232 | } |
1283 | 1233 | ||
@@ -1336,8 +1286,13 @@ static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp, | |||
1336 | struct fid *fid = (struct fid *)fh; | 1286 | struct fid *fid = (struct fid *)fh; |
1337 | int type = FILEID_UDF_WITHOUT_PARENT; | 1287 | int type = FILEID_UDF_WITHOUT_PARENT; |
1338 | 1288 | ||
1339 | if (len < 3 || (connectable && len < 5)) | 1289 | if (connectable && (len < 5)) { |
1290 | *lenp = 5; | ||
1340 | return 255; | 1291 | return 255; |
1292 | } else if (len < 3) { | ||
1293 | *lenp = 3; | ||
1294 | return 255; | ||
1295 | } | ||
1341 | 1296 | ||
1342 | *lenp = 3; | 1297 | *lenp = 3; |
1343 | fid->udf.block = location.logicalBlockNum; | 1298 | fid->udf.block = location.logicalBlockNum; |
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 65412d84a45d..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> |
@@ -107,17 +106,16 @@ struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi) | |||
107 | } | 106 | } |
108 | 107 | ||
109 | /* UDF filesystem type */ | 108 | /* UDF filesystem type */ |
110 | static int udf_get_sb(struct file_system_type *fs_type, | 109 | static struct dentry *udf_mount(struct file_system_type *fs_type, |
111 | int flags, const char *dev_name, void *data, | 110 | int flags, const char *dev_name, void *data) |
112 | struct vfsmount *mnt) | ||
113 | { | 111 | { |
114 | return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super, mnt); | 112 | return mount_bdev(fs_type, flags, dev_name, data, udf_fill_super); |
115 | } | 113 | } |
116 | 114 | ||
117 | static struct file_system_type udf_fstype = { | 115 | static struct file_system_type udf_fstype = { |
118 | .owner = THIS_MODULE, | 116 | .owner = THIS_MODULE, |
119 | .name = "udf", | 117 | .name = "udf", |
120 | .get_sb = udf_get_sb, | 118 | .mount = udf_mount, |
121 | .kill_sb = kill_block_super, | 119 | .kill_sb = kill_block_super, |
122 | .fs_flags = FS_REQUIRES_DEV, | 120 | .fs_flags = FS_REQUIRES_DEV, |
123 | }; | 121 | }; |
@@ -136,15 +134,23 @@ static struct inode *udf_alloc_inode(struct super_block *sb) | |||
136 | ei->i_next_alloc_block = 0; | 134 | ei->i_next_alloc_block = 0; |
137 | ei->i_next_alloc_goal = 0; | 135 | ei->i_next_alloc_goal = 0; |
138 | ei->i_strat4096 = 0; | 136 | ei->i_strat4096 = 0; |
137 | init_rwsem(&ei->i_data_sem); | ||
139 | 138 | ||
140 | return &ei->vfs_inode; | 139 | return &ei->vfs_inode; |
141 | } | 140 | } |
142 | 141 | ||
143 | static void udf_destroy_inode(struct inode *inode) | 142 | static void udf_i_callback(struct rcu_head *head) |
144 | { | 143 | { |
144 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
145 | INIT_LIST_HEAD(&inode->i_dentry); | ||
145 | kmem_cache_free(udf_inode_cachep, UDF_I(inode)); | 146 | kmem_cache_free(udf_inode_cachep, UDF_I(inode)); |
146 | } | 147 | } |
147 | 148 | ||
149 | static void udf_destroy_inode(struct inode *inode) | ||
150 | { | ||
151 | call_rcu(&inode->i_rcu, udf_i_callback); | ||
152 | } | ||
153 | |||
148 | static void init_once(void *foo) | 154 | static void init_once(void *foo) |
149 | { | 155 | { |
150 | struct udf_inode_info *ei = (struct udf_inode_info *)foo; | 156 | struct udf_inode_info *ei = (struct udf_inode_info *)foo; |
@@ -568,13 +574,14 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
568 | if (!udf_parse_options(options, &uopt, true)) | 574 | if (!udf_parse_options(options, &uopt, true)) |
569 | return -EINVAL; | 575 | return -EINVAL; |
570 | 576 | ||
571 | lock_kernel(); | 577 | write_lock(&sbi->s_cred_lock); |
572 | sbi->s_flags = uopt.flags; | 578 | sbi->s_flags = uopt.flags; |
573 | sbi->s_uid = uopt.uid; | 579 | sbi->s_uid = uopt.uid; |
574 | sbi->s_gid = uopt.gid; | 580 | sbi->s_gid = uopt.gid; |
575 | sbi->s_umask = uopt.umask; | 581 | sbi->s_umask = uopt.umask; |
576 | sbi->s_fmode = uopt.fmode; | 582 | sbi->s_fmode = uopt.fmode; |
577 | sbi->s_dmode = uopt.dmode; | 583 | sbi->s_dmode = uopt.dmode; |
584 | write_unlock(&sbi->s_cred_lock); | ||
578 | 585 | ||
579 | if (sbi->s_lvid_bh) { | 586 | if (sbi->s_lvid_bh) { |
580 | int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); | 587 | int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); |
@@ -591,7 +598,6 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
591 | udf_open_lvid(sb); | 598 | udf_open_lvid(sb); |
592 | 599 | ||
593 | out_unlock: | 600 | out_unlock: |
594 | unlock_kernel(); | ||
595 | return error; | 601 | return error; |
596 | } | 602 | } |
597 | 603 | ||
@@ -960,9 +966,9 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | |||
960 | (sizeof(struct buffer_head *) * nr_groups); | 966 | (sizeof(struct buffer_head *) * nr_groups); |
961 | 967 | ||
962 | if (size <= PAGE_SIZE) | 968 | if (size <= PAGE_SIZE) |
963 | bitmap = kmalloc(size, GFP_KERNEL); | 969 | bitmap = kzalloc(size, GFP_KERNEL); |
964 | else | 970 | else |
965 | bitmap = vmalloc(size); /* TODO: get rid of vmalloc */ | 971 | bitmap = vzalloc(size); /* TODO: get rid of vzalloc */ |
966 | 972 | ||
967 | if (bitmap == NULL) { | 973 | if (bitmap == NULL) { |
968 | udf_error(sb, __func__, | 974 | udf_error(sb, __func__, |
@@ -971,7 +977,6 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | |||
971 | return NULL; | 977 | return NULL; |
972 | } | 978 | } |
973 | 979 | ||
974 | memset(bitmap, 0x00, size); | ||
975 | bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1); | 980 | bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1); |
976 | bitmap->s_nr_groups = nr_groups; | 981 | bitmap->s_nr_groups = nr_groups; |
977 | return bitmap; | 982 | return bitmap; |
@@ -1775,6 +1780,8 @@ static void udf_open_lvid(struct super_block *sb) | |||
1775 | 1780 | ||
1776 | if (!bh) | 1781 | if (!bh) |
1777 | return; | 1782 | return; |
1783 | |||
1784 | mutex_lock(&sbi->s_alloc_mutex); | ||
1778 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1785 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
1779 | lvidiu = udf_sb_lvidiu(sbi); | 1786 | lvidiu = udf_sb_lvidiu(sbi); |
1780 | 1787 | ||
@@ -1791,6 +1798,7 @@ static void udf_open_lvid(struct super_block *sb) | |||
1791 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | 1798 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
1792 | mark_buffer_dirty(bh); | 1799 | mark_buffer_dirty(bh); |
1793 | sbi->s_lvid_dirty = 0; | 1800 | sbi->s_lvid_dirty = 0; |
1801 | mutex_unlock(&sbi->s_alloc_mutex); | ||
1794 | } | 1802 | } |
1795 | 1803 | ||
1796 | static void udf_close_lvid(struct super_block *sb) | 1804 | static void udf_close_lvid(struct super_block *sb) |
@@ -1803,6 +1811,7 @@ static void udf_close_lvid(struct super_block *sb) | |||
1803 | if (!bh) | 1811 | if (!bh) |
1804 | return; | 1812 | return; |
1805 | 1813 | ||
1814 | mutex_lock(&sbi->s_alloc_mutex); | ||
1806 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1815 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
1807 | lvidiu = udf_sb_lvidiu(sbi); | 1816 | lvidiu = udf_sb_lvidiu(sbi); |
1808 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1817 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
@@ -1823,6 +1832,34 @@ static void udf_close_lvid(struct super_block *sb) | |||
1823 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | 1832 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
1824 | mark_buffer_dirty(bh); | 1833 | mark_buffer_dirty(bh); |
1825 | 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; | ||
1826 | } | 1863 | } |
1827 | 1864 | ||
1828 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | 1865 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) |
@@ -1926,6 +1963,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1926 | sbi->s_fmode = uopt.fmode; | 1963 | sbi->s_fmode = uopt.fmode; |
1927 | sbi->s_dmode = uopt.dmode; | 1964 | sbi->s_dmode = uopt.dmode; |
1928 | sbi->s_nls_map = uopt.nls_map; | 1965 | sbi->s_nls_map = uopt.nls_map; |
1966 | rwlock_init(&sbi->s_cred_lock); | ||
1929 | 1967 | ||
1930 | if (uopt.session == 0xFFFFFFFF) | 1968 | if (uopt.session == 0xFFFFFFFF) |
1931 | sbi->s_session = udf_get_last_session(sb); | 1969 | sbi->s_session = udf_get_last_session(sb); |
@@ -2093,8 +2131,6 @@ static void udf_put_super(struct super_block *sb) | |||
2093 | 2131 | ||
2094 | sbi = UDF_SB(sb); | 2132 | sbi = UDF_SB(sb); |
2095 | 2133 | ||
2096 | lock_kernel(); | ||
2097 | |||
2098 | if (sbi->s_vat_inode) | 2134 | if (sbi->s_vat_inode) |
2099 | iput(sbi->s_vat_inode); | 2135 | iput(sbi->s_vat_inode); |
2100 | if (sbi->s_partitions) | 2136 | if (sbi->s_partitions) |
@@ -2110,8 +2146,6 @@ static void udf_put_super(struct super_block *sb) | |||
2110 | kfree(sbi->s_partmaps); | 2146 | kfree(sbi->s_partmaps); |
2111 | kfree(sb->s_fs_info); | 2147 | kfree(sb->s_fs_info); |
2112 | sb->s_fs_info = NULL; | 2148 | sb->s_fs_info = NULL; |
2113 | |||
2114 | unlock_kernel(); | ||
2115 | } | 2149 | } |
2116 | 2150 | ||
2117 | static int udf_sync_fs(struct super_block *sb, int wait) | 2151 | static int udf_sync_fs(struct super_block *sb, int wait) |
@@ -2174,8 +2208,6 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
2174 | uint16_t ident; | 2208 | uint16_t ident; |
2175 | struct spaceBitmapDesc *bm; | 2209 | struct spaceBitmapDesc *bm; |
2176 | 2210 | ||
2177 | lock_kernel(); | ||
2178 | |||
2179 | loc.logicalBlockNum = bitmap->s_extPosition; | 2211 | loc.logicalBlockNum = bitmap->s_extPosition; |
2180 | loc.partitionReferenceNum = UDF_SB(sb)->s_partition; | 2212 | loc.partitionReferenceNum = UDF_SB(sb)->s_partition; |
2181 | bh = udf_read_ptagged(sb, &loc, 0, &ident); | 2213 | bh = udf_read_ptagged(sb, &loc, 0, &ident); |
@@ -2212,10 +2244,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
2212 | } | 2244 | } |
2213 | } | 2245 | } |
2214 | brelse(bh); | 2246 | brelse(bh); |
2215 | |||
2216 | out: | 2247 | out: |
2217 | unlock_kernel(); | ||
2218 | |||
2219 | return accum; | 2248 | return accum; |
2220 | } | 2249 | } |
2221 | 2250 | ||
@@ -2228,8 +2257,7 @@ static unsigned int udf_count_free_table(struct super_block *sb, | |||
2228 | int8_t etype; | 2257 | int8_t etype; |
2229 | struct extent_position epos; | 2258 | struct extent_position epos; |
2230 | 2259 | ||
2231 | lock_kernel(); | 2260 | mutex_lock(&UDF_SB(sb)->s_alloc_mutex); |
2232 | |||
2233 | epos.block = UDF_I(table)->i_location; | 2261 | epos.block = UDF_I(table)->i_location; |
2234 | epos.offset = sizeof(struct unallocSpaceEntry); | 2262 | epos.offset = sizeof(struct unallocSpaceEntry); |
2235 | epos.bh = NULL; | 2263 | epos.bh = NULL; |
@@ -2238,8 +2266,7 @@ static unsigned int udf_count_free_table(struct super_block *sb, | |||
2238 | accum += (elen >> table->i_sb->s_blocksize_bits); | 2266 | accum += (elen >> table->i_sb->s_blocksize_bits); |
2239 | 2267 | ||
2240 | brelse(epos.bh); | 2268 | brelse(epos.bh); |
2241 | 2269 | mutex_unlock(&UDF_SB(sb)->s_alloc_mutex); | |
2242 | unlock_kernel(); | ||
2243 | 2270 | ||
2244 | return accum; | 2271 | return accum; |
2245 | } | 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/truncate.c b/fs/udf/truncate.c index 225527cdc885..8424308db4b4 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c | |||
@@ -197,6 +197,11 @@ static void udf_update_alloc_ext_desc(struct inode *inode, | |||
197 | mark_buffer_dirty_inode(epos->bh, inode); | 197 | mark_buffer_dirty_inode(epos->bh, inode); |
198 | } | 198 | } |
199 | 199 | ||
200 | /* | ||
201 | * Truncate extents of inode to inode->i_size. This function can be used only | ||
202 | * for making file shorter. For making file longer, udf_extend_file() has to | ||
203 | * be used. | ||
204 | */ | ||
200 | void udf_truncate_extents(struct inode *inode) | 205 | void udf_truncate_extents(struct inode *inode) |
201 | { | 206 | { |
202 | struct extent_position epos; | 207 | struct extent_position epos; |
@@ -219,96 +224,65 @@ void udf_truncate_extents(struct inode *inode) | |||
219 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); | 224 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); |
220 | byte_offset = (offset << sb->s_blocksize_bits) + | 225 | byte_offset = (offset << sb->s_blocksize_bits) + |
221 | (inode->i_size & (sb->s_blocksize - 1)); | 226 | (inode->i_size & (sb->s_blocksize - 1)); |
222 | if (etype != -1) { | 227 | if (etype == -1) { |
223 | epos.offset -= adsize; | 228 | /* We should extend the file? */ |
224 | extent_trunc(inode, &epos, &eloc, etype, elen, byte_offset); | 229 | WARN_ON(byte_offset); |
225 | epos.offset += adsize; | 230 | return; |
226 | if (byte_offset) | 231 | } |
227 | lenalloc = epos.offset; | 232 | epos.offset -= adsize; |
228 | else | 233 | extent_trunc(inode, &epos, &eloc, etype, elen, byte_offset); |
229 | lenalloc = epos.offset - adsize; | 234 | epos.offset += adsize; |
230 | 235 | if (byte_offset) | |
231 | if (!epos.bh) | 236 | lenalloc = epos.offset; |
232 | lenalloc -= udf_file_entry_alloc_offset(inode); | 237 | else |
233 | else | 238 | lenalloc = epos.offset - adsize; |
234 | lenalloc -= sizeof(struct allocExtDesc); | ||
235 | |||
236 | while ((etype = udf_current_aext(inode, &epos, &eloc, | ||
237 | &elen, 0)) != -1) { | ||
238 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { | ||
239 | udf_write_aext(inode, &epos, &neloc, nelen, 0); | ||
240 | if (indirect_ext_len) { | ||
241 | /* We managed to free all extents in the | ||
242 | * indirect extent - free it too */ | ||
243 | BUG_ON(!epos.bh); | ||
244 | udf_free_blocks(sb, inode, &epos.block, | ||
245 | 0, indirect_ext_len); | ||
246 | } else if (!epos.bh) { | ||
247 | iinfo->i_lenAlloc = lenalloc; | ||
248 | mark_inode_dirty(inode); | ||
249 | } else | ||
250 | udf_update_alloc_ext_desc(inode, | ||
251 | &epos, lenalloc); | ||
252 | brelse(epos.bh); | ||
253 | epos.offset = sizeof(struct allocExtDesc); | ||
254 | epos.block = eloc; | ||
255 | epos.bh = udf_tread(sb, | ||
256 | udf_get_lb_pblock(sb, &eloc, 0)); | ||
257 | if (elen) | ||
258 | indirect_ext_len = | ||
259 | (elen + sb->s_blocksize - 1) >> | ||
260 | sb->s_blocksize_bits; | ||
261 | else | ||
262 | indirect_ext_len = 1; | ||
263 | } else { | ||
264 | extent_trunc(inode, &epos, &eloc, etype, | ||
265 | elen, 0); | ||
266 | epos.offset += adsize; | ||
267 | } | ||
268 | } | ||
269 | 239 | ||
270 | if (indirect_ext_len) { | 240 | if (!epos.bh) |
271 | BUG_ON(!epos.bh); | 241 | lenalloc -= udf_file_entry_alloc_offset(inode); |
272 | udf_free_blocks(sb, inode, &epos.block, 0, | 242 | else |
273 | indirect_ext_len); | 243 | lenalloc -= sizeof(struct allocExtDesc); |
274 | } else if (!epos.bh) { | ||
275 | iinfo->i_lenAlloc = lenalloc; | ||
276 | mark_inode_dirty(inode); | ||
277 | } else | ||
278 | udf_update_alloc_ext_desc(inode, &epos, lenalloc); | ||
279 | } else if (inode->i_size) { | ||
280 | if (byte_offset) { | ||
281 | struct kernel_long_ad extent; | ||
282 | 244 | ||
283 | /* | 245 | while ((etype = udf_current_aext(inode, &epos, &eloc, |
284 | * OK, there is not extent covering inode->i_size and | 246 | &elen, 0)) != -1) { |
285 | * no extent above inode->i_size => truncate is | 247 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { |
286 | * extending the file by 'offset' blocks. | 248 | udf_write_aext(inode, &epos, &neloc, nelen, 0); |
287 | */ | 249 | if (indirect_ext_len) { |
288 | if ((!epos.bh && | 250 | /* We managed to free all extents in the |
289 | epos.offset == | 251 | * indirect extent - free it too */ |
290 | udf_file_entry_alloc_offset(inode)) || | 252 | BUG_ON(!epos.bh); |
291 | (epos.bh && epos.offset == | 253 | udf_free_blocks(sb, inode, &epos.block, |
292 | sizeof(struct allocExtDesc))) { | 254 | 0, indirect_ext_len); |
293 | /* File has no extents at all or has empty last | 255 | } else if (!epos.bh) { |
294 | * indirect extent! Create a fake extent... */ | 256 | iinfo->i_lenAlloc = lenalloc; |
295 | extent.extLocation.logicalBlockNum = 0; | 257 | mark_inode_dirty(inode); |
296 | extent.extLocation.partitionReferenceNum = 0; | 258 | } else |
297 | extent.extLength = | 259 | udf_update_alloc_ext_desc(inode, |
298 | EXT_NOT_RECORDED_NOT_ALLOCATED; | 260 | &epos, lenalloc); |
299 | } else { | 261 | brelse(epos.bh); |
300 | epos.offset -= adsize; | 262 | epos.offset = sizeof(struct allocExtDesc); |
301 | etype = udf_next_aext(inode, &epos, | 263 | epos.block = eloc; |
302 | &extent.extLocation, | 264 | epos.bh = udf_tread(sb, |
303 | &extent.extLength, 0); | 265 | udf_get_lb_pblock(sb, &eloc, 0)); |
304 | extent.extLength |= etype << 30; | 266 | if (elen) |
305 | } | 267 | indirect_ext_len = |
306 | udf_extend_file(inode, &epos, &extent, | 268 | (elen + sb->s_blocksize - 1) >> |
307 | offset + | 269 | sb->s_blocksize_bits; |
308 | ((inode->i_size & | 270 | else |
309 | (sb->s_blocksize - 1)) != 0)); | 271 | indirect_ext_len = 1; |
272 | } else { | ||
273 | extent_trunc(inode, &epos, &eloc, etype, elen, 0); | ||
274 | epos.offset += adsize; | ||
310 | } | 275 | } |
311 | } | 276 | } |
277 | |||
278 | if (indirect_ext_len) { | ||
279 | BUG_ON(!epos.bh); | ||
280 | udf_free_blocks(sb, inode, &epos.block, 0, indirect_ext_len); | ||
281 | } else if (!epos.bh) { | ||
282 | iinfo->i_lenAlloc = lenalloc; | ||
283 | mark_inode_dirty(inode); | ||
284 | } else | ||
285 | udf_update_alloc_ext_desc(inode, &epos, lenalloc); | ||
312 | iinfo->i_lenExtents = inode->i_size; | 286 | iinfo->i_lenExtents = inode->i_size; |
313 | 287 | ||
314 | brelse(epos.bh); | 288 | brelse(epos.bh); |
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..dbd52d4b5eed 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,23 +136,20 @@ 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 *); | 139 | extern int udf_expand_file_adinicb(struct inode *); |
137 | 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 *); |
140 | extern void udf_truncate(struct inode *); | 142 | extern int udf_setsize(struct inode *, loff_t); |
141 | extern void udf_read_inode(struct inode *); | 143 | extern void udf_read_inode(struct inode *); |
142 | extern void udf_evict_inode(struct inode *); | 144 | extern void udf_evict_inode(struct inode *); |
143 | extern int udf_write_inode(struct inode *, struct writeback_control *wbc); | 145 | extern int udf_write_inode(struct inode *, struct writeback_control *wbc); |
144 | extern long udf_block_map(struct inode *, sector_t); | 146 | extern long udf_block_map(struct inode *, sector_t); |
145 | extern int udf_extend_file(struct inode *, struct extent_position *, | ||
146 | struct kernel_long_ad *, sector_t); | ||
147 | extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, | 147 | extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, |
148 | struct kernel_lb_addr *, uint32_t *, sector_t *); | 148 | struct kernel_lb_addr *, uint32_t *, sector_t *); |
149 | extern int8_t udf_add_aext(struct inode *, struct extent_position *, | 149 | extern int udf_add_aext(struct inode *, struct extent_position *, |
150 | struct kernel_lb_addr *, uint32_t, int); | ||
151 | extern void udf_write_aext(struct inode *, struct extent_position *, | ||
150 | struct kernel_lb_addr *, uint32_t, int); | 152 | struct kernel_lb_addr *, uint32_t, int); |
151 | extern int8_t udf_write_aext(struct inode *, struct extent_position *, | ||
152 | struct kernel_lb_addr *, uint32_t, int); | ||
153 | extern int8_t udf_delete_aext(struct inode *, struct extent_position, | 153 | extern int8_t udf_delete_aext(struct inode *, struct extent_position, |
154 | struct kernel_lb_addr, uint32_t); | 154 | struct kernel_lb_addr, uint32_t); |
155 | extern int8_t udf_next_aext(struct inode *, struct extent_position *, | 155 | extern int8_t udf_next_aext(struct inode *, struct extent_position *, |