Commit b9d4a35f0a5dd25b85462741a8fb539b355ea95c
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull UDF & isofs fixes from Jan Kara: "A couple of UDF fixes of handling of corrupted media and one iso9660 fix of the same" * 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: udf: Reduce repeated dereferences udf: Check component length before reading it udf: Check path length when reading symlink udf: Verify symlink size before loading it udf: Verify i_size when loading inode isofs: Fix unchecked printing of ER records
Showing 7 changed files Inline Diff
fs/isofs/rock.c
1 | /* | 1 | /* |
2 | * linux/fs/isofs/rock.c | 2 | * linux/fs/isofs/rock.c |
3 | * | 3 | * |
4 | * (C) 1992, 1993 Eric Youngdale | 4 | * (C) 1992, 1993 Eric Youngdale |
5 | * | 5 | * |
6 | * Rock Ridge Extensions to iso9660 | 6 | * Rock Ridge Extensions to iso9660 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
10 | #include <linux/pagemap.h> | 10 | #include <linux/pagemap.h> |
11 | 11 | ||
12 | #include "isofs.h" | 12 | #include "isofs.h" |
13 | #include "rock.h" | 13 | #include "rock.h" |
14 | 14 | ||
15 | /* | 15 | /* |
16 | * These functions are designed to read the system areas of a directory record | 16 | * These functions are designed to read the system areas of a directory record |
17 | * and extract relevant information. There are different functions provided | 17 | * and extract relevant information. There are different functions provided |
18 | * depending upon what information we need at the time. One function fills | 18 | * depending upon what information we need at the time. One function fills |
19 | * out an inode structure, a second one extracts a filename, a third one | 19 | * out an inode structure, a second one extracts a filename, a third one |
20 | * returns a symbolic link name, and a fourth one returns the extent number | 20 | * returns a symbolic link name, and a fourth one returns the extent number |
21 | * for the file. | 21 | * for the file. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */ | 24 | #define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */ |
25 | 25 | ||
26 | struct rock_state { | 26 | struct rock_state { |
27 | void *buffer; | 27 | void *buffer; |
28 | unsigned char *chr; | 28 | unsigned char *chr; |
29 | int len; | 29 | int len; |
30 | int cont_size; | 30 | int cont_size; |
31 | int cont_extent; | 31 | int cont_extent; |
32 | int cont_offset; | 32 | int cont_offset; |
33 | int cont_loops; | 33 | int cont_loops; |
34 | struct inode *inode; | 34 | struct inode *inode; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * This is a way of ensuring that we have something in the system | 38 | * This is a way of ensuring that we have something in the system |
39 | * use fields that is compatible with Rock Ridge. Return zero on success. | 39 | * use fields that is compatible with Rock Ridge. Return zero on success. |
40 | */ | 40 | */ |
41 | 41 | ||
42 | static int check_sp(struct rock_ridge *rr, struct inode *inode) | 42 | static int check_sp(struct rock_ridge *rr, struct inode *inode) |
43 | { | 43 | { |
44 | if (rr->u.SP.magic[0] != 0xbe) | 44 | if (rr->u.SP.magic[0] != 0xbe) |
45 | return -1; | 45 | return -1; |
46 | if (rr->u.SP.magic[1] != 0xef) | 46 | if (rr->u.SP.magic[1] != 0xef) |
47 | return -1; | 47 | return -1; |
48 | ISOFS_SB(inode->i_sb)->s_rock_offset = rr->u.SP.skip; | 48 | ISOFS_SB(inode->i_sb)->s_rock_offset = rr->u.SP.skip; |
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | 51 | ||
52 | static void setup_rock_ridge(struct iso_directory_record *de, | 52 | static void setup_rock_ridge(struct iso_directory_record *de, |
53 | struct inode *inode, struct rock_state *rs) | 53 | struct inode *inode, struct rock_state *rs) |
54 | { | 54 | { |
55 | rs->len = sizeof(struct iso_directory_record) + de->name_len[0]; | 55 | rs->len = sizeof(struct iso_directory_record) + de->name_len[0]; |
56 | if (rs->len & 1) | 56 | if (rs->len & 1) |
57 | (rs->len)++; | 57 | (rs->len)++; |
58 | rs->chr = (unsigned char *)de + rs->len; | 58 | rs->chr = (unsigned char *)de + rs->len; |
59 | rs->len = *((unsigned char *)de) - rs->len; | 59 | rs->len = *((unsigned char *)de) - rs->len; |
60 | if (rs->len < 0) | 60 | if (rs->len < 0) |
61 | rs->len = 0; | 61 | rs->len = 0; |
62 | 62 | ||
63 | if (ISOFS_SB(inode->i_sb)->s_rock_offset != -1) { | 63 | if (ISOFS_SB(inode->i_sb)->s_rock_offset != -1) { |
64 | rs->len -= ISOFS_SB(inode->i_sb)->s_rock_offset; | 64 | rs->len -= ISOFS_SB(inode->i_sb)->s_rock_offset; |
65 | rs->chr += ISOFS_SB(inode->i_sb)->s_rock_offset; | 65 | rs->chr += ISOFS_SB(inode->i_sb)->s_rock_offset; |
66 | if (rs->len < 0) | 66 | if (rs->len < 0) |
67 | rs->len = 0; | 67 | rs->len = 0; |
68 | } | 68 | } |
69 | } | 69 | } |
70 | 70 | ||
71 | static void init_rock_state(struct rock_state *rs, struct inode *inode) | 71 | static void init_rock_state(struct rock_state *rs, struct inode *inode) |
72 | { | 72 | { |
73 | memset(rs, 0, sizeof(*rs)); | 73 | memset(rs, 0, sizeof(*rs)); |
74 | rs->inode = inode; | 74 | rs->inode = inode; |
75 | } | 75 | } |
76 | 76 | ||
77 | /* Maximum number of Rock Ridge continuation entries */ | 77 | /* Maximum number of Rock Ridge continuation entries */ |
78 | #define RR_MAX_CE_ENTRIES 32 | 78 | #define RR_MAX_CE_ENTRIES 32 |
79 | 79 | ||
80 | /* | 80 | /* |
81 | * Returns 0 if the caller should continue scanning, 1 if the scan must end | 81 | * Returns 0 if the caller should continue scanning, 1 if the scan must end |
82 | * and -ve on error. | 82 | * and -ve on error. |
83 | */ | 83 | */ |
84 | static int rock_continue(struct rock_state *rs) | 84 | static int rock_continue(struct rock_state *rs) |
85 | { | 85 | { |
86 | int ret = 1; | 86 | int ret = 1; |
87 | int blocksize = 1 << rs->inode->i_blkbits; | 87 | int blocksize = 1 << rs->inode->i_blkbits; |
88 | const int min_de_size = offsetof(struct rock_ridge, u); | 88 | const int min_de_size = offsetof(struct rock_ridge, u); |
89 | 89 | ||
90 | kfree(rs->buffer); | 90 | kfree(rs->buffer); |
91 | rs->buffer = NULL; | 91 | rs->buffer = NULL; |
92 | 92 | ||
93 | if ((unsigned)rs->cont_offset > blocksize - min_de_size || | 93 | if ((unsigned)rs->cont_offset > blocksize - min_de_size || |
94 | (unsigned)rs->cont_size > blocksize || | 94 | (unsigned)rs->cont_size > blocksize || |
95 | (unsigned)(rs->cont_offset + rs->cont_size) > blocksize) { | 95 | (unsigned)(rs->cont_offset + rs->cont_size) > blocksize) { |
96 | printk(KERN_NOTICE "rock: corrupted directory entry. " | 96 | printk(KERN_NOTICE "rock: corrupted directory entry. " |
97 | "extent=%d, offset=%d, size=%d\n", | 97 | "extent=%d, offset=%d, size=%d\n", |
98 | rs->cont_extent, rs->cont_offset, rs->cont_size); | 98 | rs->cont_extent, rs->cont_offset, rs->cont_size); |
99 | ret = -EIO; | 99 | ret = -EIO; |
100 | goto out; | 100 | goto out; |
101 | } | 101 | } |
102 | 102 | ||
103 | if (rs->cont_extent) { | 103 | if (rs->cont_extent) { |
104 | struct buffer_head *bh; | 104 | struct buffer_head *bh; |
105 | 105 | ||
106 | rs->buffer = kmalloc(rs->cont_size, GFP_KERNEL); | 106 | rs->buffer = kmalloc(rs->cont_size, GFP_KERNEL); |
107 | if (!rs->buffer) { | 107 | if (!rs->buffer) { |
108 | ret = -ENOMEM; | 108 | ret = -ENOMEM; |
109 | goto out; | 109 | goto out; |
110 | } | 110 | } |
111 | ret = -EIO; | 111 | ret = -EIO; |
112 | if (++rs->cont_loops >= RR_MAX_CE_ENTRIES) | 112 | if (++rs->cont_loops >= RR_MAX_CE_ENTRIES) |
113 | goto out; | 113 | goto out; |
114 | bh = sb_bread(rs->inode->i_sb, rs->cont_extent); | 114 | bh = sb_bread(rs->inode->i_sb, rs->cont_extent); |
115 | if (bh) { | 115 | if (bh) { |
116 | memcpy(rs->buffer, bh->b_data + rs->cont_offset, | 116 | memcpy(rs->buffer, bh->b_data + rs->cont_offset, |
117 | rs->cont_size); | 117 | rs->cont_size); |
118 | put_bh(bh); | 118 | put_bh(bh); |
119 | rs->chr = rs->buffer; | 119 | rs->chr = rs->buffer; |
120 | rs->len = rs->cont_size; | 120 | rs->len = rs->cont_size; |
121 | rs->cont_extent = 0; | 121 | rs->cont_extent = 0; |
122 | rs->cont_size = 0; | 122 | rs->cont_size = 0; |
123 | rs->cont_offset = 0; | 123 | rs->cont_offset = 0; |
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
126 | printk("Unable to read rock-ridge attributes\n"); | 126 | printk("Unable to read rock-ridge attributes\n"); |
127 | } | 127 | } |
128 | out: | 128 | out: |
129 | kfree(rs->buffer); | 129 | kfree(rs->buffer); |
130 | rs->buffer = NULL; | 130 | rs->buffer = NULL; |
131 | return ret; | 131 | return ret; |
132 | } | 132 | } |
133 | 133 | ||
134 | /* | 134 | /* |
135 | * We think there's a record of type `sig' at rs->chr. Parse the signature | 135 | * We think there's a record of type `sig' at rs->chr. Parse the signature |
136 | * and make sure that there's really room for a record of that type. | 136 | * and make sure that there's really room for a record of that type. |
137 | */ | 137 | */ |
138 | static int rock_check_overflow(struct rock_state *rs, int sig) | 138 | static int rock_check_overflow(struct rock_state *rs, int sig) |
139 | { | 139 | { |
140 | int len; | 140 | int len; |
141 | 141 | ||
142 | switch (sig) { | 142 | switch (sig) { |
143 | case SIG('S', 'P'): | 143 | case SIG('S', 'P'): |
144 | len = sizeof(struct SU_SP_s); | 144 | len = sizeof(struct SU_SP_s); |
145 | break; | 145 | break; |
146 | case SIG('C', 'E'): | 146 | case SIG('C', 'E'): |
147 | len = sizeof(struct SU_CE_s); | 147 | len = sizeof(struct SU_CE_s); |
148 | break; | 148 | break; |
149 | case SIG('E', 'R'): | 149 | case SIG('E', 'R'): |
150 | len = sizeof(struct SU_ER_s); | 150 | len = sizeof(struct SU_ER_s); |
151 | break; | 151 | break; |
152 | case SIG('R', 'R'): | 152 | case SIG('R', 'R'): |
153 | len = sizeof(struct RR_RR_s); | 153 | len = sizeof(struct RR_RR_s); |
154 | break; | 154 | break; |
155 | case SIG('P', 'X'): | 155 | case SIG('P', 'X'): |
156 | len = sizeof(struct RR_PX_s); | 156 | len = sizeof(struct RR_PX_s); |
157 | break; | 157 | break; |
158 | case SIG('P', 'N'): | 158 | case SIG('P', 'N'): |
159 | len = sizeof(struct RR_PN_s); | 159 | len = sizeof(struct RR_PN_s); |
160 | break; | 160 | break; |
161 | case SIG('S', 'L'): | 161 | case SIG('S', 'L'): |
162 | len = sizeof(struct RR_SL_s); | 162 | len = sizeof(struct RR_SL_s); |
163 | break; | 163 | break; |
164 | case SIG('N', 'M'): | 164 | case SIG('N', 'M'): |
165 | len = sizeof(struct RR_NM_s); | 165 | len = sizeof(struct RR_NM_s); |
166 | break; | 166 | break; |
167 | case SIG('C', 'L'): | 167 | case SIG('C', 'L'): |
168 | len = sizeof(struct RR_CL_s); | 168 | len = sizeof(struct RR_CL_s); |
169 | break; | 169 | break; |
170 | case SIG('P', 'L'): | 170 | case SIG('P', 'L'): |
171 | len = sizeof(struct RR_PL_s); | 171 | len = sizeof(struct RR_PL_s); |
172 | break; | 172 | break; |
173 | case SIG('T', 'F'): | 173 | case SIG('T', 'F'): |
174 | len = sizeof(struct RR_TF_s); | 174 | len = sizeof(struct RR_TF_s); |
175 | break; | 175 | break; |
176 | case SIG('Z', 'F'): | 176 | case SIG('Z', 'F'): |
177 | len = sizeof(struct RR_ZF_s); | 177 | len = sizeof(struct RR_ZF_s); |
178 | break; | 178 | break; |
179 | default: | 179 | default: |
180 | len = 0; | 180 | len = 0; |
181 | break; | 181 | break; |
182 | } | 182 | } |
183 | len += offsetof(struct rock_ridge, u); | 183 | len += offsetof(struct rock_ridge, u); |
184 | if (len > rs->len) { | 184 | if (len > rs->len) { |
185 | printk(KERN_NOTICE "rock: directory entry would overflow " | 185 | printk(KERN_NOTICE "rock: directory entry would overflow " |
186 | "storage\n"); | 186 | "storage\n"); |
187 | printk(KERN_NOTICE "rock: sig=0x%02x, size=%d, remaining=%d\n", | 187 | printk(KERN_NOTICE "rock: sig=0x%02x, size=%d, remaining=%d\n", |
188 | sig, len, rs->len); | 188 | sig, len, rs->len); |
189 | return -EIO; | 189 | return -EIO; |
190 | } | 190 | } |
191 | return 0; | 191 | return 0; |
192 | } | 192 | } |
193 | 193 | ||
194 | /* | 194 | /* |
195 | * return length of name field; 0: not found, -1: to be ignored | 195 | * return length of name field; 0: not found, -1: to be ignored |
196 | */ | 196 | */ |
197 | int get_rock_ridge_filename(struct iso_directory_record *de, | 197 | int get_rock_ridge_filename(struct iso_directory_record *de, |
198 | char *retname, struct inode *inode) | 198 | char *retname, struct inode *inode) |
199 | { | 199 | { |
200 | struct rock_state rs; | 200 | struct rock_state rs; |
201 | struct rock_ridge *rr; | 201 | struct rock_ridge *rr; |
202 | int sig; | 202 | int sig; |
203 | int retnamlen = 0; | 203 | int retnamlen = 0; |
204 | int truncate = 0; | 204 | int truncate = 0; |
205 | int ret = 0; | 205 | int ret = 0; |
206 | 206 | ||
207 | if (!ISOFS_SB(inode->i_sb)->s_rock) | 207 | if (!ISOFS_SB(inode->i_sb)->s_rock) |
208 | return 0; | 208 | return 0; |
209 | *retname = 0; | 209 | *retname = 0; |
210 | 210 | ||
211 | init_rock_state(&rs, inode); | 211 | init_rock_state(&rs, inode); |
212 | setup_rock_ridge(de, inode, &rs); | 212 | setup_rock_ridge(de, inode, &rs); |
213 | repeat: | 213 | repeat: |
214 | 214 | ||
215 | while (rs.len > 2) { /* There may be one byte for padding somewhere */ | 215 | while (rs.len > 2) { /* There may be one byte for padding somewhere */ |
216 | rr = (struct rock_ridge *)rs.chr; | 216 | rr = (struct rock_ridge *)rs.chr; |
217 | /* | 217 | /* |
218 | * Ignore rock ridge info if rr->len is out of range, but | 218 | * Ignore rock ridge info if rr->len is out of range, but |
219 | * don't return -EIO because that would make the file | 219 | * don't return -EIO because that would make the file |
220 | * invisible. | 220 | * invisible. |
221 | */ | 221 | */ |
222 | if (rr->len < 3) | 222 | if (rr->len < 3) |
223 | goto out; /* Something got screwed up here */ | 223 | goto out; /* Something got screwed up here */ |
224 | sig = isonum_721(rs.chr); | 224 | sig = isonum_721(rs.chr); |
225 | if (rock_check_overflow(&rs, sig)) | 225 | if (rock_check_overflow(&rs, sig)) |
226 | goto eio; | 226 | goto eio; |
227 | rs.chr += rr->len; | 227 | rs.chr += rr->len; |
228 | rs.len -= rr->len; | 228 | rs.len -= rr->len; |
229 | /* | 229 | /* |
230 | * As above, just ignore the rock ridge info if rr->len | 230 | * As above, just ignore the rock ridge info if rr->len |
231 | * is bogus. | 231 | * is bogus. |
232 | */ | 232 | */ |
233 | if (rs.len < 0) | 233 | if (rs.len < 0) |
234 | goto out; /* Something got screwed up here */ | 234 | goto out; /* Something got screwed up here */ |
235 | 235 | ||
236 | switch (sig) { | 236 | switch (sig) { |
237 | case SIG('R', 'R'): | 237 | case SIG('R', 'R'): |
238 | if ((rr->u.RR.flags[0] & RR_NM) == 0) | 238 | if ((rr->u.RR.flags[0] & RR_NM) == 0) |
239 | goto out; | 239 | goto out; |
240 | break; | 240 | break; |
241 | case SIG('S', 'P'): | 241 | case SIG('S', 'P'): |
242 | if (check_sp(rr, inode)) | 242 | if (check_sp(rr, inode)) |
243 | goto out; | 243 | goto out; |
244 | break; | 244 | break; |
245 | case SIG('C', 'E'): | 245 | case SIG('C', 'E'): |
246 | rs.cont_extent = isonum_733(rr->u.CE.extent); | 246 | rs.cont_extent = isonum_733(rr->u.CE.extent); |
247 | rs.cont_offset = isonum_733(rr->u.CE.offset); | 247 | rs.cont_offset = isonum_733(rr->u.CE.offset); |
248 | rs.cont_size = isonum_733(rr->u.CE.size); | 248 | rs.cont_size = isonum_733(rr->u.CE.size); |
249 | break; | 249 | break; |
250 | case SIG('N', 'M'): | 250 | case SIG('N', 'M'): |
251 | if (truncate) | 251 | if (truncate) |
252 | break; | 252 | break; |
253 | if (rr->len < 5) | 253 | if (rr->len < 5) |
254 | break; | 254 | break; |
255 | /* | 255 | /* |
256 | * If the flags are 2 or 4, this indicates '.' or '..'. | 256 | * If the flags are 2 or 4, this indicates '.' or '..'. |
257 | * We don't want to do anything with this, because it | 257 | * We don't want to do anything with this, because it |
258 | * screws up the code that calls us. We don't really | 258 | * screws up the code that calls us. We don't really |
259 | * care anyways, since we can just use the non-RR | 259 | * care anyways, since we can just use the non-RR |
260 | * name. | 260 | * name. |
261 | */ | 261 | */ |
262 | if (rr->u.NM.flags & 6) | 262 | if (rr->u.NM.flags & 6) |
263 | break; | 263 | break; |
264 | 264 | ||
265 | if (rr->u.NM.flags & ~1) { | 265 | if (rr->u.NM.flags & ~1) { |
266 | printk("Unsupported NM flag settings (%d)\n", | 266 | printk("Unsupported NM flag settings (%d)\n", |
267 | rr->u.NM.flags); | 267 | rr->u.NM.flags); |
268 | break; | 268 | break; |
269 | } | 269 | } |
270 | if ((strlen(retname) + rr->len - 5) >= 254) { | 270 | if ((strlen(retname) + rr->len - 5) >= 254) { |
271 | truncate = 1; | 271 | truncate = 1; |
272 | break; | 272 | break; |
273 | } | 273 | } |
274 | strncat(retname, rr->u.NM.name, rr->len - 5); | 274 | strncat(retname, rr->u.NM.name, rr->len - 5); |
275 | retnamlen += rr->len - 5; | 275 | retnamlen += rr->len - 5; |
276 | break; | 276 | break; |
277 | case SIG('R', 'E'): | 277 | case SIG('R', 'E'): |
278 | kfree(rs.buffer); | 278 | kfree(rs.buffer); |
279 | return -1; | 279 | return -1; |
280 | default: | 280 | default: |
281 | break; | 281 | break; |
282 | } | 282 | } |
283 | } | 283 | } |
284 | ret = rock_continue(&rs); | 284 | ret = rock_continue(&rs); |
285 | if (ret == 0) | 285 | if (ret == 0) |
286 | goto repeat; | 286 | goto repeat; |
287 | if (ret == 1) | 287 | if (ret == 1) |
288 | return retnamlen; /* If 0, this file did not have a NM field */ | 288 | return retnamlen; /* If 0, this file did not have a NM field */ |
289 | out: | 289 | out: |
290 | kfree(rs.buffer); | 290 | kfree(rs.buffer); |
291 | return ret; | 291 | return ret; |
292 | eio: | 292 | eio: |
293 | ret = -EIO; | 293 | ret = -EIO; |
294 | goto out; | 294 | goto out; |
295 | } | 295 | } |
296 | 296 | ||
297 | #define RR_REGARD_XA 1 | 297 | #define RR_REGARD_XA 1 |
298 | #define RR_RELOC_DE 2 | 298 | #define RR_RELOC_DE 2 |
299 | 299 | ||
300 | static int | 300 | static int |
301 | parse_rock_ridge_inode_internal(struct iso_directory_record *de, | 301 | parse_rock_ridge_inode_internal(struct iso_directory_record *de, |
302 | struct inode *inode, int flags) | 302 | struct inode *inode, int flags) |
303 | { | 303 | { |
304 | int symlink_len = 0; | 304 | int symlink_len = 0; |
305 | int cnt, sig; | 305 | int cnt, sig; |
306 | unsigned int reloc_block; | 306 | unsigned int reloc_block; |
307 | struct inode *reloc; | 307 | struct inode *reloc; |
308 | struct rock_ridge *rr; | 308 | struct rock_ridge *rr; |
309 | int rootflag; | 309 | int rootflag; |
310 | struct rock_state rs; | 310 | struct rock_state rs; |
311 | int ret = 0; | 311 | int ret = 0; |
312 | 312 | ||
313 | if (!ISOFS_SB(inode->i_sb)->s_rock) | 313 | if (!ISOFS_SB(inode->i_sb)->s_rock) |
314 | return 0; | 314 | return 0; |
315 | 315 | ||
316 | init_rock_state(&rs, inode); | 316 | init_rock_state(&rs, inode); |
317 | setup_rock_ridge(de, inode, &rs); | 317 | setup_rock_ridge(de, inode, &rs); |
318 | if (flags & RR_REGARD_XA) { | 318 | if (flags & RR_REGARD_XA) { |
319 | rs.chr += 14; | 319 | rs.chr += 14; |
320 | rs.len -= 14; | 320 | rs.len -= 14; |
321 | if (rs.len < 0) | 321 | if (rs.len < 0) |
322 | rs.len = 0; | 322 | rs.len = 0; |
323 | } | 323 | } |
324 | 324 | ||
325 | repeat: | 325 | repeat: |
326 | while (rs.len > 2) { /* There may be one byte for padding somewhere */ | 326 | while (rs.len > 2) { /* There may be one byte for padding somewhere */ |
327 | rr = (struct rock_ridge *)rs.chr; | 327 | rr = (struct rock_ridge *)rs.chr; |
328 | /* | 328 | /* |
329 | * Ignore rock ridge info if rr->len is out of range, but | 329 | * Ignore rock ridge info if rr->len is out of range, but |
330 | * don't return -EIO because that would make the file | 330 | * don't return -EIO because that would make the file |
331 | * invisible. | 331 | * invisible. |
332 | */ | 332 | */ |
333 | if (rr->len < 3) | 333 | if (rr->len < 3) |
334 | goto out; /* Something got screwed up here */ | 334 | goto out; /* Something got screwed up here */ |
335 | sig = isonum_721(rs.chr); | 335 | sig = isonum_721(rs.chr); |
336 | if (rock_check_overflow(&rs, sig)) | 336 | if (rock_check_overflow(&rs, sig)) |
337 | goto eio; | 337 | goto eio; |
338 | rs.chr += rr->len; | 338 | rs.chr += rr->len; |
339 | rs.len -= rr->len; | 339 | rs.len -= rr->len; |
340 | /* | 340 | /* |
341 | * As above, just ignore the rock ridge info if rr->len | 341 | * As above, just ignore the rock ridge info if rr->len |
342 | * is bogus. | 342 | * is bogus. |
343 | */ | 343 | */ |
344 | if (rs.len < 0) | 344 | if (rs.len < 0) |
345 | goto out; /* Something got screwed up here */ | 345 | goto out; /* Something got screwed up here */ |
346 | 346 | ||
347 | switch (sig) { | 347 | switch (sig) { |
348 | #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ | 348 | #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ |
349 | case SIG('R', 'R'): | 349 | case SIG('R', 'R'): |
350 | if ((rr->u.RR.flags[0] & | 350 | if ((rr->u.RR.flags[0] & |
351 | (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) | 351 | (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) |
352 | goto out; | 352 | goto out; |
353 | break; | 353 | break; |
354 | #endif | 354 | #endif |
355 | case SIG('S', 'P'): | 355 | case SIG('S', 'P'): |
356 | if (check_sp(rr, inode)) | 356 | if (check_sp(rr, inode)) |
357 | goto out; | 357 | goto out; |
358 | break; | 358 | break; |
359 | case SIG('C', 'E'): | 359 | case SIG('C', 'E'): |
360 | rs.cont_extent = isonum_733(rr->u.CE.extent); | 360 | rs.cont_extent = isonum_733(rr->u.CE.extent); |
361 | rs.cont_offset = isonum_733(rr->u.CE.offset); | 361 | rs.cont_offset = isonum_733(rr->u.CE.offset); |
362 | rs.cont_size = isonum_733(rr->u.CE.size); | 362 | rs.cont_size = isonum_733(rr->u.CE.size); |
363 | break; | 363 | break; |
364 | case SIG('E', 'R'): | 364 | case SIG('E', 'R'): |
365 | /* Invalid length of ER tag id? */ | ||
366 | if (rr->u.ER.len_id + offsetof(struct rock_ridge, u.ER.data) > rr->len) | ||
367 | goto out; | ||
365 | ISOFS_SB(inode->i_sb)->s_rock = 1; | 368 | ISOFS_SB(inode->i_sb)->s_rock = 1; |
366 | printk(KERN_DEBUG "ISO 9660 Extensions: "); | 369 | printk(KERN_DEBUG "ISO 9660 Extensions: "); |
367 | { | 370 | { |
368 | int p; | 371 | int p; |
369 | for (p = 0; p < rr->u.ER.len_id; p++) | 372 | for (p = 0; p < rr->u.ER.len_id; p++) |
370 | printk("%c", rr->u.ER.data[p]); | 373 | printk("%c", rr->u.ER.data[p]); |
371 | } | 374 | } |
372 | printk("\n"); | 375 | printk("\n"); |
373 | break; | 376 | break; |
374 | case SIG('P', 'X'): | 377 | case SIG('P', 'X'): |
375 | inode->i_mode = isonum_733(rr->u.PX.mode); | 378 | inode->i_mode = isonum_733(rr->u.PX.mode); |
376 | set_nlink(inode, isonum_733(rr->u.PX.n_links)); | 379 | set_nlink(inode, isonum_733(rr->u.PX.n_links)); |
377 | i_uid_write(inode, isonum_733(rr->u.PX.uid)); | 380 | i_uid_write(inode, isonum_733(rr->u.PX.uid)); |
378 | i_gid_write(inode, isonum_733(rr->u.PX.gid)); | 381 | i_gid_write(inode, isonum_733(rr->u.PX.gid)); |
379 | break; | 382 | break; |
380 | case SIG('P', 'N'): | 383 | case SIG('P', 'N'): |
381 | { | 384 | { |
382 | int high, low; | 385 | int high, low; |
383 | high = isonum_733(rr->u.PN.dev_high); | 386 | high = isonum_733(rr->u.PN.dev_high); |
384 | low = isonum_733(rr->u.PN.dev_low); | 387 | low = isonum_733(rr->u.PN.dev_low); |
385 | /* | 388 | /* |
386 | * The Rock Ridge standard specifies that if | 389 | * The Rock Ridge standard specifies that if |
387 | * sizeof(dev_t) <= 4, then the high field is | 390 | * sizeof(dev_t) <= 4, then the high field is |
388 | * unused, and the device number is completely | 391 | * unused, and the device number is completely |
389 | * stored in the low field. Some writers may | 392 | * stored in the low field. Some writers may |
390 | * ignore this subtlety, | 393 | * ignore this subtlety, |
391 | * and as a result we test to see if the entire | 394 | * and as a result we test to see if the entire |
392 | * device number is | 395 | * device number is |
393 | * stored in the low field, and use that. | 396 | * stored in the low field, and use that. |
394 | */ | 397 | */ |
395 | if ((low & ~0xff) && high == 0) { | 398 | if ((low & ~0xff) && high == 0) { |
396 | inode->i_rdev = | 399 | inode->i_rdev = |
397 | MKDEV(low >> 8, low & 0xff); | 400 | MKDEV(low >> 8, low & 0xff); |
398 | } else { | 401 | } else { |
399 | inode->i_rdev = | 402 | inode->i_rdev = |
400 | MKDEV(high, low); | 403 | MKDEV(high, low); |
401 | } | 404 | } |
402 | } | 405 | } |
403 | break; | 406 | break; |
404 | case SIG('T', 'F'): | 407 | case SIG('T', 'F'): |
405 | /* | 408 | /* |
406 | * Some RRIP writers incorrectly place ctime in the | 409 | * Some RRIP writers incorrectly place ctime in the |
407 | * TF_CREATE field. Try to handle this correctly for | 410 | * TF_CREATE field. Try to handle this correctly for |
408 | * either case. | 411 | * either case. |
409 | */ | 412 | */ |
410 | /* Rock ridge never appears on a High Sierra disk */ | 413 | /* Rock ridge never appears on a High Sierra disk */ |
411 | cnt = 0; | 414 | cnt = 0; |
412 | if (rr->u.TF.flags & TF_CREATE) { | 415 | if (rr->u.TF.flags & TF_CREATE) { |
413 | inode->i_ctime.tv_sec = | 416 | inode->i_ctime.tv_sec = |
414 | iso_date(rr->u.TF.times[cnt++].time, | 417 | iso_date(rr->u.TF.times[cnt++].time, |
415 | 0); | 418 | 0); |
416 | inode->i_ctime.tv_nsec = 0; | 419 | inode->i_ctime.tv_nsec = 0; |
417 | } | 420 | } |
418 | if (rr->u.TF.flags & TF_MODIFY) { | 421 | if (rr->u.TF.flags & TF_MODIFY) { |
419 | inode->i_mtime.tv_sec = | 422 | inode->i_mtime.tv_sec = |
420 | iso_date(rr->u.TF.times[cnt++].time, | 423 | iso_date(rr->u.TF.times[cnt++].time, |
421 | 0); | 424 | 0); |
422 | inode->i_mtime.tv_nsec = 0; | 425 | inode->i_mtime.tv_nsec = 0; |
423 | } | 426 | } |
424 | if (rr->u.TF.flags & TF_ACCESS) { | 427 | if (rr->u.TF.flags & TF_ACCESS) { |
425 | inode->i_atime.tv_sec = | 428 | inode->i_atime.tv_sec = |
426 | iso_date(rr->u.TF.times[cnt++].time, | 429 | iso_date(rr->u.TF.times[cnt++].time, |
427 | 0); | 430 | 0); |
428 | inode->i_atime.tv_nsec = 0; | 431 | inode->i_atime.tv_nsec = 0; |
429 | } | 432 | } |
430 | if (rr->u.TF.flags & TF_ATTRIBUTES) { | 433 | if (rr->u.TF.flags & TF_ATTRIBUTES) { |
431 | inode->i_ctime.tv_sec = | 434 | inode->i_ctime.tv_sec = |
432 | iso_date(rr->u.TF.times[cnt++].time, | 435 | iso_date(rr->u.TF.times[cnt++].time, |
433 | 0); | 436 | 0); |
434 | inode->i_ctime.tv_nsec = 0; | 437 | inode->i_ctime.tv_nsec = 0; |
435 | } | 438 | } |
436 | break; | 439 | break; |
437 | case SIG('S', 'L'): | 440 | case SIG('S', 'L'): |
438 | { | 441 | { |
439 | int slen; | 442 | int slen; |
440 | struct SL_component *slp; | 443 | struct SL_component *slp; |
441 | struct SL_component *oldslp; | 444 | struct SL_component *oldslp; |
442 | slen = rr->len - 5; | 445 | slen = rr->len - 5; |
443 | slp = &rr->u.SL.link; | 446 | slp = &rr->u.SL.link; |
444 | inode->i_size = symlink_len; | 447 | inode->i_size = symlink_len; |
445 | while (slen > 1) { | 448 | while (slen > 1) { |
446 | rootflag = 0; | 449 | rootflag = 0; |
447 | switch (slp->flags & ~1) { | 450 | switch (slp->flags & ~1) { |
448 | case 0: | 451 | case 0: |
449 | inode->i_size += | 452 | inode->i_size += |
450 | slp->len; | 453 | slp->len; |
451 | break; | 454 | break; |
452 | case 2: | 455 | case 2: |
453 | inode->i_size += 1; | 456 | inode->i_size += 1; |
454 | break; | 457 | break; |
455 | case 4: | 458 | case 4: |
456 | inode->i_size += 2; | 459 | inode->i_size += 2; |
457 | break; | 460 | break; |
458 | case 8: | 461 | case 8: |
459 | rootflag = 1; | 462 | rootflag = 1; |
460 | inode->i_size += 1; | 463 | inode->i_size += 1; |
461 | break; | 464 | break; |
462 | default: | 465 | default: |
463 | printk("Symlink component flag " | 466 | printk("Symlink component flag " |
464 | "not implemented\n"); | 467 | "not implemented\n"); |
465 | } | 468 | } |
466 | slen -= slp->len + 2; | 469 | slen -= slp->len + 2; |
467 | oldslp = slp; | 470 | oldslp = slp; |
468 | slp = (struct SL_component *) | 471 | slp = (struct SL_component *) |
469 | (((char *)slp) + slp->len + 2); | 472 | (((char *)slp) + slp->len + 2); |
470 | 473 | ||
471 | if (slen < 2) { | 474 | if (slen < 2) { |
472 | if (((rr->u.SL. | 475 | if (((rr->u.SL. |
473 | flags & 1) != 0) | 476 | flags & 1) != 0) |
474 | && | 477 | && |
475 | ((oldslp-> | 478 | ((oldslp-> |
476 | flags & 1) == 0)) | 479 | flags & 1) == 0)) |
477 | inode->i_size += | 480 | inode->i_size += |
478 | 1; | 481 | 1; |
479 | break; | 482 | break; |
480 | } | 483 | } |
481 | 484 | ||
482 | /* | 485 | /* |
483 | * If this component record isn't | 486 | * If this component record isn't |
484 | * continued, then append a '/'. | 487 | * continued, then append a '/'. |
485 | */ | 488 | */ |
486 | if (!rootflag | 489 | if (!rootflag |
487 | && (oldslp->flags & 1) == 0) | 490 | && (oldslp->flags & 1) == 0) |
488 | inode->i_size += 1; | 491 | inode->i_size += 1; |
489 | } | 492 | } |
490 | } | 493 | } |
491 | symlink_len = inode->i_size; | 494 | symlink_len = inode->i_size; |
492 | break; | 495 | break; |
493 | case SIG('R', 'E'): | 496 | case SIG('R', 'E'): |
494 | printk(KERN_WARNING "Attempt to read inode for " | 497 | printk(KERN_WARNING "Attempt to read inode for " |
495 | "relocated directory\n"); | 498 | "relocated directory\n"); |
496 | goto out; | 499 | goto out; |
497 | case SIG('C', 'L'): | 500 | case SIG('C', 'L'): |
498 | if (flags & RR_RELOC_DE) { | 501 | if (flags & RR_RELOC_DE) { |
499 | printk(KERN_ERR | 502 | printk(KERN_ERR |
500 | "ISOFS: Recursive directory relocation " | 503 | "ISOFS: Recursive directory relocation " |
501 | "is not supported\n"); | 504 | "is not supported\n"); |
502 | goto eio; | 505 | goto eio; |
503 | } | 506 | } |
504 | reloc_block = isonum_733(rr->u.CL.location); | 507 | reloc_block = isonum_733(rr->u.CL.location); |
505 | if (reloc_block == ISOFS_I(inode)->i_iget5_block && | 508 | if (reloc_block == ISOFS_I(inode)->i_iget5_block && |
506 | ISOFS_I(inode)->i_iget5_offset == 0) { | 509 | ISOFS_I(inode)->i_iget5_offset == 0) { |
507 | printk(KERN_ERR | 510 | printk(KERN_ERR |
508 | "ISOFS: Directory relocation points to " | 511 | "ISOFS: Directory relocation points to " |
509 | "itself\n"); | 512 | "itself\n"); |
510 | goto eio; | 513 | goto eio; |
511 | } | 514 | } |
512 | ISOFS_I(inode)->i_first_extent = reloc_block; | 515 | ISOFS_I(inode)->i_first_extent = reloc_block; |
513 | reloc = isofs_iget_reloc(inode->i_sb, reloc_block, 0); | 516 | reloc = isofs_iget_reloc(inode->i_sb, reloc_block, 0); |
514 | if (IS_ERR(reloc)) { | 517 | if (IS_ERR(reloc)) { |
515 | ret = PTR_ERR(reloc); | 518 | ret = PTR_ERR(reloc); |
516 | goto out; | 519 | goto out; |
517 | } | 520 | } |
518 | inode->i_mode = reloc->i_mode; | 521 | inode->i_mode = reloc->i_mode; |
519 | set_nlink(inode, reloc->i_nlink); | 522 | set_nlink(inode, reloc->i_nlink); |
520 | inode->i_uid = reloc->i_uid; | 523 | inode->i_uid = reloc->i_uid; |
521 | inode->i_gid = reloc->i_gid; | 524 | inode->i_gid = reloc->i_gid; |
522 | inode->i_rdev = reloc->i_rdev; | 525 | inode->i_rdev = reloc->i_rdev; |
523 | inode->i_size = reloc->i_size; | 526 | inode->i_size = reloc->i_size; |
524 | inode->i_blocks = reloc->i_blocks; | 527 | inode->i_blocks = reloc->i_blocks; |
525 | inode->i_atime = reloc->i_atime; | 528 | inode->i_atime = reloc->i_atime; |
526 | inode->i_ctime = reloc->i_ctime; | 529 | inode->i_ctime = reloc->i_ctime; |
527 | inode->i_mtime = reloc->i_mtime; | 530 | inode->i_mtime = reloc->i_mtime; |
528 | iput(reloc); | 531 | iput(reloc); |
529 | break; | 532 | break; |
530 | #ifdef CONFIG_ZISOFS | 533 | #ifdef CONFIG_ZISOFS |
531 | case SIG('Z', 'F'): { | 534 | case SIG('Z', 'F'): { |
532 | int algo; | 535 | int algo; |
533 | 536 | ||
534 | if (ISOFS_SB(inode->i_sb)->s_nocompress) | 537 | if (ISOFS_SB(inode->i_sb)->s_nocompress) |
535 | break; | 538 | break; |
536 | algo = isonum_721(rr->u.ZF.algorithm); | 539 | algo = isonum_721(rr->u.ZF.algorithm); |
537 | if (algo == SIG('p', 'z')) { | 540 | if (algo == SIG('p', 'z')) { |
538 | int block_shift = | 541 | int block_shift = |
539 | isonum_711(&rr->u.ZF.parms[1]); | 542 | isonum_711(&rr->u.ZF.parms[1]); |
540 | if (block_shift > 17) { | 543 | if (block_shift > 17) { |
541 | printk(KERN_WARNING "isofs: " | 544 | printk(KERN_WARNING "isofs: " |
542 | "Can't handle ZF block " | 545 | "Can't handle ZF block " |
543 | "size of 2^%d\n", | 546 | "size of 2^%d\n", |
544 | block_shift); | 547 | block_shift); |
545 | } else { | 548 | } else { |
546 | /* | 549 | /* |
547 | * Note: we don't change | 550 | * Note: we don't change |
548 | * i_blocks here | 551 | * i_blocks here |
549 | */ | 552 | */ |
550 | ISOFS_I(inode)->i_file_format = | 553 | ISOFS_I(inode)->i_file_format = |
551 | isofs_file_compressed; | 554 | isofs_file_compressed; |
552 | /* | 555 | /* |
553 | * Parameters to compression | 556 | * Parameters to compression |
554 | * algorithm (header size, | 557 | * algorithm (header size, |
555 | * block size) | 558 | * block size) |
556 | */ | 559 | */ |
557 | ISOFS_I(inode)->i_format_parm[0] = | 560 | ISOFS_I(inode)->i_format_parm[0] = |
558 | isonum_711(&rr->u.ZF.parms[0]); | 561 | isonum_711(&rr->u.ZF.parms[0]); |
559 | ISOFS_I(inode)->i_format_parm[1] = | 562 | ISOFS_I(inode)->i_format_parm[1] = |
560 | isonum_711(&rr->u.ZF.parms[1]); | 563 | isonum_711(&rr->u.ZF.parms[1]); |
561 | inode->i_size = | 564 | inode->i_size = |
562 | isonum_733(rr->u.ZF. | 565 | isonum_733(rr->u.ZF. |
563 | real_size); | 566 | real_size); |
564 | } | 567 | } |
565 | } else { | 568 | } else { |
566 | printk(KERN_WARNING | 569 | printk(KERN_WARNING |
567 | "isofs: Unknown ZF compression " | 570 | "isofs: Unknown ZF compression " |
568 | "algorithm: %c%c\n", | 571 | "algorithm: %c%c\n", |
569 | rr->u.ZF.algorithm[0], | 572 | rr->u.ZF.algorithm[0], |
570 | rr->u.ZF.algorithm[1]); | 573 | rr->u.ZF.algorithm[1]); |
571 | } | 574 | } |
572 | break; | 575 | break; |
573 | } | 576 | } |
574 | #endif | 577 | #endif |
575 | default: | 578 | default: |
576 | break; | 579 | break; |
577 | } | 580 | } |
578 | } | 581 | } |
579 | ret = rock_continue(&rs); | 582 | ret = rock_continue(&rs); |
580 | if (ret == 0) | 583 | if (ret == 0) |
581 | goto repeat; | 584 | goto repeat; |
582 | if (ret == 1) | 585 | if (ret == 1) |
583 | ret = 0; | 586 | ret = 0; |
584 | out: | 587 | out: |
585 | kfree(rs.buffer); | 588 | kfree(rs.buffer); |
586 | return ret; | 589 | return ret; |
587 | eio: | 590 | eio: |
588 | ret = -EIO; | 591 | ret = -EIO; |
589 | goto out; | 592 | goto out; |
590 | } | 593 | } |
591 | 594 | ||
592 | static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) | 595 | static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) |
593 | { | 596 | { |
594 | int slen; | 597 | int slen; |
595 | int rootflag; | 598 | int rootflag; |
596 | struct SL_component *oldslp; | 599 | struct SL_component *oldslp; |
597 | struct SL_component *slp; | 600 | struct SL_component *slp; |
598 | slen = rr->len - 5; | 601 | slen = rr->len - 5; |
599 | slp = &rr->u.SL.link; | 602 | slp = &rr->u.SL.link; |
600 | while (slen > 1) { | 603 | while (slen > 1) { |
601 | rootflag = 0; | 604 | rootflag = 0; |
602 | switch (slp->flags & ~1) { | 605 | switch (slp->flags & ~1) { |
603 | case 0: | 606 | case 0: |
604 | if (slp->len > plimit - rpnt) | 607 | if (slp->len > plimit - rpnt) |
605 | return NULL; | 608 | return NULL; |
606 | memcpy(rpnt, slp->text, slp->len); | 609 | memcpy(rpnt, slp->text, slp->len); |
607 | rpnt += slp->len; | 610 | rpnt += slp->len; |
608 | break; | 611 | break; |
609 | case 2: | 612 | case 2: |
610 | if (rpnt >= plimit) | 613 | if (rpnt >= plimit) |
611 | return NULL; | 614 | return NULL; |
612 | *rpnt++ = '.'; | 615 | *rpnt++ = '.'; |
613 | break; | 616 | break; |
614 | case 4: | 617 | case 4: |
615 | if (2 > plimit - rpnt) | 618 | if (2 > plimit - rpnt) |
616 | return NULL; | 619 | return NULL; |
617 | *rpnt++ = '.'; | 620 | *rpnt++ = '.'; |
618 | *rpnt++ = '.'; | 621 | *rpnt++ = '.'; |
619 | break; | 622 | break; |
620 | case 8: | 623 | case 8: |
621 | if (rpnt >= plimit) | 624 | if (rpnt >= plimit) |
622 | return NULL; | 625 | return NULL; |
623 | rootflag = 1; | 626 | rootflag = 1; |
624 | *rpnt++ = '/'; | 627 | *rpnt++ = '/'; |
625 | break; | 628 | break; |
626 | default: | 629 | default: |
627 | printk("Symlink component flag not implemented (%d)\n", | 630 | printk("Symlink component flag not implemented (%d)\n", |
628 | slp->flags); | 631 | slp->flags); |
629 | } | 632 | } |
630 | slen -= slp->len + 2; | 633 | slen -= slp->len + 2; |
631 | oldslp = slp; | 634 | oldslp = slp; |
632 | slp = (struct SL_component *)((char *)slp + slp->len + 2); | 635 | slp = (struct SL_component *)((char *)slp + slp->len + 2); |
633 | 636 | ||
634 | if (slen < 2) { | 637 | if (slen < 2) { |
635 | /* | 638 | /* |
636 | * If there is another SL record, and this component | 639 | * If there is another SL record, and this component |
637 | * record isn't continued, then add a slash. | 640 | * record isn't continued, then add a slash. |
638 | */ | 641 | */ |
639 | if ((!rootflag) && (rr->u.SL.flags & 1) && | 642 | if ((!rootflag) && (rr->u.SL.flags & 1) && |
640 | !(oldslp->flags & 1)) { | 643 | !(oldslp->flags & 1)) { |
641 | if (rpnt >= plimit) | 644 | if (rpnt >= plimit) |
642 | return NULL; | 645 | return NULL; |
643 | *rpnt++ = '/'; | 646 | *rpnt++ = '/'; |
644 | } | 647 | } |
645 | break; | 648 | break; |
646 | } | 649 | } |
647 | 650 | ||
648 | /* | 651 | /* |
649 | * If this component record isn't continued, then append a '/'. | 652 | * If this component record isn't continued, then append a '/'. |
650 | */ | 653 | */ |
651 | if (!rootflag && !(oldslp->flags & 1)) { | 654 | if (!rootflag && !(oldslp->flags & 1)) { |
652 | if (rpnt >= plimit) | 655 | if (rpnt >= plimit) |
653 | return NULL; | 656 | return NULL; |
654 | *rpnt++ = '/'; | 657 | *rpnt++ = '/'; |
655 | } | 658 | } |
656 | } | 659 | } |
657 | return rpnt; | 660 | return rpnt; |
658 | } | 661 | } |
659 | 662 | ||
660 | int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode, | 663 | int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode, |
661 | int relocated) | 664 | int relocated) |
662 | { | 665 | { |
663 | int flags = relocated ? RR_RELOC_DE : 0; | 666 | int flags = relocated ? RR_RELOC_DE : 0; |
664 | int result = parse_rock_ridge_inode_internal(de, inode, flags); | 667 | int result = parse_rock_ridge_inode_internal(de, inode, flags); |
665 | 668 | ||
666 | /* | 669 | /* |
667 | * if rockridge flag was reset and we didn't look for attributes | 670 | * if rockridge flag was reset and we didn't look for attributes |
668 | * behind eventual XA attributes, have a look there | 671 | * behind eventual XA attributes, have a look there |
669 | */ | 672 | */ |
670 | if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) | 673 | if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) |
671 | && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { | 674 | && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { |
672 | result = parse_rock_ridge_inode_internal(de, inode, | 675 | result = parse_rock_ridge_inode_internal(de, inode, |
673 | flags | RR_REGARD_XA); | 676 | flags | RR_REGARD_XA); |
674 | } | 677 | } |
675 | return result; | 678 | return result; |
676 | } | 679 | } |
677 | 680 | ||
678 | /* | 681 | /* |
679 | * readpage() for symlinks: reads symlink contents into the page and either | 682 | * readpage() for symlinks: reads symlink contents into the page and either |
680 | * makes it uptodate and returns 0 or returns error (-EIO) | 683 | * makes it uptodate and returns 0 or returns error (-EIO) |
681 | */ | 684 | */ |
682 | static int rock_ridge_symlink_readpage(struct file *file, struct page *page) | 685 | static int rock_ridge_symlink_readpage(struct file *file, struct page *page) |
683 | { | 686 | { |
684 | struct inode *inode = page->mapping->host; | 687 | struct inode *inode = page->mapping->host; |
685 | struct iso_inode_info *ei = ISOFS_I(inode); | 688 | struct iso_inode_info *ei = ISOFS_I(inode); |
686 | struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb); | 689 | struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb); |
687 | char *link = kmap(page); | 690 | char *link = kmap(page); |
688 | unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); | 691 | unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); |
689 | struct buffer_head *bh; | 692 | struct buffer_head *bh; |
690 | char *rpnt = link; | 693 | char *rpnt = link; |
691 | unsigned char *pnt; | 694 | unsigned char *pnt; |
692 | struct iso_directory_record *raw_de; | 695 | struct iso_directory_record *raw_de; |
693 | unsigned long block, offset; | 696 | unsigned long block, offset; |
694 | int sig; | 697 | int sig; |
695 | struct rock_ridge *rr; | 698 | struct rock_ridge *rr; |
696 | struct rock_state rs; | 699 | struct rock_state rs; |
697 | int ret; | 700 | int ret; |
698 | 701 | ||
699 | if (!sbi->s_rock) | 702 | if (!sbi->s_rock) |
700 | goto error; | 703 | goto error; |
701 | 704 | ||
702 | init_rock_state(&rs, inode); | 705 | init_rock_state(&rs, inode); |
703 | block = ei->i_iget5_block; | 706 | block = ei->i_iget5_block; |
704 | bh = sb_bread(inode->i_sb, block); | 707 | bh = sb_bread(inode->i_sb, block); |
705 | if (!bh) | 708 | if (!bh) |
706 | goto out_noread; | 709 | goto out_noread; |
707 | 710 | ||
708 | offset = ei->i_iget5_offset; | 711 | offset = ei->i_iget5_offset; |
709 | pnt = (unsigned char *)bh->b_data + offset; | 712 | pnt = (unsigned char *)bh->b_data + offset; |
710 | 713 | ||
711 | raw_de = (struct iso_directory_record *)pnt; | 714 | raw_de = (struct iso_directory_record *)pnt; |
712 | 715 | ||
713 | /* | 716 | /* |
714 | * If we go past the end of the buffer, there is some sort of error. | 717 | * If we go past the end of the buffer, there is some sort of error. |
715 | */ | 718 | */ |
716 | if (offset + *pnt > bufsize) | 719 | if (offset + *pnt > bufsize) |
717 | goto out_bad_span; | 720 | goto out_bad_span; |
718 | 721 | ||
719 | /* | 722 | /* |
720 | * Now test for possible Rock Ridge extensions which will override | 723 | * Now test for possible Rock Ridge extensions which will override |
721 | * some of these numbers in the inode structure. | 724 | * some of these numbers in the inode structure. |
722 | */ | 725 | */ |
723 | 726 | ||
724 | setup_rock_ridge(raw_de, inode, &rs); | 727 | setup_rock_ridge(raw_de, inode, &rs); |
725 | 728 | ||
726 | repeat: | 729 | repeat: |
727 | while (rs.len > 2) { /* There may be one byte for padding somewhere */ | 730 | while (rs.len > 2) { /* There may be one byte for padding somewhere */ |
728 | rr = (struct rock_ridge *)rs.chr; | 731 | rr = (struct rock_ridge *)rs.chr; |
729 | if (rr->len < 3) | 732 | if (rr->len < 3) |
730 | goto out; /* Something got screwed up here */ | 733 | goto out; /* Something got screwed up here */ |
731 | sig = isonum_721(rs.chr); | 734 | sig = isonum_721(rs.chr); |
732 | if (rock_check_overflow(&rs, sig)) | 735 | if (rock_check_overflow(&rs, sig)) |
733 | goto out; | 736 | goto out; |
734 | rs.chr += rr->len; | 737 | rs.chr += rr->len; |
735 | rs.len -= rr->len; | 738 | rs.len -= rr->len; |
736 | if (rs.len < 0) | 739 | if (rs.len < 0) |
737 | goto out; /* corrupted isofs */ | 740 | goto out; /* corrupted isofs */ |
738 | 741 | ||
739 | switch (sig) { | 742 | switch (sig) { |
740 | case SIG('R', 'R'): | 743 | case SIG('R', 'R'): |
741 | if ((rr->u.RR.flags[0] & RR_SL) == 0) | 744 | if ((rr->u.RR.flags[0] & RR_SL) == 0) |
742 | goto out; | 745 | goto out; |
743 | break; | 746 | break; |
744 | case SIG('S', 'P'): | 747 | case SIG('S', 'P'): |
745 | if (check_sp(rr, inode)) | 748 | if (check_sp(rr, inode)) |
746 | goto out; | 749 | goto out; |
747 | break; | 750 | break; |
748 | case SIG('S', 'L'): | 751 | case SIG('S', 'L'): |
749 | rpnt = get_symlink_chunk(rpnt, rr, | 752 | rpnt = get_symlink_chunk(rpnt, rr, |
750 | link + (PAGE_SIZE - 1)); | 753 | link + (PAGE_SIZE - 1)); |
751 | if (rpnt == NULL) | 754 | if (rpnt == NULL) |
752 | goto out; | 755 | goto out; |
753 | break; | 756 | break; |
754 | case SIG('C', 'E'): | 757 | case SIG('C', 'E'): |
755 | /* This tells is if there is a continuation record */ | 758 | /* This tells is if there is a continuation record */ |
756 | rs.cont_extent = isonum_733(rr->u.CE.extent); | 759 | rs.cont_extent = isonum_733(rr->u.CE.extent); |
757 | rs.cont_offset = isonum_733(rr->u.CE.offset); | 760 | rs.cont_offset = isonum_733(rr->u.CE.offset); |
758 | rs.cont_size = isonum_733(rr->u.CE.size); | 761 | rs.cont_size = isonum_733(rr->u.CE.size); |
759 | default: | 762 | default: |
760 | break; | 763 | break; |
761 | } | 764 | } |
762 | } | 765 | } |
763 | ret = rock_continue(&rs); | 766 | ret = rock_continue(&rs); |
764 | if (ret == 0) | 767 | if (ret == 0) |
765 | goto repeat; | 768 | goto repeat; |
766 | if (ret < 0) | 769 | if (ret < 0) |
767 | goto fail; | 770 | goto fail; |
768 | 771 | ||
769 | if (rpnt == link) | 772 | if (rpnt == link) |
770 | goto fail; | 773 | goto fail; |
771 | brelse(bh); | 774 | brelse(bh); |
772 | *rpnt = '\0'; | 775 | *rpnt = '\0'; |
773 | SetPageUptodate(page); | 776 | SetPageUptodate(page); |
774 | kunmap(page); | 777 | kunmap(page); |
775 | unlock_page(page); | 778 | unlock_page(page); |
776 | return 0; | 779 | return 0; |
777 | 780 | ||
778 | /* error exit from macro */ | 781 | /* error exit from macro */ |
779 | out: | 782 | out: |
780 | kfree(rs.buffer); | 783 | kfree(rs.buffer); |
781 | goto fail; | 784 | goto fail; |
782 | out_noread: | 785 | out_noread: |
783 | printk("unable to read i-node block"); | 786 | printk("unable to read i-node block"); |
784 | goto fail; | 787 | goto fail; |
785 | out_bad_span: | 788 | out_bad_span: |
786 | printk("symlink spans iso9660 blocks\n"); | 789 | printk("symlink spans iso9660 blocks\n"); |
787 | fail: | 790 | fail: |
788 | brelse(bh); | 791 | brelse(bh); |
789 | error: | 792 | error: |
790 | SetPageError(page); | 793 | SetPageError(page); |
791 | kunmap(page); | 794 | kunmap(page); |
792 | unlock_page(page); | 795 | unlock_page(page); |
793 | return -EIO; | 796 | return -EIO; |
794 | } | 797 | } |
795 | 798 | ||
796 | const struct address_space_operations isofs_symlink_aops = { | 799 | const struct address_space_operations isofs_symlink_aops = { |
797 | .readpage = rock_ridge_symlink_readpage | 800 | .readpage = rock_ridge_symlink_readpage |
798 | }; | 801 | }; |
799 | 802 |
fs/udf/dir.c
1 | /* | 1 | /* |
2 | * dir.c | 2 | * dir.c |
3 | * | 3 | * |
4 | * PURPOSE | 4 | * PURPOSE |
5 | * Directory handling routines for the OSTA-UDF(tm) filesystem. | 5 | * Directory handling routines for the OSTA-UDF(tm) filesystem. |
6 | * | 6 | * |
7 | * COPYRIGHT | 7 | * COPYRIGHT |
8 | * This file is distributed under the terms of the GNU General Public | 8 | * This file is distributed under the terms of the GNU General Public |
9 | * License (GPL). Copies of the GPL can be obtained from: | 9 | * License (GPL). Copies of the GPL can be obtained from: |
10 | * ftp://prep.ai.mit.edu/pub/gnu/GPL | 10 | * ftp://prep.ai.mit.edu/pub/gnu/GPL |
11 | * Each contributing author retains all rights to their own work. | 11 | * Each contributing author retains all rights to their own work. |
12 | * | 12 | * |
13 | * (C) 1998-2004 Ben Fennema | 13 | * (C) 1998-2004 Ben Fennema |
14 | * | 14 | * |
15 | * HISTORY | 15 | * HISTORY |
16 | * | 16 | * |
17 | * 10/05/98 dgb Split directory operations into its own file | 17 | * 10/05/98 dgb Split directory operations into its own file |
18 | * Implemented directory reads via do_udf_readdir | 18 | * Implemented directory reads via do_udf_readdir |
19 | * 10/06/98 Made directory operations work! | 19 | * 10/06/98 Made directory operations work! |
20 | * 11/17/98 Rewrote directory to support ICBTAG_FLAG_AD_LONG | 20 | * 11/17/98 Rewrote directory to support ICBTAG_FLAG_AD_LONG |
21 | * 11/25/98 blf Rewrote directory handling (readdir+lookup) to support reading | 21 | * 11/25/98 blf Rewrote directory handling (readdir+lookup) to support reading |
22 | * across blocks. | 22 | * across blocks. |
23 | * 12/12/98 Split out the lookup code to namei.c. bulk of directory | 23 | * 12/12/98 Split out the lookup code to namei.c. bulk of directory |
24 | * code now in directory.c:udf_fileident_read. | 24 | * code now in directory.c:udf_fileident_read. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "udfdecl.h" | 27 | #include "udfdecl.h" |
28 | 28 | ||
29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
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/buffer_head.h> | 33 | #include <linux/buffer_head.h> |
34 | 34 | ||
35 | #include "udf_i.h" | 35 | #include "udf_i.h" |
36 | #include "udf_sb.h" | 36 | #include "udf_sb.h" |
37 | 37 | ||
38 | 38 | ||
39 | static int udf_readdir(struct file *file, struct dir_context *ctx) | 39 | static int udf_readdir(struct file *file, struct dir_context *ctx) |
40 | { | 40 | { |
41 | struct inode *dir = file_inode(file); | 41 | struct inode *dir = file_inode(file); |
42 | struct udf_inode_info *iinfo = UDF_I(dir); | 42 | struct udf_inode_info *iinfo = UDF_I(dir); |
43 | struct udf_fileident_bh fibh = { .sbh = NULL, .ebh = NULL}; | 43 | struct udf_fileident_bh fibh = { .sbh = NULL, .ebh = NULL}; |
44 | struct fileIdentDesc *fi = NULL; | 44 | struct fileIdentDesc *fi = NULL; |
45 | struct fileIdentDesc cfi; | 45 | struct fileIdentDesc cfi; |
46 | int block, iblock; | 46 | int block, iblock; |
47 | loff_t nf_pos; | 47 | loff_t nf_pos; |
48 | int flen; | 48 | int flen; |
49 | unsigned char *fname = NULL; | 49 | unsigned char *fname = NULL; |
50 | unsigned char *nameptr; | 50 | unsigned char *nameptr; |
51 | uint16_t liu; | 51 | uint16_t liu; |
52 | uint8_t lfi; | 52 | uint8_t lfi; |
53 | loff_t size = udf_ext0_offset(dir) + dir->i_size; | 53 | loff_t size = udf_ext0_offset(dir) + dir->i_size; |
54 | struct buffer_head *tmp, *bha[16]; | 54 | struct buffer_head *tmp, *bha[16]; |
55 | struct kernel_lb_addr eloc; | 55 | struct kernel_lb_addr eloc; |
56 | uint32_t elen; | 56 | uint32_t elen; |
57 | sector_t offset; | 57 | sector_t offset; |
58 | int i, num, ret = 0; | 58 | int i, num, ret = 0; |
59 | struct extent_position epos = { NULL, 0, {0, 0} }; | 59 | struct extent_position epos = { NULL, 0, {0, 0} }; |
60 | struct super_block *sb = dir->i_sb; | ||
60 | 61 | ||
61 | if (ctx->pos == 0) { | 62 | if (ctx->pos == 0) { |
62 | if (!dir_emit_dot(file, ctx)) | 63 | if (!dir_emit_dot(file, ctx)) |
63 | return 0; | 64 | return 0; |
64 | ctx->pos = 1; | 65 | ctx->pos = 1; |
65 | } | 66 | } |
66 | nf_pos = (ctx->pos - 1) << 2; | 67 | nf_pos = (ctx->pos - 1) << 2; |
67 | if (nf_pos >= size) | 68 | if (nf_pos >= size) |
68 | goto out; | 69 | goto out; |
69 | 70 | ||
70 | fname = kmalloc(UDF_NAME_LEN, GFP_NOFS); | 71 | fname = kmalloc(UDF_NAME_LEN, GFP_NOFS); |
71 | if (!fname) { | 72 | if (!fname) { |
72 | ret = -ENOMEM; | 73 | ret = -ENOMEM; |
73 | goto out; | 74 | goto out; |
74 | } | 75 | } |
75 | 76 | ||
76 | if (nf_pos == 0) | 77 | if (nf_pos == 0) |
77 | nf_pos = udf_ext0_offset(dir); | 78 | nf_pos = udf_ext0_offset(dir); |
78 | 79 | ||
79 | fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1); | 80 | fibh.soffset = fibh.eoffset = nf_pos & (sb->s_blocksize - 1); |
80 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 81 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
81 | if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, | 82 | if (inode_bmap(dir, nf_pos >> sb->s_blocksize_bits, |
82 | &epos, &eloc, &elen, &offset) | 83 | &epos, &eloc, &elen, &offset) |
83 | != (EXT_RECORDED_ALLOCATED >> 30)) { | 84 | != (EXT_RECORDED_ALLOCATED >> 30)) { |
84 | ret = -ENOENT; | 85 | ret = -ENOENT; |
85 | goto out; | 86 | goto out; |
86 | } | 87 | } |
87 | block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); | 88 | block = udf_get_lb_pblock(sb, &eloc, offset); |
88 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 89 | if ((++offset << sb->s_blocksize_bits) < elen) { |
89 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 90 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
90 | epos.offset -= sizeof(struct short_ad); | 91 | epos.offset -= sizeof(struct short_ad); |
91 | else if (iinfo->i_alloc_type == | 92 | else if (iinfo->i_alloc_type == |
92 | ICBTAG_FLAG_AD_LONG) | 93 | ICBTAG_FLAG_AD_LONG) |
93 | epos.offset -= sizeof(struct long_ad); | 94 | epos.offset -= sizeof(struct long_ad); |
94 | } else { | 95 | } else { |
95 | offset = 0; | 96 | offset = 0; |
96 | } | 97 | } |
97 | 98 | ||
98 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) { | 99 | if (!(fibh.sbh = fibh.ebh = udf_tread(sb, block))) { |
99 | ret = -EIO; | 100 | ret = -EIO; |
100 | goto out; | 101 | goto out; |
101 | } | 102 | } |
102 | 103 | ||
103 | if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) { | 104 | if (!(offset & ((16 >> (sb->s_blocksize_bits - 9)) - 1))) { |
104 | i = 16 >> (dir->i_sb->s_blocksize_bits - 9); | 105 | i = 16 >> (sb->s_blocksize_bits - 9); |
105 | if (i + offset > (elen >> dir->i_sb->s_blocksize_bits)) | 106 | if (i + offset > (elen >> sb->s_blocksize_bits)) |
106 | i = (elen >> dir->i_sb->s_blocksize_bits) - offset; | 107 | i = (elen >> sb->s_blocksize_bits) - offset; |
107 | for (num = 0; i > 0; i--) { | 108 | for (num = 0; i > 0; i--) { |
108 | block = udf_get_lb_pblock(dir->i_sb, &eloc, offset + i); | 109 | block = udf_get_lb_pblock(sb, &eloc, offset + i); |
109 | tmp = udf_tgetblk(dir->i_sb, block); | 110 | tmp = udf_tgetblk(sb, block); |
110 | if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) | 111 | if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) |
111 | bha[num++] = tmp; | 112 | bha[num++] = tmp; |
112 | else | 113 | else |
113 | brelse(tmp); | 114 | brelse(tmp); |
114 | } | 115 | } |
115 | if (num) { | 116 | if (num) { |
116 | ll_rw_block(READA, num, bha); | 117 | ll_rw_block(READA, num, bha); |
117 | for (i = 0; i < num; i++) | 118 | for (i = 0; i < num; i++) |
118 | brelse(bha[i]); | 119 | brelse(bha[i]); |
119 | } | 120 | } |
120 | } | 121 | } |
121 | } | 122 | } |
122 | 123 | ||
123 | while (nf_pos < size) { | 124 | while (nf_pos < size) { |
124 | struct kernel_lb_addr tloc; | 125 | struct kernel_lb_addr tloc; |
125 | 126 | ||
126 | ctx->pos = (nf_pos >> 2) + 1; | 127 | ctx->pos = (nf_pos >> 2) + 1; |
127 | 128 | ||
128 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, | 129 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, |
129 | &elen, &offset); | 130 | &elen, &offset); |
130 | if (!fi) | 131 | if (!fi) |
131 | goto out; | 132 | goto out; |
132 | 133 | ||
133 | liu = le16_to_cpu(cfi.lengthOfImpUse); | 134 | liu = le16_to_cpu(cfi.lengthOfImpUse); |
134 | lfi = cfi.lengthFileIdent; | 135 | lfi = cfi.lengthFileIdent; |
135 | 136 | ||
136 | if (fibh.sbh == fibh.ebh) { | 137 | if (fibh.sbh == fibh.ebh) { |
137 | nameptr = fi->fileIdent + liu; | 138 | nameptr = fi->fileIdent + liu; |
138 | } else { | 139 | } else { |
139 | int poffset; /* Unpaded ending offset */ | 140 | int poffset; /* Unpaded ending offset */ |
140 | 141 | ||
141 | poffset = fibh.soffset + sizeof(struct fileIdentDesc) + liu + lfi; | 142 | poffset = fibh.soffset + sizeof(struct fileIdentDesc) + liu + lfi; |
142 | 143 | ||
143 | if (poffset >= lfi) { | 144 | if (poffset >= lfi) { |
144 | nameptr = (char *)(fibh.ebh->b_data + poffset - lfi); | 145 | nameptr = (char *)(fibh.ebh->b_data + poffset - lfi); |
145 | } else { | 146 | } else { |
146 | nameptr = fname; | 147 | nameptr = fname; |
147 | memcpy(nameptr, fi->fileIdent + liu, | 148 | memcpy(nameptr, fi->fileIdent + liu, |
148 | lfi - poffset); | 149 | lfi - poffset); |
149 | memcpy(nameptr + lfi - poffset, | 150 | memcpy(nameptr + lfi - poffset, |
150 | fibh.ebh->b_data, poffset); | 151 | fibh.ebh->b_data, poffset); |
151 | } | 152 | } |
152 | } | 153 | } |
153 | 154 | ||
154 | if ((cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { | 155 | if ((cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { |
155 | if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE)) | 156 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNDELETE)) |
156 | continue; | 157 | continue; |
157 | } | 158 | } |
158 | 159 | ||
159 | if ((cfi.fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) { | 160 | if ((cfi.fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) { |
160 | if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE)) | 161 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) |
161 | continue; | 162 | continue; |
162 | } | 163 | } |
163 | 164 | ||
164 | if (cfi.fileCharacteristics & FID_FILE_CHAR_PARENT) { | 165 | if (cfi.fileCharacteristics & FID_FILE_CHAR_PARENT) { |
165 | if (!dir_emit_dotdot(file, ctx)) | 166 | if (!dir_emit_dotdot(file, ctx)) |
166 | goto out; | 167 | goto out; |
167 | continue; | 168 | continue; |
168 | } | 169 | } |
169 | 170 | ||
170 | flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); | 171 | flen = udf_get_filename(sb, nameptr, lfi, fname, UDF_NAME_LEN); |
171 | if (!flen) | 172 | if (!flen) |
172 | continue; | 173 | continue; |
173 | 174 | ||
174 | tloc = lelb_to_cpu(cfi.icb.extLocation); | 175 | tloc = lelb_to_cpu(cfi.icb.extLocation); |
175 | iblock = udf_get_lb_pblock(dir->i_sb, &tloc, 0); | 176 | iblock = udf_get_lb_pblock(sb, &tloc, 0); |
176 | if (!dir_emit(ctx, fname, flen, iblock, DT_UNKNOWN)) | 177 | if (!dir_emit(ctx, fname, flen, iblock, DT_UNKNOWN)) |
177 | goto out; | 178 | goto out; |
178 | } /* end while */ | 179 | } /* end while */ |
179 | 180 | ||
180 | ctx->pos = (nf_pos >> 2) + 1; | 181 | ctx->pos = (nf_pos >> 2) + 1; |
181 | 182 | ||
182 | out: | 183 | out: |
183 | if (fibh.sbh != fibh.ebh) | 184 | if (fibh.sbh != fibh.ebh) |
184 | brelse(fibh.ebh); | 185 | brelse(fibh.ebh); |
185 | brelse(fibh.sbh); | 186 | brelse(fibh.sbh); |
186 | brelse(epos.bh); | 187 | brelse(epos.bh); |
187 | kfree(fname); | 188 | kfree(fname); |
188 | 189 | ||
189 | return ret; | 190 | return ret; |
190 | } | 191 | } |
191 | 192 | ||
192 | /* readdir and lookup functions */ | 193 | /* readdir and lookup functions */ |
193 | const struct file_operations udf_dir_operations = { | 194 | const struct file_operations udf_dir_operations = { |
194 | .llseek = generic_file_llseek, | 195 | .llseek = generic_file_llseek, |
195 | .read = generic_read_dir, | 196 | .read = generic_read_dir, |
196 | .iterate = udf_readdir, | 197 | .iterate = udf_readdir, |
197 | .unlocked_ioctl = udf_ioctl, | 198 | .unlocked_ioctl = udf_ioctl, |
198 | .fsync = generic_file_fsync, | 199 | .fsync = generic_file_fsync, |
199 | }; | 200 | }; |
200 | 201 |
fs/udf/inode.c
1 | /* | 1 | /* |
2 | * inode.c | 2 | * inode.c |
3 | * | 3 | * |
4 | * PURPOSE | 4 | * PURPOSE |
5 | * Inode handling routines for the OSTA-UDF(tm) filesystem. | 5 | * Inode handling routines for the OSTA-UDF(tm) filesystem. |
6 | * | 6 | * |
7 | * COPYRIGHT | 7 | * COPYRIGHT |
8 | * This file is distributed under the terms of the GNU General Public | 8 | * This file is distributed under the terms of the GNU General Public |
9 | * License (GPL). Copies of the GPL can be obtained from: | 9 | * License (GPL). Copies of the GPL can be obtained from: |
10 | * ftp://prep.ai.mit.edu/pub/gnu/GPL | 10 | * ftp://prep.ai.mit.edu/pub/gnu/GPL |
11 | * Each contributing author retains all rights to their own work. | 11 | * Each contributing author retains all rights to their own work. |
12 | * | 12 | * |
13 | * (C) 1998 Dave Boynton | 13 | * (C) 1998 Dave Boynton |
14 | * (C) 1998-2004 Ben Fennema | 14 | * (C) 1998-2004 Ben Fennema |
15 | * (C) 1999-2000 Stelias Computing Inc | 15 | * (C) 1999-2000 Stelias Computing Inc |
16 | * | 16 | * |
17 | * HISTORY | 17 | * HISTORY |
18 | * | 18 | * |
19 | * 10/04/98 dgb Added rudimentary directory functions | 19 | * 10/04/98 dgb Added rudimentary directory functions |
20 | * 10/07/98 Fully working udf_block_map! It works! | 20 | * 10/07/98 Fully working udf_block_map! It works! |
21 | * 11/25/98 bmap altered to better support extents | 21 | * 11/25/98 bmap altered to better support extents |
22 | * 12/06/98 blf partition support in udf_iget, udf_block_map | 22 | * 12/06/98 blf partition support in udf_iget, udf_block_map |
23 | * and udf_read_inode | 23 | * and udf_read_inode |
24 | * 12/12/98 rewrote udf_block_map to handle next extents and descs across | 24 | * 12/12/98 rewrote udf_block_map to handle next extents and descs across |
25 | * block boundaries (which is not actually allowed) | 25 | * block boundaries (which is not actually allowed) |
26 | * 12/20/98 added support for strategy 4096 | 26 | * 12/20/98 added support for strategy 4096 |
27 | * 03/07/99 rewrote udf_block_map (again) | 27 | * 03/07/99 rewrote udf_block_map (again) |
28 | * New funcs, inode_bmap, udf_next_aext | 28 | * New funcs, inode_bmap, udf_next_aext |
29 | * 04/19/99 Support for writing device EA's for major/minor # | 29 | * 04/19/99 Support for writing device EA's for major/minor # |
30 | */ | 30 | */ |
31 | 31 | ||
32 | #include "udfdecl.h" | 32 | #include "udfdecl.h" |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/buffer_head.h> | 36 | #include <linux/buffer_head.h> |
37 | #include <linux/writeback.h> | 37 | #include <linux/writeback.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/crc-itu-t.h> | 39 | #include <linux/crc-itu-t.h> |
40 | #include <linux/mpage.h> | 40 | #include <linux/mpage.h> |
41 | #include <linux/aio.h> | 41 | #include <linux/aio.h> |
42 | 42 | ||
43 | #include "udf_i.h" | 43 | #include "udf_i.h" |
44 | #include "udf_sb.h" | 44 | #include "udf_sb.h" |
45 | 45 | ||
46 | MODULE_AUTHOR("Ben Fennema"); | 46 | MODULE_AUTHOR("Ben Fennema"); |
47 | MODULE_DESCRIPTION("Universal Disk Format Filesystem"); | 47 | MODULE_DESCRIPTION("Universal Disk Format Filesystem"); |
48 | MODULE_LICENSE("GPL"); | 48 | MODULE_LICENSE("GPL"); |
49 | 49 | ||
50 | #define EXTENT_MERGE_SIZE 5 | 50 | #define EXTENT_MERGE_SIZE 5 |
51 | 51 | ||
52 | static umode_t udf_convert_permissions(struct fileEntry *); | 52 | static umode_t udf_convert_permissions(struct fileEntry *); |
53 | static int udf_update_inode(struct inode *, int); | 53 | static int udf_update_inode(struct inode *, int); |
54 | static int udf_sync_inode(struct inode *inode); | 54 | static int udf_sync_inode(struct inode *inode); |
55 | static int udf_alloc_i_data(struct inode *inode, size_t size); | 55 | static int udf_alloc_i_data(struct inode *inode, size_t size); |
56 | static sector_t inode_getblk(struct inode *, sector_t, int *, int *); | 56 | static sector_t inode_getblk(struct inode *, sector_t, int *, int *); |
57 | static int8_t udf_insert_aext(struct inode *, struct extent_position, | 57 | static int8_t udf_insert_aext(struct inode *, struct extent_position, |
58 | struct kernel_lb_addr, uint32_t); | 58 | struct kernel_lb_addr, uint32_t); |
59 | static void udf_split_extents(struct inode *, int *, int, int, | 59 | static void udf_split_extents(struct inode *, int *, int, int, |
60 | struct kernel_long_ad[EXTENT_MERGE_SIZE], int *); | 60 | struct kernel_long_ad[EXTENT_MERGE_SIZE], int *); |
61 | static void udf_prealloc_extents(struct inode *, int, int, | 61 | static void udf_prealloc_extents(struct inode *, int, int, |
62 | struct kernel_long_ad[EXTENT_MERGE_SIZE], int *); | 62 | struct kernel_long_ad[EXTENT_MERGE_SIZE], int *); |
63 | static void udf_merge_extents(struct inode *, | 63 | static void udf_merge_extents(struct inode *, |
64 | struct kernel_long_ad[EXTENT_MERGE_SIZE], int *); | 64 | struct kernel_long_ad[EXTENT_MERGE_SIZE], int *); |
65 | static void udf_update_extents(struct inode *, | 65 | static void udf_update_extents(struct inode *, |
66 | struct kernel_long_ad[EXTENT_MERGE_SIZE], int, int, | 66 | struct kernel_long_ad[EXTENT_MERGE_SIZE], int, int, |
67 | struct extent_position *); | 67 | struct extent_position *); |
68 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); | 68 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); |
69 | 69 | ||
70 | static void __udf_clear_extent_cache(struct inode *inode) | 70 | static void __udf_clear_extent_cache(struct inode *inode) |
71 | { | 71 | { |
72 | struct udf_inode_info *iinfo = UDF_I(inode); | 72 | struct udf_inode_info *iinfo = UDF_I(inode); |
73 | 73 | ||
74 | if (iinfo->cached_extent.lstart != -1) { | 74 | if (iinfo->cached_extent.lstart != -1) { |
75 | brelse(iinfo->cached_extent.epos.bh); | 75 | brelse(iinfo->cached_extent.epos.bh); |
76 | iinfo->cached_extent.lstart = -1; | 76 | iinfo->cached_extent.lstart = -1; |
77 | } | 77 | } |
78 | } | 78 | } |
79 | 79 | ||
80 | /* Invalidate extent cache */ | 80 | /* Invalidate extent cache */ |
81 | static void udf_clear_extent_cache(struct inode *inode) | 81 | static void udf_clear_extent_cache(struct inode *inode) |
82 | { | 82 | { |
83 | struct udf_inode_info *iinfo = UDF_I(inode); | 83 | struct udf_inode_info *iinfo = UDF_I(inode); |
84 | 84 | ||
85 | spin_lock(&iinfo->i_extent_cache_lock); | 85 | spin_lock(&iinfo->i_extent_cache_lock); |
86 | __udf_clear_extent_cache(inode); | 86 | __udf_clear_extent_cache(inode); |
87 | spin_unlock(&iinfo->i_extent_cache_lock); | 87 | spin_unlock(&iinfo->i_extent_cache_lock); |
88 | } | 88 | } |
89 | 89 | ||
90 | /* Return contents of extent cache */ | 90 | /* Return contents of extent cache */ |
91 | static int udf_read_extent_cache(struct inode *inode, loff_t bcount, | 91 | static int udf_read_extent_cache(struct inode *inode, loff_t bcount, |
92 | loff_t *lbcount, struct extent_position *pos) | 92 | loff_t *lbcount, struct extent_position *pos) |
93 | { | 93 | { |
94 | struct udf_inode_info *iinfo = UDF_I(inode); | 94 | struct udf_inode_info *iinfo = UDF_I(inode); |
95 | int ret = 0; | 95 | int ret = 0; |
96 | 96 | ||
97 | spin_lock(&iinfo->i_extent_cache_lock); | 97 | spin_lock(&iinfo->i_extent_cache_lock); |
98 | if ((iinfo->cached_extent.lstart <= bcount) && | 98 | if ((iinfo->cached_extent.lstart <= bcount) && |
99 | (iinfo->cached_extent.lstart != -1)) { | 99 | (iinfo->cached_extent.lstart != -1)) { |
100 | /* Cache hit */ | 100 | /* Cache hit */ |
101 | *lbcount = iinfo->cached_extent.lstart; | 101 | *lbcount = iinfo->cached_extent.lstart; |
102 | memcpy(pos, &iinfo->cached_extent.epos, | 102 | memcpy(pos, &iinfo->cached_extent.epos, |
103 | sizeof(struct extent_position)); | 103 | sizeof(struct extent_position)); |
104 | if (pos->bh) | 104 | if (pos->bh) |
105 | get_bh(pos->bh); | 105 | get_bh(pos->bh); |
106 | ret = 1; | 106 | ret = 1; |
107 | } | 107 | } |
108 | spin_unlock(&iinfo->i_extent_cache_lock); | 108 | spin_unlock(&iinfo->i_extent_cache_lock); |
109 | return ret; | 109 | return ret; |
110 | } | 110 | } |
111 | 111 | ||
112 | /* Add extent to extent cache */ | 112 | /* Add extent to extent cache */ |
113 | static void udf_update_extent_cache(struct inode *inode, loff_t estart, | 113 | static void udf_update_extent_cache(struct inode *inode, loff_t estart, |
114 | struct extent_position *pos, int next_epos) | 114 | struct extent_position *pos, int next_epos) |
115 | { | 115 | { |
116 | struct udf_inode_info *iinfo = UDF_I(inode); | 116 | struct udf_inode_info *iinfo = UDF_I(inode); |
117 | 117 | ||
118 | spin_lock(&iinfo->i_extent_cache_lock); | 118 | spin_lock(&iinfo->i_extent_cache_lock); |
119 | /* Invalidate previously cached extent */ | 119 | /* Invalidate previously cached extent */ |
120 | __udf_clear_extent_cache(inode); | 120 | __udf_clear_extent_cache(inode); |
121 | if (pos->bh) | 121 | if (pos->bh) |
122 | get_bh(pos->bh); | 122 | get_bh(pos->bh); |
123 | memcpy(&iinfo->cached_extent.epos, pos, | 123 | memcpy(&iinfo->cached_extent.epos, pos, |
124 | sizeof(struct extent_position)); | 124 | sizeof(struct extent_position)); |
125 | iinfo->cached_extent.lstart = estart; | 125 | iinfo->cached_extent.lstart = estart; |
126 | if (next_epos) | 126 | if (next_epos) |
127 | switch (iinfo->i_alloc_type) { | 127 | switch (iinfo->i_alloc_type) { |
128 | case ICBTAG_FLAG_AD_SHORT: | 128 | case ICBTAG_FLAG_AD_SHORT: |
129 | iinfo->cached_extent.epos.offset -= | 129 | iinfo->cached_extent.epos.offset -= |
130 | sizeof(struct short_ad); | 130 | sizeof(struct short_ad); |
131 | break; | 131 | break; |
132 | case ICBTAG_FLAG_AD_LONG: | 132 | case ICBTAG_FLAG_AD_LONG: |
133 | iinfo->cached_extent.epos.offset -= | 133 | iinfo->cached_extent.epos.offset -= |
134 | sizeof(struct long_ad); | 134 | sizeof(struct long_ad); |
135 | } | 135 | } |
136 | spin_unlock(&iinfo->i_extent_cache_lock); | 136 | spin_unlock(&iinfo->i_extent_cache_lock); |
137 | } | 137 | } |
138 | 138 | ||
139 | void udf_evict_inode(struct inode *inode) | 139 | void udf_evict_inode(struct inode *inode) |
140 | { | 140 | { |
141 | struct udf_inode_info *iinfo = UDF_I(inode); | 141 | struct udf_inode_info *iinfo = UDF_I(inode); |
142 | int want_delete = 0; | 142 | int want_delete = 0; |
143 | 143 | ||
144 | if (!inode->i_nlink && !is_bad_inode(inode)) { | 144 | if (!inode->i_nlink && !is_bad_inode(inode)) { |
145 | want_delete = 1; | 145 | want_delete = 1; |
146 | udf_setsize(inode, 0); | 146 | udf_setsize(inode, 0); |
147 | udf_update_inode(inode, IS_SYNC(inode)); | 147 | udf_update_inode(inode, IS_SYNC(inode)); |
148 | } | 148 | } |
149 | truncate_inode_pages_final(&inode->i_data); | 149 | truncate_inode_pages_final(&inode->i_data); |
150 | invalidate_inode_buffers(inode); | 150 | invalidate_inode_buffers(inode); |
151 | clear_inode(inode); | 151 | clear_inode(inode); |
152 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && | 152 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && |
153 | inode->i_size != iinfo->i_lenExtents) { | 153 | inode->i_size != iinfo->i_lenExtents) { |
154 | udf_warn(inode->i_sb, "Inode %lu (mode %o) has inode size %llu different from extent length %llu. Filesystem need not be standards compliant.\n", | 154 | udf_warn(inode->i_sb, "Inode %lu (mode %o) has inode size %llu different from extent length %llu. Filesystem need not be standards compliant.\n", |
155 | inode->i_ino, inode->i_mode, | 155 | inode->i_ino, inode->i_mode, |
156 | (unsigned long long)inode->i_size, | 156 | (unsigned long long)inode->i_size, |
157 | (unsigned long long)iinfo->i_lenExtents); | 157 | (unsigned long long)iinfo->i_lenExtents); |
158 | } | 158 | } |
159 | kfree(iinfo->i_ext.i_data); | 159 | kfree(iinfo->i_ext.i_data); |
160 | iinfo->i_ext.i_data = NULL; | 160 | iinfo->i_ext.i_data = NULL; |
161 | udf_clear_extent_cache(inode); | 161 | udf_clear_extent_cache(inode); |
162 | if (want_delete) { | 162 | if (want_delete) { |
163 | udf_free_inode(inode); | 163 | udf_free_inode(inode); |
164 | } | 164 | } |
165 | } | 165 | } |
166 | 166 | ||
167 | static void udf_write_failed(struct address_space *mapping, loff_t to) | 167 | static void udf_write_failed(struct address_space *mapping, loff_t to) |
168 | { | 168 | { |
169 | struct inode *inode = mapping->host; | 169 | struct inode *inode = mapping->host; |
170 | struct udf_inode_info *iinfo = UDF_I(inode); | 170 | struct udf_inode_info *iinfo = UDF_I(inode); |
171 | loff_t isize = inode->i_size; | 171 | loff_t isize = inode->i_size; |
172 | 172 | ||
173 | if (to > isize) { | 173 | if (to > isize) { |
174 | truncate_pagecache(inode, isize); | 174 | truncate_pagecache(inode, isize); |
175 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 175 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
176 | down_write(&iinfo->i_data_sem); | 176 | down_write(&iinfo->i_data_sem); |
177 | udf_clear_extent_cache(inode); | 177 | udf_clear_extent_cache(inode); |
178 | udf_truncate_extents(inode); | 178 | udf_truncate_extents(inode); |
179 | up_write(&iinfo->i_data_sem); | 179 | up_write(&iinfo->i_data_sem); |
180 | } | 180 | } |
181 | } | 181 | } |
182 | } | 182 | } |
183 | 183 | ||
184 | static int udf_writepage(struct page *page, struct writeback_control *wbc) | 184 | static int udf_writepage(struct page *page, struct writeback_control *wbc) |
185 | { | 185 | { |
186 | return block_write_full_page(page, udf_get_block, wbc); | 186 | return block_write_full_page(page, udf_get_block, wbc); |
187 | } | 187 | } |
188 | 188 | ||
189 | static int udf_writepages(struct address_space *mapping, | 189 | static int udf_writepages(struct address_space *mapping, |
190 | struct writeback_control *wbc) | 190 | struct writeback_control *wbc) |
191 | { | 191 | { |
192 | return mpage_writepages(mapping, wbc, udf_get_block); | 192 | return mpage_writepages(mapping, wbc, udf_get_block); |
193 | } | 193 | } |
194 | 194 | ||
195 | static int udf_readpage(struct file *file, struct page *page) | 195 | static int udf_readpage(struct file *file, struct page *page) |
196 | { | 196 | { |
197 | return mpage_readpage(page, udf_get_block); | 197 | return mpage_readpage(page, udf_get_block); |
198 | } | 198 | } |
199 | 199 | ||
200 | static int udf_readpages(struct file *file, struct address_space *mapping, | 200 | static int udf_readpages(struct file *file, struct address_space *mapping, |
201 | struct list_head *pages, unsigned nr_pages) | 201 | struct list_head *pages, unsigned nr_pages) |
202 | { | 202 | { |
203 | return mpage_readpages(mapping, pages, nr_pages, udf_get_block); | 203 | return mpage_readpages(mapping, pages, nr_pages, udf_get_block); |
204 | } | 204 | } |
205 | 205 | ||
206 | static int udf_write_begin(struct file *file, struct address_space *mapping, | 206 | static int udf_write_begin(struct file *file, struct address_space *mapping, |
207 | loff_t pos, unsigned len, unsigned flags, | 207 | loff_t pos, unsigned len, unsigned flags, |
208 | struct page **pagep, void **fsdata) | 208 | struct page **pagep, void **fsdata) |
209 | { | 209 | { |
210 | int ret; | 210 | int ret; |
211 | 211 | ||
212 | ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block); | 212 | ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block); |
213 | if (unlikely(ret)) | 213 | if (unlikely(ret)) |
214 | udf_write_failed(mapping, pos + len); | 214 | udf_write_failed(mapping, pos + len); |
215 | return ret; | 215 | return ret; |
216 | } | 216 | } |
217 | 217 | ||
218 | static ssize_t udf_direct_IO(int rw, struct kiocb *iocb, | 218 | static ssize_t udf_direct_IO(int rw, struct kiocb *iocb, |
219 | struct iov_iter *iter, | 219 | struct iov_iter *iter, |
220 | loff_t offset) | 220 | loff_t offset) |
221 | { | 221 | { |
222 | struct file *file = iocb->ki_filp; | 222 | struct file *file = iocb->ki_filp; |
223 | struct address_space *mapping = file->f_mapping; | 223 | struct address_space *mapping = file->f_mapping; |
224 | struct inode *inode = mapping->host; | 224 | struct inode *inode = mapping->host; |
225 | size_t count = iov_iter_count(iter); | 225 | size_t count = iov_iter_count(iter); |
226 | ssize_t ret; | 226 | ssize_t ret; |
227 | 227 | ||
228 | ret = blockdev_direct_IO(rw, iocb, inode, iter, offset, udf_get_block); | 228 | ret = blockdev_direct_IO(rw, iocb, inode, iter, offset, udf_get_block); |
229 | if (unlikely(ret < 0 && (rw & WRITE))) | 229 | if (unlikely(ret < 0 && (rw & WRITE))) |
230 | udf_write_failed(mapping, offset + count); | 230 | udf_write_failed(mapping, offset + count); |
231 | return ret; | 231 | return ret; |
232 | } | 232 | } |
233 | 233 | ||
234 | static sector_t udf_bmap(struct address_space *mapping, sector_t block) | 234 | static sector_t udf_bmap(struct address_space *mapping, sector_t block) |
235 | { | 235 | { |
236 | return generic_block_bmap(mapping, block, udf_get_block); | 236 | return generic_block_bmap(mapping, block, udf_get_block); |
237 | } | 237 | } |
238 | 238 | ||
239 | const struct address_space_operations udf_aops = { | 239 | const struct address_space_operations udf_aops = { |
240 | .readpage = udf_readpage, | 240 | .readpage = udf_readpage, |
241 | .readpages = udf_readpages, | 241 | .readpages = udf_readpages, |
242 | .writepage = udf_writepage, | 242 | .writepage = udf_writepage, |
243 | .writepages = udf_writepages, | 243 | .writepages = udf_writepages, |
244 | .write_begin = udf_write_begin, | 244 | .write_begin = udf_write_begin, |
245 | .write_end = generic_write_end, | 245 | .write_end = generic_write_end, |
246 | .direct_IO = udf_direct_IO, | 246 | .direct_IO = udf_direct_IO, |
247 | .bmap = udf_bmap, | 247 | .bmap = udf_bmap, |
248 | }; | 248 | }; |
249 | 249 | ||
250 | /* | 250 | /* |
251 | * Expand file stored in ICB to a normal one-block-file | 251 | * Expand file stored in ICB to a normal one-block-file |
252 | * | 252 | * |
253 | * This function requires i_data_sem for writing and releases it. | 253 | * This function requires i_data_sem for writing and releases it. |
254 | * This function requires i_mutex held | 254 | * This function requires i_mutex held |
255 | */ | 255 | */ |
256 | int udf_expand_file_adinicb(struct inode *inode) | 256 | int udf_expand_file_adinicb(struct inode *inode) |
257 | { | 257 | { |
258 | struct page *page; | 258 | struct page *page; |
259 | char *kaddr; | 259 | char *kaddr; |
260 | struct udf_inode_info *iinfo = UDF_I(inode); | 260 | struct udf_inode_info *iinfo = UDF_I(inode); |
261 | int err; | 261 | int err; |
262 | struct writeback_control udf_wbc = { | 262 | struct writeback_control udf_wbc = { |
263 | .sync_mode = WB_SYNC_NONE, | 263 | .sync_mode = WB_SYNC_NONE, |
264 | .nr_to_write = 1, | 264 | .nr_to_write = 1, |
265 | }; | 265 | }; |
266 | 266 | ||
267 | WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex)); | 267 | WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex)); |
268 | if (!iinfo->i_lenAlloc) { | 268 | if (!iinfo->i_lenAlloc) { |
269 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) | 269 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) |
270 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; | 270 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; |
271 | else | 271 | else |
272 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; | 272 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; |
273 | /* from now on we have normal address_space methods */ | 273 | /* from now on we have normal address_space methods */ |
274 | inode->i_data.a_ops = &udf_aops; | 274 | inode->i_data.a_ops = &udf_aops; |
275 | up_write(&iinfo->i_data_sem); | 275 | up_write(&iinfo->i_data_sem); |
276 | mark_inode_dirty(inode); | 276 | mark_inode_dirty(inode); |
277 | return 0; | 277 | return 0; |
278 | } | 278 | } |
279 | /* | 279 | /* |
280 | * Release i_data_sem so that we can lock a page - page lock ranks | 280 | * Release i_data_sem so that we can lock a page - page lock ranks |
281 | * above i_data_sem. i_mutex still protects us against file changes. | 281 | * above i_data_sem. i_mutex still protects us against file changes. |
282 | */ | 282 | */ |
283 | up_write(&iinfo->i_data_sem); | 283 | up_write(&iinfo->i_data_sem); |
284 | 284 | ||
285 | page = find_or_create_page(inode->i_mapping, 0, GFP_NOFS); | 285 | page = find_or_create_page(inode->i_mapping, 0, GFP_NOFS); |
286 | if (!page) | 286 | if (!page) |
287 | return -ENOMEM; | 287 | return -ENOMEM; |
288 | 288 | ||
289 | if (!PageUptodate(page)) { | 289 | if (!PageUptodate(page)) { |
290 | kaddr = kmap(page); | 290 | kaddr = kmap(page); |
291 | memset(kaddr + iinfo->i_lenAlloc, 0x00, | 291 | memset(kaddr + iinfo->i_lenAlloc, 0x00, |
292 | PAGE_CACHE_SIZE - iinfo->i_lenAlloc); | 292 | PAGE_CACHE_SIZE - iinfo->i_lenAlloc); |
293 | memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, | 293 | memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, |
294 | iinfo->i_lenAlloc); | 294 | iinfo->i_lenAlloc); |
295 | flush_dcache_page(page); | 295 | flush_dcache_page(page); |
296 | SetPageUptodate(page); | 296 | SetPageUptodate(page); |
297 | kunmap(page); | 297 | kunmap(page); |
298 | } | 298 | } |
299 | down_write(&iinfo->i_data_sem); | 299 | down_write(&iinfo->i_data_sem); |
300 | memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0x00, | 300 | memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0x00, |
301 | iinfo->i_lenAlloc); | 301 | iinfo->i_lenAlloc); |
302 | iinfo->i_lenAlloc = 0; | 302 | iinfo->i_lenAlloc = 0; |
303 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) | 303 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) |
304 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; | 304 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; |
305 | else | 305 | else |
306 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; | 306 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; |
307 | /* from now on we have normal address_space methods */ | 307 | /* from now on we have normal address_space methods */ |
308 | inode->i_data.a_ops = &udf_aops; | 308 | inode->i_data.a_ops = &udf_aops; |
309 | up_write(&iinfo->i_data_sem); | 309 | up_write(&iinfo->i_data_sem); |
310 | err = inode->i_data.a_ops->writepage(page, &udf_wbc); | 310 | err = inode->i_data.a_ops->writepage(page, &udf_wbc); |
311 | if (err) { | 311 | if (err) { |
312 | /* Restore everything back so that we don't lose data... */ | 312 | /* Restore everything back so that we don't lose data... */ |
313 | lock_page(page); | 313 | lock_page(page); |
314 | kaddr = kmap(page); | 314 | kaddr = kmap(page); |
315 | down_write(&iinfo->i_data_sem); | 315 | down_write(&iinfo->i_data_sem); |
316 | memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr, | 316 | memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr, |
317 | inode->i_size); | 317 | inode->i_size); |
318 | kunmap(page); | 318 | kunmap(page); |
319 | unlock_page(page); | 319 | unlock_page(page); |
320 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; | 320 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; |
321 | inode->i_data.a_ops = &udf_adinicb_aops; | 321 | inode->i_data.a_ops = &udf_adinicb_aops; |
322 | up_write(&iinfo->i_data_sem); | 322 | up_write(&iinfo->i_data_sem); |
323 | } | 323 | } |
324 | page_cache_release(page); | 324 | page_cache_release(page); |
325 | mark_inode_dirty(inode); | 325 | mark_inode_dirty(inode); |
326 | 326 | ||
327 | return err; | 327 | return err; |
328 | } | 328 | } |
329 | 329 | ||
330 | struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, | 330 | struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, |
331 | int *err) | 331 | int *err) |
332 | { | 332 | { |
333 | int newblock; | 333 | int newblock; |
334 | struct buffer_head *dbh = NULL; | 334 | struct buffer_head *dbh = NULL; |
335 | struct kernel_lb_addr eloc; | 335 | struct kernel_lb_addr eloc; |
336 | uint8_t alloctype; | 336 | uint8_t alloctype; |
337 | struct extent_position epos; | 337 | struct extent_position epos; |
338 | 338 | ||
339 | struct udf_fileident_bh sfibh, dfibh; | 339 | struct udf_fileident_bh sfibh, dfibh; |
340 | loff_t f_pos = udf_ext0_offset(inode); | 340 | loff_t f_pos = udf_ext0_offset(inode); |
341 | int size = udf_ext0_offset(inode) + inode->i_size; | 341 | int size = udf_ext0_offset(inode) + inode->i_size; |
342 | struct fileIdentDesc cfi, *sfi, *dfi; | 342 | struct fileIdentDesc cfi, *sfi, *dfi; |
343 | struct udf_inode_info *iinfo = UDF_I(inode); | 343 | struct udf_inode_info *iinfo = UDF_I(inode); |
344 | 344 | ||
345 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) | 345 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) |
346 | alloctype = ICBTAG_FLAG_AD_SHORT; | 346 | alloctype = ICBTAG_FLAG_AD_SHORT; |
347 | else | 347 | else |
348 | alloctype = ICBTAG_FLAG_AD_LONG; | 348 | alloctype = ICBTAG_FLAG_AD_LONG; |
349 | 349 | ||
350 | if (!inode->i_size) { | 350 | if (!inode->i_size) { |
351 | iinfo->i_alloc_type = alloctype; | 351 | iinfo->i_alloc_type = alloctype; |
352 | mark_inode_dirty(inode); | 352 | mark_inode_dirty(inode); |
353 | return NULL; | 353 | return NULL; |
354 | } | 354 | } |
355 | 355 | ||
356 | /* alloc block, and copy data to it */ | 356 | /* alloc block, and copy data to it */ |
357 | *block = udf_new_block(inode->i_sb, inode, | 357 | *block = udf_new_block(inode->i_sb, inode, |
358 | iinfo->i_location.partitionReferenceNum, | 358 | iinfo->i_location.partitionReferenceNum, |
359 | iinfo->i_location.logicalBlockNum, err); | 359 | iinfo->i_location.logicalBlockNum, err); |
360 | if (!(*block)) | 360 | if (!(*block)) |
361 | return NULL; | 361 | return NULL; |
362 | newblock = udf_get_pblock(inode->i_sb, *block, | 362 | newblock = udf_get_pblock(inode->i_sb, *block, |
363 | iinfo->i_location.partitionReferenceNum, | 363 | iinfo->i_location.partitionReferenceNum, |
364 | 0); | 364 | 0); |
365 | if (!newblock) | 365 | if (!newblock) |
366 | return NULL; | 366 | return NULL; |
367 | dbh = udf_tgetblk(inode->i_sb, newblock); | 367 | dbh = udf_tgetblk(inode->i_sb, newblock); |
368 | if (!dbh) | 368 | if (!dbh) |
369 | return NULL; | 369 | return NULL; |
370 | lock_buffer(dbh); | 370 | lock_buffer(dbh); |
371 | memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize); | 371 | memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize); |
372 | set_buffer_uptodate(dbh); | 372 | set_buffer_uptodate(dbh); |
373 | unlock_buffer(dbh); | 373 | unlock_buffer(dbh); |
374 | mark_buffer_dirty_inode(dbh, inode); | 374 | mark_buffer_dirty_inode(dbh, inode); |
375 | 375 | ||
376 | sfibh.soffset = sfibh.eoffset = | 376 | sfibh.soffset = sfibh.eoffset = |
377 | f_pos & (inode->i_sb->s_blocksize - 1); | 377 | f_pos & (inode->i_sb->s_blocksize - 1); |
378 | sfibh.sbh = sfibh.ebh = NULL; | 378 | sfibh.sbh = sfibh.ebh = NULL; |
379 | dfibh.soffset = dfibh.eoffset = 0; | 379 | dfibh.soffset = dfibh.eoffset = 0; |
380 | dfibh.sbh = dfibh.ebh = dbh; | 380 | dfibh.sbh = dfibh.ebh = dbh; |
381 | while (f_pos < size) { | 381 | while (f_pos < size) { |
382 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; | 382 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; |
383 | sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, | 383 | sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, |
384 | NULL, NULL, NULL); | 384 | NULL, NULL, NULL); |
385 | if (!sfi) { | 385 | if (!sfi) { |
386 | brelse(dbh); | 386 | brelse(dbh); |
387 | return NULL; | 387 | return NULL; |
388 | } | 388 | } |
389 | iinfo->i_alloc_type = alloctype; | 389 | iinfo->i_alloc_type = alloctype; |
390 | sfi->descTag.tagLocation = cpu_to_le32(*block); | 390 | sfi->descTag.tagLocation = cpu_to_le32(*block); |
391 | dfibh.soffset = dfibh.eoffset; | 391 | dfibh.soffset = dfibh.eoffset; |
392 | dfibh.eoffset += (sfibh.eoffset - sfibh.soffset); | 392 | dfibh.eoffset += (sfibh.eoffset - sfibh.soffset); |
393 | dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset); | 393 | dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset); |
394 | if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse, | 394 | if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse, |
395 | sfi->fileIdent + | 395 | sfi->fileIdent + |
396 | le16_to_cpu(sfi->lengthOfImpUse))) { | 396 | le16_to_cpu(sfi->lengthOfImpUse))) { |
397 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; | 397 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; |
398 | brelse(dbh); | 398 | brelse(dbh); |
399 | return NULL; | 399 | return NULL; |
400 | } | 400 | } |
401 | } | 401 | } |
402 | mark_buffer_dirty_inode(dbh, inode); | 402 | mark_buffer_dirty_inode(dbh, inode); |
403 | 403 | ||
404 | memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0, | 404 | memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0, |
405 | iinfo->i_lenAlloc); | 405 | iinfo->i_lenAlloc); |
406 | iinfo->i_lenAlloc = 0; | 406 | iinfo->i_lenAlloc = 0; |
407 | eloc.logicalBlockNum = *block; | 407 | eloc.logicalBlockNum = *block; |
408 | eloc.partitionReferenceNum = | 408 | eloc.partitionReferenceNum = |
409 | iinfo->i_location.partitionReferenceNum; | 409 | iinfo->i_location.partitionReferenceNum; |
410 | iinfo->i_lenExtents = inode->i_size; | 410 | iinfo->i_lenExtents = inode->i_size; |
411 | epos.bh = NULL; | 411 | epos.bh = NULL; |
412 | epos.block = iinfo->i_location; | 412 | epos.block = iinfo->i_location; |
413 | epos.offset = udf_file_entry_alloc_offset(inode); | 413 | epos.offset = udf_file_entry_alloc_offset(inode); |
414 | udf_add_aext(inode, &epos, &eloc, inode->i_size, 0); | 414 | udf_add_aext(inode, &epos, &eloc, inode->i_size, 0); |
415 | /* UniqueID stuff */ | 415 | /* UniqueID stuff */ |
416 | 416 | ||
417 | brelse(epos.bh); | 417 | brelse(epos.bh); |
418 | mark_inode_dirty(inode); | 418 | mark_inode_dirty(inode); |
419 | return dbh; | 419 | return dbh; |
420 | } | 420 | } |
421 | 421 | ||
422 | static int udf_get_block(struct inode *inode, sector_t block, | 422 | static int udf_get_block(struct inode *inode, sector_t block, |
423 | struct buffer_head *bh_result, int create) | 423 | struct buffer_head *bh_result, int create) |
424 | { | 424 | { |
425 | int err, new; | 425 | int err, new; |
426 | sector_t phys = 0; | 426 | sector_t phys = 0; |
427 | struct udf_inode_info *iinfo; | 427 | struct udf_inode_info *iinfo; |
428 | 428 | ||
429 | if (!create) { | 429 | if (!create) { |
430 | phys = udf_block_map(inode, block); | 430 | phys = udf_block_map(inode, block); |
431 | if (phys) | 431 | if (phys) |
432 | map_bh(bh_result, inode->i_sb, phys); | 432 | map_bh(bh_result, inode->i_sb, phys); |
433 | return 0; | 433 | return 0; |
434 | } | 434 | } |
435 | 435 | ||
436 | err = -EIO; | 436 | err = -EIO; |
437 | new = 0; | 437 | new = 0; |
438 | iinfo = UDF_I(inode); | 438 | iinfo = UDF_I(inode); |
439 | 439 | ||
440 | down_write(&iinfo->i_data_sem); | 440 | down_write(&iinfo->i_data_sem); |
441 | if (block == iinfo->i_next_alloc_block + 1) { | 441 | if (block == iinfo->i_next_alloc_block + 1) { |
442 | iinfo->i_next_alloc_block++; | 442 | iinfo->i_next_alloc_block++; |
443 | iinfo->i_next_alloc_goal++; | 443 | iinfo->i_next_alloc_goal++; |
444 | } | 444 | } |
445 | 445 | ||
446 | udf_clear_extent_cache(inode); | 446 | udf_clear_extent_cache(inode); |
447 | phys = inode_getblk(inode, block, &err, &new); | 447 | phys = inode_getblk(inode, block, &err, &new); |
448 | if (!phys) | 448 | if (!phys) |
449 | goto abort; | 449 | goto abort; |
450 | 450 | ||
451 | if (new) | 451 | if (new) |
452 | set_buffer_new(bh_result); | 452 | set_buffer_new(bh_result); |
453 | map_bh(bh_result, inode->i_sb, phys); | 453 | map_bh(bh_result, inode->i_sb, phys); |
454 | 454 | ||
455 | abort: | 455 | abort: |
456 | up_write(&iinfo->i_data_sem); | 456 | up_write(&iinfo->i_data_sem); |
457 | return err; | 457 | return err; |
458 | } | 458 | } |
459 | 459 | ||
460 | static struct buffer_head *udf_getblk(struct inode *inode, long block, | 460 | static struct buffer_head *udf_getblk(struct inode *inode, long block, |
461 | int create, int *err) | 461 | int create, int *err) |
462 | { | 462 | { |
463 | struct buffer_head *bh; | 463 | struct buffer_head *bh; |
464 | struct buffer_head dummy; | 464 | struct buffer_head dummy; |
465 | 465 | ||
466 | dummy.b_state = 0; | 466 | dummy.b_state = 0; |
467 | dummy.b_blocknr = -1000; | 467 | dummy.b_blocknr = -1000; |
468 | *err = udf_get_block(inode, block, &dummy, create); | 468 | *err = udf_get_block(inode, block, &dummy, create); |
469 | if (!*err && buffer_mapped(&dummy)) { | 469 | if (!*err && buffer_mapped(&dummy)) { |
470 | bh = sb_getblk(inode->i_sb, dummy.b_blocknr); | 470 | bh = sb_getblk(inode->i_sb, dummy.b_blocknr); |
471 | if (buffer_new(&dummy)) { | 471 | if (buffer_new(&dummy)) { |
472 | lock_buffer(bh); | 472 | lock_buffer(bh); |
473 | memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); | 473 | memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); |
474 | set_buffer_uptodate(bh); | 474 | set_buffer_uptodate(bh); |
475 | unlock_buffer(bh); | 475 | unlock_buffer(bh); |
476 | mark_buffer_dirty_inode(bh, inode); | 476 | mark_buffer_dirty_inode(bh, inode); |
477 | } | 477 | } |
478 | return bh; | 478 | return bh; |
479 | } | 479 | } |
480 | 480 | ||
481 | return NULL; | 481 | return NULL; |
482 | } | 482 | } |
483 | 483 | ||
484 | /* Extend the file by 'blocks' blocks, return the number of extents added */ | 484 | /* Extend the file by 'blocks' blocks, return the number of extents added */ |
485 | static int udf_do_extend_file(struct inode *inode, | 485 | static int udf_do_extend_file(struct inode *inode, |
486 | struct extent_position *last_pos, | 486 | struct extent_position *last_pos, |
487 | struct kernel_long_ad *last_ext, | 487 | struct kernel_long_ad *last_ext, |
488 | sector_t blocks) | 488 | sector_t blocks) |
489 | { | 489 | { |
490 | sector_t add; | 490 | sector_t add; |
491 | int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); | 491 | int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); |
492 | struct super_block *sb = inode->i_sb; | 492 | struct super_block *sb = inode->i_sb; |
493 | struct kernel_lb_addr prealloc_loc = {}; | 493 | struct kernel_lb_addr prealloc_loc = {}; |
494 | int prealloc_len = 0; | 494 | int prealloc_len = 0; |
495 | struct udf_inode_info *iinfo; | 495 | struct udf_inode_info *iinfo; |
496 | int err; | 496 | int err; |
497 | 497 | ||
498 | /* The previous extent is fake and we should not extend by anything | 498 | /* The previous extent is fake and we should not extend by anything |
499 | * - there's nothing to do... */ | 499 | * - there's nothing to do... */ |
500 | if (!blocks && fake) | 500 | if (!blocks && fake) |
501 | return 0; | 501 | return 0; |
502 | 502 | ||
503 | iinfo = UDF_I(inode); | 503 | iinfo = UDF_I(inode); |
504 | /* Round the last extent up to a multiple of block size */ | 504 | /* Round the last extent up to a multiple of block size */ |
505 | if (last_ext->extLength & (sb->s_blocksize - 1)) { | 505 | if (last_ext->extLength & (sb->s_blocksize - 1)) { |
506 | last_ext->extLength = | 506 | last_ext->extLength = |
507 | (last_ext->extLength & UDF_EXTENT_FLAG_MASK) | | 507 | (last_ext->extLength & UDF_EXTENT_FLAG_MASK) | |
508 | (((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) + | 508 | (((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) + |
509 | sb->s_blocksize - 1) & ~(sb->s_blocksize - 1)); | 509 | sb->s_blocksize - 1) & ~(sb->s_blocksize - 1)); |
510 | iinfo->i_lenExtents = | 510 | iinfo->i_lenExtents = |
511 | (iinfo->i_lenExtents + sb->s_blocksize - 1) & | 511 | (iinfo->i_lenExtents + sb->s_blocksize - 1) & |
512 | ~(sb->s_blocksize - 1); | 512 | ~(sb->s_blocksize - 1); |
513 | } | 513 | } |
514 | 514 | ||
515 | /* Last extent are just preallocated blocks? */ | 515 | /* Last extent are just preallocated blocks? */ |
516 | if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == | 516 | if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == |
517 | EXT_NOT_RECORDED_ALLOCATED) { | 517 | EXT_NOT_RECORDED_ALLOCATED) { |
518 | /* Save the extent so that we can reattach it to the end */ | 518 | /* Save the extent so that we can reattach it to the end */ |
519 | prealloc_loc = last_ext->extLocation; | 519 | prealloc_loc = last_ext->extLocation; |
520 | prealloc_len = last_ext->extLength; | 520 | prealloc_len = last_ext->extLength; |
521 | /* Mark the extent as a hole */ | 521 | /* Mark the extent as a hole */ |
522 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | 522 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
523 | (last_ext->extLength & UDF_EXTENT_LENGTH_MASK); | 523 | (last_ext->extLength & UDF_EXTENT_LENGTH_MASK); |
524 | last_ext->extLocation.logicalBlockNum = 0; | 524 | last_ext->extLocation.logicalBlockNum = 0; |
525 | last_ext->extLocation.partitionReferenceNum = 0; | 525 | last_ext->extLocation.partitionReferenceNum = 0; |
526 | } | 526 | } |
527 | 527 | ||
528 | /* Can we merge with the previous extent? */ | 528 | /* Can we merge with the previous extent? */ |
529 | if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == | 529 | if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == |
530 | EXT_NOT_RECORDED_NOT_ALLOCATED) { | 530 | EXT_NOT_RECORDED_NOT_ALLOCATED) { |
531 | add = ((1 << 30) - sb->s_blocksize - | 531 | add = ((1 << 30) - sb->s_blocksize - |
532 | (last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) >> | 532 | (last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) >> |
533 | sb->s_blocksize_bits; | 533 | sb->s_blocksize_bits; |
534 | if (add > blocks) | 534 | if (add > blocks) |
535 | add = blocks; | 535 | add = blocks; |
536 | blocks -= add; | 536 | blocks -= add; |
537 | last_ext->extLength += add << sb->s_blocksize_bits; | 537 | last_ext->extLength += add << sb->s_blocksize_bits; |
538 | } | 538 | } |
539 | 539 | ||
540 | if (fake) { | 540 | if (fake) { |
541 | udf_add_aext(inode, last_pos, &last_ext->extLocation, | 541 | udf_add_aext(inode, last_pos, &last_ext->extLocation, |
542 | last_ext->extLength, 1); | 542 | last_ext->extLength, 1); |
543 | count++; | 543 | count++; |
544 | } else | 544 | } else |
545 | udf_write_aext(inode, last_pos, &last_ext->extLocation, | 545 | udf_write_aext(inode, last_pos, &last_ext->extLocation, |
546 | last_ext->extLength, 1); | 546 | last_ext->extLength, 1); |
547 | 547 | ||
548 | /* Managed to do everything necessary? */ | 548 | /* Managed to do everything necessary? */ |
549 | if (!blocks) | 549 | if (!blocks) |
550 | goto out; | 550 | goto out; |
551 | 551 | ||
552 | /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */ | 552 | /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */ |
553 | last_ext->extLocation.logicalBlockNum = 0; | 553 | last_ext->extLocation.logicalBlockNum = 0; |
554 | last_ext->extLocation.partitionReferenceNum = 0; | 554 | last_ext->extLocation.partitionReferenceNum = 0; |
555 | add = (1 << (30-sb->s_blocksize_bits)) - 1; | 555 | add = (1 << (30-sb->s_blocksize_bits)) - 1; |
556 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | 556 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
557 | (add << sb->s_blocksize_bits); | 557 | (add << sb->s_blocksize_bits); |
558 | 558 | ||
559 | /* Create enough extents to cover the whole hole */ | 559 | /* Create enough extents to cover the whole hole */ |
560 | while (blocks > add) { | 560 | while (blocks > add) { |
561 | blocks -= add; | 561 | blocks -= add; |
562 | err = udf_add_aext(inode, last_pos, &last_ext->extLocation, | 562 | err = udf_add_aext(inode, last_pos, &last_ext->extLocation, |
563 | last_ext->extLength, 1); | 563 | last_ext->extLength, 1); |
564 | if (err) | 564 | if (err) |
565 | return err; | 565 | return err; |
566 | count++; | 566 | count++; |
567 | } | 567 | } |
568 | if (blocks) { | 568 | if (blocks) { |
569 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | 569 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
570 | (blocks << sb->s_blocksize_bits); | 570 | (blocks << sb->s_blocksize_bits); |
571 | err = udf_add_aext(inode, last_pos, &last_ext->extLocation, | 571 | err = udf_add_aext(inode, last_pos, &last_ext->extLocation, |
572 | last_ext->extLength, 1); | 572 | last_ext->extLength, 1); |
573 | if (err) | 573 | if (err) |
574 | return err; | 574 | return err; |
575 | count++; | 575 | count++; |
576 | } | 576 | } |
577 | 577 | ||
578 | out: | 578 | out: |
579 | /* Do we have some preallocated blocks saved? */ | 579 | /* Do we have some preallocated blocks saved? */ |
580 | if (prealloc_len) { | 580 | if (prealloc_len) { |
581 | err = udf_add_aext(inode, last_pos, &prealloc_loc, | 581 | err = udf_add_aext(inode, last_pos, &prealloc_loc, |
582 | prealloc_len, 1); | 582 | prealloc_len, 1); |
583 | if (err) | 583 | if (err) |
584 | return err; | 584 | return err; |
585 | last_ext->extLocation = prealloc_loc; | 585 | last_ext->extLocation = prealloc_loc; |
586 | last_ext->extLength = prealloc_len; | 586 | last_ext->extLength = prealloc_len; |
587 | count++; | 587 | count++; |
588 | } | 588 | } |
589 | 589 | ||
590 | /* last_pos should point to the last written extent... */ | 590 | /* last_pos should point to the last written extent... */ |
591 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 591 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
592 | last_pos->offset -= sizeof(struct short_ad); | 592 | last_pos->offset -= sizeof(struct short_ad); |
593 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 593 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
594 | last_pos->offset -= sizeof(struct long_ad); | 594 | last_pos->offset -= sizeof(struct long_ad); |
595 | else | 595 | else |
596 | return -EIO; | 596 | return -EIO; |
597 | 597 | ||
598 | return count; | 598 | return count; |
599 | } | 599 | } |
600 | 600 | ||
601 | static int udf_extend_file(struct inode *inode, loff_t newsize) | 601 | static int udf_extend_file(struct inode *inode, loff_t newsize) |
602 | { | 602 | { |
603 | 603 | ||
604 | struct extent_position epos; | 604 | struct extent_position epos; |
605 | struct kernel_lb_addr eloc; | 605 | struct kernel_lb_addr eloc; |
606 | uint32_t elen; | 606 | uint32_t elen; |
607 | int8_t etype; | 607 | int8_t etype; |
608 | struct super_block *sb = inode->i_sb; | 608 | struct super_block *sb = inode->i_sb; |
609 | sector_t first_block = newsize >> sb->s_blocksize_bits, offset; | 609 | sector_t first_block = newsize >> sb->s_blocksize_bits, offset; |
610 | int adsize; | 610 | int adsize; |
611 | struct udf_inode_info *iinfo = UDF_I(inode); | 611 | struct udf_inode_info *iinfo = UDF_I(inode); |
612 | struct kernel_long_ad extent; | 612 | struct kernel_long_ad extent; |
613 | int err; | 613 | int err; |
614 | 614 | ||
615 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 615 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
616 | adsize = sizeof(struct short_ad); | 616 | adsize = sizeof(struct short_ad); |
617 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 617 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
618 | adsize = sizeof(struct long_ad); | 618 | adsize = sizeof(struct long_ad); |
619 | else | 619 | else |
620 | BUG(); | 620 | BUG(); |
621 | 621 | ||
622 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); | 622 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); |
623 | 623 | ||
624 | /* File has extent covering the new size (could happen when extending | 624 | /* File has extent covering the new size (could happen when extending |
625 | * inside a block)? */ | 625 | * inside a block)? */ |
626 | if (etype != -1) | 626 | if (etype != -1) |
627 | return 0; | 627 | return 0; |
628 | if (newsize & (sb->s_blocksize - 1)) | 628 | if (newsize & (sb->s_blocksize - 1)) |
629 | offset++; | 629 | offset++; |
630 | /* Extended file just to the boundary of the last file block? */ | 630 | /* Extended file just to the boundary of the last file block? */ |
631 | if (offset == 0) | 631 | if (offset == 0) |
632 | return 0; | 632 | return 0; |
633 | 633 | ||
634 | /* Truncate is extending the file by 'offset' blocks */ | 634 | /* Truncate is extending the file by 'offset' blocks */ |
635 | if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || | 635 | if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || |
636 | (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { | 636 | (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { |
637 | /* File has no extents at all or has empty last | 637 | /* File has no extents at all or has empty last |
638 | * indirect extent! Create a fake extent... */ | 638 | * indirect extent! Create a fake extent... */ |
639 | extent.extLocation.logicalBlockNum = 0; | 639 | extent.extLocation.logicalBlockNum = 0; |
640 | extent.extLocation.partitionReferenceNum = 0; | 640 | extent.extLocation.partitionReferenceNum = 0; |
641 | extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; | 641 | extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; |
642 | } else { | 642 | } else { |
643 | epos.offset -= adsize; | 643 | epos.offset -= adsize; |
644 | etype = udf_next_aext(inode, &epos, &extent.extLocation, | 644 | etype = udf_next_aext(inode, &epos, &extent.extLocation, |
645 | &extent.extLength, 0); | 645 | &extent.extLength, 0); |
646 | extent.extLength |= etype << 30; | 646 | extent.extLength |= etype << 30; |
647 | } | 647 | } |
648 | err = udf_do_extend_file(inode, &epos, &extent, offset); | 648 | err = udf_do_extend_file(inode, &epos, &extent, offset); |
649 | if (err < 0) | 649 | if (err < 0) |
650 | goto out; | 650 | goto out; |
651 | err = 0; | 651 | err = 0; |
652 | iinfo->i_lenExtents = newsize; | 652 | iinfo->i_lenExtents = newsize; |
653 | out: | 653 | out: |
654 | brelse(epos.bh); | 654 | brelse(epos.bh); |
655 | return err; | 655 | return err; |
656 | } | 656 | } |
657 | 657 | ||
658 | static sector_t inode_getblk(struct inode *inode, sector_t block, | 658 | static sector_t inode_getblk(struct inode *inode, sector_t block, |
659 | int *err, int *new) | 659 | int *err, int *new) |
660 | { | 660 | { |
661 | struct kernel_long_ad laarr[EXTENT_MERGE_SIZE]; | 661 | struct kernel_long_ad laarr[EXTENT_MERGE_SIZE]; |
662 | struct extent_position prev_epos, cur_epos, next_epos; | 662 | struct extent_position prev_epos, cur_epos, next_epos; |
663 | int count = 0, startnum = 0, endnum = 0; | 663 | int count = 0, startnum = 0, endnum = 0; |
664 | uint32_t elen = 0, tmpelen; | 664 | uint32_t elen = 0, tmpelen; |
665 | struct kernel_lb_addr eloc, tmpeloc; | 665 | struct kernel_lb_addr eloc, tmpeloc; |
666 | int c = 1; | 666 | int c = 1; |
667 | loff_t lbcount = 0, b_off = 0; | 667 | loff_t lbcount = 0, b_off = 0; |
668 | uint32_t newblocknum, newblock; | 668 | uint32_t newblocknum, newblock; |
669 | sector_t offset = 0; | 669 | sector_t offset = 0; |
670 | int8_t etype; | 670 | int8_t etype; |
671 | struct udf_inode_info *iinfo = UDF_I(inode); | 671 | struct udf_inode_info *iinfo = UDF_I(inode); |
672 | int goal = 0, pgoal = iinfo->i_location.logicalBlockNum; | 672 | int goal = 0, pgoal = iinfo->i_location.logicalBlockNum; |
673 | int lastblock = 0; | 673 | int lastblock = 0; |
674 | bool isBeyondEOF; | 674 | bool isBeyondEOF; |
675 | 675 | ||
676 | *err = 0; | 676 | *err = 0; |
677 | *new = 0; | 677 | *new = 0; |
678 | prev_epos.offset = udf_file_entry_alloc_offset(inode); | 678 | prev_epos.offset = udf_file_entry_alloc_offset(inode); |
679 | prev_epos.block = iinfo->i_location; | 679 | prev_epos.block = iinfo->i_location; |
680 | prev_epos.bh = NULL; | 680 | prev_epos.bh = NULL; |
681 | cur_epos = next_epos = prev_epos; | 681 | cur_epos = next_epos = prev_epos; |
682 | b_off = (loff_t)block << inode->i_sb->s_blocksize_bits; | 682 | b_off = (loff_t)block << inode->i_sb->s_blocksize_bits; |
683 | 683 | ||
684 | /* find the extent which contains the block we are looking for. | 684 | /* find the extent which contains the block we are looking for. |
685 | alternate between laarr[0] and laarr[1] for locations of the | 685 | alternate between laarr[0] and laarr[1] for locations of the |
686 | current extent, and the previous extent */ | 686 | current extent, and the previous extent */ |
687 | do { | 687 | do { |
688 | if (prev_epos.bh != cur_epos.bh) { | 688 | if (prev_epos.bh != cur_epos.bh) { |
689 | brelse(prev_epos.bh); | 689 | brelse(prev_epos.bh); |
690 | get_bh(cur_epos.bh); | 690 | get_bh(cur_epos.bh); |
691 | prev_epos.bh = cur_epos.bh; | 691 | prev_epos.bh = cur_epos.bh; |
692 | } | 692 | } |
693 | if (cur_epos.bh != next_epos.bh) { | 693 | if (cur_epos.bh != next_epos.bh) { |
694 | brelse(cur_epos.bh); | 694 | brelse(cur_epos.bh); |
695 | get_bh(next_epos.bh); | 695 | get_bh(next_epos.bh); |
696 | cur_epos.bh = next_epos.bh; | 696 | cur_epos.bh = next_epos.bh; |
697 | } | 697 | } |
698 | 698 | ||
699 | lbcount += elen; | 699 | lbcount += elen; |
700 | 700 | ||
701 | prev_epos.block = cur_epos.block; | 701 | prev_epos.block = cur_epos.block; |
702 | cur_epos.block = next_epos.block; | 702 | cur_epos.block = next_epos.block; |
703 | 703 | ||
704 | prev_epos.offset = cur_epos.offset; | 704 | prev_epos.offset = cur_epos.offset; |
705 | cur_epos.offset = next_epos.offset; | 705 | cur_epos.offset = next_epos.offset; |
706 | 706 | ||
707 | etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1); | 707 | etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1); |
708 | if (etype == -1) | 708 | if (etype == -1) |
709 | break; | 709 | break; |
710 | 710 | ||
711 | c = !c; | 711 | c = !c; |
712 | 712 | ||
713 | laarr[c].extLength = (etype << 30) | elen; | 713 | laarr[c].extLength = (etype << 30) | elen; |
714 | laarr[c].extLocation = eloc; | 714 | laarr[c].extLocation = eloc; |
715 | 715 | ||
716 | if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) | 716 | if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) |
717 | pgoal = eloc.logicalBlockNum + | 717 | pgoal = eloc.logicalBlockNum + |
718 | ((elen + inode->i_sb->s_blocksize - 1) >> | 718 | ((elen + inode->i_sb->s_blocksize - 1) >> |
719 | inode->i_sb->s_blocksize_bits); | 719 | inode->i_sb->s_blocksize_bits); |
720 | 720 | ||
721 | count++; | 721 | count++; |
722 | } while (lbcount + elen <= b_off); | 722 | } while (lbcount + elen <= b_off); |
723 | 723 | ||
724 | b_off -= lbcount; | 724 | b_off -= lbcount; |
725 | offset = b_off >> inode->i_sb->s_blocksize_bits; | 725 | offset = b_off >> inode->i_sb->s_blocksize_bits; |
726 | /* | 726 | /* |
727 | * Move prev_epos and cur_epos into indirect extent if we are at | 727 | * Move prev_epos and cur_epos into indirect extent if we are at |
728 | * the pointer to it | 728 | * the pointer to it |
729 | */ | 729 | */ |
730 | udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0); | 730 | udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0); |
731 | udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0); | 731 | udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0); |
732 | 732 | ||
733 | /* if the extent is allocated and recorded, return the block | 733 | /* if the extent is allocated and recorded, return the block |
734 | if the extent is not a multiple of the blocksize, round up */ | 734 | if the extent is not a multiple of the blocksize, round up */ |
735 | 735 | ||
736 | if (etype == (EXT_RECORDED_ALLOCATED >> 30)) { | 736 | if (etype == (EXT_RECORDED_ALLOCATED >> 30)) { |
737 | if (elen & (inode->i_sb->s_blocksize - 1)) { | 737 | if (elen & (inode->i_sb->s_blocksize - 1)) { |
738 | elen = EXT_RECORDED_ALLOCATED | | 738 | elen = EXT_RECORDED_ALLOCATED | |
739 | ((elen + inode->i_sb->s_blocksize - 1) & | 739 | ((elen + inode->i_sb->s_blocksize - 1) & |
740 | ~(inode->i_sb->s_blocksize - 1)); | 740 | ~(inode->i_sb->s_blocksize - 1)); |
741 | udf_write_aext(inode, &cur_epos, &eloc, elen, 1); | 741 | udf_write_aext(inode, &cur_epos, &eloc, elen, 1); |
742 | } | 742 | } |
743 | brelse(prev_epos.bh); | 743 | brelse(prev_epos.bh); |
744 | brelse(cur_epos.bh); | 744 | brelse(cur_epos.bh); |
745 | brelse(next_epos.bh); | 745 | brelse(next_epos.bh); |
746 | newblock = udf_get_lb_pblock(inode->i_sb, &eloc, offset); | 746 | newblock = udf_get_lb_pblock(inode->i_sb, &eloc, offset); |
747 | return newblock; | 747 | return newblock; |
748 | } | 748 | } |
749 | 749 | ||
750 | /* Are we beyond EOF? */ | 750 | /* Are we beyond EOF? */ |
751 | if (etype == -1) { | 751 | if (etype == -1) { |
752 | int ret; | 752 | int ret; |
753 | isBeyondEOF = 1; | 753 | isBeyondEOF = 1; |
754 | if (count) { | 754 | if (count) { |
755 | if (c) | 755 | if (c) |
756 | laarr[0] = laarr[1]; | 756 | laarr[0] = laarr[1]; |
757 | startnum = 1; | 757 | startnum = 1; |
758 | } else { | 758 | } else { |
759 | /* Create a fake extent when there's not one */ | 759 | /* Create a fake extent when there's not one */ |
760 | memset(&laarr[0].extLocation, 0x00, | 760 | memset(&laarr[0].extLocation, 0x00, |
761 | sizeof(struct kernel_lb_addr)); | 761 | sizeof(struct kernel_lb_addr)); |
762 | laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; | 762 | laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; |
763 | /* Will udf_do_extend_file() create real extent from | 763 | /* Will udf_do_extend_file() create real extent from |
764 | a fake one? */ | 764 | a fake one? */ |
765 | startnum = (offset > 0); | 765 | startnum = (offset > 0); |
766 | } | 766 | } |
767 | /* Create extents for the hole between EOF and offset */ | 767 | /* Create extents for the hole between EOF and offset */ |
768 | ret = udf_do_extend_file(inode, &prev_epos, laarr, offset); | 768 | ret = udf_do_extend_file(inode, &prev_epos, laarr, offset); |
769 | if (ret < 0) { | 769 | if (ret < 0) { |
770 | brelse(prev_epos.bh); | 770 | brelse(prev_epos.bh); |
771 | brelse(cur_epos.bh); | 771 | brelse(cur_epos.bh); |
772 | brelse(next_epos.bh); | 772 | brelse(next_epos.bh); |
773 | *err = ret; | 773 | *err = ret; |
774 | return 0; | 774 | return 0; |
775 | } | 775 | } |
776 | c = 0; | 776 | c = 0; |
777 | offset = 0; | 777 | offset = 0; |
778 | count += ret; | 778 | count += ret; |
779 | /* We are not covered by a preallocated extent? */ | 779 | /* We are not covered by a preallocated extent? */ |
780 | if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != | 780 | if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != |
781 | EXT_NOT_RECORDED_ALLOCATED) { | 781 | EXT_NOT_RECORDED_ALLOCATED) { |
782 | /* Is there any real extent? - otherwise we overwrite | 782 | /* Is there any real extent? - otherwise we overwrite |
783 | * the fake one... */ | 783 | * the fake one... */ |
784 | if (count) | 784 | if (count) |
785 | c = !c; | 785 | c = !c; |
786 | laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | 786 | laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
787 | inode->i_sb->s_blocksize; | 787 | inode->i_sb->s_blocksize; |
788 | memset(&laarr[c].extLocation, 0x00, | 788 | memset(&laarr[c].extLocation, 0x00, |
789 | sizeof(struct kernel_lb_addr)); | 789 | sizeof(struct kernel_lb_addr)); |
790 | count++; | 790 | count++; |
791 | } | 791 | } |
792 | endnum = c + 1; | 792 | endnum = c + 1; |
793 | lastblock = 1; | 793 | lastblock = 1; |
794 | } else { | 794 | } else { |
795 | isBeyondEOF = 0; | 795 | isBeyondEOF = 0; |
796 | endnum = startnum = ((count > 2) ? 2 : count); | 796 | endnum = startnum = ((count > 2) ? 2 : count); |
797 | 797 | ||
798 | /* if the current extent is in position 0, | 798 | /* if the current extent is in position 0, |
799 | swap it with the previous */ | 799 | swap it with the previous */ |
800 | if (!c && count != 1) { | 800 | if (!c && count != 1) { |
801 | laarr[2] = laarr[0]; | 801 | laarr[2] = laarr[0]; |
802 | laarr[0] = laarr[1]; | 802 | laarr[0] = laarr[1]; |
803 | laarr[1] = laarr[2]; | 803 | laarr[1] = laarr[2]; |
804 | c = 1; | 804 | c = 1; |
805 | } | 805 | } |
806 | 806 | ||
807 | /* if the current block is located in an extent, | 807 | /* if the current block is located in an extent, |
808 | read the next extent */ | 808 | read the next extent */ |
809 | etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0); | 809 | etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0); |
810 | if (etype != -1) { | 810 | if (etype != -1) { |
811 | laarr[c + 1].extLength = (etype << 30) | elen; | 811 | laarr[c + 1].extLength = (etype << 30) | elen; |
812 | laarr[c + 1].extLocation = eloc; | 812 | laarr[c + 1].extLocation = eloc; |
813 | count++; | 813 | count++; |
814 | startnum++; | 814 | startnum++; |
815 | endnum++; | 815 | endnum++; |
816 | } else | 816 | } else |
817 | lastblock = 1; | 817 | lastblock = 1; |
818 | } | 818 | } |
819 | 819 | ||
820 | /* if the current extent is not recorded but allocated, get the | 820 | /* if the current extent is not recorded but allocated, get the |
821 | * block in the extent corresponding to the requested block */ | 821 | * block in the extent corresponding to the requested block */ |
822 | if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) | 822 | if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) |
823 | newblocknum = laarr[c].extLocation.logicalBlockNum + offset; | 823 | newblocknum = laarr[c].extLocation.logicalBlockNum + offset; |
824 | else { /* otherwise, allocate a new block */ | 824 | else { /* otherwise, allocate a new block */ |
825 | if (iinfo->i_next_alloc_block == block) | 825 | if (iinfo->i_next_alloc_block == block) |
826 | goal = iinfo->i_next_alloc_goal; | 826 | goal = iinfo->i_next_alloc_goal; |
827 | 827 | ||
828 | if (!goal) { | 828 | if (!goal) { |
829 | if (!(goal = pgoal)) /* XXX: what was intended here? */ | 829 | if (!(goal = pgoal)) /* XXX: what was intended here? */ |
830 | goal = iinfo->i_location.logicalBlockNum + 1; | 830 | goal = iinfo->i_location.logicalBlockNum + 1; |
831 | } | 831 | } |
832 | 832 | ||
833 | newblocknum = udf_new_block(inode->i_sb, inode, | 833 | newblocknum = udf_new_block(inode->i_sb, inode, |
834 | iinfo->i_location.partitionReferenceNum, | 834 | iinfo->i_location.partitionReferenceNum, |
835 | goal, err); | 835 | goal, err); |
836 | if (!newblocknum) { | 836 | if (!newblocknum) { |
837 | brelse(prev_epos.bh); | 837 | brelse(prev_epos.bh); |
838 | brelse(cur_epos.bh); | 838 | brelse(cur_epos.bh); |
839 | brelse(next_epos.bh); | 839 | brelse(next_epos.bh); |
840 | *err = -ENOSPC; | 840 | *err = -ENOSPC; |
841 | return 0; | 841 | return 0; |
842 | } | 842 | } |
843 | if (isBeyondEOF) | 843 | if (isBeyondEOF) |
844 | iinfo->i_lenExtents += inode->i_sb->s_blocksize; | 844 | iinfo->i_lenExtents += inode->i_sb->s_blocksize; |
845 | } | 845 | } |
846 | 846 | ||
847 | /* if the extent the requsted block is located in contains multiple | 847 | /* if the extent the requsted block is located in contains multiple |
848 | * blocks, split the extent into at most three extents. blocks prior | 848 | * blocks, split the extent into at most three extents. blocks prior |
849 | * to requested block, requested block, and blocks after requested | 849 | * to requested block, requested block, and blocks after requested |
850 | * block */ | 850 | * block */ |
851 | udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum); | 851 | udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum); |
852 | 852 | ||
853 | #ifdef UDF_PREALLOCATE | 853 | #ifdef UDF_PREALLOCATE |
854 | /* We preallocate blocks only for regular files. It also makes sense | 854 | /* We preallocate blocks only for regular files. It also makes sense |
855 | * for directories but there's a problem when to drop the | 855 | * for directories but there's a problem when to drop the |
856 | * preallocation. We might use some delayed work for that but I feel | 856 | * preallocation. We might use some delayed work for that but I feel |
857 | * it's overengineering for a filesystem like UDF. */ | 857 | * it's overengineering for a filesystem like UDF. */ |
858 | if (S_ISREG(inode->i_mode)) | 858 | if (S_ISREG(inode->i_mode)) |
859 | udf_prealloc_extents(inode, c, lastblock, laarr, &endnum); | 859 | udf_prealloc_extents(inode, c, lastblock, laarr, &endnum); |
860 | #endif | 860 | #endif |
861 | 861 | ||
862 | /* merge any continuous blocks in laarr */ | 862 | /* merge any continuous blocks in laarr */ |
863 | udf_merge_extents(inode, laarr, &endnum); | 863 | udf_merge_extents(inode, laarr, &endnum); |
864 | 864 | ||
865 | /* write back the new extents, inserting new extents if the new number | 865 | /* write back the new extents, inserting new extents if the new number |
866 | * of extents is greater than the old number, and deleting extents if | 866 | * of extents is greater than the old number, and deleting extents if |
867 | * the new number of extents is less than the old number */ | 867 | * the new number of extents is less than the old number */ |
868 | udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); | 868 | udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); |
869 | 869 | ||
870 | brelse(prev_epos.bh); | 870 | brelse(prev_epos.bh); |
871 | brelse(cur_epos.bh); | 871 | brelse(cur_epos.bh); |
872 | brelse(next_epos.bh); | 872 | brelse(next_epos.bh); |
873 | 873 | ||
874 | newblock = udf_get_pblock(inode->i_sb, newblocknum, | 874 | newblock = udf_get_pblock(inode->i_sb, newblocknum, |
875 | iinfo->i_location.partitionReferenceNum, 0); | 875 | iinfo->i_location.partitionReferenceNum, 0); |
876 | if (!newblock) { | 876 | if (!newblock) { |
877 | *err = -EIO; | 877 | *err = -EIO; |
878 | return 0; | 878 | return 0; |
879 | } | 879 | } |
880 | *new = 1; | 880 | *new = 1; |
881 | iinfo->i_next_alloc_block = block; | 881 | iinfo->i_next_alloc_block = block; |
882 | iinfo->i_next_alloc_goal = newblocknum; | 882 | iinfo->i_next_alloc_goal = newblocknum; |
883 | inode->i_ctime = current_fs_time(inode->i_sb); | 883 | inode->i_ctime = current_fs_time(inode->i_sb); |
884 | 884 | ||
885 | if (IS_SYNC(inode)) | 885 | if (IS_SYNC(inode)) |
886 | udf_sync_inode(inode); | 886 | udf_sync_inode(inode); |
887 | else | 887 | else |
888 | mark_inode_dirty(inode); | 888 | mark_inode_dirty(inode); |
889 | 889 | ||
890 | return newblock; | 890 | return newblock; |
891 | } | 891 | } |
892 | 892 | ||
893 | static void udf_split_extents(struct inode *inode, int *c, int offset, | 893 | static void udf_split_extents(struct inode *inode, int *c, int offset, |
894 | int newblocknum, | 894 | int newblocknum, |
895 | struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], | 895 | struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], |
896 | int *endnum) | 896 | int *endnum) |
897 | { | 897 | { |
898 | unsigned long blocksize = inode->i_sb->s_blocksize; | 898 | unsigned long blocksize = inode->i_sb->s_blocksize; |
899 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; | 899 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; |
900 | 900 | ||
901 | if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) || | 901 | if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) || |
902 | (laarr[*c].extLength >> 30) == | 902 | (laarr[*c].extLength >> 30) == |
903 | (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) { | 903 | (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) { |
904 | int curr = *c; | 904 | int curr = *c; |
905 | int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) + | 905 | int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) + |
906 | blocksize - 1) >> blocksize_bits; | 906 | blocksize - 1) >> blocksize_bits; |
907 | int8_t etype = (laarr[curr].extLength >> 30); | 907 | int8_t etype = (laarr[curr].extLength >> 30); |
908 | 908 | ||
909 | if (blen == 1) | 909 | if (blen == 1) |
910 | ; | 910 | ; |
911 | else if (!offset || blen == offset + 1) { | 911 | else if (!offset || blen == offset + 1) { |
912 | laarr[curr + 2] = laarr[curr + 1]; | 912 | laarr[curr + 2] = laarr[curr + 1]; |
913 | laarr[curr + 1] = laarr[curr]; | 913 | laarr[curr + 1] = laarr[curr]; |
914 | } else { | 914 | } else { |
915 | laarr[curr + 3] = laarr[curr + 1]; | 915 | laarr[curr + 3] = laarr[curr + 1]; |
916 | laarr[curr + 2] = laarr[curr + 1] = laarr[curr]; | 916 | laarr[curr + 2] = laarr[curr + 1] = laarr[curr]; |
917 | } | 917 | } |
918 | 918 | ||
919 | if (offset) { | 919 | if (offset) { |
920 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { | 920 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { |
921 | udf_free_blocks(inode->i_sb, inode, | 921 | udf_free_blocks(inode->i_sb, inode, |
922 | &laarr[curr].extLocation, | 922 | &laarr[curr].extLocation, |
923 | 0, offset); | 923 | 0, offset); |
924 | laarr[curr].extLength = | 924 | laarr[curr].extLength = |
925 | EXT_NOT_RECORDED_NOT_ALLOCATED | | 925 | EXT_NOT_RECORDED_NOT_ALLOCATED | |
926 | (offset << blocksize_bits); | 926 | (offset << blocksize_bits); |
927 | laarr[curr].extLocation.logicalBlockNum = 0; | 927 | laarr[curr].extLocation.logicalBlockNum = 0; |
928 | laarr[curr].extLocation. | 928 | laarr[curr].extLocation. |
929 | partitionReferenceNum = 0; | 929 | partitionReferenceNum = 0; |
930 | } else | 930 | } else |
931 | laarr[curr].extLength = (etype << 30) | | 931 | laarr[curr].extLength = (etype << 30) | |
932 | (offset << blocksize_bits); | 932 | (offset << blocksize_bits); |
933 | curr++; | 933 | curr++; |
934 | (*c)++; | 934 | (*c)++; |
935 | (*endnum)++; | 935 | (*endnum)++; |
936 | } | 936 | } |
937 | 937 | ||
938 | laarr[curr].extLocation.logicalBlockNum = newblocknum; | 938 | laarr[curr].extLocation.logicalBlockNum = newblocknum; |
939 | if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) | 939 | if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) |
940 | laarr[curr].extLocation.partitionReferenceNum = | 940 | laarr[curr].extLocation.partitionReferenceNum = |
941 | UDF_I(inode)->i_location.partitionReferenceNum; | 941 | UDF_I(inode)->i_location.partitionReferenceNum; |
942 | laarr[curr].extLength = EXT_RECORDED_ALLOCATED | | 942 | laarr[curr].extLength = EXT_RECORDED_ALLOCATED | |
943 | blocksize; | 943 | blocksize; |
944 | curr++; | 944 | curr++; |
945 | 945 | ||
946 | if (blen != offset + 1) { | 946 | if (blen != offset + 1) { |
947 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) | 947 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) |
948 | laarr[curr].extLocation.logicalBlockNum += | 948 | laarr[curr].extLocation.logicalBlockNum += |
949 | offset + 1; | 949 | offset + 1; |
950 | laarr[curr].extLength = (etype << 30) | | 950 | laarr[curr].extLength = (etype << 30) | |
951 | ((blen - (offset + 1)) << blocksize_bits); | 951 | ((blen - (offset + 1)) << blocksize_bits); |
952 | curr++; | 952 | curr++; |
953 | (*endnum)++; | 953 | (*endnum)++; |
954 | } | 954 | } |
955 | } | 955 | } |
956 | } | 956 | } |
957 | 957 | ||
958 | static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, | 958 | static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, |
959 | struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], | 959 | struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], |
960 | int *endnum) | 960 | int *endnum) |
961 | { | 961 | { |
962 | int start, length = 0, currlength = 0, i; | 962 | int start, length = 0, currlength = 0, i; |
963 | 963 | ||
964 | if (*endnum >= (c + 1)) { | 964 | if (*endnum >= (c + 1)) { |
965 | if (!lastblock) | 965 | if (!lastblock) |
966 | return; | 966 | return; |
967 | else | 967 | else |
968 | start = c; | 968 | start = c; |
969 | } else { | 969 | } else { |
970 | if ((laarr[c + 1].extLength >> 30) == | 970 | if ((laarr[c + 1].extLength >> 30) == |
971 | (EXT_NOT_RECORDED_ALLOCATED >> 30)) { | 971 | (EXT_NOT_RECORDED_ALLOCATED >> 30)) { |
972 | start = c + 1; | 972 | start = c + 1; |
973 | length = currlength = | 973 | length = currlength = |
974 | (((laarr[c + 1].extLength & | 974 | (((laarr[c + 1].extLength & |
975 | UDF_EXTENT_LENGTH_MASK) + | 975 | UDF_EXTENT_LENGTH_MASK) + |
976 | inode->i_sb->s_blocksize - 1) >> | 976 | inode->i_sb->s_blocksize - 1) >> |
977 | inode->i_sb->s_blocksize_bits); | 977 | inode->i_sb->s_blocksize_bits); |
978 | } else | 978 | } else |
979 | start = c; | 979 | start = c; |
980 | } | 980 | } |
981 | 981 | ||
982 | for (i = start + 1; i <= *endnum; i++) { | 982 | for (i = start + 1; i <= *endnum; i++) { |
983 | if (i == *endnum) { | 983 | if (i == *endnum) { |
984 | if (lastblock) | 984 | if (lastblock) |
985 | length += UDF_DEFAULT_PREALLOC_BLOCKS; | 985 | length += UDF_DEFAULT_PREALLOC_BLOCKS; |
986 | } else if ((laarr[i].extLength >> 30) == | 986 | } else if ((laarr[i].extLength >> 30) == |
987 | (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) { | 987 | (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) { |
988 | length += (((laarr[i].extLength & | 988 | length += (((laarr[i].extLength & |
989 | UDF_EXTENT_LENGTH_MASK) + | 989 | UDF_EXTENT_LENGTH_MASK) + |
990 | inode->i_sb->s_blocksize - 1) >> | 990 | inode->i_sb->s_blocksize - 1) >> |
991 | inode->i_sb->s_blocksize_bits); | 991 | inode->i_sb->s_blocksize_bits); |
992 | } else | 992 | } else |
993 | break; | 993 | break; |
994 | } | 994 | } |
995 | 995 | ||
996 | if (length) { | 996 | if (length) { |
997 | int next = laarr[start].extLocation.logicalBlockNum + | 997 | int next = laarr[start].extLocation.logicalBlockNum + |
998 | (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) + | 998 | (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) + |
999 | inode->i_sb->s_blocksize - 1) >> | 999 | inode->i_sb->s_blocksize - 1) >> |
1000 | inode->i_sb->s_blocksize_bits); | 1000 | inode->i_sb->s_blocksize_bits); |
1001 | int numalloc = udf_prealloc_blocks(inode->i_sb, inode, | 1001 | int numalloc = udf_prealloc_blocks(inode->i_sb, inode, |
1002 | laarr[start].extLocation.partitionReferenceNum, | 1002 | laarr[start].extLocation.partitionReferenceNum, |
1003 | next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? | 1003 | next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? |
1004 | length : UDF_DEFAULT_PREALLOC_BLOCKS) - | 1004 | length : UDF_DEFAULT_PREALLOC_BLOCKS) - |
1005 | currlength); | 1005 | currlength); |
1006 | if (numalloc) { | 1006 | if (numalloc) { |
1007 | if (start == (c + 1)) | 1007 | if (start == (c + 1)) |
1008 | laarr[start].extLength += | 1008 | laarr[start].extLength += |
1009 | (numalloc << | 1009 | (numalloc << |
1010 | inode->i_sb->s_blocksize_bits); | 1010 | inode->i_sb->s_blocksize_bits); |
1011 | else { | 1011 | else { |
1012 | memmove(&laarr[c + 2], &laarr[c + 1], | 1012 | memmove(&laarr[c + 2], &laarr[c + 1], |
1013 | sizeof(struct long_ad) * (*endnum - (c + 1))); | 1013 | sizeof(struct long_ad) * (*endnum - (c + 1))); |
1014 | (*endnum)++; | 1014 | (*endnum)++; |
1015 | laarr[c + 1].extLocation.logicalBlockNum = next; | 1015 | laarr[c + 1].extLocation.logicalBlockNum = next; |
1016 | laarr[c + 1].extLocation.partitionReferenceNum = | 1016 | laarr[c + 1].extLocation.partitionReferenceNum = |
1017 | laarr[c].extLocation. | 1017 | laarr[c].extLocation. |
1018 | partitionReferenceNum; | 1018 | partitionReferenceNum; |
1019 | laarr[c + 1].extLength = | 1019 | laarr[c + 1].extLength = |
1020 | EXT_NOT_RECORDED_ALLOCATED | | 1020 | EXT_NOT_RECORDED_ALLOCATED | |
1021 | (numalloc << | 1021 | (numalloc << |
1022 | inode->i_sb->s_blocksize_bits); | 1022 | inode->i_sb->s_blocksize_bits); |
1023 | start = c + 1; | 1023 | start = c + 1; |
1024 | } | 1024 | } |
1025 | 1025 | ||
1026 | for (i = start + 1; numalloc && i < *endnum; i++) { | 1026 | for (i = start + 1; numalloc && i < *endnum; i++) { |
1027 | int elen = ((laarr[i].extLength & | 1027 | int elen = ((laarr[i].extLength & |
1028 | UDF_EXTENT_LENGTH_MASK) + | 1028 | UDF_EXTENT_LENGTH_MASK) + |
1029 | inode->i_sb->s_blocksize - 1) >> | 1029 | inode->i_sb->s_blocksize - 1) >> |
1030 | inode->i_sb->s_blocksize_bits; | 1030 | inode->i_sb->s_blocksize_bits; |
1031 | 1031 | ||
1032 | if (elen > numalloc) { | 1032 | if (elen > numalloc) { |
1033 | laarr[i].extLength -= | 1033 | laarr[i].extLength -= |
1034 | (numalloc << | 1034 | (numalloc << |
1035 | inode->i_sb->s_blocksize_bits); | 1035 | inode->i_sb->s_blocksize_bits); |
1036 | numalloc = 0; | 1036 | numalloc = 0; |
1037 | } else { | 1037 | } else { |
1038 | numalloc -= elen; | 1038 | numalloc -= elen; |
1039 | if (*endnum > (i + 1)) | 1039 | if (*endnum > (i + 1)) |
1040 | memmove(&laarr[i], | 1040 | memmove(&laarr[i], |
1041 | &laarr[i + 1], | 1041 | &laarr[i + 1], |
1042 | sizeof(struct long_ad) * | 1042 | sizeof(struct long_ad) * |
1043 | (*endnum - (i + 1))); | 1043 | (*endnum - (i + 1))); |
1044 | i--; | 1044 | i--; |
1045 | (*endnum)--; | 1045 | (*endnum)--; |
1046 | } | 1046 | } |
1047 | } | 1047 | } |
1048 | UDF_I(inode)->i_lenExtents += | 1048 | UDF_I(inode)->i_lenExtents += |
1049 | numalloc << inode->i_sb->s_blocksize_bits; | 1049 | numalloc << inode->i_sb->s_blocksize_bits; |
1050 | } | 1050 | } |
1051 | } | 1051 | } |
1052 | } | 1052 | } |
1053 | 1053 | ||
1054 | static void udf_merge_extents(struct inode *inode, | 1054 | static void udf_merge_extents(struct inode *inode, |
1055 | struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], | 1055 | struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], |
1056 | int *endnum) | 1056 | int *endnum) |
1057 | { | 1057 | { |
1058 | int i; | 1058 | int i; |
1059 | unsigned long blocksize = inode->i_sb->s_blocksize; | 1059 | unsigned long blocksize = inode->i_sb->s_blocksize; |
1060 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; | 1060 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; |
1061 | 1061 | ||
1062 | for (i = 0; i < (*endnum - 1); i++) { | 1062 | for (i = 0; i < (*endnum - 1); i++) { |
1063 | struct kernel_long_ad *li /*l[i]*/ = &laarr[i]; | 1063 | struct kernel_long_ad *li /*l[i]*/ = &laarr[i]; |
1064 | struct kernel_long_ad *lip1 /*l[i plus 1]*/ = &laarr[i + 1]; | 1064 | struct kernel_long_ad *lip1 /*l[i plus 1]*/ = &laarr[i + 1]; |
1065 | 1065 | ||
1066 | if (((li->extLength >> 30) == (lip1->extLength >> 30)) && | 1066 | if (((li->extLength >> 30) == (lip1->extLength >> 30)) && |
1067 | (((li->extLength >> 30) == | 1067 | (((li->extLength >> 30) == |
1068 | (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) || | 1068 | (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) || |
1069 | ((lip1->extLocation.logicalBlockNum - | 1069 | ((lip1->extLocation.logicalBlockNum - |
1070 | li->extLocation.logicalBlockNum) == | 1070 | li->extLocation.logicalBlockNum) == |
1071 | (((li->extLength & UDF_EXTENT_LENGTH_MASK) + | 1071 | (((li->extLength & UDF_EXTENT_LENGTH_MASK) + |
1072 | blocksize - 1) >> blocksize_bits)))) { | 1072 | blocksize - 1) >> blocksize_bits)))) { |
1073 | 1073 | ||
1074 | if (((li->extLength & UDF_EXTENT_LENGTH_MASK) + | 1074 | if (((li->extLength & UDF_EXTENT_LENGTH_MASK) + |
1075 | (lip1->extLength & UDF_EXTENT_LENGTH_MASK) + | 1075 | (lip1->extLength & UDF_EXTENT_LENGTH_MASK) + |
1076 | blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) { | 1076 | blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) { |
1077 | lip1->extLength = (lip1->extLength - | 1077 | lip1->extLength = (lip1->extLength - |
1078 | (li->extLength & | 1078 | (li->extLength & |
1079 | UDF_EXTENT_LENGTH_MASK) + | 1079 | UDF_EXTENT_LENGTH_MASK) + |
1080 | UDF_EXTENT_LENGTH_MASK) & | 1080 | UDF_EXTENT_LENGTH_MASK) & |
1081 | ~(blocksize - 1); | 1081 | ~(blocksize - 1); |
1082 | li->extLength = (li->extLength & | 1082 | li->extLength = (li->extLength & |
1083 | UDF_EXTENT_FLAG_MASK) + | 1083 | UDF_EXTENT_FLAG_MASK) + |
1084 | (UDF_EXTENT_LENGTH_MASK + 1) - | 1084 | (UDF_EXTENT_LENGTH_MASK + 1) - |
1085 | blocksize; | 1085 | blocksize; |
1086 | lip1->extLocation.logicalBlockNum = | 1086 | lip1->extLocation.logicalBlockNum = |
1087 | li->extLocation.logicalBlockNum + | 1087 | li->extLocation.logicalBlockNum + |
1088 | ((li->extLength & | 1088 | ((li->extLength & |
1089 | UDF_EXTENT_LENGTH_MASK) >> | 1089 | UDF_EXTENT_LENGTH_MASK) >> |
1090 | blocksize_bits); | 1090 | blocksize_bits); |
1091 | } else { | 1091 | } else { |
1092 | li->extLength = lip1->extLength + | 1092 | li->extLength = lip1->extLength + |
1093 | (((li->extLength & | 1093 | (((li->extLength & |
1094 | UDF_EXTENT_LENGTH_MASK) + | 1094 | UDF_EXTENT_LENGTH_MASK) + |
1095 | blocksize - 1) & ~(blocksize - 1)); | 1095 | blocksize - 1) & ~(blocksize - 1)); |
1096 | if (*endnum > (i + 2)) | 1096 | if (*endnum > (i + 2)) |
1097 | memmove(&laarr[i + 1], &laarr[i + 2], | 1097 | memmove(&laarr[i + 1], &laarr[i + 2], |
1098 | sizeof(struct long_ad) * | 1098 | sizeof(struct long_ad) * |
1099 | (*endnum - (i + 2))); | 1099 | (*endnum - (i + 2))); |
1100 | i--; | 1100 | i--; |
1101 | (*endnum)--; | 1101 | (*endnum)--; |
1102 | } | 1102 | } |
1103 | } else if (((li->extLength >> 30) == | 1103 | } else if (((li->extLength >> 30) == |
1104 | (EXT_NOT_RECORDED_ALLOCATED >> 30)) && | 1104 | (EXT_NOT_RECORDED_ALLOCATED >> 30)) && |
1105 | ((lip1->extLength >> 30) == | 1105 | ((lip1->extLength >> 30) == |
1106 | (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) { | 1106 | (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) { |
1107 | udf_free_blocks(inode->i_sb, inode, &li->extLocation, 0, | 1107 | udf_free_blocks(inode->i_sb, inode, &li->extLocation, 0, |
1108 | ((li->extLength & | 1108 | ((li->extLength & |
1109 | UDF_EXTENT_LENGTH_MASK) + | 1109 | UDF_EXTENT_LENGTH_MASK) + |
1110 | blocksize - 1) >> blocksize_bits); | 1110 | blocksize - 1) >> blocksize_bits); |
1111 | li->extLocation.logicalBlockNum = 0; | 1111 | li->extLocation.logicalBlockNum = 0; |
1112 | li->extLocation.partitionReferenceNum = 0; | 1112 | li->extLocation.partitionReferenceNum = 0; |
1113 | 1113 | ||
1114 | if (((li->extLength & UDF_EXTENT_LENGTH_MASK) + | 1114 | if (((li->extLength & UDF_EXTENT_LENGTH_MASK) + |
1115 | (lip1->extLength & UDF_EXTENT_LENGTH_MASK) + | 1115 | (lip1->extLength & UDF_EXTENT_LENGTH_MASK) + |
1116 | blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) { | 1116 | blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) { |
1117 | lip1->extLength = (lip1->extLength - | 1117 | lip1->extLength = (lip1->extLength - |
1118 | (li->extLength & | 1118 | (li->extLength & |
1119 | UDF_EXTENT_LENGTH_MASK) + | 1119 | UDF_EXTENT_LENGTH_MASK) + |
1120 | UDF_EXTENT_LENGTH_MASK) & | 1120 | UDF_EXTENT_LENGTH_MASK) & |
1121 | ~(blocksize - 1); | 1121 | ~(blocksize - 1); |
1122 | li->extLength = (li->extLength & | 1122 | li->extLength = (li->extLength & |
1123 | UDF_EXTENT_FLAG_MASK) + | 1123 | UDF_EXTENT_FLAG_MASK) + |
1124 | (UDF_EXTENT_LENGTH_MASK + 1) - | 1124 | (UDF_EXTENT_LENGTH_MASK + 1) - |
1125 | blocksize; | 1125 | blocksize; |
1126 | } else { | 1126 | } else { |
1127 | li->extLength = lip1->extLength + | 1127 | li->extLength = lip1->extLength + |
1128 | (((li->extLength & | 1128 | (((li->extLength & |
1129 | UDF_EXTENT_LENGTH_MASK) + | 1129 | UDF_EXTENT_LENGTH_MASK) + |
1130 | blocksize - 1) & ~(blocksize - 1)); | 1130 | blocksize - 1) & ~(blocksize - 1)); |
1131 | if (*endnum > (i + 2)) | 1131 | if (*endnum > (i + 2)) |
1132 | memmove(&laarr[i + 1], &laarr[i + 2], | 1132 | memmove(&laarr[i + 1], &laarr[i + 2], |
1133 | sizeof(struct long_ad) * | 1133 | sizeof(struct long_ad) * |
1134 | (*endnum - (i + 2))); | 1134 | (*endnum - (i + 2))); |
1135 | i--; | 1135 | i--; |
1136 | (*endnum)--; | 1136 | (*endnum)--; |
1137 | } | 1137 | } |
1138 | } else if ((li->extLength >> 30) == | 1138 | } else if ((li->extLength >> 30) == |
1139 | (EXT_NOT_RECORDED_ALLOCATED >> 30)) { | 1139 | (EXT_NOT_RECORDED_ALLOCATED >> 30)) { |
1140 | udf_free_blocks(inode->i_sb, inode, | 1140 | udf_free_blocks(inode->i_sb, inode, |
1141 | &li->extLocation, 0, | 1141 | &li->extLocation, 0, |
1142 | ((li->extLength & | 1142 | ((li->extLength & |
1143 | UDF_EXTENT_LENGTH_MASK) + | 1143 | UDF_EXTENT_LENGTH_MASK) + |
1144 | blocksize - 1) >> blocksize_bits); | 1144 | blocksize - 1) >> blocksize_bits); |
1145 | li->extLocation.logicalBlockNum = 0; | 1145 | li->extLocation.logicalBlockNum = 0; |
1146 | li->extLocation.partitionReferenceNum = 0; | 1146 | li->extLocation.partitionReferenceNum = 0; |
1147 | li->extLength = (li->extLength & | 1147 | li->extLength = (li->extLength & |
1148 | UDF_EXTENT_LENGTH_MASK) | | 1148 | UDF_EXTENT_LENGTH_MASK) | |
1149 | EXT_NOT_RECORDED_NOT_ALLOCATED; | 1149 | EXT_NOT_RECORDED_NOT_ALLOCATED; |
1150 | } | 1150 | } |
1151 | } | 1151 | } |
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | static void udf_update_extents(struct inode *inode, | 1154 | static void udf_update_extents(struct inode *inode, |
1155 | struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], | 1155 | struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], |
1156 | int startnum, int endnum, | 1156 | int startnum, int endnum, |
1157 | struct extent_position *epos) | 1157 | struct extent_position *epos) |
1158 | { | 1158 | { |
1159 | int start = 0, i; | 1159 | int start = 0, i; |
1160 | struct kernel_lb_addr tmploc; | 1160 | struct kernel_lb_addr tmploc; |
1161 | uint32_t tmplen; | 1161 | uint32_t tmplen; |
1162 | 1162 | ||
1163 | if (startnum > endnum) { | 1163 | if (startnum > endnum) { |
1164 | for (i = 0; i < (startnum - endnum); i++) | 1164 | for (i = 0; i < (startnum - endnum); i++) |
1165 | udf_delete_aext(inode, *epos, laarr[i].extLocation, | 1165 | udf_delete_aext(inode, *epos, laarr[i].extLocation, |
1166 | laarr[i].extLength); | 1166 | laarr[i].extLength); |
1167 | } else if (startnum < endnum) { | 1167 | } else if (startnum < endnum) { |
1168 | for (i = 0; i < (endnum - startnum); i++) { | 1168 | for (i = 0; i < (endnum - startnum); i++) { |
1169 | udf_insert_aext(inode, *epos, laarr[i].extLocation, | 1169 | udf_insert_aext(inode, *epos, laarr[i].extLocation, |
1170 | laarr[i].extLength); | 1170 | laarr[i].extLength); |
1171 | udf_next_aext(inode, epos, &laarr[i].extLocation, | 1171 | udf_next_aext(inode, epos, &laarr[i].extLocation, |
1172 | &laarr[i].extLength, 1); | 1172 | &laarr[i].extLength, 1); |
1173 | start++; | 1173 | start++; |
1174 | } | 1174 | } |
1175 | } | 1175 | } |
1176 | 1176 | ||
1177 | for (i = start; i < endnum; i++) { | 1177 | for (i = start; i < endnum; i++) { |
1178 | udf_next_aext(inode, epos, &tmploc, &tmplen, 0); | 1178 | udf_next_aext(inode, epos, &tmploc, &tmplen, 0); |
1179 | udf_write_aext(inode, epos, &laarr[i].extLocation, | 1179 | udf_write_aext(inode, epos, &laarr[i].extLocation, |
1180 | laarr[i].extLength, 1); | 1180 | laarr[i].extLength, 1); |
1181 | } | 1181 | } |
1182 | } | 1182 | } |
1183 | 1183 | ||
1184 | struct buffer_head *udf_bread(struct inode *inode, int block, | 1184 | struct buffer_head *udf_bread(struct inode *inode, int block, |
1185 | int create, int *err) | 1185 | int create, int *err) |
1186 | { | 1186 | { |
1187 | struct buffer_head *bh = NULL; | 1187 | struct buffer_head *bh = NULL; |
1188 | 1188 | ||
1189 | bh = udf_getblk(inode, block, create, err); | 1189 | bh = udf_getblk(inode, block, create, err); |
1190 | if (!bh) | 1190 | if (!bh) |
1191 | return NULL; | 1191 | return NULL; |
1192 | 1192 | ||
1193 | if (buffer_uptodate(bh)) | 1193 | if (buffer_uptodate(bh)) |
1194 | return bh; | 1194 | return bh; |
1195 | 1195 | ||
1196 | ll_rw_block(READ, 1, &bh); | 1196 | ll_rw_block(READ, 1, &bh); |
1197 | 1197 | ||
1198 | wait_on_buffer(bh); | 1198 | wait_on_buffer(bh); |
1199 | if (buffer_uptodate(bh)) | 1199 | if (buffer_uptodate(bh)) |
1200 | return bh; | 1200 | return bh; |
1201 | 1201 | ||
1202 | brelse(bh); | 1202 | brelse(bh); |
1203 | *err = -EIO; | 1203 | *err = -EIO; |
1204 | return NULL; | 1204 | return NULL; |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | int udf_setsize(struct inode *inode, loff_t newsize) | 1207 | int udf_setsize(struct inode *inode, loff_t newsize) |
1208 | { | 1208 | { |
1209 | int err; | 1209 | int err; |
1210 | struct udf_inode_info *iinfo; | 1210 | struct udf_inode_info *iinfo; |
1211 | int bsize = 1 << inode->i_blkbits; | 1211 | int bsize = 1 << inode->i_blkbits; |
1212 | 1212 | ||
1213 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 1213 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
1214 | S_ISLNK(inode->i_mode))) | 1214 | S_ISLNK(inode->i_mode))) |
1215 | return -EINVAL; | 1215 | return -EINVAL; |
1216 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 1216 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
1217 | return -EPERM; | 1217 | return -EPERM; |
1218 | 1218 | ||
1219 | iinfo = UDF_I(inode); | 1219 | iinfo = UDF_I(inode); |
1220 | if (newsize > inode->i_size) { | 1220 | if (newsize > inode->i_size) { |
1221 | down_write(&iinfo->i_data_sem); | 1221 | down_write(&iinfo->i_data_sem); |
1222 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1222 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1223 | if (bsize < | 1223 | if (bsize < |
1224 | (udf_file_entry_alloc_offset(inode) + newsize)) { | 1224 | (udf_file_entry_alloc_offset(inode) + newsize)) { |
1225 | err = udf_expand_file_adinicb(inode); | 1225 | err = udf_expand_file_adinicb(inode); |
1226 | if (err) | 1226 | if (err) |
1227 | return err; | 1227 | return err; |
1228 | down_write(&iinfo->i_data_sem); | 1228 | down_write(&iinfo->i_data_sem); |
1229 | } else { | 1229 | } else { |
1230 | iinfo->i_lenAlloc = newsize; | 1230 | iinfo->i_lenAlloc = newsize; |
1231 | goto set_size; | 1231 | goto set_size; |
1232 | } | 1232 | } |
1233 | } | 1233 | } |
1234 | err = udf_extend_file(inode, newsize); | 1234 | err = udf_extend_file(inode, newsize); |
1235 | if (err) { | 1235 | if (err) { |
1236 | up_write(&iinfo->i_data_sem); | 1236 | up_write(&iinfo->i_data_sem); |
1237 | return err; | 1237 | return err; |
1238 | } | 1238 | } |
1239 | set_size: | 1239 | set_size: |
1240 | truncate_setsize(inode, newsize); | 1240 | truncate_setsize(inode, newsize); |
1241 | up_write(&iinfo->i_data_sem); | 1241 | up_write(&iinfo->i_data_sem); |
1242 | } else { | 1242 | } else { |
1243 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1243 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1244 | down_write(&iinfo->i_data_sem); | 1244 | down_write(&iinfo->i_data_sem); |
1245 | udf_clear_extent_cache(inode); | 1245 | udf_clear_extent_cache(inode); |
1246 | memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + newsize, | 1246 | memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + newsize, |
1247 | 0x00, bsize - newsize - | 1247 | 0x00, bsize - newsize - |
1248 | udf_file_entry_alloc_offset(inode)); | 1248 | udf_file_entry_alloc_offset(inode)); |
1249 | iinfo->i_lenAlloc = newsize; | 1249 | iinfo->i_lenAlloc = newsize; |
1250 | truncate_setsize(inode, newsize); | 1250 | truncate_setsize(inode, newsize); |
1251 | up_write(&iinfo->i_data_sem); | 1251 | up_write(&iinfo->i_data_sem); |
1252 | goto update_time; | 1252 | goto update_time; |
1253 | } | 1253 | } |
1254 | err = block_truncate_page(inode->i_mapping, newsize, | 1254 | err = block_truncate_page(inode->i_mapping, newsize, |
1255 | udf_get_block); | 1255 | udf_get_block); |
1256 | if (err) | 1256 | if (err) |
1257 | return err; | 1257 | return err; |
1258 | down_write(&iinfo->i_data_sem); | 1258 | down_write(&iinfo->i_data_sem); |
1259 | udf_clear_extent_cache(inode); | 1259 | udf_clear_extent_cache(inode); |
1260 | truncate_setsize(inode, newsize); | 1260 | truncate_setsize(inode, newsize); |
1261 | udf_truncate_extents(inode); | 1261 | udf_truncate_extents(inode); |
1262 | up_write(&iinfo->i_data_sem); | 1262 | up_write(&iinfo->i_data_sem); |
1263 | } | 1263 | } |
1264 | update_time: | 1264 | update_time: |
1265 | inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); | 1265 | inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); |
1266 | if (IS_SYNC(inode)) | 1266 | if (IS_SYNC(inode)) |
1267 | udf_sync_inode(inode); | 1267 | udf_sync_inode(inode); |
1268 | else | 1268 | else |
1269 | mark_inode_dirty(inode); | 1269 | mark_inode_dirty(inode); |
1270 | return 0; | 1270 | return 0; |
1271 | } | 1271 | } |
1272 | 1272 | ||
1273 | /* | 1273 | /* |
1274 | * Maximum length of linked list formed by ICB hierarchy. The chosen number is | 1274 | * Maximum length of linked list formed by ICB hierarchy. The chosen number is |
1275 | * arbitrary - just that we hopefully don't limit any real use of rewritten | 1275 | * arbitrary - just that we hopefully don't limit any real use of rewritten |
1276 | * inode on write-once media but avoid looping for too long on corrupted media. | 1276 | * inode on write-once media but avoid looping for too long on corrupted media. |
1277 | */ | 1277 | */ |
1278 | #define UDF_MAX_ICB_NESTING 1024 | 1278 | #define UDF_MAX_ICB_NESTING 1024 |
1279 | 1279 | ||
1280 | static int udf_read_inode(struct inode *inode, bool hidden_inode) | 1280 | static int udf_read_inode(struct inode *inode, bool hidden_inode) |
1281 | { | 1281 | { |
1282 | struct buffer_head *bh = NULL; | 1282 | struct buffer_head *bh = NULL; |
1283 | struct fileEntry *fe; | 1283 | struct fileEntry *fe; |
1284 | struct extendedFileEntry *efe; | 1284 | struct extendedFileEntry *efe; |
1285 | uint16_t ident; | 1285 | uint16_t ident; |
1286 | struct udf_inode_info *iinfo = UDF_I(inode); | 1286 | struct udf_inode_info *iinfo = UDF_I(inode); |
1287 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); | 1287 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); |
1288 | struct kernel_lb_addr *iloc = &iinfo->i_location; | 1288 | struct kernel_lb_addr *iloc = &iinfo->i_location; |
1289 | unsigned int link_count; | 1289 | unsigned int link_count; |
1290 | unsigned int indirections = 0; | 1290 | unsigned int indirections = 0; |
1291 | int ret = -EIO; | 1291 | int ret = -EIO; |
1292 | 1292 | ||
1293 | reread: | 1293 | reread: |
1294 | if (iloc->logicalBlockNum >= | 1294 | if (iloc->logicalBlockNum >= |
1295 | sbi->s_partmaps[iloc->partitionReferenceNum].s_partition_len) { | 1295 | sbi->s_partmaps[iloc->partitionReferenceNum].s_partition_len) { |
1296 | udf_debug("block=%d, partition=%d out of range\n", | 1296 | udf_debug("block=%d, partition=%d out of range\n", |
1297 | iloc->logicalBlockNum, iloc->partitionReferenceNum); | 1297 | iloc->logicalBlockNum, iloc->partitionReferenceNum); |
1298 | return -EIO; | 1298 | return -EIO; |
1299 | } | 1299 | } |
1300 | 1300 | ||
1301 | /* | 1301 | /* |
1302 | * Set defaults, but the inode is still incomplete! | 1302 | * Set defaults, but the inode is still incomplete! |
1303 | * Note: get_new_inode() sets the following on a new inode: | 1303 | * Note: get_new_inode() sets the following on a new inode: |
1304 | * i_sb = sb | 1304 | * i_sb = sb |
1305 | * i_no = ino | 1305 | * i_no = ino |
1306 | * i_flags = sb->s_flags | 1306 | * i_flags = sb->s_flags |
1307 | * i_state = 0 | 1307 | * i_state = 0 |
1308 | * clean_inode(): zero fills and sets | 1308 | * clean_inode(): zero fills and sets |
1309 | * i_count = 1 | 1309 | * i_count = 1 |
1310 | * i_nlink = 1 | 1310 | * i_nlink = 1 |
1311 | * i_op = NULL; | 1311 | * i_op = NULL; |
1312 | */ | 1312 | */ |
1313 | bh = udf_read_ptagged(inode->i_sb, iloc, 0, &ident); | 1313 | bh = udf_read_ptagged(inode->i_sb, iloc, 0, &ident); |
1314 | if (!bh) { | 1314 | if (!bh) { |
1315 | udf_err(inode->i_sb, "(ino %ld) failed !bh\n", inode->i_ino); | 1315 | udf_err(inode->i_sb, "(ino %ld) failed !bh\n", inode->i_ino); |
1316 | return -EIO; | 1316 | return -EIO; |
1317 | } | 1317 | } |
1318 | 1318 | ||
1319 | if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE && | 1319 | if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE && |
1320 | ident != TAG_IDENT_USE) { | 1320 | ident != TAG_IDENT_USE) { |
1321 | udf_err(inode->i_sb, "(ino %ld) failed ident=%d\n", | 1321 | udf_err(inode->i_sb, "(ino %ld) failed ident=%d\n", |
1322 | inode->i_ino, ident); | 1322 | inode->i_ino, ident); |
1323 | goto out; | 1323 | goto out; |
1324 | } | 1324 | } |
1325 | 1325 | ||
1326 | fe = (struct fileEntry *)bh->b_data; | 1326 | fe = (struct fileEntry *)bh->b_data; |
1327 | efe = (struct extendedFileEntry *)bh->b_data; | 1327 | efe = (struct extendedFileEntry *)bh->b_data; |
1328 | 1328 | ||
1329 | if (fe->icbTag.strategyType == cpu_to_le16(4096)) { | 1329 | if (fe->icbTag.strategyType == cpu_to_le16(4096)) { |
1330 | struct buffer_head *ibh; | 1330 | struct buffer_head *ibh; |
1331 | 1331 | ||
1332 | ibh = udf_read_ptagged(inode->i_sb, iloc, 1, &ident); | 1332 | ibh = udf_read_ptagged(inode->i_sb, iloc, 1, &ident); |
1333 | if (ident == TAG_IDENT_IE && ibh) { | 1333 | if (ident == TAG_IDENT_IE && ibh) { |
1334 | struct kernel_lb_addr loc; | 1334 | struct kernel_lb_addr loc; |
1335 | struct indirectEntry *ie; | 1335 | struct indirectEntry *ie; |
1336 | 1336 | ||
1337 | ie = (struct indirectEntry *)ibh->b_data; | 1337 | ie = (struct indirectEntry *)ibh->b_data; |
1338 | loc = lelb_to_cpu(ie->indirectICB.extLocation); | 1338 | loc = lelb_to_cpu(ie->indirectICB.extLocation); |
1339 | 1339 | ||
1340 | if (ie->indirectICB.extLength) { | 1340 | if (ie->indirectICB.extLength) { |
1341 | brelse(ibh); | 1341 | brelse(ibh); |
1342 | memcpy(&iinfo->i_location, &loc, | 1342 | memcpy(&iinfo->i_location, &loc, |
1343 | sizeof(struct kernel_lb_addr)); | 1343 | sizeof(struct kernel_lb_addr)); |
1344 | if (++indirections > UDF_MAX_ICB_NESTING) { | 1344 | if (++indirections > UDF_MAX_ICB_NESTING) { |
1345 | udf_err(inode->i_sb, | 1345 | udf_err(inode->i_sb, |
1346 | "too many ICBs in ICB hierarchy" | 1346 | "too many ICBs in ICB hierarchy" |
1347 | " (max %d supported)\n", | 1347 | " (max %d supported)\n", |
1348 | UDF_MAX_ICB_NESTING); | 1348 | UDF_MAX_ICB_NESTING); |
1349 | goto out; | 1349 | goto out; |
1350 | } | 1350 | } |
1351 | brelse(bh); | 1351 | brelse(bh); |
1352 | goto reread; | 1352 | goto reread; |
1353 | } | 1353 | } |
1354 | } | 1354 | } |
1355 | brelse(ibh); | 1355 | brelse(ibh); |
1356 | } else if (fe->icbTag.strategyType != cpu_to_le16(4)) { | 1356 | } else if (fe->icbTag.strategyType != cpu_to_le16(4)) { |
1357 | udf_err(inode->i_sb, "unsupported strategy type: %d\n", | 1357 | udf_err(inode->i_sb, "unsupported strategy type: %d\n", |
1358 | le16_to_cpu(fe->icbTag.strategyType)); | 1358 | le16_to_cpu(fe->icbTag.strategyType)); |
1359 | goto out; | 1359 | goto out; |
1360 | } | 1360 | } |
1361 | if (fe->icbTag.strategyType == cpu_to_le16(4)) | 1361 | if (fe->icbTag.strategyType == cpu_to_le16(4)) |
1362 | iinfo->i_strat4096 = 0; | 1362 | iinfo->i_strat4096 = 0; |
1363 | else /* if (fe->icbTag.strategyType == cpu_to_le16(4096)) */ | 1363 | else /* if (fe->icbTag.strategyType == cpu_to_le16(4096)) */ |
1364 | iinfo->i_strat4096 = 1; | 1364 | iinfo->i_strat4096 = 1; |
1365 | 1365 | ||
1366 | iinfo->i_alloc_type = le16_to_cpu(fe->icbTag.flags) & | 1366 | iinfo->i_alloc_type = le16_to_cpu(fe->icbTag.flags) & |
1367 | ICBTAG_FLAG_AD_MASK; | 1367 | ICBTAG_FLAG_AD_MASK; |
1368 | iinfo->i_unique = 0; | 1368 | iinfo->i_unique = 0; |
1369 | iinfo->i_lenEAttr = 0; | 1369 | iinfo->i_lenEAttr = 0; |
1370 | iinfo->i_lenExtents = 0; | 1370 | iinfo->i_lenExtents = 0; |
1371 | iinfo->i_lenAlloc = 0; | 1371 | iinfo->i_lenAlloc = 0; |
1372 | iinfo->i_next_alloc_block = 0; | 1372 | iinfo->i_next_alloc_block = 0; |
1373 | iinfo->i_next_alloc_goal = 0; | 1373 | iinfo->i_next_alloc_goal = 0; |
1374 | if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) { | 1374 | if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) { |
1375 | iinfo->i_efe = 1; | 1375 | iinfo->i_efe = 1; |
1376 | iinfo->i_use = 0; | 1376 | iinfo->i_use = 0; |
1377 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - | 1377 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - |
1378 | sizeof(struct extendedFileEntry)); | 1378 | sizeof(struct extendedFileEntry)); |
1379 | if (ret) | 1379 | if (ret) |
1380 | goto out; | 1380 | goto out; |
1381 | memcpy(iinfo->i_ext.i_data, | 1381 | memcpy(iinfo->i_ext.i_data, |
1382 | bh->b_data + sizeof(struct extendedFileEntry), | 1382 | bh->b_data + sizeof(struct extendedFileEntry), |
1383 | inode->i_sb->s_blocksize - | 1383 | inode->i_sb->s_blocksize - |
1384 | sizeof(struct extendedFileEntry)); | 1384 | sizeof(struct extendedFileEntry)); |
1385 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) { | 1385 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) { |
1386 | iinfo->i_efe = 0; | 1386 | iinfo->i_efe = 0; |
1387 | iinfo->i_use = 0; | 1387 | iinfo->i_use = 0; |
1388 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - | 1388 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - |
1389 | sizeof(struct fileEntry)); | 1389 | sizeof(struct fileEntry)); |
1390 | if (ret) | 1390 | if (ret) |
1391 | goto out; | 1391 | goto out; |
1392 | memcpy(iinfo->i_ext.i_data, | 1392 | memcpy(iinfo->i_ext.i_data, |
1393 | bh->b_data + sizeof(struct fileEntry), | 1393 | bh->b_data + sizeof(struct fileEntry), |
1394 | inode->i_sb->s_blocksize - sizeof(struct fileEntry)); | 1394 | inode->i_sb->s_blocksize - sizeof(struct fileEntry)); |
1395 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) { | 1395 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) { |
1396 | iinfo->i_efe = 0; | 1396 | iinfo->i_efe = 0; |
1397 | iinfo->i_use = 1; | 1397 | iinfo->i_use = 1; |
1398 | iinfo->i_lenAlloc = le32_to_cpu( | 1398 | iinfo->i_lenAlloc = le32_to_cpu( |
1399 | ((struct unallocSpaceEntry *)bh->b_data)-> | 1399 | ((struct unallocSpaceEntry *)bh->b_data)-> |
1400 | lengthAllocDescs); | 1400 | lengthAllocDescs); |
1401 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - | 1401 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - |
1402 | sizeof(struct unallocSpaceEntry)); | 1402 | sizeof(struct unallocSpaceEntry)); |
1403 | if (ret) | 1403 | if (ret) |
1404 | goto out; | 1404 | goto out; |
1405 | memcpy(iinfo->i_ext.i_data, | 1405 | memcpy(iinfo->i_ext.i_data, |
1406 | bh->b_data + sizeof(struct unallocSpaceEntry), | 1406 | bh->b_data + sizeof(struct unallocSpaceEntry), |
1407 | inode->i_sb->s_blocksize - | 1407 | inode->i_sb->s_blocksize - |
1408 | sizeof(struct unallocSpaceEntry)); | 1408 | sizeof(struct unallocSpaceEntry)); |
1409 | return 0; | 1409 | return 0; |
1410 | } | 1410 | } |
1411 | 1411 | ||
1412 | ret = -EIO; | 1412 | ret = -EIO; |
1413 | read_lock(&sbi->s_cred_lock); | 1413 | read_lock(&sbi->s_cred_lock); |
1414 | i_uid_write(inode, le32_to_cpu(fe->uid)); | 1414 | i_uid_write(inode, le32_to_cpu(fe->uid)); |
1415 | if (!uid_valid(inode->i_uid) || | 1415 | if (!uid_valid(inode->i_uid) || |
1416 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) || | 1416 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) || |
1417 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_SET)) | 1417 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_SET)) |
1418 | inode->i_uid = UDF_SB(inode->i_sb)->s_uid; | 1418 | inode->i_uid = UDF_SB(inode->i_sb)->s_uid; |
1419 | 1419 | ||
1420 | i_gid_write(inode, le32_to_cpu(fe->gid)); | 1420 | i_gid_write(inode, le32_to_cpu(fe->gid)); |
1421 | if (!gid_valid(inode->i_gid) || | 1421 | if (!gid_valid(inode->i_gid) || |
1422 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_IGNORE) || | 1422 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_IGNORE) || |
1423 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) | 1423 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) |
1424 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; | 1424 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; |
1425 | 1425 | ||
1426 | if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY && | 1426 | if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY && |
1427 | sbi->s_fmode != UDF_INVALID_MODE) | 1427 | sbi->s_fmode != UDF_INVALID_MODE) |
1428 | inode->i_mode = sbi->s_fmode; | 1428 | inode->i_mode = sbi->s_fmode; |
1429 | else if (fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY && | 1429 | else if (fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY && |
1430 | sbi->s_dmode != UDF_INVALID_MODE) | 1430 | sbi->s_dmode != UDF_INVALID_MODE) |
1431 | inode->i_mode = sbi->s_dmode; | 1431 | inode->i_mode = sbi->s_dmode; |
1432 | else | 1432 | else |
1433 | inode->i_mode = udf_convert_permissions(fe); | 1433 | inode->i_mode = udf_convert_permissions(fe); |
1434 | inode->i_mode &= ~sbi->s_umask; | 1434 | inode->i_mode &= ~sbi->s_umask; |
1435 | read_unlock(&sbi->s_cred_lock); | 1435 | read_unlock(&sbi->s_cred_lock); |
1436 | 1436 | ||
1437 | link_count = le16_to_cpu(fe->fileLinkCount); | 1437 | link_count = le16_to_cpu(fe->fileLinkCount); |
1438 | if (!link_count) { | 1438 | if (!link_count) { |
1439 | if (!hidden_inode) { | 1439 | if (!hidden_inode) { |
1440 | ret = -ESTALE; | 1440 | ret = -ESTALE; |
1441 | goto out; | 1441 | goto out; |
1442 | } | 1442 | } |
1443 | link_count = 1; | 1443 | link_count = 1; |
1444 | } | 1444 | } |
1445 | set_nlink(inode, link_count); | 1445 | set_nlink(inode, link_count); |
1446 | 1446 | ||
1447 | inode->i_size = le64_to_cpu(fe->informationLength); | 1447 | inode->i_size = le64_to_cpu(fe->informationLength); |
1448 | iinfo->i_lenExtents = inode->i_size; | 1448 | iinfo->i_lenExtents = inode->i_size; |
1449 | 1449 | ||
1450 | if (iinfo->i_efe == 0) { | 1450 | if (iinfo->i_efe == 0) { |
1451 | inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << | 1451 | inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << |
1452 | (inode->i_sb->s_blocksize_bits - 9); | 1452 | (inode->i_sb->s_blocksize_bits - 9); |
1453 | 1453 | ||
1454 | if (!udf_disk_stamp_to_time(&inode->i_atime, fe->accessTime)) | 1454 | if (!udf_disk_stamp_to_time(&inode->i_atime, fe->accessTime)) |
1455 | inode->i_atime = sbi->s_record_time; | 1455 | inode->i_atime = sbi->s_record_time; |
1456 | 1456 | ||
1457 | if (!udf_disk_stamp_to_time(&inode->i_mtime, | 1457 | if (!udf_disk_stamp_to_time(&inode->i_mtime, |
1458 | fe->modificationTime)) | 1458 | fe->modificationTime)) |
1459 | inode->i_mtime = sbi->s_record_time; | 1459 | inode->i_mtime = sbi->s_record_time; |
1460 | 1460 | ||
1461 | if (!udf_disk_stamp_to_time(&inode->i_ctime, fe->attrTime)) | 1461 | if (!udf_disk_stamp_to_time(&inode->i_ctime, fe->attrTime)) |
1462 | inode->i_ctime = sbi->s_record_time; | 1462 | inode->i_ctime = sbi->s_record_time; |
1463 | 1463 | ||
1464 | iinfo->i_unique = le64_to_cpu(fe->uniqueID); | 1464 | iinfo->i_unique = le64_to_cpu(fe->uniqueID); |
1465 | iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); | 1465 | iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); |
1466 | iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs); | 1466 | iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs); |
1467 | iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint); | 1467 | iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint); |
1468 | } else { | 1468 | } else { |
1469 | inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << | 1469 | inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << |
1470 | (inode->i_sb->s_blocksize_bits - 9); | 1470 | (inode->i_sb->s_blocksize_bits - 9); |
1471 | 1471 | ||
1472 | if (!udf_disk_stamp_to_time(&inode->i_atime, efe->accessTime)) | 1472 | if (!udf_disk_stamp_to_time(&inode->i_atime, efe->accessTime)) |
1473 | inode->i_atime = sbi->s_record_time; | 1473 | inode->i_atime = sbi->s_record_time; |
1474 | 1474 | ||
1475 | if (!udf_disk_stamp_to_time(&inode->i_mtime, | 1475 | if (!udf_disk_stamp_to_time(&inode->i_mtime, |
1476 | efe->modificationTime)) | 1476 | efe->modificationTime)) |
1477 | inode->i_mtime = sbi->s_record_time; | 1477 | inode->i_mtime = sbi->s_record_time; |
1478 | 1478 | ||
1479 | if (!udf_disk_stamp_to_time(&iinfo->i_crtime, efe->createTime)) | 1479 | if (!udf_disk_stamp_to_time(&iinfo->i_crtime, efe->createTime)) |
1480 | iinfo->i_crtime = sbi->s_record_time; | 1480 | iinfo->i_crtime = sbi->s_record_time; |
1481 | 1481 | ||
1482 | if (!udf_disk_stamp_to_time(&inode->i_ctime, efe->attrTime)) | 1482 | if (!udf_disk_stamp_to_time(&inode->i_ctime, efe->attrTime)) |
1483 | inode->i_ctime = sbi->s_record_time; | 1483 | inode->i_ctime = sbi->s_record_time; |
1484 | 1484 | ||
1485 | iinfo->i_unique = le64_to_cpu(efe->uniqueID); | 1485 | iinfo->i_unique = le64_to_cpu(efe->uniqueID); |
1486 | iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); | 1486 | iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); |
1487 | iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs); | 1487 | iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs); |
1488 | iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint); | 1488 | iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint); |
1489 | } | 1489 | } |
1490 | inode->i_generation = iinfo->i_unique; | 1490 | inode->i_generation = iinfo->i_unique; |
1491 | 1491 | ||
1492 | /* Sanity checks for files in ICB so that we don't get confused later */ | ||
1493 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | ||
1494 | /* | ||
1495 | * For file in ICB data is stored in allocation descriptor | ||
1496 | * so sizes should match | ||
1497 | */ | ||
1498 | if (iinfo->i_lenAlloc != inode->i_size) | ||
1499 | goto out; | ||
1500 | /* File in ICB has to fit in there... */ | ||
1501 | if (inode->i_size > inode->i_sb->s_blocksize - | ||
1502 | udf_file_entry_alloc_offset(inode)) | ||
1503 | goto out; | ||
1504 | } | ||
1505 | |||
1492 | switch (fe->icbTag.fileType) { | 1506 | switch (fe->icbTag.fileType) { |
1493 | case ICBTAG_FILE_TYPE_DIRECTORY: | 1507 | case ICBTAG_FILE_TYPE_DIRECTORY: |
1494 | inode->i_op = &udf_dir_inode_operations; | 1508 | inode->i_op = &udf_dir_inode_operations; |
1495 | inode->i_fop = &udf_dir_operations; | 1509 | inode->i_fop = &udf_dir_operations; |
1496 | inode->i_mode |= S_IFDIR; | 1510 | inode->i_mode |= S_IFDIR; |
1497 | inc_nlink(inode); | 1511 | inc_nlink(inode); |
1498 | break; | 1512 | break; |
1499 | case ICBTAG_FILE_TYPE_REALTIME: | 1513 | case ICBTAG_FILE_TYPE_REALTIME: |
1500 | case ICBTAG_FILE_TYPE_REGULAR: | 1514 | case ICBTAG_FILE_TYPE_REGULAR: |
1501 | case ICBTAG_FILE_TYPE_UNDEF: | 1515 | case ICBTAG_FILE_TYPE_UNDEF: |
1502 | case ICBTAG_FILE_TYPE_VAT20: | 1516 | case ICBTAG_FILE_TYPE_VAT20: |
1503 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1517 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
1504 | inode->i_data.a_ops = &udf_adinicb_aops; | 1518 | inode->i_data.a_ops = &udf_adinicb_aops; |
1505 | else | 1519 | else |
1506 | inode->i_data.a_ops = &udf_aops; | 1520 | inode->i_data.a_ops = &udf_aops; |
1507 | inode->i_op = &udf_file_inode_operations; | 1521 | inode->i_op = &udf_file_inode_operations; |
1508 | inode->i_fop = &udf_file_operations; | 1522 | inode->i_fop = &udf_file_operations; |
1509 | inode->i_mode |= S_IFREG; | 1523 | inode->i_mode |= S_IFREG; |
1510 | break; | 1524 | break; |
1511 | case ICBTAG_FILE_TYPE_BLOCK: | 1525 | case ICBTAG_FILE_TYPE_BLOCK: |
1512 | inode->i_mode |= S_IFBLK; | 1526 | inode->i_mode |= S_IFBLK; |
1513 | break; | 1527 | break; |
1514 | case ICBTAG_FILE_TYPE_CHAR: | 1528 | case ICBTAG_FILE_TYPE_CHAR: |
1515 | inode->i_mode |= S_IFCHR; | 1529 | inode->i_mode |= S_IFCHR; |
1516 | break; | 1530 | break; |
1517 | case ICBTAG_FILE_TYPE_FIFO: | 1531 | case ICBTAG_FILE_TYPE_FIFO: |
1518 | init_special_inode(inode, inode->i_mode | S_IFIFO, 0); | 1532 | init_special_inode(inode, inode->i_mode | S_IFIFO, 0); |
1519 | break; | 1533 | break; |
1520 | case ICBTAG_FILE_TYPE_SOCKET: | 1534 | case ICBTAG_FILE_TYPE_SOCKET: |
1521 | init_special_inode(inode, inode->i_mode | S_IFSOCK, 0); | 1535 | init_special_inode(inode, inode->i_mode | S_IFSOCK, 0); |
1522 | break; | 1536 | break; |
1523 | case ICBTAG_FILE_TYPE_SYMLINK: | 1537 | case ICBTAG_FILE_TYPE_SYMLINK: |
1524 | inode->i_data.a_ops = &udf_symlink_aops; | 1538 | inode->i_data.a_ops = &udf_symlink_aops; |
1525 | inode->i_op = &udf_symlink_inode_operations; | 1539 | inode->i_op = &udf_symlink_inode_operations; |
1526 | inode->i_mode = S_IFLNK | S_IRWXUGO; | 1540 | inode->i_mode = S_IFLNK | S_IRWXUGO; |
1527 | break; | 1541 | break; |
1528 | case ICBTAG_FILE_TYPE_MAIN: | 1542 | case ICBTAG_FILE_TYPE_MAIN: |
1529 | udf_debug("METADATA FILE-----\n"); | 1543 | udf_debug("METADATA FILE-----\n"); |
1530 | break; | 1544 | break; |
1531 | case ICBTAG_FILE_TYPE_MIRROR: | 1545 | case ICBTAG_FILE_TYPE_MIRROR: |
1532 | udf_debug("METADATA MIRROR FILE-----\n"); | 1546 | udf_debug("METADATA MIRROR FILE-----\n"); |
1533 | break; | 1547 | break; |
1534 | case ICBTAG_FILE_TYPE_BITMAP: | 1548 | case ICBTAG_FILE_TYPE_BITMAP: |
1535 | udf_debug("METADATA BITMAP FILE-----\n"); | 1549 | udf_debug("METADATA BITMAP FILE-----\n"); |
1536 | break; | 1550 | break; |
1537 | default: | 1551 | default: |
1538 | udf_err(inode->i_sb, "(ino %ld) failed unknown file type=%d\n", | 1552 | udf_err(inode->i_sb, "(ino %ld) failed unknown file type=%d\n", |
1539 | inode->i_ino, fe->icbTag.fileType); | 1553 | inode->i_ino, fe->icbTag.fileType); |
1540 | goto out; | 1554 | goto out; |
1541 | } | 1555 | } |
1542 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { | 1556 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { |
1543 | struct deviceSpec *dsea = | 1557 | struct deviceSpec *dsea = |
1544 | (struct deviceSpec *)udf_get_extendedattr(inode, 12, 1); | 1558 | (struct deviceSpec *)udf_get_extendedattr(inode, 12, 1); |
1545 | if (dsea) { | 1559 | if (dsea) { |
1546 | init_special_inode(inode, inode->i_mode, | 1560 | init_special_inode(inode, inode->i_mode, |
1547 | MKDEV(le32_to_cpu(dsea->majorDeviceIdent), | 1561 | MKDEV(le32_to_cpu(dsea->majorDeviceIdent), |
1548 | le32_to_cpu(dsea->minorDeviceIdent))); | 1562 | le32_to_cpu(dsea->minorDeviceIdent))); |
1549 | /* Developer ID ??? */ | 1563 | /* Developer ID ??? */ |
1550 | } else | 1564 | } else |
1551 | goto out; | 1565 | goto out; |
1552 | } | 1566 | } |
1553 | ret = 0; | 1567 | ret = 0; |
1554 | out: | 1568 | out: |
1555 | brelse(bh); | 1569 | brelse(bh); |
1556 | return ret; | 1570 | return ret; |
1557 | } | 1571 | } |
1558 | 1572 | ||
1559 | static int udf_alloc_i_data(struct inode *inode, size_t size) | 1573 | static int udf_alloc_i_data(struct inode *inode, size_t size) |
1560 | { | 1574 | { |
1561 | struct udf_inode_info *iinfo = UDF_I(inode); | 1575 | struct udf_inode_info *iinfo = UDF_I(inode); |
1562 | iinfo->i_ext.i_data = kmalloc(size, GFP_KERNEL); | 1576 | iinfo->i_ext.i_data = kmalloc(size, GFP_KERNEL); |
1563 | 1577 | ||
1564 | if (!iinfo->i_ext.i_data) { | 1578 | if (!iinfo->i_ext.i_data) { |
1565 | udf_err(inode->i_sb, "(ino %ld) no free memory\n", | 1579 | udf_err(inode->i_sb, "(ino %ld) no free memory\n", |
1566 | inode->i_ino); | 1580 | inode->i_ino); |
1567 | return -ENOMEM; | 1581 | return -ENOMEM; |
1568 | } | 1582 | } |
1569 | 1583 | ||
1570 | return 0; | 1584 | return 0; |
1571 | } | 1585 | } |
1572 | 1586 | ||
1573 | static umode_t udf_convert_permissions(struct fileEntry *fe) | 1587 | static umode_t udf_convert_permissions(struct fileEntry *fe) |
1574 | { | 1588 | { |
1575 | umode_t mode; | 1589 | umode_t mode; |
1576 | uint32_t permissions; | 1590 | uint32_t permissions; |
1577 | uint32_t flags; | 1591 | uint32_t flags; |
1578 | 1592 | ||
1579 | permissions = le32_to_cpu(fe->permissions); | 1593 | permissions = le32_to_cpu(fe->permissions); |
1580 | flags = le16_to_cpu(fe->icbTag.flags); | 1594 | flags = le16_to_cpu(fe->icbTag.flags); |
1581 | 1595 | ||
1582 | mode = ((permissions) & S_IRWXO) | | 1596 | mode = ((permissions) & S_IRWXO) | |
1583 | ((permissions >> 2) & S_IRWXG) | | 1597 | ((permissions >> 2) & S_IRWXG) | |
1584 | ((permissions >> 4) & S_IRWXU) | | 1598 | ((permissions >> 4) & S_IRWXU) | |
1585 | ((flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) | | 1599 | ((flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) | |
1586 | ((flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) | | 1600 | ((flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) | |
1587 | ((flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0); | 1601 | ((flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0); |
1588 | 1602 | ||
1589 | return mode; | 1603 | return mode; |
1590 | } | 1604 | } |
1591 | 1605 | ||
1592 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) | 1606 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) |
1593 | { | 1607 | { |
1594 | return udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); | 1608 | return udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); |
1595 | } | 1609 | } |
1596 | 1610 | ||
1597 | static int udf_sync_inode(struct inode *inode) | 1611 | static int udf_sync_inode(struct inode *inode) |
1598 | { | 1612 | { |
1599 | return udf_update_inode(inode, 1); | 1613 | return udf_update_inode(inode, 1); |
1600 | } | 1614 | } |
1601 | 1615 | ||
1602 | static int udf_update_inode(struct inode *inode, int do_sync) | 1616 | static int udf_update_inode(struct inode *inode, int do_sync) |
1603 | { | 1617 | { |
1604 | struct buffer_head *bh = NULL; | 1618 | struct buffer_head *bh = NULL; |
1605 | struct fileEntry *fe; | 1619 | struct fileEntry *fe; |
1606 | struct extendedFileEntry *efe; | 1620 | struct extendedFileEntry *efe; |
1607 | uint64_t lb_recorded; | 1621 | uint64_t lb_recorded; |
1608 | uint32_t udfperms; | 1622 | uint32_t udfperms; |
1609 | uint16_t icbflags; | 1623 | uint16_t icbflags; |
1610 | uint16_t crclen; | 1624 | uint16_t crclen; |
1611 | int err = 0; | 1625 | int err = 0; |
1612 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); | 1626 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); |
1613 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; | 1627 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; |
1614 | struct udf_inode_info *iinfo = UDF_I(inode); | 1628 | struct udf_inode_info *iinfo = UDF_I(inode); |
1615 | 1629 | ||
1616 | bh = udf_tgetblk(inode->i_sb, | 1630 | bh = udf_tgetblk(inode->i_sb, |
1617 | udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0)); | 1631 | udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0)); |
1618 | if (!bh) { | 1632 | if (!bh) { |
1619 | udf_debug("getblk failure\n"); | 1633 | udf_debug("getblk failure\n"); |
1620 | return -ENOMEM; | 1634 | return -ENOMEM; |
1621 | } | 1635 | } |
1622 | 1636 | ||
1623 | lock_buffer(bh); | 1637 | lock_buffer(bh); |
1624 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); | 1638 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); |
1625 | fe = (struct fileEntry *)bh->b_data; | 1639 | fe = (struct fileEntry *)bh->b_data; |
1626 | efe = (struct extendedFileEntry *)bh->b_data; | 1640 | efe = (struct extendedFileEntry *)bh->b_data; |
1627 | 1641 | ||
1628 | if (iinfo->i_use) { | 1642 | if (iinfo->i_use) { |
1629 | struct unallocSpaceEntry *use = | 1643 | struct unallocSpaceEntry *use = |
1630 | (struct unallocSpaceEntry *)bh->b_data; | 1644 | (struct unallocSpaceEntry *)bh->b_data; |
1631 | 1645 | ||
1632 | use->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); | 1646 | use->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); |
1633 | memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), | 1647 | memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), |
1634 | iinfo->i_ext.i_data, inode->i_sb->s_blocksize - | 1648 | iinfo->i_ext.i_data, inode->i_sb->s_blocksize - |
1635 | sizeof(struct unallocSpaceEntry)); | 1649 | sizeof(struct unallocSpaceEntry)); |
1636 | use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE); | 1650 | use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE); |
1637 | use->descTag.tagLocation = | 1651 | use->descTag.tagLocation = |
1638 | cpu_to_le32(iinfo->i_location.logicalBlockNum); | 1652 | cpu_to_le32(iinfo->i_location.logicalBlockNum); |
1639 | crclen = sizeof(struct unallocSpaceEntry) + | 1653 | crclen = sizeof(struct unallocSpaceEntry) + |
1640 | iinfo->i_lenAlloc - sizeof(struct tag); | 1654 | iinfo->i_lenAlloc - sizeof(struct tag); |
1641 | use->descTag.descCRCLength = cpu_to_le16(crclen); | 1655 | use->descTag.descCRCLength = cpu_to_le16(crclen); |
1642 | use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use + | 1656 | use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use + |
1643 | sizeof(struct tag), | 1657 | sizeof(struct tag), |
1644 | crclen)); | 1658 | crclen)); |
1645 | use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); | 1659 | use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); |
1646 | 1660 | ||
1647 | goto out; | 1661 | goto out; |
1648 | } | 1662 | } |
1649 | 1663 | ||
1650 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) | 1664 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) |
1651 | fe->uid = cpu_to_le32(-1); | 1665 | fe->uid = cpu_to_le32(-1); |
1652 | else | 1666 | else |
1653 | fe->uid = cpu_to_le32(i_uid_read(inode)); | 1667 | fe->uid = cpu_to_le32(i_uid_read(inode)); |
1654 | 1668 | ||
1655 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET)) | 1669 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET)) |
1656 | fe->gid = cpu_to_le32(-1); | 1670 | fe->gid = cpu_to_le32(-1); |
1657 | else | 1671 | else |
1658 | fe->gid = cpu_to_le32(i_gid_read(inode)); | 1672 | fe->gid = cpu_to_le32(i_gid_read(inode)); |
1659 | 1673 | ||
1660 | udfperms = ((inode->i_mode & S_IRWXO)) | | 1674 | udfperms = ((inode->i_mode & S_IRWXO)) | |
1661 | ((inode->i_mode & S_IRWXG) << 2) | | 1675 | ((inode->i_mode & S_IRWXG) << 2) | |
1662 | ((inode->i_mode & S_IRWXU) << 4); | 1676 | ((inode->i_mode & S_IRWXU) << 4); |
1663 | 1677 | ||
1664 | udfperms |= (le32_to_cpu(fe->permissions) & | 1678 | udfperms |= (le32_to_cpu(fe->permissions) & |
1665 | (FE_PERM_O_DELETE | FE_PERM_O_CHATTR | | 1679 | (FE_PERM_O_DELETE | FE_PERM_O_CHATTR | |
1666 | FE_PERM_G_DELETE | FE_PERM_G_CHATTR | | 1680 | FE_PERM_G_DELETE | FE_PERM_G_CHATTR | |
1667 | FE_PERM_U_DELETE | FE_PERM_U_CHATTR)); | 1681 | FE_PERM_U_DELETE | FE_PERM_U_CHATTR)); |
1668 | fe->permissions = cpu_to_le32(udfperms); | 1682 | fe->permissions = cpu_to_le32(udfperms); |
1669 | 1683 | ||
1670 | if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0) | 1684 | if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0) |
1671 | fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1); | 1685 | fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1); |
1672 | else | 1686 | else |
1673 | fe->fileLinkCount = cpu_to_le16(inode->i_nlink); | 1687 | fe->fileLinkCount = cpu_to_le16(inode->i_nlink); |
1674 | 1688 | ||
1675 | fe->informationLength = cpu_to_le64(inode->i_size); | 1689 | fe->informationLength = cpu_to_le64(inode->i_size); |
1676 | 1690 | ||
1677 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { | 1691 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { |
1678 | struct regid *eid; | 1692 | struct regid *eid; |
1679 | struct deviceSpec *dsea = | 1693 | struct deviceSpec *dsea = |
1680 | (struct deviceSpec *)udf_get_extendedattr(inode, 12, 1); | 1694 | (struct deviceSpec *)udf_get_extendedattr(inode, 12, 1); |
1681 | if (!dsea) { | 1695 | if (!dsea) { |
1682 | dsea = (struct deviceSpec *) | 1696 | dsea = (struct deviceSpec *) |
1683 | udf_add_extendedattr(inode, | 1697 | udf_add_extendedattr(inode, |
1684 | sizeof(struct deviceSpec) + | 1698 | sizeof(struct deviceSpec) + |
1685 | sizeof(struct regid), 12, 0x3); | 1699 | sizeof(struct regid), 12, 0x3); |
1686 | dsea->attrType = cpu_to_le32(12); | 1700 | dsea->attrType = cpu_to_le32(12); |
1687 | dsea->attrSubtype = 1; | 1701 | dsea->attrSubtype = 1; |
1688 | dsea->attrLength = cpu_to_le32( | 1702 | dsea->attrLength = cpu_to_le32( |
1689 | sizeof(struct deviceSpec) + | 1703 | sizeof(struct deviceSpec) + |
1690 | sizeof(struct regid)); | 1704 | sizeof(struct regid)); |
1691 | dsea->impUseLength = cpu_to_le32(sizeof(struct regid)); | 1705 | dsea->impUseLength = cpu_to_le32(sizeof(struct regid)); |
1692 | } | 1706 | } |
1693 | eid = (struct regid *)dsea->impUse; | 1707 | eid = (struct regid *)dsea->impUse; |
1694 | memset(eid, 0, sizeof(struct regid)); | 1708 | memset(eid, 0, sizeof(struct regid)); |
1695 | strcpy(eid->ident, UDF_ID_DEVELOPER); | 1709 | strcpy(eid->ident, UDF_ID_DEVELOPER); |
1696 | eid->identSuffix[0] = UDF_OS_CLASS_UNIX; | 1710 | eid->identSuffix[0] = UDF_OS_CLASS_UNIX; |
1697 | eid->identSuffix[1] = UDF_OS_ID_LINUX; | 1711 | eid->identSuffix[1] = UDF_OS_ID_LINUX; |
1698 | dsea->majorDeviceIdent = cpu_to_le32(imajor(inode)); | 1712 | dsea->majorDeviceIdent = cpu_to_le32(imajor(inode)); |
1699 | dsea->minorDeviceIdent = cpu_to_le32(iminor(inode)); | 1713 | dsea->minorDeviceIdent = cpu_to_le32(iminor(inode)); |
1700 | } | 1714 | } |
1701 | 1715 | ||
1702 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1716 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
1703 | lb_recorded = 0; /* No extents => no blocks! */ | 1717 | lb_recorded = 0; /* No extents => no blocks! */ |
1704 | else | 1718 | else |
1705 | lb_recorded = | 1719 | lb_recorded = |
1706 | (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> | 1720 | (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> |
1707 | (blocksize_bits - 9); | 1721 | (blocksize_bits - 9); |
1708 | 1722 | ||
1709 | if (iinfo->i_efe == 0) { | 1723 | if (iinfo->i_efe == 0) { |
1710 | memcpy(bh->b_data + sizeof(struct fileEntry), | 1724 | memcpy(bh->b_data + sizeof(struct fileEntry), |
1711 | iinfo->i_ext.i_data, | 1725 | iinfo->i_ext.i_data, |
1712 | inode->i_sb->s_blocksize - sizeof(struct fileEntry)); | 1726 | inode->i_sb->s_blocksize - sizeof(struct fileEntry)); |
1713 | fe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); | 1727 | fe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); |
1714 | 1728 | ||
1715 | udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime); | 1729 | udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime); |
1716 | udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime); | 1730 | udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime); |
1717 | udf_time_to_disk_stamp(&fe->attrTime, inode->i_ctime); | 1731 | udf_time_to_disk_stamp(&fe->attrTime, inode->i_ctime); |
1718 | memset(&(fe->impIdent), 0, sizeof(struct regid)); | 1732 | memset(&(fe->impIdent), 0, sizeof(struct regid)); |
1719 | strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER); | 1733 | strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER); |
1720 | fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1734 | fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
1721 | fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1735 | fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
1722 | fe->uniqueID = cpu_to_le64(iinfo->i_unique); | 1736 | fe->uniqueID = cpu_to_le64(iinfo->i_unique); |
1723 | fe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr); | 1737 | fe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr); |
1724 | fe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); | 1738 | fe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); |
1725 | fe->checkpoint = cpu_to_le32(iinfo->i_checkpoint); | 1739 | fe->checkpoint = cpu_to_le32(iinfo->i_checkpoint); |
1726 | fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE); | 1740 | fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE); |
1727 | crclen = sizeof(struct fileEntry); | 1741 | crclen = sizeof(struct fileEntry); |
1728 | } else { | 1742 | } else { |
1729 | memcpy(bh->b_data + sizeof(struct extendedFileEntry), | 1743 | memcpy(bh->b_data + sizeof(struct extendedFileEntry), |
1730 | iinfo->i_ext.i_data, | 1744 | iinfo->i_ext.i_data, |
1731 | inode->i_sb->s_blocksize - | 1745 | inode->i_sb->s_blocksize - |
1732 | sizeof(struct extendedFileEntry)); | 1746 | sizeof(struct extendedFileEntry)); |
1733 | efe->objectSize = cpu_to_le64(inode->i_size); | 1747 | efe->objectSize = cpu_to_le64(inode->i_size); |
1734 | efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); | 1748 | efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); |
1735 | 1749 | ||
1736 | if (iinfo->i_crtime.tv_sec > inode->i_atime.tv_sec || | 1750 | if (iinfo->i_crtime.tv_sec > inode->i_atime.tv_sec || |
1737 | (iinfo->i_crtime.tv_sec == inode->i_atime.tv_sec && | 1751 | (iinfo->i_crtime.tv_sec == inode->i_atime.tv_sec && |
1738 | iinfo->i_crtime.tv_nsec > inode->i_atime.tv_nsec)) | 1752 | iinfo->i_crtime.tv_nsec > inode->i_atime.tv_nsec)) |
1739 | iinfo->i_crtime = inode->i_atime; | 1753 | iinfo->i_crtime = inode->i_atime; |
1740 | 1754 | ||
1741 | if (iinfo->i_crtime.tv_sec > inode->i_mtime.tv_sec || | 1755 | if (iinfo->i_crtime.tv_sec > inode->i_mtime.tv_sec || |
1742 | (iinfo->i_crtime.tv_sec == inode->i_mtime.tv_sec && | 1756 | (iinfo->i_crtime.tv_sec == inode->i_mtime.tv_sec && |
1743 | iinfo->i_crtime.tv_nsec > inode->i_mtime.tv_nsec)) | 1757 | iinfo->i_crtime.tv_nsec > inode->i_mtime.tv_nsec)) |
1744 | iinfo->i_crtime = inode->i_mtime; | 1758 | iinfo->i_crtime = inode->i_mtime; |
1745 | 1759 | ||
1746 | if (iinfo->i_crtime.tv_sec > inode->i_ctime.tv_sec || | 1760 | if (iinfo->i_crtime.tv_sec > inode->i_ctime.tv_sec || |
1747 | (iinfo->i_crtime.tv_sec == inode->i_ctime.tv_sec && | 1761 | (iinfo->i_crtime.tv_sec == inode->i_ctime.tv_sec && |
1748 | iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec)) | 1762 | iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec)) |
1749 | iinfo->i_crtime = inode->i_ctime; | 1763 | iinfo->i_crtime = inode->i_ctime; |
1750 | 1764 | ||
1751 | udf_time_to_disk_stamp(&efe->accessTime, inode->i_atime); | 1765 | udf_time_to_disk_stamp(&efe->accessTime, inode->i_atime); |
1752 | udf_time_to_disk_stamp(&efe->modificationTime, inode->i_mtime); | 1766 | udf_time_to_disk_stamp(&efe->modificationTime, inode->i_mtime); |
1753 | udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime); | 1767 | udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime); |
1754 | udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime); | 1768 | udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime); |
1755 | 1769 | ||
1756 | memset(&(efe->impIdent), 0, sizeof(struct regid)); | 1770 | memset(&(efe->impIdent), 0, sizeof(struct regid)); |
1757 | strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER); | 1771 | strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER); |
1758 | efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1772 | efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
1759 | efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1773 | efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
1760 | efe->uniqueID = cpu_to_le64(iinfo->i_unique); | 1774 | efe->uniqueID = cpu_to_le64(iinfo->i_unique); |
1761 | efe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr); | 1775 | efe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr); |
1762 | efe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); | 1776 | efe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); |
1763 | efe->checkpoint = cpu_to_le32(iinfo->i_checkpoint); | 1777 | efe->checkpoint = cpu_to_le32(iinfo->i_checkpoint); |
1764 | efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE); | 1778 | efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE); |
1765 | crclen = sizeof(struct extendedFileEntry); | 1779 | crclen = sizeof(struct extendedFileEntry); |
1766 | } | 1780 | } |
1767 | if (iinfo->i_strat4096) { | 1781 | if (iinfo->i_strat4096) { |
1768 | fe->icbTag.strategyType = cpu_to_le16(4096); | 1782 | fe->icbTag.strategyType = cpu_to_le16(4096); |
1769 | fe->icbTag.strategyParameter = cpu_to_le16(1); | 1783 | fe->icbTag.strategyParameter = cpu_to_le16(1); |
1770 | fe->icbTag.numEntries = cpu_to_le16(2); | 1784 | fe->icbTag.numEntries = cpu_to_le16(2); |
1771 | } else { | 1785 | } else { |
1772 | fe->icbTag.strategyType = cpu_to_le16(4); | 1786 | fe->icbTag.strategyType = cpu_to_le16(4); |
1773 | fe->icbTag.numEntries = cpu_to_le16(1); | 1787 | fe->icbTag.numEntries = cpu_to_le16(1); |
1774 | } | 1788 | } |
1775 | 1789 | ||
1776 | if (S_ISDIR(inode->i_mode)) | 1790 | if (S_ISDIR(inode->i_mode)) |
1777 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY; | 1791 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY; |
1778 | else if (S_ISREG(inode->i_mode)) | 1792 | else if (S_ISREG(inode->i_mode)) |
1779 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR; | 1793 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR; |
1780 | else if (S_ISLNK(inode->i_mode)) | 1794 | else if (S_ISLNK(inode->i_mode)) |
1781 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_SYMLINK; | 1795 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_SYMLINK; |
1782 | else if (S_ISBLK(inode->i_mode)) | 1796 | else if (S_ISBLK(inode->i_mode)) |
1783 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_BLOCK; | 1797 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_BLOCK; |
1784 | else if (S_ISCHR(inode->i_mode)) | 1798 | else if (S_ISCHR(inode->i_mode)) |
1785 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_CHAR; | 1799 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_CHAR; |
1786 | else if (S_ISFIFO(inode->i_mode)) | 1800 | else if (S_ISFIFO(inode->i_mode)) |
1787 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_FIFO; | 1801 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_FIFO; |
1788 | else if (S_ISSOCK(inode->i_mode)) | 1802 | else if (S_ISSOCK(inode->i_mode)) |
1789 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET; | 1803 | fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET; |
1790 | 1804 | ||
1791 | icbflags = iinfo->i_alloc_type | | 1805 | icbflags = iinfo->i_alloc_type | |
1792 | ((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) | | 1806 | ((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) | |
1793 | ((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) | | 1807 | ((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) | |
1794 | ((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) | | 1808 | ((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) | |
1795 | (le16_to_cpu(fe->icbTag.flags) & | 1809 | (le16_to_cpu(fe->icbTag.flags) & |
1796 | ~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID | | 1810 | ~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID | |
1797 | ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY)); | 1811 | ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY)); |
1798 | 1812 | ||
1799 | fe->icbTag.flags = cpu_to_le16(icbflags); | 1813 | fe->icbTag.flags = cpu_to_le16(icbflags); |
1800 | if (sbi->s_udfrev >= 0x0200) | 1814 | if (sbi->s_udfrev >= 0x0200) |
1801 | fe->descTag.descVersion = cpu_to_le16(3); | 1815 | fe->descTag.descVersion = cpu_to_le16(3); |
1802 | else | 1816 | else |
1803 | fe->descTag.descVersion = cpu_to_le16(2); | 1817 | fe->descTag.descVersion = cpu_to_le16(2); |
1804 | fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number); | 1818 | fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number); |
1805 | fe->descTag.tagLocation = cpu_to_le32( | 1819 | fe->descTag.tagLocation = cpu_to_le32( |
1806 | iinfo->i_location.logicalBlockNum); | 1820 | iinfo->i_location.logicalBlockNum); |
1807 | crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - sizeof(struct tag); | 1821 | crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - sizeof(struct tag); |
1808 | fe->descTag.descCRCLength = cpu_to_le16(crclen); | 1822 | fe->descTag.descCRCLength = cpu_to_le16(crclen); |
1809 | fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag), | 1823 | fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag), |
1810 | crclen)); | 1824 | crclen)); |
1811 | fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); | 1825 | fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); |
1812 | 1826 | ||
1813 | out: | 1827 | out: |
1814 | set_buffer_uptodate(bh); | 1828 | set_buffer_uptodate(bh); |
1815 | unlock_buffer(bh); | 1829 | unlock_buffer(bh); |
1816 | 1830 | ||
1817 | /* write the data blocks */ | 1831 | /* write the data blocks */ |
1818 | mark_buffer_dirty(bh); | 1832 | mark_buffer_dirty(bh); |
1819 | if (do_sync) { | 1833 | if (do_sync) { |
1820 | sync_dirty_buffer(bh); | 1834 | sync_dirty_buffer(bh); |
1821 | if (buffer_write_io_error(bh)) { | 1835 | if (buffer_write_io_error(bh)) { |
1822 | udf_warn(inode->i_sb, "IO error syncing udf inode [%08lx]\n", | 1836 | udf_warn(inode->i_sb, "IO error syncing udf inode [%08lx]\n", |
1823 | inode->i_ino); | 1837 | inode->i_ino); |
1824 | err = -EIO; | 1838 | err = -EIO; |
1825 | } | 1839 | } |
1826 | } | 1840 | } |
1827 | brelse(bh); | 1841 | brelse(bh); |
1828 | 1842 | ||
1829 | return err; | 1843 | return err; |
1830 | } | 1844 | } |
1831 | 1845 | ||
1832 | struct inode *__udf_iget(struct super_block *sb, struct kernel_lb_addr *ino, | 1846 | struct inode *__udf_iget(struct super_block *sb, struct kernel_lb_addr *ino, |
1833 | bool hidden_inode) | 1847 | bool hidden_inode) |
1834 | { | 1848 | { |
1835 | unsigned long block = udf_get_lb_pblock(sb, ino, 0); | 1849 | unsigned long block = udf_get_lb_pblock(sb, ino, 0); |
1836 | struct inode *inode = iget_locked(sb, block); | 1850 | struct inode *inode = iget_locked(sb, block); |
1837 | int err; | 1851 | int err; |
1838 | 1852 | ||
1839 | if (!inode) | 1853 | if (!inode) |
1840 | return ERR_PTR(-ENOMEM); | 1854 | return ERR_PTR(-ENOMEM); |
1841 | 1855 | ||
1842 | if (!(inode->i_state & I_NEW)) | 1856 | if (!(inode->i_state & I_NEW)) |
1843 | return inode; | 1857 | return inode; |
1844 | 1858 | ||
1845 | memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr)); | 1859 | memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr)); |
1846 | err = udf_read_inode(inode, hidden_inode); | 1860 | err = udf_read_inode(inode, hidden_inode); |
1847 | if (err < 0) { | 1861 | if (err < 0) { |
1848 | iget_failed(inode); | 1862 | iget_failed(inode); |
1849 | return ERR_PTR(err); | 1863 | return ERR_PTR(err); |
1850 | } | 1864 | } |
1851 | unlock_new_inode(inode); | 1865 | unlock_new_inode(inode); |
1852 | 1866 | ||
1853 | return inode; | 1867 | return inode; |
1854 | } | 1868 | } |
1855 | 1869 | ||
1856 | int udf_add_aext(struct inode *inode, struct extent_position *epos, | 1870 | int udf_add_aext(struct inode *inode, struct extent_position *epos, |
1857 | struct kernel_lb_addr *eloc, uint32_t elen, int inc) | 1871 | struct kernel_lb_addr *eloc, uint32_t elen, int inc) |
1858 | { | 1872 | { |
1859 | int adsize; | 1873 | int adsize; |
1860 | struct short_ad *sad = NULL; | 1874 | struct short_ad *sad = NULL; |
1861 | struct long_ad *lad = NULL; | 1875 | struct long_ad *lad = NULL; |
1862 | struct allocExtDesc *aed; | 1876 | struct allocExtDesc *aed; |
1863 | uint8_t *ptr; | 1877 | uint8_t *ptr; |
1864 | struct udf_inode_info *iinfo = UDF_I(inode); | 1878 | struct udf_inode_info *iinfo = UDF_I(inode); |
1865 | 1879 | ||
1866 | if (!epos->bh) | 1880 | if (!epos->bh) |
1867 | ptr = iinfo->i_ext.i_data + epos->offset - | 1881 | ptr = iinfo->i_ext.i_data + epos->offset - |
1868 | udf_file_entry_alloc_offset(inode) + | 1882 | udf_file_entry_alloc_offset(inode) + |
1869 | iinfo->i_lenEAttr; | 1883 | iinfo->i_lenEAttr; |
1870 | else | 1884 | else |
1871 | ptr = epos->bh->b_data + epos->offset; | 1885 | ptr = epos->bh->b_data + epos->offset; |
1872 | 1886 | ||
1873 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 1887 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
1874 | adsize = sizeof(struct short_ad); | 1888 | adsize = sizeof(struct short_ad); |
1875 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 1889 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
1876 | adsize = sizeof(struct long_ad); | 1890 | adsize = sizeof(struct long_ad); |
1877 | else | 1891 | else |
1878 | return -EIO; | 1892 | return -EIO; |
1879 | 1893 | ||
1880 | if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) { | 1894 | if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) { |
1881 | unsigned char *sptr, *dptr; | 1895 | unsigned char *sptr, *dptr; |
1882 | struct buffer_head *nbh; | 1896 | struct buffer_head *nbh; |
1883 | int err, loffset; | 1897 | int err, loffset; |
1884 | struct kernel_lb_addr obloc = epos->block; | 1898 | struct kernel_lb_addr obloc = epos->block; |
1885 | 1899 | ||
1886 | epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL, | 1900 | epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL, |
1887 | obloc.partitionReferenceNum, | 1901 | obloc.partitionReferenceNum, |
1888 | obloc.logicalBlockNum, &err); | 1902 | obloc.logicalBlockNum, &err); |
1889 | if (!epos->block.logicalBlockNum) | 1903 | if (!epos->block.logicalBlockNum) |
1890 | return -ENOSPC; | 1904 | return -ENOSPC; |
1891 | nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, | 1905 | nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, |
1892 | &epos->block, | 1906 | &epos->block, |
1893 | 0)); | 1907 | 0)); |
1894 | if (!nbh) | 1908 | if (!nbh) |
1895 | return -EIO; | 1909 | return -EIO; |
1896 | lock_buffer(nbh); | 1910 | lock_buffer(nbh); |
1897 | memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize); | 1911 | memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize); |
1898 | set_buffer_uptodate(nbh); | 1912 | set_buffer_uptodate(nbh); |
1899 | unlock_buffer(nbh); | 1913 | unlock_buffer(nbh); |
1900 | mark_buffer_dirty_inode(nbh, inode); | 1914 | mark_buffer_dirty_inode(nbh, inode); |
1901 | 1915 | ||
1902 | aed = (struct allocExtDesc *)(nbh->b_data); | 1916 | aed = (struct allocExtDesc *)(nbh->b_data); |
1903 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) | 1917 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) |
1904 | aed->previousAllocExtLocation = | 1918 | aed->previousAllocExtLocation = |
1905 | cpu_to_le32(obloc.logicalBlockNum); | 1919 | cpu_to_le32(obloc.logicalBlockNum); |
1906 | if (epos->offset + adsize > inode->i_sb->s_blocksize) { | 1920 | if (epos->offset + adsize > inode->i_sb->s_blocksize) { |
1907 | loffset = epos->offset; | 1921 | loffset = epos->offset; |
1908 | aed->lengthAllocDescs = cpu_to_le32(adsize); | 1922 | aed->lengthAllocDescs = cpu_to_le32(adsize); |
1909 | sptr = ptr - adsize; | 1923 | sptr = ptr - adsize; |
1910 | dptr = nbh->b_data + sizeof(struct allocExtDesc); | 1924 | dptr = nbh->b_data + sizeof(struct allocExtDesc); |
1911 | memcpy(dptr, sptr, adsize); | 1925 | memcpy(dptr, sptr, adsize); |
1912 | epos->offset = sizeof(struct allocExtDesc) + adsize; | 1926 | epos->offset = sizeof(struct allocExtDesc) + adsize; |
1913 | } else { | 1927 | } else { |
1914 | loffset = epos->offset + adsize; | 1928 | loffset = epos->offset + adsize; |
1915 | aed->lengthAllocDescs = cpu_to_le32(0); | 1929 | aed->lengthAllocDescs = cpu_to_le32(0); |
1916 | sptr = ptr; | 1930 | sptr = ptr; |
1917 | epos->offset = sizeof(struct allocExtDesc); | 1931 | epos->offset = sizeof(struct allocExtDesc); |
1918 | 1932 | ||
1919 | if (epos->bh) { | 1933 | if (epos->bh) { |
1920 | aed = (struct allocExtDesc *)epos->bh->b_data; | 1934 | aed = (struct allocExtDesc *)epos->bh->b_data; |
1921 | le32_add_cpu(&aed->lengthAllocDescs, adsize); | 1935 | le32_add_cpu(&aed->lengthAllocDescs, adsize); |
1922 | } else { | 1936 | } else { |
1923 | iinfo->i_lenAlloc += adsize; | 1937 | iinfo->i_lenAlloc += adsize; |
1924 | mark_inode_dirty(inode); | 1938 | mark_inode_dirty(inode); |
1925 | } | 1939 | } |
1926 | } | 1940 | } |
1927 | if (UDF_SB(inode->i_sb)->s_udfrev >= 0x0200) | 1941 | if (UDF_SB(inode->i_sb)->s_udfrev >= 0x0200) |
1928 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, | 1942 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, |
1929 | epos->block.logicalBlockNum, sizeof(struct tag)); | 1943 | epos->block.logicalBlockNum, sizeof(struct tag)); |
1930 | else | 1944 | else |
1931 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, | 1945 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, |
1932 | epos->block.logicalBlockNum, sizeof(struct tag)); | 1946 | epos->block.logicalBlockNum, sizeof(struct tag)); |
1933 | switch (iinfo->i_alloc_type) { | 1947 | switch (iinfo->i_alloc_type) { |
1934 | case ICBTAG_FLAG_AD_SHORT: | 1948 | case ICBTAG_FLAG_AD_SHORT: |
1935 | sad = (struct short_ad *)sptr; | 1949 | sad = (struct short_ad *)sptr; |
1936 | sad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS | | 1950 | sad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS | |
1937 | inode->i_sb->s_blocksize); | 1951 | inode->i_sb->s_blocksize); |
1938 | sad->extPosition = | 1952 | sad->extPosition = |
1939 | cpu_to_le32(epos->block.logicalBlockNum); | 1953 | cpu_to_le32(epos->block.logicalBlockNum); |
1940 | break; | 1954 | break; |
1941 | case ICBTAG_FLAG_AD_LONG: | 1955 | case ICBTAG_FLAG_AD_LONG: |
1942 | lad = (struct long_ad *)sptr; | 1956 | lad = (struct long_ad *)sptr; |
1943 | lad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS | | 1957 | lad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS | |
1944 | inode->i_sb->s_blocksize); | 1958 | inode->i_sb->s_blocksize); |
1945 | lad->extLocation = cpu_to_lelb(epos->block); | 1959 | lad->extLocation = cpu_to_lelb(epos->block); |
1946 | memset(lad->impUse, 0x00, sizeof(lad->impUse)); | 1960 | memset(lad->impUse, 0x00, sizeof(lad->impUse)); |
1947 | break; | 1961 | break; |
1948 | } | 1962 | } |
1949 | if (epos->bh) { | 1963 | if (epos->bh) { |
1950 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || | 1964 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || |
1951 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) | 1965 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) |
1952 | udf_update_tag(epos->bh->b_data, loffset); | 1966 | udf_update_tag(epos->bh->b_data, loffset); |
1953 | else | 1967 | else |
1954 | udf_update_tag(epos->bh->b_data, | 1968 | udf_update_tag(epos->bh->b_data, |
1955 | sizeof(struct allocExtDesc)); | 1969 | sizeof(struct allocExtDesc)); |
1956 | mark_buffer_dirty_inode(epos->bh, inode); | 1970 | mark_buffer_dirty_inode(epos->bh, inode); |
1957 | brelse(epos->bh); | 1971 | brelse(epos->bh); |
1958 | } else { | 1972 | } else { |
1959 | mark_inode_dirty(inode); | 1973 | mark_inode_dirty(inode); |
1960 | } | 1974 | } |
1961 | epos->bh = nbh; | 1975 | epos->bh = nbh; |
1962 | } | 1976 | } |
1963 | 1977 | ||
1964 | udf_write_aext(inode, epos, eloc, elen, inc); | 1978 | udf_write_aext(inode, epos, eloc, elen, inc); |
1965 | 1979 | ||
1966 | if (!epos->bh) { | 1980 | if (!epos->bh) { |
1967 | iinfo->i_lenAlloc += adsize; | 1981 | iinfo->i_lenAlloc += adsize; |
1968 | mark_inode_dirty(inode); | 1982 | mark_inode_dirty(inode); |
1969 | } else { | 1983 | } else { |
1970 | aed = (struct allocExtDesc *)epos->bh->b_data; | 1984 | aed = (struct allocExtDesc *)epos->bh->b_data; |
1971 | le32_add_cpu(&aed->lengthAllocDescs, adsize); | 1985 | le32_add_cpu(&aed->lengthAllocDescs, adsize); |
1972 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || | 1986 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || |
1973 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) | 1987 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) |
1974 | udf_update_tag(epos->bh->b_data, | 1988 | udf_update_tag(epos->bh->b_data, |
1975 | epos->offset + (inc ? 0 : adsize)); | 1989 | epos->offset + (inc ? 0 : adsize)); |
1976 | else | 1990 | else |
1977 | udf_update_tag(epos->bh->b_data, | 1991 | udf_update_tag(epos->bh->b_data, |
1978 | sizeof(struct allocExtDesc)); | 1992 | sizeof(struct allocExtDesc)); |
1979 | mark_buffer_dirty_inode(epos->bh, inode); | 1993 | mark_buffer_dirty_inode(epos->bh, inode); |
1980 | } | 1994 | } |
1981 | 1995 | ||
1982 | return 0; | 1996 | return 0; |
1983 | } | 1997 | } |
1984 | 1998 | ||
1985 | void udf_write_aext(struct inode *inode, struct extent_position *epos, | 1999 | void udf_write_aext(struct inode *inode, struct extent_position *epos, |
1986 | struct kernel_lb_addr *eloc, uint32_t elen, int inc) | 2000 | struct kernel_lb_addr *eloc, uint32_t elen, int inc) |
1987 | { | 2001 | { |
1988 | int adsize; | 2002 | int adsize; |
1989 | uint8_t *ptr; | 2003 | uint8_t *ptr; |
1990 | struct short_ad *sad; | 2004 | struct short_ad *sad; |
1991 | struct long_ad *lad; | 2005 | struct long_ad *lad; |
1992 | struct udf_inode_info *iinfo = UDF_I(inode); | 2006 | struct udf_inode_info *iinfo = UDF_I(inode); |
1993 | 2007 | ||
1994 | if (!epos->bh) | 2008 | if (!epos->bh) |
1995 | ptr = iinfo->i_ext.i_data + epos->offset - | 2009 | ptr = iinfo->i_ext.i_data + epos->offset - |
1996 | udf_file_entry_alloc_offset(inode) + | 2010 | udf_file_entry_alloc_offset(inode) + |
1997 | iinfo->i_lenEAttr; | 2011 | iinfo->i_lenEAttr; |
1998 | else | 2012 | else |
1999 | ptr = epos->bh->b_data + epos->offset; | 2013 | ptr = epos->bh->b_data + epos->offset; |
2000 | 2014 | ||
2001 | switch (iinfo->i_alloc_type) { | 2015 | switch (iinfo->i_alloc_type) { |
2002 | case ICBTAG_FLAG_AD_SHORT: | 2016 | case ICBTAG_FLAG_AD_SHORT: |
2003 | sad = (struct short_ad *)ptr; | 2017 | sad = (struct short_ad *)ptr; |
2004 | sad->extLength = cpu_to_le32(elen); | 2018 | sad->extLength = cpu_to_le32(elen); |
2005 | sad->extPosition = cpu_to_le32(eloc->logicalBlockNum); | 2019 | sad->extPosition = cpu_to_le32(eloc->logicalBlockNum); |
2006 | adsize = sizeof(struct short_ad); | 2020 | adsize = sizeof(struct short_ad); |
2007 | break; | 2021 | break; |
2008 | case ICBTAG_FLAG_AD_LONG: | 2022 | case ICBTAG_FLAG_AD_LONG: |
2009 | lad = (struct long_ad *)ptr; | 2023 | lad = (struct long_ad *)ptr; |
2010 | lad->extLength = cpu_to_le32(elen); | 2024 | lad->extLength = cpu_to_le32(elen); |
2011 | lad->extLocation = cpu_to_lelb(*eloc); | 2025 | lad->extLocation = cpu_to_lelb(*eloc); |
2012 | memset(lad->impUse, 0x00, sizeof(lad->impUse)); | 2026 | memset(lad->impUse, 0x00, sizeof(lad->impUse)); |
2013 | adsize = sizeof(struct long_ad); | 2027 | adsize = sizeof(struct long_ad); |
2014 | break; | 2028 | break; |
2015 | default: | 2029 | default: |
2016 | return; | 2030 | return; |
2017 | } | 2031 | } |
2018 | 2032 | ||
2019 | if (epos->bh) { | 2033 | if (epos->bh) { |
2020 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || | 2034 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || |
2021 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) { | 2035 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) { |
2022 | struct allocExtDesc *aed = | 2036 | struct allocExtDesc *aed = |
2023 | (struct allocExtDesc *)epos->bh->b_data; | 2037 | (struct allocExtDesc *)epos->bh->b_data; |
2024 | udf_update_tag(epos->bh->b_data, | 2038 | udf_update_tag(epos->bh->b_data, |
2025 | le32_to_cpu(aed->lengthAllocDescs) + | 2039 | le32_to_cpu(aed->lengthAllocDescs) + |
2026 | sizeof(struct allocExtDesc)); | 2040 | sizeof(struct allocExtDesc)); |
2027 | } | 2041 | } |
2028 | mark_buffer_dirty_inode(epos->bh, inode); | 2042 | mark_buffer_dirty_inode(epos->bh, inode); |
2029 | } else { | 2043 | } else { |
2030 | mark_inode_dirty(inode); | 2044 | mark_inode_dirty(inode); |
2031 | } | 2045 | } |
2032 | 2046 | ||
2033 | if (inc) | 2047 | if (inc) |
2034 | epos->offset += adsize; | 2048 | epos->offset += adsize; |
2035 | } | 2049 | } |
2036 | 2050 | ||
2037 | int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, | 2051 | int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, |
2038 | struct kernel_lb_addr *eloc, uint32_t *elen, int inc) | 2052 | struct kernel_lb_addr *eloc, uint32_t *elen, int inc) |
2039 | { | 2053 | { |
2040 | int8_t etype; | 2054 | int8_t etype; |
2041 | 2055 | ||
2042 | while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == | 2056 | while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == |
2043 | (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { | 2057 | (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { |
2044 | int block; | 2058 | int block; |
2045 | epos->block = *eloc; | 2059 | epos->block = *eloc; |
2046 | epos->offset = sizeof(struct allocExtDesc); | 2060 | epos->offset = sizeof(struct allocExtDesc); |
2047 | brelse(epos->bh); | 2061 | brelse(epos->bh); |
2048 | block = udf_get_lb_pblock(inode->i_sb, &epos->block, 0); | 2062 | block = udf_get_lb_pblock(inode->i_sb, &epos->block, 0); |
2049 | epos->bh = udf_tread(inode->i_sb, block); | 2063 | epos->bh = udf_tread(inode->i_sb, block); |
2050 | if (!epos->bh) { | 2064 | if (!epos->bh) { |
2051 | udf_debug("reading block %d failed!\n", block); | 2065 | udf_debug("reading block %d failed!\n", block); |
2052 | return -1; | 2066 | return -1; |
2053 | } | 2067 | } |
2054 | } | 2068 | } |
2055 | 2069 | ||
2056 | return etype; | 2070 | return etype; |
2057 | } | 2071 | } |
2058 | 2072 | ||
2059 | int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, | 2073 | int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, |
2060 | struct kernel_lb_addr *eloc, uint32_t *elen, int inc) | 2074 | struct kernel_lb_addr *eloc, uint32_t *elen, int inc) |
2061 | { | 2075 | { |
2062 | int alen; | 2076 | int alen; |
2063 | int8_t etype; | 2077 | int8_t etype; |
2064 | uint8_t *ptr; | 2078 | uint8_t *ptr; |
2065 | struct short_ad *sad; | 2079 | struct short_ad *sad; |
2066 | struct long_ad *lad; | 2080 | struct long_ad *lad; |
2067 | struct udf_inode_info *iinfo = UDF_I(inode); | 2081 | struct udf_inode_info *iinfo = UDF_I(inode); |
2068 | 2082 | ||
2069 | if (!epos->bh) { | 2083 | if (!epos->bh) { |
2070 | if (!epos->offset) | 2084 | if (!epos->offset) |
2071 | epos->offset = udf_file_entry_alloc_offset(inode); | 2085 | epos->offset = udf_file_entry_alloc_offset(inode); |
2072 | ptr = iinfo->i_ext.i_data + epos->offset - | 2086 | ptr = iinfo->i_ext.i_data + epos->offset - |
2073 | udf_file_entry_alloc_offset(inode) + | 2087 | udf_file_entry_alloc_offset(inode) + |
2074 | iinfo->i_lenEAttr; | 2088 | iinfo->i_lenEAttr; |
2075 | alen = udf_file_entry_alloc_offset(inode) + | 2089 | alen = udf_file_entry_alloc_offset(inode) + |
2076 | iinfo->i_lenAlloc; | 2090 | iinfo->i_lenAlloc; |
2077 | } else { | 2091 | } else { |
2078 | if (!epos->offset) | 2092 | if (!epos->offset) |
2079 | epos->offset = sizeof(struct allocExtDesc); | 2093 | epos->offset = sizeof(struct allocExtDesc); |
2080 | ptr = epos->bh->b_data + epos->offset; | 2094 | ptr = epos->bh->b_data + epos->offset; |
2081 | alen = sizeof(struct allocExtDesc) + | 2095 | alen = sizeof(struct allocExtDesc) + |
2082 | le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)-> | 2096 | le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)-> |
2083 | lengthAllocDescs); | 2097 | lengthAllocDescs); |
2084 | } | 2098 | } |
2085 | 2099 | ||
2086 | switch (iinfo->i_alloc_type) { | 2100 | switch (iinfo->i_alloc_type) { |
2087 | case ICBTAG_FLAG_AD_SHORT: | 2101 | case ICBTAG_FLAG_AD_SHORT: |
2088 | sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc); | 2102 | sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc); |
2089 | if (!sad) | 2103 | if (!sad) |
2090 | return -1; | 2104 | return -1; |
2091 | etype = le32_to_cpu(sad->extLength) >> 30; | 2105 | etype = le32_to_cpu(sad->extLength) >> 30; |
2092 | eloc->logicalBlockNum = le32_to_cpu(sad->extPosition); | 2106 | eloc->logicalBlockNum = le32_to_cpu(sad->extPosition); |
2093 | eloc->partitionReferenceNum = | 2107 | eloc->partitionReferenceNum = |
2094 | iinfo->i_location.partitionReferenceNum; | 2108 | iinfo->i_location.partitionReferenceNum; |
2095 | *elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK; | 2109 | *elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK; |
2096 | break; | 2110 | break; |
2097 | case ICBTAG_FLAG_AD_LONG: | 2111 | case ICBTAG_FLAG_AD_LONG: |
2098 | lad = udf_get_filelongad(ptr, alen, &epos->offset, inc); | 2112 | lad = udf_get_filelongad(ptr, alen, &epos->offset, inc); |
2099 | if (!lad) | 2113 | if (!lad) |
2100 | return -1; | 2114 | return -1; |
2101 | etype = le32_to_cpu(lad->extLength) >> 30; | 2115 | etype = le32_to_cpu(lad->extLength) >> 30; |
2102 | *eloc = lelb_to_cpu(lad->extLocation); | 2116 | *eloc = lelb_to_cpu(lad->extLocation); |
2103 | *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK; | 2117 | *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK; |
2104 | break; | 2118 | break; |
2105 | default: | 2119 | default: |
2106 | udf_debug("alloc_type = %d unsupported\n", iinfo->i_alloc_type); | 2120 | udf_debug("alloc_type = %d unsupported\n", iinfo->i_alloc_type); |
2107 | return -1; | 2121 | return -1; |
2108 | } | 2122 | } |
2109 | 2123 | ||
2110 | return etype; | 2124 | return etype; |
2111 | } | 2125 | } |
2112 | 2126 | ||
2113 | static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos, | 2127 | static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos, |
2114 | struct kernel_lb_addr neloc, uint32_t nelen) | 2128 | struct kernel_lb_addr neloc, uint32_t nelen) |
2115 | { | 2129 | { |
2116 | struct kernel_lb_addr oeloc; | 2130 | struct kernel_lb_addr oeloc; |
2117 | uint32_t oelen; | 2131 | uint32_t oelen; |
2118 | int8_t etype; | 2132 | int8_t etype; |
2119 | 2133 | ||
2120 | if (epos.bh) | 2134 | if (epos.bh) |
2121 | get_bh(epos.bh); | 2135 | get_bh(epos.bh); |
2122 | 2136 | ||
2123 | while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) { | 2137 | while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) { |
2124 | udf_write_aext(inode, &epos, &neloc, nelen, 1); | 2138 | udf_write_aext(inode, &epos, &neloc, nelen, 1); |
2125 | neloc = oeloc; | 2139 | neloc = oeloc; |
2126 | nelen = (etype << 30) | oelen; | 2140 | nelen = (etype << 30) | oelen; |
2127 | } | 2141 | } |
2128 | udf_add_aext(inode, &epos, &neloc, nelen, 1); | 2142 | udf_add_aext(inode, &epos, &neloc, nelen, 1); |
2129 | brelse(epos.bh); | 2143 | brelse(epos.bh); |
2130 | 2144 | ||
2131 | return (nelen >> 30); | 2145 | return (nelen >> 30); |
2132 | } | 2146 | } |
2133 | 2147 | ||
2134 | int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, | 2148 | int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, |
2135 | struct kernel_lb_addr eloc, uint32_t elen) | 2149 | struct kernel_lb_addr eloc, uint32_t elen) |
2136 | { | 2150 | { |
2137 | struct extent_position oepos; | 2151 | struct extent_position oepos; |
2138 | int adsize; | 2152 | int adsize; |
2139 | int8_t etype; | 2153 | int8_t etype; |
2140 | struct allocExtDesc *aed; | 2154 | struct allocExtDesc *aed; |
2141 | struct udf_inode_info *iinfo; | 2155 | struct udf_inode_info *iinfo; |
2142 | 2156 | ||
2143 | if (epos.bh) { | 2157 | if (epos.bh) { |
2144 | get_bh(epos.bh); | 2158 | get_bh(epos.bh); |
2145 | get_bh(epos.bh); | 2159 | get_bh(epos.bh); |
2146 | } | 2160 | } |
2147 | 2161 | ||
2148 | iinfo = UDF_I(inode); | 2162 | iinfo = UDF_I(inode); |
2149 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 2163 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
2150 | adsize = sizeof(struct short_ad); | 2164 | adsize = sizeof(struct short_ad); |
2151 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 2165 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
2152 | adsize = sizeof(struct long_ad); | 2166 | adsize = sizeof(struct long_ad); |
2153 | else | 2167 | else |
2154 | adsize = 0; | 2168 | adsize = 0; |
2155 | 2169 | ||
2156 | oepos = epos; | 2170 | oepos = epos; |
2157 | if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1) | 2171 | if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1) |
2158 | return -1; | 2172 | return -1; |
2159 | 2173 | ||
2160 | while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) { | 2174 | while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) { |
2161 | udf_write_aext(inode, &oepos, &eloc, (etype << 30) | elen, 1); | 2175 | udf_write_aext(inode, &oepos, &eloc, (etype << 30) | elen, 1); |
2162 | if (oepos.bh != epos.bh) { | 2176 | if (oepos.bh != epos.bh) { |
2163 | oepos.block = epos.block; | 2177 | oepos.block = epos.block; |
2164 | brelse(oepos.bh); | 2178 | brelse(oepos.bh); |
2165 | get_bh(epos.bh); | 2179 | get_bh(epos.bh); |
2166 | oepos.bh = epos.bh; | 2180 | oepos.bh = epos.bh; |
2167 | oepos.offset = epos.offset - adsize; | 2181 | oepos.offset = epos.offset - adsize; |
2168 | } | 2182 | } |
2169 | } | 2183 | } |
2170 | memset(&eloc, 0x00, sizeof(struct kernel_lb_addr)); | 2184 | memset(&eloc, 0x00, sizeof(struct kernel_lb_addr)); |
2171 | elen = 0; | 2185 | elen = 0; |
2172 | 2186 | ||
2173 | if (epos.bh != oepos.bh) { | 2187 | if (epos.bh != oepos.bh) { |
2174 | udf_free_blocks(inode->i_sb, inode, &epos.block, 0, 1); | 2188 | udf_free_blocks(inode->i_sb, inode, &epos.block, 0, 1); |
2175 | udf_write_aext(inode, &oepos, &eloc, elen, 1); | 2189 | udf_write_aext(inode, &oepos, &eloc, elen, 1); |
2176 | udf_write_aext(inode, &oepos, &eloc, elen, 1); | 2190 | udf_write_aext(inode, &oepos, &eloc, elen, 1); |
2177 | if (!oepos.bh) { | 2191 | if (!oepos.bh) { |
2178 | iinfo->i_lenAlloc -= (adsize * 2); | 2192 | iinfo->i_lenAlloc -= (adsize * 2); |
2179 | mark_inode_dirty(inode); | 2193 | mark_inode_dirty(inode); |
2180 | } else { | 2194 | } else { |
2181 | aed = (struct allocExtDesc *)oepos.bh->b_data; | 2195 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
2182 | le32_add_cpu(&aed->lengthAllocDescs, -(2 * adsize)); | 2196 | le32_add_cpu(&aed->lengthAllocDescs, -(2 * adsize)); |
2183 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || | 2197 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || |
2184 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) | 2198 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) |
2185 | udf_update_tag(oepos.bh->b_data, | 2199 | udf_update_tag(oepos.bh->b_data, |
2186 | oepos.offset - (2 * adsize)); | 2200 | oepos.offset - (2 * adsize)); |
2187 | else | 2201 | else |
2188 | udf_update_tag(oepos.bh->b_data, | 2202 | udf_update_tag(oepos.bh->b_data, |
2189 | sizeof(struct allocExtDesc)); | 2203 | sizeof(struct allocExtDesc)); |
2190 | mark_buffer_dirty_inode(oepos.bh, inode); | 2204 | mark_buffer_dirty_inode(oepos.bh, inode); |
2191 | } | 2205 | } |
2192 | } else { | 2206 | } else { |
2193 | udf_write_aext(inode, &oepos, &eloc, elen, 1); | 2207 | udf_write_aext(inode, &oepos, &eloc, elen, 1); |
2194 | if (!oepos.bh) { | 2208 | if (!oepos.bh) { |
2195 | iinfo->i_lenAlloc -= adsize; | 2209 | iinfo->i_lenAlloc -= adsize; |
2196 | mark_inode_dirty(inode); | 2210 | mark_inode_dirty(inode); |
2197 | } else { | 2211 | } else { |
2198 | aed = (struct allocExtDesc *)oepos.bh->b_data; | 2212 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
2199 | le32_add_cpu(&aed->lengthAllocDescs, -adsize); | 2213 | le32_add_cpu(&aed->lengthAllocDescs, -adsize); |
2200 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || | 2214 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || |
2201 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) | 2215 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) |
2202 | udf_update_tag(oepos.bh->b_data, | 2216 | udf_update_tag(oepos.bh->b_data, |
2203 | epos.offset - adsize); | 2217 | epos.offset - adsize); |
2204 | else | 2218 | else |
2205 | udf_update_tag(oepos.bh->b_data, | 2219 | udf_update_tag(oepos.bh->b_data, |
2206 | sizeof(struct allocExtDesc)); | 2220 | sizeof(struct allocExtDesc)); |
2207 | mark_buffer_dirty_inode(oepos.bh, inode); | 2221 | mark_buffer_dirty_inode(oepos.bh, inode); |
2208 | } | 2222 | } |
2209 | } | 2223 | } |
2210 | 2224 | ||
2211 | brelse(epos.bh); | 2225 | brelse(epos.bh); |
2212 | brelse(oepos.bh); | 2226 | brelse(oepos.bh); |
2213 | 2227 | ||
2214 | return (elen >> 30); | 2228 | return (elen >> 30); |
2215 | } | 2229 | } |
2216 | 2230 | ||
2217 | int8_t inode_bmap(struct inode *inode, sector_t block, | 2231 | int8_t inode_bmap(struct inode *inode, sector_t block, |
2218 | struct extent_position *pos, struct kernel_lb_addr *eloc, | 2232 | struct extent_position *pos, struct kernel_lb_addr *eloc, |
2219 | uint32_t *elen, sector_t *offset) | 2233 | uint32_t *elen, sector_t *offset) |
2220 | { | 2234 | { |
2221 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; | 2235 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; |
2222 | loff_t lbcount = 0, bcount = | 2236 | loff_t lbcount = 0, bcount = |
2223 | (loff_t) block << blocksize_bits; | 2237 | (loff_t) block << blocksize_bits; |
2224 | int8_t etype; | 2238 | int8_t etype; |
2225 | struct udf_inode_info *iinfo; | 2239 | struct udf_inode_info *iinfo; |
2226 | 2240 | ||
2227 | iinfo = UDF_I(inode); | 2241 | iinfo = UDF_I(inode); |
2228 | if (!udf_read_extent_cache(inode, bcount, &lbcount, pos)) { | 2242 | if (!udf_read_extent_cache(inode, bcount, &lbcount, pos)) { |
2229 | pos->offset = 0; | 2243 | pos->offset = 0; |
2230 | pos->block = iinfo->i_location; | 2244 | pos->block = iinfo->i_location; |
2231 | pos->bh = NULL; | 2245 | pos->bh = NULL; |
2232 | } | 2246 | } |
2233 | *elen = 0; | 2247 | *elen = 0; |
2234 | do { | 2248 | do { |
2235 | etype = udf_next_aext(inode, pos, eloc, elen, 1); | 2249 | etype = udf_next_aext(inode, pos, eloc, elen, 1); |
2236 | if (etype == -1) { | 2250 | if (etype == -1) { |
2237 | *offset = (bcount - lbcount) >> blocksize_bits; | 2251 | *offset = (bcount - lbcount) >> blocksize_bits; |
2238 | iinfo->i_lenExtents = lbcount; | 2252 | iinfo->i_lenExtents = lbcount; |
2239 | return -1; | 2253 | return -1; |
2240 | } | 2254 | } |
2241 | lbcount += *elen; | 2255 | lbcount += *elen; |
2242 | } while (lbcount <= bcount); | 2256 | } while (lbcount <= bcount); |
2243 | /* update extent cache */ | 2257 | /* update extent cache */ |
2244 | udf_update_extent_cache(inode, lbcount - *elen, pos, 1); | 2258 | udf_update_extent_cache(inode, lbcount - *elen, pos, 1); |
2245 | *offset = (bcount + *elen - lbcount) >> blocksize_bits; | 2259 | *offset = (bcount + *elen - lbcount) >> blocksize_bits; |
2246 | 2260 | ||
2247 | return etype; | 2261 | return etype; |
2248 | } | 2262 | } |
2249 | 2263 | ||
2250 | long udf_block_map(struct inode *inode, sector_t block) | 2264 | long udf_block_map(struct inode *inode, sector_t block) |
2251 | { | 2265 | { |
2252 | struct kernel_lb_addr eloc; | 2266 | struct kernel_lb_addr eloc; |
2253 | uint32_t elen; | 2267 | uint32_t elen; |
2254 | sector_t offset; | 2268 | sector_t offset; |
2255 | struct extent_position epos = {}; | 2269 | struct extent_position epos = {}; |
2256 | int ret; | 2270 | int ret; |
2257 | 2271 | ||
2258 | down_read(&UDF_I(inode)->i_data_sem); | 2272 | down_read(&UDF_I(inode)->i_data_sem); |
2259 | 2273 | ||
2260 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == | 2274 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == |
2261 | (EXT_RECORDED_ALLOCATED >> 30)) | 2275 | (EXT_RECORDED_ALLOCATED >> 30)) |
2262 | ret = udf_get_lb_pblock(inode->i_sb, &eloc, offset); | 2276 | ret = udf_get_lb_pblock(inode->i_sb, &eloc, offset); |
2263 | else | 2277 | else |
2264 | ret = 0; | 2278 | ret = 0; |
2265 | 2279 | ||
2266 | up_read(&UDF_I(inode)->i_data_sem); | 2280 | up_read(&UDF_I(inode)->i_data_sem); |
2267 | brelse(epos.bh); | 2281 | brelse(epos.bh); |
2268 | 2282 | ||
2269 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) | 2283 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) |
2270 | return udf_fixed_to_variable(ret); | 2284 | return udf_fixed_to_variable(ret); |
2271 | else | 2285 | else |
2272 | return ret; | 2286 | return ret; |
2273 | } | 2287 | } |
2274 | 2288 |
fs/udf/namei.c
1 | /* | 1 | /* |
2 | * namei.c | 2 | * namei.c |
3 | * | 3 | * |
4 | * PURPOSE | 4 | * PURPOSE |
5 | * Inode name handling routines for the OSTA-UDF(tm) filesystem. | 5 | * Inode name handling routines for the OSTA-UDF(tm) filesystem. |
6 | * | 6 | * |
7 | * COPYRIGHT | 7 | * COPYRIGHT |
8 | * This file is distributed under the terms of the GNU General Public | 8 | * This file is distributed under the terms of the GNU General Public |
9 | * License (GPL). Copies of the GPL can be obtained from: | 9 | * License (GPL). Copies of the GPL can be obtained from: |
10 | * ftp://prep.ai.mit.edu/pub/gnu/GPL | 10 | * ftp://prep.ai.mit.edu/pub/gnu/GPL |
11 | * Each contributing author retains all rights to their own work. | 11 | * Each contributing author retains all rights to their own work. |
12 | * | 12 | * |
13 | * (C) 1998-2004 Ben Fennema | 13 | * (C) 1998-2004 Ben Fennema |
14 | * (C) 1999-2000 Stelias Computing Inc | 14 | * (C) 1999-2000 Stelias Computing Inc |
15 | * | 15 | * |
16 | * HISTORY | 16 | * HISTORY |
17 | * | 17 | * |
18 | * 12/12/98 blf Created. Split out the lookup code from dir.c | 18 | * 12/12/98 blf Created. Split out the lookup code from dir.c |
19 | * 04/19/99 blf link, mknod, symlink support | 19 | * 04/19/99 blf link, mknod, symlink support |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include "udfdecl.h" | 22 | #include "udfdecl.h" |
23 | 23 | ||
24 | #include "udf_i.h" | 24 | #include "udf_i.h" |
25 | #include "udf_sb.h" | 25 | #include "udf_sb.h" |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
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/buffer_head.h> | 30 | #include <linux/buffer_head.h> |
31 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
32 | #include <linux/crc-itu-t.h> | 32 | #include <linux/crc-itu-t.h> |
33 | #include <linux/exportfs.h> | 33 | #include <linux/exportfs.h> |
34 | 34 | ||
35 | static inline int udf_match(int len1, const unsigned char *name1, int len2, | 35 | static inline int udf_match(int len1, const unsigned char *name1, int len2, |
36 | const unsigned char *name2) | 36 | const unsigned char *name2) |
37 | { | 37 | { |
38 | if (len1 != len2) | 38 | if (len1 != len2) |
39 | return 0; | 39 | return 0; |
40 | 40 | ||
41 | return !memcmp(name1, name2, len1); | 41 | return !memcmp(name1, name2, len1); |
42 | } | 42 | } |
43 | 43 | ||
44 | int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, | 44 | int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, |
45 | struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh, | 45 | struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh, |
46 | uint8_t *impuse, uint8_t *fileident) | 46 | uint8_t *impuse, uint8_t *fileident) |
47 | { | 47 | { |
48 | uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(struct tag); | 48 | uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(struct tag); |
49 | uint16_t crc; | 49 | uint16_t crc; |
50 | int offset; | 50 | int offset; |
51 | uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse); | 51 | uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse); |
52 | uint8_t lfi = cfi->lengthFileIdent; | 52 | uint8_t lfi = cfi->lengthFileIdent; |
53 | int padlen = fibh->eoffset - fibh->soffset - liu - lfi - | 53 | int padlen = fibh->eoffset - fibh->soffset - liu - lfi - |
54 | sizeof(struct fileIdentDesc); | 54 | sizeof(struct fileIdentDesc); |
55 | int adinicb = 0; | 55 | int adinicb = 0; |
56 | 56 | ||
57 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 57 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
58 | adinicb = 1; | 58 | adinicb = 1; |
59 | 59 | ||
60 | offset = fibh->soffset + sizeof(struct fileIdentDesc); | 60 | offset = fibh->soffset + sizeof(struct fileIdentDesc); |
61 | 61 | ||
62 | if (impuse) { | 62 | if (impuse) { |
63 | if (adinicb || (offset + liu < 0)) { | 63 | if (adinicb || (offset + liu < 0)) { |
64 | memcpy((uint8_t *)sfi->impUse, impuse, liu); | 64 | memcpy((uint8_t *)sfi->impUse, impuse, liu); |
65 | } else if (offset >= 0) { | 65 | } else if (offset >= 0) { |
66 | memcpy(fibh->ebh->b_data + offset, impuse, liu); | 66 | memcpy(fibh->ebh->b_data + offset, impuse, liu); |
67 | } else { | 67 | } else { |
68 | memcpy((uint8_t *)sfi->impUse, impuse, -offset); | 68 | memcpy((uint8_t *)sfi->impUse, impuse, -offset); |
69 | memcpy(fibh->ebh->b_data, impuse - offset, | 69 | memcpy(fibh->ebh->b_data, impuse - offset, |
70 | liu + offset); | 70 | liu + offset); |
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
74 | offset += liu; | 74 | offset += liu; |
75 | 75 | ||
76 | if (fileident) { | 76 | if (fileident) { |
77 | if (adinicb || (offset + lfi < 0)) { | 77 | if (adinicb || (offset + lfi < 0)) { |
78 | memcpy((uint8_t *)sfi->fileIdent + liu, fileident, lfi); | 78 | memcpy((uint8_t *)sfi->fileIdent + liu, fileident, lfi); |
79 | } else if (offset >= 0) { | 79 | } else if (offset >= 0) { |
80 | memcpy(fibh->ebh->b_data + offset, fileident, lfi); | 80 | memcpy(fibh->ebh->b_data + offset, fileident, lfi); |
81 | } else { | 81 | } else { |
82 | memcpy((uint8_t *)sfi->fileIdent + liu, fileident, | 82 | memcpy((uint8_t *)sfi->fileIdent + liu, fileident, |
83 | -offset); | 83 | -offset); |
84 | memcpy(fibh->ebh->b_data, fileident - offset, | 84 | memcpy(fibh->ebh->b_data, fileident - offset, |
85 | lfi + offset); | 85 | lfi + offset); |
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | offset += lfi; | 89 | offset += lfi; |
90 | 90 | ||
91 | if (adinicb || (offset + padlen < 0)) { | 91 | if (adinicb || (offset + padlen < 0)) { |
92 | memset((uint8_t *)sfi->padding + liu + lfi, 0x00, padlen); | 92 | memset((uint8_t *)sfi->padding + liu + lfi, 0x00, padlen); |
93 | } else if (offset >= 0) { | 93 | } else if (offset >= 0) { |
94 | memset(fibh->ebh->b_data + offset, 0x00, padlen); | 94 | memset(fibh->ebh->b_data + offset, 0x00, padlen); |
95 | } else { | 95 | } else { |
96 | memset((uint8_t *)sfi->padding + liu + lfi, 0x00, -offset); | 96 | memset((uint8_t *)sfi->padding + liu + lfi, 0x00, -offset); |
97 | memset(fibh->ebh->b_data, 0x00, padlen + offset); | 97 | memset(fibh->ebh->b_data, 0x00, padlen + offset); |
98 | } | 98 | } |
99 | 99 | ||
100 | crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(struct tag), | 100 | crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(struct tag), |
101 | sizeof(struct fileIdentDesc) - sizeof(struct tag)); | 101 | sizeof(struct fileIdentDesc) - sizeof(struct tag)); |
102 | 102 | ||
103 | if (fibh->sbh == fibh->ebh) { | 103 | if (fibh->sbh == fibh->ebh) { |
104 | crc = crc_itu_t(crc, (uint8_t *)sfi->impUse, | 104 | crc = crc_itu_t(crc, (uint8_t *)sfi->impUse, |
105 | crclen + sizeof(struct tag) - | 105 | crclen + sizeof(struct tag) - |
106 | sizeof(struct fileIdentDesc)); | 106 | sizeof(struct fileIdentDesc)); |
107 | } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) { | 107 | } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) { |
108 | crc = crc_itu_t(crc, fibh->ebh->b_data + | 108 | crc = crc_itu_t(crc, fibh->ebh->b_data + |
109 | sizeof(struct fileIdentDesc) + | 109 | sizeof(struct fileIdentDesc) + |
110 | fibh->soffset, | 110 | fibh->soffset, |
111 | crclen + sizeof(struct tag) - | 111 | crclen + sizeof(struct tag) - |
112 | sizeof(struct fileIdentDesc)); | 112 | sizeof(struct fileIdentDesc)); |
113 | } else { | 113 | } else { |
114 | crc = crc_itu_t(crc, (uint8_t *)sfi->impUse, | 114 | crc = crc_itu_t(crc, (uint8_t *)sfi->impUse, |
115 | -fibh->soffset - sizeof(struct fileIdentDesc)); | 115 | -fibh->soffset - sizeof(struct fileIdentDesc)); |
116 | crc = crc_itu_t(crc, fibh->ebh->b_data, fibh->eoffset); | 116 | crc = crc_itu_t(crc, fibh->ebh->b_data, fibh->eoffset); |
117 | } | 117 | } |
118 | 118 | ||
119 | cfi->descTag.descCRC = cpu_to_le16(crc); | 119 | cfi->descTag.descCRC = cpu_to_le16(crc); |
120 | cfi->descTag.descCRCLength = cpu_to_le16(crclen); | 120 | cfi->descTag.descCRCLength = cpu_to_le16(crclen); |
121 | cfi->descTag.tagChecksum = udf_tag_checksum(&cfi->descTag); | 121 | cfi->descTag.tagChecksum = udf_tag_checksum(&cfi->descTag); |
122 | 122 | ||
123 | if (adinicb || (sizeof(struct fileIdentDesc) <= -fibh->soffset)) { | 123 | if (adinicb || (sizeof(struct fileIdentDesc) <= -fibh->soffset)) { |
124 | memcpy((uint8_t *)sfi, (uint8_t *)cfi, | 124 | memcpy((uint8_t *)sfi, (uint8_t *)cfi, |
125 | sizeof(struct fileIdentDesc)); | 125 | sizeof(struct fileIdentDesc)); |
126 | } else { | 126 | } else { |
127 | memcpy((uint8_t *)sfi, (uint8_t *)cfi, -fibh->soffset); | 127 | memcpy((uint8_t *)sfi, (uint8_t *)cfi, -fibh->soffset); |
128 | memcpy(fibh->ebh->b_data, (uint8_t *)cfi - fibh->soffset, | 128 | memcpy(fibh->ebh->b_data, (uint8_t *)cfi - fibh->soffset, |
129 | sizeof(struct fileIdentDesc) + fibh->soffset); | 129 | sizeof(struct fileIdentDesc) + fibh->soffset); |
130 | } | 130 | } |
131 | 131 | ||
132 | if (adinicb) { | 132 | if (adinicb) { |
133 | mark_inode_dirty(inode); | 133 | mark_inode_dirty(inode); |
134 | } else { | 134 | } else { |
135 | if (fibh->sbh != fibh->ebh) | 135 | if (fibh->sbh != fibh->ebh) |
136 | mark_buffer_dirty_inode(fibh->ebh, inode); | 136 | mark_buffer_dirty_inode(fibh->ebh, inode); |
137 | mark_buffer_dirty_inode(fibh->sbh, inode); | 137 | mark_buffer_dirty_inode(fibh->sbh, inode); |
138 | } | 138 | } |
139 | return 0; | 139 | return 0; |
140 | } | 140 | } |
141 | 141 | ||
142 | static struct fileIdentDesc *udf_find_entry(struct inode *dir, | 142 | static struct fileIdentDesc *udf_find_entry(struct inode *dir, |
143 | const struct qstr *child, | 143 | const struct qstr *child, |
144 | struct udf_fileident_bh *fibh, | 144 | struct udf_fileident_bh *fibh, |
145 | struct fileIdentDesc *cfi) | 145 | struct fileIdentDesc *cfi) |
146 | { | 146 | { |
147 | struct fileIdentDesc *fi = NULL; | 147 | struct fileIdentDesc *fi = NULL; |
148 | loff_t f_pos; | 148 | loff_t f_pos; |
149 | int block, flen; | 149 | int block, flen; |
150 | unsigned char *fname = NULL; | 150 | unsigned char *fname = NULL; |
151 | unsigned char *nameptr; | 151 | unsigned char *nameptr; |
152 | uint8_t lfi; | 152 | uint8_t lfi; |
153 | uint16_t liu; | 153 | uint16_t liu; |
154 | loff_t size; | 154 | loff_t size; |
155 | struct kernel_lb_addr eloc; | 155 | struct kernel_lb_addr eloc; |
156 | uint32_t elen; | 156 | uint32_t elen; |
157 | sector_t offset; | 157 | sector_t offset; |
158 | struct extent_position epos = {}; | 158 | struct extent_position epos = {}; |
159 | struct udf_inode_info *dinfo = UDF_I(dir); | 159 | struct udf_inode_info *dinfo = UDF_I(dir); |
160 | int isdotdot = child->len == 2 && | 160 | int isdotdot = child->len == 2 && |
161 | child->name[0] == '.' && child->name[1] == '.'; | 161 | child->name[0] == '.' && child->name[1] == '.'; |
162 | struct super_block *sb = dir->i_sb; | ||
162 | 163 | ||
163 | size = udf_ext0_offset(dir) + dir->i_size; | 164 | size = udf_ext0_offset(dir) + dir->i_size; |
164 | f_pos = udf_ext0_offset(dir); | 165 | f_pos = udf_ext0_offset(dir); |
165 | 166 | ||
166 | fibh->sbh = fibh->ebh = NULL; | 167 | fibh->sbh = fibh->ebh = NULL; |
167 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); | 168 | fibh->soffset = fibh->eoffset = f_pos & (sb->s_blocksize - 1); |
168 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 169 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
169 | if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos, | 170 | if (inode_bmap(dir, f_pos >> sb->s_blocksize_bits, &epos, |
170 | &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) | 171 | &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) |
171 | goto out_err; | 172 | goto out_err; |
172 | block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); | 173 | block = udf_get_lb_pblock(sb, &eloc, offset); |
173 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 174 | if ((++offset << sb->s_blocksize_bits) < elen) { |
174 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 175 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
175 | epos.offset -= sizeof(struct short_ad); | 176 | epos.offset -= sizeof(struct short_ad); |
176 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 177 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
177 | epos.offset -= sizeof(struct long_ad); | 178 | epos.offset -= sizeof(struct long_ad); |
178 | } else | 179 | } else |
179 | offset = 0; | 180 | offset = 0; |
180 | 181 | ||
181 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); | 182 | fibh->sbh = fibh->ebh = udf_tread(sb, block); |
182 | if (!fibh->sbh) | 183 | if (!fibh->sbh) |
183 | goto out_err; | 184 | goto out_err; |
184 | } | 185 | } |
185 | 186 | ||
186 | fname = kmalloc(UDF_NAME_LEN, GFP_NOFS); | 187 | fname = kmalloc(UDF_NAME_LEN, GFP_NOFS); |
187 | if (!fname) | 188 | if (!fname) |
188 | goto out_err; | 189 | goto out_err; |
189 | 190 | ||
190 | while (f_pos < size) { | 191 | while (f_pos < size) { |
191 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, | 192 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, |
192 | &elen, &offset); | 193 | &elen, &offset); |
193 | if (!fi) | 194 | if (!fi) |
194 | goto out_err; | 195 | goto out_err; |
195 | 196 | ||
196 | liu = le16_to_cpu(cfi->lengthOfImpUse); | 197 | liu = le16_to_cpu(cfi->lengthOfImpUse); |
197 | lfi = cfi->lengthFileIdent; | 198 | lfi = cfi->lengthFileIdent; |
198 | 199 | ||
199 | if (fibh->sbh == fibh->ebh) { | 200 | if (fibh->sbh == fibh->ebh) { |
200 | nameptr = fi->fileIdent + liu; | 201 | nameptr = fi->fileIdent + liu; |
201 | } else { | 202 | } else { |
202 | int poffset; /* Unpaded ending offset */ | 203 | int poffset; /* Unpaded ending offset */ |
203 | 204 | ||
204 | poffset = fibh->soffset + sizeof(struct fileIdentDesc) + | 205 | poffset = fibh->soffset + sizeof(struct fileIdentDesc) + |
205 | liu + lfi; | 206 | liu + lfi; |
206 | 207 | ||
207 | if (poffset >= lfi) | 208 | if (poffset >= lfi) |
208 | nameptr = (uint8_t *)(fibh->ebh->b_data + | 209 | nameptr = (uint8_t *)(fibh->ebh->b_data + |
209 | poffset - lfi); | 210 | poffset - lfi); |
210 | else { | 211 | else { |
211 | nameptr = fname; | 212 | nameptr = fname; |
212 | memcpy(nameptr, fi->fileIdent + liu, | 213 | memcpy(nameptr, fi->fileIdent + liu, |
213 | lfi - poffset); | 214 | lfi - poffset); |
214 | memcpy(nameptr + lfi - poffset, | 215 | memcpy(nameptr + lfi - poffset, |
215 | fibh->ebh->b_data, poffset); | 216 | fibh->ebh->b_data, poffset); |
216 | } | 217 | } |
217 | } | 218 | } |
218 | 219 | ||
219 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { | 220 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { |
220 | if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE)) | 221 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNDELETE)) |
221 | continue; | 222 | continue; |
222 | } | 223 | } |
223 | 224 | ||
224 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) { | 225 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) { |
225 | if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE)) | 226 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) |
226 | continue; | 227 | continue; |
227 | } | 228 | } |
228 | 229 | ||
229 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) && | 230 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) && |
230 | isdotdot) | 231 | isdotdot) |
231 | goto out_ok; | 232 | goto out_ok; |
232 | 233 | ||
233 | if (!lfi) | 234 | if (!lfi) |
234 | continue; | 235 | continue; |
235 | 236 | ||
236 | flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); | 237 | flen = udf_get_filename(sb, nameptr, lfi, fname, UDF_NAME_LEN); |
237 | if (flen && udf_match(flen, fname, child->len, child->name)) | 238 | if (flen && udf_match(flen, fname, child->len, child->name)) |
238 | goto out_ok; | 239 | goto out_ok; |
239 | } | 240 | } |
240 | 241 | ||
241 | out_err: | 242 | out_err: |
242 | fi = NULL; | 243 | fi = NULL; |
243 | if (fibh->sbh != fibh->ebh) | 244 | if (fibh->sbh != fibh->ebh) |
244 | brelse(fibh->ebh); | 245 | brelse(fibh->ebh); |
245 | brelse(fibh->sbh); | 246 | brelse(fibh->sbh); |
246 | out_ok: | 247 | out_ok: |
247 | brelse(epos.bh); | 248 | brelse(epos.bh); |
248 | kfree(fname); | 249 | kfree(fname); |
249 | 250 | ||
250 | return fi; | 251 | return fi; |
251 | } | 252 | } |
252 | 253 | ||
253 | static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | 254 | static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, |
254 | unsigned int flags) | 255 | unsigned int flags) |
255 | { | 256 | { |
256 | struct inode *inode = NULL; | 257 | struct inode *inode = NULL; |
257 | struct fileIdentDesc cfi; | 258 | struct fileIdentDesc cfi; |
258 | struct udf_fileident_bh fibh; | 259 | struct udf_fileident_bh fibh; |
259 | 260 | ||
260 | if (dentry->d_name.len > UDF_NAME_LEN - 2) | 261 | if (dentry->d_name.len > UDF_NAME_LEN - 2) |
261 | return ERR_PTR(-ENAMETOOLONG); | 262 | return ERR_PTR(-ENAMETOOLONG); |
262 | 263 | ||
263 | #ifdef UDF_RECOVERY | 264 | #ifdef UDF_RECOVERY |
264 | /* temporary shorthand for specifying files by inode number */ | 265 | /* temporary shorthand for specifying files by inode number */ |
265 | if (!strncmp(dentry->d_name.name, ".B=", 3)) { | 266 | if (!strncmp(dentry->d_name.name, ".B=", 3)) { |
266 | struct kernel_lb_addr lb = { | 267 | struct kernel_lb_addr lb = { |
267 | .logicalBlockNum = 0, | 268 | .logicalBlockNum = 0, |
268 | .partitionReferenceNum = | 269 | .partitionReferenceNum = |
269 | simple_strtoul(dentry->d_name.name + 3, | 270 | simple_strtoul(dentry->d_name.name + 3, |
270 | NULL, 0), | 271 | NULL, 0), |
271 | }; | 272 | }; |
272 | inode = udf_iget(dir->i_sb, lb); | 273 | inode = udf_iget(dir->i_sb, lb); |
273 | if (IS_ERR(inode)) | 274 | if (IS_ERR(inode)) |
274 | return inode; | 275 | return inode; |
275 | } else | 276 | } else |
276 | #endif /* UDF_RECOVERY */ | 277 | #endif /* UDF_RECOVERY */ |
277 | 278 | ||
278 | if (udf_find_entry(dir, &dentry->d_name, &fibh, &cfi)) { | 279 | if (udf_find_entry(dir, &dentry->d_name, &fibh, &cfi)) { |
279 | struct kernel_lb_addr loc; | 280 | struct kernel_lb_addr loc; |
280 | 281 | ||
281 | if (fibh.sbh != fibh.ebh) | 282 | if (fibh.sbh != fibh.ebh) |
282 | brelse(fibh.ebh); | 283 | brelse(fibh.ebh); |
283 | brelse(fibh.sbh); | 284 | brelse(fibh.sbh); |
284 | 285 | ||
285 | loc = lelb_to_cpu(cfi.icb.extLocation); | 286 | loc = lelb_to_cpu(cfi.icb.extLocation); |
286 | inode = udf_iget(dir->i_sb, &loc); | 287 | inode = udf_iget(dir->i_sb, &loc); |
287 | if (IS_ERR(inode)) | 288 | if (IS_ERR(inode)) |
288 | return ERR_CAST(inode); | 289 | return ERR_CAST(inode); |
289 | } | 290 | } |
290 | 291 | ||
291 | return d_splice_alias(inode, dentry); | 292 | return d_splice_alias(inode, dentry); |
292 | } | 293 | } |
293 | 294 | ||
294 | static struct fileIdentDesc *udf_add_entry(struct inode *dir, | 295 | static struct fileIdentDesc *udf_add_entry(struct inode *dir, |
295 | struct dentry *dentry, | 296 | struct dentry *dentry, |
296 | struct udf_fileident_bh *fibh, | 297 | struct udf_fileident_bh *fibh, |
297 | struct fileIdentDesc *cfi, int *err) | 298 | struct fileIdentDesc *cfi, int *err) |
298 | { | 299 | { |
299 | struct super_block *sb = dir->i_sb; | 300 | struct super_block *sb = dir->i_sb; |
300 | struct fileIdentDesc *fi = NULL; | 301 | struct fileIdentDesc *fi = NULL; |
301 | unsigned char *name = NULL; | 302 | unsigned char *name = NULL; |
302 | int namelen; | 303 | int namelen; |
303 | loff_t f_pos; | 304 | loff_t f_pos; |
304 | loff_t size = udf_ext0_offset(dir) + dir->i_size; | 305 | loff_t size = udf_ext0_offset(dir) + dir->i_size; |
305 | int nfidlen; | 306 | int nfidlen; |
306 | uint8_t lfi; | 307 | uint8_t lfi; |
307 | uint16_t liu; | 308 | uint16_t liu; |
308 | int block; | 309 | int block; |
309 | struct kernel_lb_addr eloc; | 310 | struct kernel_lb_addr eloc; |
310 | uint32_t elen = 0; | 311 | uint32_t elen = 0; |
311 | sector_t offset; | 312 | sector_t offset; |
312 | struct extent_position epos = {}; | 313 | struct extent_position epos = {}; |
313 | struct udf_inode_info *dinfo; | 314 | struct udf_inode_info *dinfo; |
314 | 315 | ||
315 | fibh->sbh = fibh->ebh = NULL; | 316 | fibh->sbh = fibh->ebh = NULL; |
316 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); | 317 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); |
317 | if (!name) { | 318 | if (!name) { |
318 | *err = -ENOMEM; | 319 | *err = -ENOMEM; |
319 | goto out_err; | 320 | goto out_err; |
320 | } | 321 | } |
321 | 322 | ||
322 | if (dentry) { | 323 | if (dentry) { |
323 | if (!dentry->d_name.len) { | 324 | if (!dentry->d_name.len) { |
324 | *err = -EINVAL; | 325 | *err = -EINVAL; |
325 | goto out_err; | 326 | goto out_err; |
326 | } | 327 | } |
327 | namelen = udf_put_filename(sb, dentry->d_name.name, name, | 328 | namelen = udf_put_filename(sb, dentry->d_name.name, name, |
328 | dentry->d_name.len); | 329 | dentry->d_name.len); |
329 | if (!namelen) { | 330 | if (!namelen) { |
330 | *err = -ENAMETOOLONG; | 331 | *err = -ENAMETOOLONG; |
331 | goto out_err; | 332 | goto out_err; |
332 | } | 333 | } |
333 | } else { | 334 | } else { |
334 | namelen = 0; | 335 | namelen = 0; |
335 | } | 336 | } |
336 | 337 | ||
337 | nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3; | 338 | nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3; |
338 | 339 | ||
339 | f_pos = udf_ext0_offset(dir); | 340 | f_pos = udf_ext0_offset(dir); |
340 | 341 | ||
341 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); | 342 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); |
342 | dinfo = UDF_I(dir); | 343 | dinfo = UDF_I(dir); |
343 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 344 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
344 | if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos, | 345 | if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos, |
345 | &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) { | 346 | &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) { |
346 | block = udf_get_lb_pblock(dir->i_sb, | 347 | block = udf_get_lb_pblock(dir->i_sb, |
347 | &dinfo->i_location, 0); | 348 | &dinfo->i_location, 0); |
348 | fibh->soffset = fibh->eoffset = sb->s_blocksize; | 349 | fibh->soffset = fibh->eoffset = sb->s_blocksize; |
349 | goto add; | 350 | goto add; |
350 | } | 351 | } |
351 | block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); | 352 | block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); |
352 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 353 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { |
353 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 354 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
354 | epos.offset -= sizeof(struct short_ad); | 355 | epos.offset -= sizeof(struct short_ad); |
355 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 356 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
356 | epos.offset -= sizeof(struct long_ad); | 357 | epos.offset -= sizeof(struct long_ad); |
357 | } else | 358 | } else |
358 | offset = 0; | 359 | offset = 0; |
359 | 360 | ||
360 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); | 361 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); |
361 | if (!fibh->sbh) { | 362 | if (!fibh->sbh) { |
362 | *err = -EIO; | 363 | *err = -EIO; |
363 | goto out_err; | 364 | goto out_err; |
364 | } | 365 | } |
365 | 366 | ||
366 | block = dinfo->i_location.logicalBlockNum; | 367 | block = dinfo->i_location.logicalBlockNum; |
367 | } | 368 | } |
368 | 369 | ||
369 | while (f_pos < size) { | 370 | while (f_pos < size) { |
370 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, | 371 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, |
371 | &elen, &offset); | 372 | &elen, &offset); |
372 | 373 | ||
373 | if (!fi) { | 374 | if (!fi) { |
374 | *err = -EIO; | 375 | *err = -EIO; |
375 | goto out_err; | 376 | goto out_err; |
376 | } | 377 | } |
377 | 378 | ||
378 | liu = le16_to_cpu(cfi->lengthOfImpUse); | 379 | liu = le16_to_cpu(cfi->lengthOfImpUse); |
379 | lfi = cfi->lengthFileIdent; | 380 | lfi = cfi->lengthFileIdent; |
380 | 381 | ||
381 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { | 382 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { |
382 | if (((sizeof(struct fileIdentDesc) + | 383 | if (((sizeof(struct fileIdentDesc) + |
383 | liu + lfi + 3) & ~3) == nfidlen) { | 384 | liu + lfi + 3) & ~3) == nfidlen) { |
384 | cfi->descTag.tagSerialNum = cpu_to_le16(1); | 385 | cfi->descTag.tagSerialNum = cpu_to_le16(1); |
385 | cfi->fileVersionNum = cpu_to_le16(1); | 386 | cfi->fileVersionNum = cpu_to_le16(1); |
386 | cfi->fileCharacteristics = 0; | 387 | cfi->fileCharacteristics = 0; |
387 | cfi->lengthFileIdent = namelen; | 388 | cfi->lengthFileIdent = namelen; |
388 | cfi->lengthOfImpUse = cpu_to_le16(0); | 389 | cfi->lengthOfImpUse = cpu_to_le16(0); |
389 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, | 390 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, |
390 | name)) | 391 | name)) |
391 | goto out_ok; | 392 | goto out_ok; |
392 | else { | 393 | else { |
393 | *err = -EIO; | 394 | *err = -EIO; |
394 | goto out_err; | 395 | goto out_err; |
395 | } | 396 | } |
396 | } | 397 | } |
397 | } | 398 | } |
398 | } | 399 | } |
399 | 400 | ||
400 | add: | 401 | add: |
401 | f_pos += nfidlen; | 402 | f_pos += nfidlen; |
402 | 403 | ||
403 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && | 404 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && |
404 | sb->s_blocksize - fibh->eoffset < nfidlen) { | 405 | sb->s_blocksize - fibh->eoffset < nfidlen) { |
405 | brelse(epos.bh); | 406 | brelse(epos.bh); |
406 | epos.bh = NULL; | 407 | epos.bh = NULL; |
407 | fibh->soffset -= udf_ext0_offset(dir); | 408 | fibh->soffset -= udf_ext0_offset(dir); |
408 | fibh->eoffset -= udf_ext0_offset(dir); | 409 | fibh->eoffset -= udf_ext0_offset(dir); |
409 | f_pos -= udf_ext0_offset(dir); | 410 | f_pos -= udf_ext0_offset(dir); |
410 | if (fibh->sbh != fibh->ebh) | 411 | if (fibh->sbh != fibh->ebh) |
411 | brelse(fibh->ebh); | 412 | brelse(fibh->ebh); |
412 | brelse(fibh->sbh); | 413 | brelse(fibh->sbh); |
413 | fibh->sbh = fibh->ebh = | 414 | fibh->sbh = fibh->ebh = |
414 | udf_expand_dir_adinicb(dir, &block, err); | 415 | udf_expand_dir_adinicb(dir, &block, err); |
415 | if (!fibh->sbh) | 416 | if (!fibh->sbh) |
416 | goto out_err; | 417 | goto out_err; |
417 | epos.block = dinfo->i_location; | 418 | epos.block = dinfo->i_location; |
418 | epos.offset = udf_file_entry_alloc_offset(dir); | 419 | epos.offset = udf_file_entry_alloc_offset(dir); |
419 | /* Load extent udf_expand_dir_adinicb() has created */ | 420 | /* Load extent udf_expand_dir_adinicb() has created */ |
420 | udf_current_aext(dir, &epos, &eloc, &elen, 1); | 421 | udf_current_aext(dir, &epos, &eloc, &elen, 1); |
421 | } | 422 | } |
422 | 423 | ||
423 | /* Entry fits into current block? */ | 424 | /* Entry fits into current block? */ |
424 | if (sb->s_blocksize - fibh->eoffset >= nfidlen) { | 425 | if (sb->s_blocksize - fibh->eoffset >= nfidlen) { |
425 | fibh->soffset = fibh->eoffset; | 426 | fibh->soffset = fibh->eoffset; |
426 | fibh->eoffset += nfidlen; | 427 | fibh->eoffset += nfidlen; |
427 | if (fibh->sbh != fibh->ebh) { | 428 | if (fibh->sbh != fibh->ebh) { |
428 | brelse(fibh->sbh); | 429 | brelse(fibh->sbh); |
429 | fibh->sbh = fibh->ebh; | 430 | fibh->sbh = fibh->ebh; |
430 | } | 431 | } |
431 | 432 | ||
432 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 433 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
433 | block = dinfo->i_location.logicalBlockNum; | 434 | block = dinfo->i_location.logicalBlockNum; |
434 | fi = (struct fileIdentDesc *) | 435 | fi = (struct fileIdentDesc *) |
435 | (dinfo->i_ext.i_data + | 436 | (dinfo->i_ext.i_data + |
436 | fibh->soffset - | 437 | fibh->soffset - |
437 | udf_ext0_offset(dir) + | 438 | udf_ext0_offset(dir) + |
438 | dinfo->i_lenEAttr); | 439 | dinfo->i_lenEAttr); |
439 | } else { | 440 | } else { |
440 | block = eloc.logicalBlockNum + | 441 | block = eloc.logicalBlockNum + |
441 | ((elen - 1) >> | 442 | ((elen - 1) >> |
442 | dir->i_sb->s_blocksize_bits); | 443 | dir->i_sb->s_blocksize_bits); |
443 | fi = (struct fileIdentDesc *) | 444 | fi = (struct fileIdentDesc *) |
444 | (fibh->sbh->b_data + fibh->soffset); | 445 | (fibh->sbh->b_data + fibh->soffset); |
445 | } | 446 | } |
446 | } else { | 447 | } else { |
447 | /* Round up last extent in the file */ | 448 | /* Round up last extent in the file */ |
448 | elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1); | 449 | elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1); |
449 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 450 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
450 | epos.offset -= sizeof(struct short_ad); | 451 | epos.offset -= sizeof(struct short_ad); |
451 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 452 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
452 | epos.offset -= sizeof(struct long_ad); | 453 | epos.offset -= sizeof(struct long_ad); |
453 | udf_write_aext(dir, &epos, &eloc, elen, 1); | 454 | udf_write_aext(dir, &epos, &eloc, elen, 1); |
454 | dinfo->i_lenExtents = (dinfo->i_lenExtents + sb->s_blocksize | 455 | dinfo->i_lenExtents = (dinfo->i_lenExtents + sb->s_blocksize |
455 | - 1) & ~(sb->s_blocksize - 1); | 456 | - 1) & ~(sb->s_blocksize - 1); |
456 | 457 | ||
457 | fibh->soffset = fibh->eoffset - sb->s_blocksize; | 458 | fibh->soffset = fibh->eoffset - sb->s_blocksize; |
458 | fibh->eoffset += nfidlen - sb->s_blocksize; | 459 | fibh->eoffset += nfidlen - sb->s_blocksize; |
459 | if (fibh->sbh != fibh->ebh) { | 460 | if (fibh->sbh != fibh->ebh) { |
460 | brelse(fibh->sbh); | 461 | brelse(fibh->sbh); |
461 | fibh->sbh = fibh->ebh; | 462 | fibh->sbh = fibh->ebh; |
462 | } | 463 | } |
463 | 464 | ||
464 | block = eloc.logicalBlockNum + ((elen - 1) >> | 465 | block = eloc.logicalBlockNum + ((elen - 1) >> |
465 | dir->i_sb->s_blocksize_bits); | 466 | dir->i_sb->s_blocksize_bits); |
466 | fibh->ebh = udf_bread(dir, | 467 | fibh->ebh = udf_bread(dir, |
467 | f_pos >> dir->i_sb->s_blocksize_bits, 1, err); | 468 | f_pos >> dir->i_sb->s_blocksize_bits, 1, err); |
468 | if (!fibh->ebh) | 469 | if (!fibh->ebh) |
469 | goto out_err; | 470 | goto out_err; |
470 | /* Extents could have been merged, invalidate our position */ | 471 | /* Extents could have been merged, invalidate our position */ |
471 | brelse(epos.bh); | 472 | brelse(epos.bh); |
472 | epos.bh = NULL; | 473 | epos.bh = NULL; |
473 | epos.block = dinfo->i_location; | 474 | epos.block = dinfo->i_location; |
474 | epos.offset = udf_file_entry_alloc_offset(dir); | 475 | epos.offset = udf_file_entry_alloc_offset(dir); |
475 | 476 | ||
476 | if (!fibh->soffset) { | 477 | if (!fibh->soffset) { |
477 | /* Find the freshly allocated block */ | 478 | /* Find the freshly allocated block */ |
478 | while (udf_next_aext(dir, &epos, &eloc, &elen, 1) == | 479 | while (udf_next_aext(dir, &epos, &eloc, &elen, 1) == |
479 | (EXT_RECORDED_ALLOCATED >> 30)) | 480 | (EXT_RECORDED_ALLOCATED >> 30)) |
480 | ; | 481 | ; |
481 | block = eloc.logicalBlockNum + ((elen - 1) >> | 482 | block = eloc.logicalBlockNum + ((elen - 1) >> |
482 | dir->i_sb->s_blocksize_bits); | 483 | dir->i_sb->s_blocksize_bits); |
483 | brelse(fibh->sbh); | 484 | brelse(fibh->sbh); |
484 | fibh->sbh = fibh->ebh; | 485 | fibh->sbh = fibh->ebh; |
485 | fi = (struct fileIdentDesc *)(fibh->sbh->b_data); | 486 | fi = (struct fileIdentDesc *)(fibh->sbh->b_data); |
486 | } else { | 487 | } else { |
487 | fi = (struct fileIdentDesc *) | 488 | fi = (struct fileIdentDesc *) |
488 | (fibh->sbh->b_data + sb->s_blocksize + | 489 | (fibh->sbh->b_data + sb->s_blocksize + |
489 | fibh->soffset); | 490 | fibh->soffset); |
490 | } | 491 | } |
491 | } | 492 | } |
492 | 493 | ||
493 | memset(cfi, 0, sizeof(struct fileIdentDesc)); | 494 | memset(cfi, 0, sizeof(struct fileIdentDesc)); |
494 | if (UDF_SB(sb)->s_udfrev >= 0x0200) | 495 | if (UDF_SB(sb)->s_udfrev >= 0x0200) |
495 | udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block, | 496 | udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block, |
496 | sizeof(struct tag)); | 497 | sizeof(struct tag)); |
497 | else | 498 | else |
498 | udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block, | 499 | udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block, |
499 | sizeof(struct tag)); | 500 | sizeof(struct tag)); |
500 | cfi->fileVersionNum = cpu_to_le16(1); | 501 | cfi->fileVersionNum = cpu_to_le16(1); |
501 | cfi->lengthFileIdent = namelen; | 502 | cfi->lengthFileIdent = namelen; |
502 | cfi->lengthOfImpUse = cpu_to_le16(0); | 503 | cfi->lengthOfImpUse = cpu_to_le16(0); |
503 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) { | 504 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) { |
504 | dir->i_size += nfidlen; | 505 | dir->i_size += nfidlen; |
505 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 506 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
506 | dinfo->i_lenAlloc += nfidlen; | 507 | dinfo->i_lenAlloc += nfidlen; |
507 | else { | 508 | else { |
508 | /* Find the last extent and truncate it to proper size */ | 509 | /* Find the last extent and truncate it to proper size */ |
509 | while (udf_next_aext(dir, &epos, &eloc, &elen, 1) == | 510 | while (udf_next_aext(dir, &epos, &eloc, &elen, 1) == |
510 | (EXT_RECORDED_ALLOCATED >> 30)) | 511 | (EXT_RECORDED_ALLOCATED >> 30)) |
511 | ; | 512 | ; |
512 | elen -= dinfo->i_lenExtents - dir->i_size; | 513 | elen -= dinfo->i_lenExtents - dir->i_size; |
513 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 514 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
514 | epos.offset -= sizeof(struct short_ad); | 515 | epos.offset -= sizeof(struct short_ad); |
515 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 516 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
516 | epos.offset -= sizeof(struct long_ad); | 517 | epos.offset -= sizeof(struct long_ad); |
517 | udf_write_aext(dir, &epos, &eloc, elen, 1); | 518 | udf_write_aext(dir, &epos, &eloc, elen, 1); |
518 | dinfo->i_lenExtents = dir->i_size; | 519 | dinfo->i_lenExtents = dir->i_size; |
519 | } | 520 | } |
520 | 521 | ||
521 | mark_inode_dirty(dir); | 522 | mark_inode_dirty(dir); |
522 | goto out_ok; | 523 | goto out_ok; |
523 | } else { | 524 | } else { |
524 | *err = -EIO; | 525 | *err = -EIO; |
525 | goto out_err; | 526 | goto out_err; |
526 | } | 527 | } |
527 | 528 | ||
528 | out_err: | 529 | out_err: |
529 | fi = NULL; | 530 | fi = NULL; |
530 | if (fibh->sbh != fibh->ebh) | 531 | if (fibh->sbh != fibh->ebh) |
531 | brelse(fibh->ebh); | 532 | brelse(fibh->ebh); |
532 | brelse(fibh->sbh); | 533 | brelse(fibh->sbh); |
533 | out_ok: | 534 | out_ok: |
534 | brelse(epos.bh); | 535 | brelse(epos.bh); |
535 | kfree(name); | 536 | kfree(name); |
536 | return fi; | 537 | return fi; |
537 | } | 538 | } |
538 | 539 | ||
539 | static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, | 540 | static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, |
540 | struct udf_fileident_bh *fibh, | 541 | struct udf_fileident_bh *fibh, |
541 | struct fileIdentDesc *cfi) | 542 | struct fileIdentDesc *cfi) |
542 | { | 543 | { |
543 | cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED; | 544 | cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED; |
544 | 545 | ||
545 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) | 546 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) |
546 | memset(&(cfi->icb), 0x00, sizeof(struct long_ad)); | 547 | memset(&(cfi->icb), 0x00, sizeof(struct long_ad)); |
547 | 548 | ||
548 | return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL); | 549 | return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL); |
549 | } | 550 | } |
550 | 551 | ||
551 | static int udf_add_nondir(struct dentry *dentry, struct inode *inode) | 552 | static int udf_add_nondir(struct dentry *dentry, struct inode *inode) |
552 | { | 553 | { |
553 | struct udf_inode_info *iinfo = UDF_I(inode); | 554 | struct udf_inode_info *iinfo = UDF_I(inode); |
554 | struct inode *dir = dentry->d_parent->d_inode; | 555 | struct inode *dir = dentry->d_parent->d_inode; |
555 | struct udf_fileident_bh fibh; | 556 | struct udf_fileident_bh fibh; |
556 | struct fileIdentDesc cfi, *fi; | 557 | struct fileIdentDesc cfi, *fi; |
557 | int err; | 558 | int err; |
558 | 559 | ||
559 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 560 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
560 | if (unlikely(!fi)) { | 561 | if (unlikely(!fi)) { |
561 | inode_dec_link_count(inode); | 562 | inode_dec_link_count(inode); |
562 | unlock_new_inode(inode); | 563 | unlock_new_inode(inode); |
563 | iput(inode); | 564 | iput(inode); |
564 | return err; | 565 | return err; |
565 | } | 566 | } |
566 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 567 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); |
567 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); | 568 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); |
568 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | 569 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = |
569 | cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL); | 570 | cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL); |
570 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 571 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
571 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 572 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
572 | mark_inode_dirty(dir); | 573 | mark_inode_dirty(dir); |
573 | if (fibh.sbh != fibh.ebh) | 574 | if (fibh.sbh != fibh.ebh) |
574 | brelse(fibh.ebh); | 575 | brelse(fibh.ebh); |
575 | brelse(fibh.sbh); | 576 | brelse(fibh.sbh); |
576 | unlock_new_inode(inode); | 577 | unlock_new_inode(inode); |
577 | d_instantiate(dentry, inode); | 578 | d_instantiate(dentry, inode); |
578 | 579 | ||
579 | return 0; | 580 | return 0; |
580 | } | 581 | } |
581 | 582 | ||
582 | static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 583 | static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
583 | bool excl) | 584 | bool excl) |
584 | { | 585 | { |
585 | struct inode *inode = udf_new_inode(dir, mode); | 586 | struct inode *inode = udf_new_inode(dir, mode); |
586 | 587 | ||
587 | if (IS_ERR(inode)) | 588 | if (IS_ERR(inode)) |
588 | return PTR_ERR(inode); | 589 | return PTR_ERR(inode); |
589 | 590 | ||
590 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 591 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
591 | inode->i_data.a_ops = &udf_adinicb_aops; | 592 | inode->i_data.a_ops = &udf_adinicb_aops; |
592 | else | 593 | else |
593 | inode->i_data.a_ops = &udf_aops; | 594 | inode->i_data.a_ops = &udf_aops; |
594 | inode->i_op = &udf_file_inode_operations; | 595 | inode->i_op = &udf_file_inode_operations; |
595 | inode->i_fop = &udf_file_operations; | 596 | inode->i_fop = &udf_file_operations; |
596 | mark_inode_dirty(inode); | 597 | mark_inode_dirty(inode); |
597 | 598 | ||
598 | return udf_add_nondir(dentry, inode); | 599 | return udf_add_nondir(dentry, inode); |
599 | } | 600 | } |
600 | 601 | ||
601 | static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | 602 | static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) |
602 | { | 603 | { |
603 | struct inode *inode = udf_new_inode(dir, mode); | 604 | struct inode *inode = udf_new_inode(dir, mode); |
604 | 605 | ||
605 | if (IS_ERR(inode)) | 606 | if (IS_ERR(inode)) |
606 | return PTR_ERR(inode); | 607 | return PTR_ERR(inode); |
607 | 608 | ||
608 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 609 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
609 | inode->i_data.a_ops = &udf_adinicb_aops; | 610 | inode->i_data.a_ops = &udf_adinicb_aops; |
610 | else | 611 | else |
611 | inode->i_data.a_ops = &udf_aops; | 612 | inode->i_data.a_ops = &udf_aops; |
612 | inode->i_op = &udf_file_inode_operations; | 613 | inode->i_op = &udf_file_inode_operations; |
613 | inode->i_fop = &udf_file_operations; | 614 | inode->i_fop = &udf_file_operations; |
614 | mark_inode_dirty(inode); | 615 | mark_inode_dirty(inode); |
615 | d_tmpfile(dentry, inode); | 616 | d_tmpfile(dentry, inode); |
616 | unlock_new_inode(inode); | 617 | unlock_new_inode(inode); |
617 | return 0; | 618 | return 0; |
618 | } | 619 | } |
619 | 620 | ||
620 | static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, | 621 | static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, |
621 | dev_t rdev) | 622 | dev_t rdev) |
622 | { | 623 | { |
623 | struct inode *inode; | 624 | struct inode *inode; |
624 | 625 | ||
625 | if (!old_valid_dev(rdev)) | 626 | if (!old_valid_dev(rdev)) |
626 | return -EINVAL; | 627 | return -EINVAL; |
627 | 628 | ||
628 | inode = udf_new_inode(dir, mode); | 629 | inode = udf_new_inode(dir, mode); |
629 | if (IS_ERR(inode)) | 630 | if (IS_ERR(inode)) |
630 | return PTR_ERR(inode); | 631 | return PTR_ERR(inode); |
631 | 632 | ||
632 | init_special_inode(inode, mode, rdev); | 633 | init_special_inode(inode, mode, rdev); |
633 | return udf_add_nondir(dentry, inode); | 634 | return udf_add_nondir(dentry, inode); |
634 | } | 635 | } |
635 | 636 | ||
636 | static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 637 | static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
637 | { | 638 | { |
638 | struct inode *inode; | 639 | struct inode *inode; |
639 | struct udf_fileident_bh fibh; | 640 | struct udf_fileident_bh fibh; |
640 | struct fileIdentDesc cfi, *fi; | 641 | struct fileIdentDesc cfi, *fi; |
641 | int err; | 642 | int err; |
642 | struct udf_inode_info *dinfo = UDF_I(dir); | 643 | struct udf_inode_info *dinfo = UDF_I(dir); |
643 | struct udf_inode_info *iinfo; | 644 | struct udf_inode_info *iinfo; |
644 | 645 | ||
645 | inode = udf_new_inode(dir, S_IFDIR | mode); | 646 | inode = udf_new_inode(dir, S_IFDIR | mode); |
646 | if (IS_ERR(inode)) | 647 | if (IS_ERR(inode)) |
647 | return PTR_ERR(inode); | 648 | return PTR_ERR(inode); |
648 | 649 | ||
649 | iinfo = UDF_I(inode); | 650 | iinfo = UDF_I(inode); |
650 | inode->i_op = &udf_dir_inode_operations; | 651 | inode->i_op = &udf_dir_inode_operations; |
651 | inode->i_fop = &udf_dir_operations; | 652 | inode->i_fop = &udf_dir_operations; |
652 | fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err); | 653 | fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err); |
653 | if (!fi) { | 654 | if (!fi) { |
654 | inode_dec_link_count(inode); | 655 | inode_dec_link_count(inode); |
655 | unlock_new_inode(inode); | 656 | unlock_new_inode(inode); |
656 | iput(inode); | 657 | iput(inode); |
657 | goto out; | 658 | goto out; |
658 | } | 659 | } |
659 | set_nlink(inode, 2); | 660 | set_nlink(inode, 2); |
660 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 661 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); |
661 | cfi.icb.extLocation = cpu_to_lelb(dinfo->i_location); | 662 | cfi.icb.extLocation = cpu_to_lelb(dinfo->i_location); |
662 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | 663 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = |
663 | cpu_to_le32(dinfo->i_unique & 0x00000000FFFFFFFFUL); | 664 | cpu_to_le32(dinfo->i_unique & 0x00000000FFFFFFFFUL); |
664 | cfi.fileCharacteristics = | 665 | cfi.fileCharacteristics = |
665 | FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; | 666 | FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; |
666 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); | 667 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); |
667 | brelse(fibh.sbh); | 668 | brelse(fibh.sbh); |
668 | mark_inode_dirty(inode); | 669 | mark_inode_dirty(inode); |
669 | 670 | ||
670 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 671 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
671 | if (!fi) { | 672 | if (!fi) { |
672 | clear_nlink(inode); | 673 | clear_nlink(inode); |
673 | mark_inode_dirty(inode); | 674 | mark_inode_dirty(inode); |
674 | unlock_new_inode(inode); | 675 | unlock_new_inode(inode); |
675 | iput(inode); | 676 | iput(inode); |
676 | goto out; | 677 | goto out; |
677 | } | 678 | } |
678 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 679 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); |
679 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); | 680 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); |
680 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | 681 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = |
681 | cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL); | 682 | cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL); |
682 | cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY; | 683 | cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY; |
683 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 684 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
684 | inc_nlink(dir); | 685 | inc_nlink(dir); |
685 | mark_inode_dirty(dir); | 686 | mark_inode_dirty(dir); |
686 | unlock_new_inode(inode); | 687 | unlock_new_inode(inode); |
687 | d_instantiate(dentry, inode); | 688 | d_instantiate(dentry, inode); |
688 | if (fibh.sbh != fibh.ebh) | 689 | if (fibh.sbh != fibh.ebh) |
689 | brelse(fibh.ebh); | 690 | brelse(fibh.ebh); |
690 | brelse(fibh.sbh); | 691 | brelse(fibh.sbh); |
691 | err = 0; | 692 | err = 0; |
692 | 693 | ||
693 | out: | 694 | out: |
694 | return err; | 695 | return err; |
695 | } | 696 | } |
696 | 697 | ||
697 | static int empty_dir(struct inode *dir) | 698 | static int empty_dir(struct inode *dir) |
698 | { | 699 | { |
699 | struct fileIdentDesc *fi, cfi; | 700 | struct fileIdentDesc *fi, cfi; |
700 | struct udf_fileident_bh fibh; | 701 | struct udf_fileident_bh fibh; |
701 | loff_t f_pos; | 702 | loff_t f_pos; |
702 | loff_t size = udf_ext0_offset(dir) + dir->i_size; | 703 | loff_t size = udf_ext0_offset(dir) + dir->i_size; |
703 | int block; | 704 | int block; |
704 | struct kernel_lb_addr eloc; | 705 | struct kernel_lb_addr eloc; |
705 | uint32_t elen; | 706 | uint32_t elen; |
706 | sector_t offset; | 707 | sector_t offset; |
707 | struct extent_position epos = {}; | 708 | struct extent_position epos = {}; |
708 | struct udf_inode_info *dinfo = UDF_I(dir); | 709 | struct udf_inode_info *dinfo = UDF_I(dir); |
709 | 710 | ||
710 | f_pos = udf_ext0_offset(dir); | 711 | f_pos = udf_ext0_offset(dir); |
711 | fibh.soffset = fibh.eoffset = f_pos & (dir->i_sb->s_blocksize - 1); | 712 | fibh.soffset = fibh.eoffset = f_pos & (dir->i_sb->s_blocksize - 1); |
712 | 713 | ||
713 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 714 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
714 | fibh.sbh = fibh.ebh = NULL; | 715 | fibh.sbh = fibh.ebh = NULL; |
715 | else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, | 716 | else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, |
716 | &epos, &eloc, &elen, &offset) == | 717 | &epos, &eloc, &elen, &offset) == |
717 | (EXT_RECORDED_ALLOCATED >> 30)) { | 718 | (EXT_RECORDED_ALLOCATED >> 30)) { |
718 | block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); | 719 | block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); |
719 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 720 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { |
720 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 721 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
721 | epos.offset -= sizeof(struct short_ad); | 722 | epos.offset -= sizeof(struct short_ad); |
722 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 723 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
723 | epos.offset -= sizeof(struct long_ad); | 724 | epos.offset -= sizeof(struct long_ad); |
724 | } else | 725 | } else |
725 | offset = 0; | 726 | offset = 0; |
726 | 727 | ||
727 | fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block); | 728 | fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block); |
728 | if (!fibh.sbh) { | 729 | if (!fibh.sbh) { |
729 | brelse(epos.bh); | 730 | brelse(epos.bh); |
730 | return 0; | 731 | return 0; |
731 | } | 732 | } |
732 | } else { | 733 | } else { |
733 | brelse(epos.bh); | 734 | brelse(epos.bh); |
734 | return 0; | 735 | return 0; |
735 | } | 736 | } |
736 | 737 | ||
737 | while (f_pos < size) { | 738 | while (f_pos < size) { |
738 | fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc, | 739 | fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc, |
739 | &elen, &offset); | 740 | &elen, &offset); |
740 | if (!fi) { | 741 | if (!fi) { |
741 | if (fibh.sbh != fibh.ebh) | 742 | if (fibh.sbh != fibh.ebh) |
742 | brelse(fibh.ebh); | 743 | brelse(fibh.ebh); |
743 | brelse(fibh.sbh); | 744 | brelse(fibh.sbh); |
744 | brelse(epos.bh); | 745 | brelse(epos.bh); |
745 | return 0; | 746 | return 0; |
746 | } | 747 | } |
747 | 748 | ||
748 | if (cfi.lengthFileIdent && | 749 | if (cfi.lengthFileIdent && |
749 | (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) { | 750 | (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) { |
750 | if (fibh.sbh != fibh.ebh) | 751 | if (fibh.sbh != fibh.ebh) |
751 | brelse(fibh.ebh); | 752 | brelse(fibh.ebh); |
752 | brelse(fibh.sbh); | 753 | brelse(fibh.sbh); |
753 | brelse(epos.bh); | 754 | brelse(epos.bh); |
754 | return 0; | 755 | return 0; |
755 | } | 756 | } |
756 | } | 757 | } |
757 | 758 | ||
758 | if (fibh.sbh != fibh.ebh) | 759 | if (fibh.sbh != fibh.ebh) |
759 | brelse(fibh.ebh); | 760 | brelse(fibh.ebh); |
760 | brelse(fibh.sbh); | 761 | brelse(fibh.sbh); |
761 | brelse(epos.bh); | 762 | brelse(epos.bh); |
762 | 763 | ||
763 | return 1; | 764 | return 1; |
764 | } | 765 | } |
765 | 766 | ||
766 | static int udf_rmdir(struct inode *dir, struct dentry *dentry) | 767 | static int udf_rmdir(struct inode *dir, struct dentry *dentry) |
767 | { | 768 | { |
768 | int retval; | 769 | int retval; |
769 | struct inode *inode = dentry->d_inode; | 770 | struct inode *inode = dentry->d_inode; |
770 | struct udf_fileident_bh fibh; | 771 | struct udf_fileident_bh fibh; |
771 | struct fileIdentDesc *fi, cfi; | 772 | struct fileIdentDesc *fi, cfi; |
772 | struct kernel_lb_addr tloc; | 773 | struct kernel_lb_addr tloc; |
773 | 774 | ||
774 | retval = -ENOENT; | 775 | retval = -ENOENT; |
775 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 776 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
776 | if (!fi) | 777 | if (!fi) |
777 | goto out; | 778 | goto out; |
778 | 779 | ||
779 | retval = -EIO; | 780 | retval = -EIO; |
780 | tloc = lelb_to_cpu(cfi.icb.extLocation); | 781 | tloc = lelb_to_cpu(cfi.icb.extLocation); |
781 | if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino) | 782 | if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino) |
782 | goto end_rmdir; | 783 | goto end_rmdir; |
783 | retval = -ENOTEMPTY; | 784 | retval = -ENOTEMPTY; |
784 | if (!empty_dir(inode)) | 785 | if (!empty_dir(inode)) |
785 | goto end_rmdir; | 786 | goto end_rmdir; |
786 | retval = udf_delete_entry(dir, fi, &fibh, &cfi); | 787 | retval = udf_delete_entry(dir, fi, &fibh, &cfi); |
787 | if (retval) | 788 | if (retval) |
788 | goto end_rmdir; | 789 | goto end_rmdir; |
789 | if (inode->i_nlink != 2) | 790 | if (inode->i_nlink != 2) |
790 | udf_warn(inode->i_sb, "empty directory has nlink != 2 (%d)\n", | 791 | udf_warn(inode->i_sb, "empty directory has nlink != 2 (%d)\n", |
791 | inode->i_nlink); | 792 | inode->i_nlink); |
792 | clear_nlink(inode); | 793 | clear_nlink(inode); |
793 | inode->i_size = 0; | 794 | inode->i_size = 0; |
794 | inode_dec_link_count(dir); | 795 | inode_dec_link_count(dir); |
795 | inode->i_ctime = dir->i_ctime = dir->i_mtime = | 796 | inode->i_ctime = dir->i_ctime = dir->i_mtime = |
796 | current_fs_time(dir->i_sb); | 797 | current_fs_time(dir->i_sb); |
797 | mark_inode_dirty(dir); | 798 | mark_inode_dirty(dir); |
798 | 799 | ||
799 | end_rmdir: | 800 | end_rmdir: |
800 | if (fibh.sbh != fibh.ebh) | 801 | if (fibh.sbh != fibh.ebh) |
801 | brelse(fibh.ebh); | 802 | brelse(fibh.ebh); |
802 | brelse(fibh.sbh); | 803 | brelse(fibh.sbh); |
803 | 804 | ||
804 | out: | 805 | out: |
805 | return retval; | 806 | return retval; |
806 | } | 807 | } |
807 | 808 | ||
808 | static int udf_unlink(struct inode *dir, struct dentry *dentry) | 809 | static int udf_unlink(struct inode *dir, struct dentry *dentry) |
809 | { | 810 | { |
810 | int retval; | 811 | int retval; |
811 | struct inode *inode = dentry->d_inode; | 812 | struct inode *inode = dentry->d_inode; |
812 | struct udf_fileident_bh fibh; | 813 | struct udf_fileident_bh fibh; |
813 | struct fileIdentDesc *fi; | 814 | struct fileIdentDesc *fi; |
814 | struct fileIdentDesc cfi; | 815 | struct fileIdentDesc cfi; |
815 | struct kernel_lb_addr tloc; | 816 | struct kernel_lb_addr tloc; |
816 | 817 | ||
817 | retval = -ENOENT; | 818 | retval = -ENOENT; |
818 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 819 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
819 | if (!fi) | 820 | if (!fi) |
820 | goto out; | 821 | goto out; |
821 | 822 | ||
822 | retval = -EIO; | 823 | retval = -EIO; |
823 | tloc = lelb_to_cpu(cfi.icb.extLocation); | 824 | tloc = lelb_to_cpu(cfi.icb.extLocation); |
824 | if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino) | 825 | if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino) |
825 | goto end_unlink; | 826 | goto end_unlink; |
826 | 827 | ||
827 | if (!inode->i_nlink) { | 828 | if (!inode->i_nlink) { |
828 | udf_debug("Deleting nonexistent file (%lu), %d\n", | 829 | udf_debug("Deleting nonexistent file (%lu), %d\n", |
829 | inode->i_ino, inode->i_nlink); | 830 | inode->i_ino, inode->i_nlink); |
830 | set_nlink(inode, 1); | 831 | set_nlink(inode, 1); |
831 | } | 832 | } |
832 | retval = udf_delete_entry(dir, fi, &fibh, &cfi); | 833 | retval = udf_delete_entry(dir, fi, &fibh, &cfi); |
833 | if (retval) | 834 | if (retval) |
834 | goto end_unlink; | 835 | goto end_unlink; |
835 | dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); | 836 | dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); |
836 | mark_inode_dirty(dir); | 837 | mark_inode_dirty(dir); |
837 | inode_dec_link_count(inode); | 838 | inode_dec_link_count(inode); |
838 | inode->i_ctime = dir->i_ctime; | 839 | inode->i_ctime = dir->i_ctime; |
839 | retval = 0; | 840 | retval = 0; |
840 | 841 | ||
841 | end_unlink: | 842 | end_unlink: |
842 | if (fibh.sbh != fibh.ebh) | 843 | if (fibh.sbh != fibh.ebh) |
843 | brelse(fibh.ebh); | 844 | brelse(fibh.ebh); |
844 | brelse(fibh.sbh); | 845 | brelse(fibh.sbh); |
845 | 846 | ||
846 | out: | 847 | out: |
847 | return retval; | 848 | return retval; |
848 | } | 849 | } |
849 | 850 | ||
850 | static int udf_symlink(struct inode *dir, struct dentry *dentry, | 851 | static int udf_symlink(struct inode *dir, struct dentry *dentry, |
851 | const char *symname) | 852 | const char *symname) |
852 | { | 853 | { |
853 | struct inode *inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO); | 854 | struct inode *inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO); |
854 | struct pathComponent *pc; | 855 | struct pathComponent *pc; |
855 | const char *compstart; | 856 | const char *compstart; |
856 | struct extent_position epos = {}; | 857 | struct extent_position epos = {}; |
857 | int eoffset, elen = 0; | 858 | int eoffset, elen = 0; |
858 | uint8_t *ea; | 859 | uint8_t *ea; |
859 | int err; | 860 | int err; |
860 | int block; | 861 | int block; |
861 | unsigned char *name = NULL; | 862 | unsigned char *name = NULL; |
862 | int namelen; | 863 | int namelen; |
863 | struct udf_inode_info *iinfo; | 864 | struct udf_inode_info *iinfo; |
864 | struct super_block *sb = dir->i_sb; | 865 | struct super_block *sb = dir->i_sb; |
865 | 866 | ||
866 | if (IS_ERR(inode)) | 867 | if (IS_ERR(inode)) |
867 | return PTR_ERR(inode); | 868 | return PTR_ERR(inode); |
868 | 869 | ||
869 | iinfo = UDF_I(inode); | 870 | iinfo = UDF_I(inode); |
870 | down_write(&iinfo->i_data_sem); | 871 | down_write(&iinfo->i_data_sem); |
871 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); | 872 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); |
872 | if (!name) { | 873 | if (!name) { |
873 | err = -ENOMEM; | 874 | err = -ENOMEM; |
874 | goto out_no_entry; | 875 | goto out_no_entry; |
875 | } | 876 | } |
876 | 877 | ||
877 | inode->i_data.a_ops = &udf_symlink_aops; | 878 | inode->i_data.a_ops = &udf_symlink_aops; |
878 | inode->i_op = &udf_symlink_inode_operations; | 879 | inode->i_op = &udf_symlink_inode_operations; |
879 | 880 | ||
880 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 881 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
881 | struct kernel_lb_addr eloc; | 882 | struct kernel_lb_addr eloc; |
882 | uint32_t bsize; | 883 | uint32_t bsize; |
883 | 884 | ||
884 | block = udf_new_block(sb, inode, | 885 | block = udf_new_block(sb, inode, |
885 | iinfo->i_location.partitionReferenceNum, | 886 | iinfo->i_location.partitionReferenceNum, |
886 | iinfo->i_location.logicalBlockNum, &err); | 887 | iinfo->i_location.logicalBlockNum, &err); |
887 | if (!block) | 888 | if (!block) |
888 | goto out_no_entry; | 889 | goto out_no_entry; |
889 | epos.block = iinfo->i_location; | 890 | epos.block = iinfo->i_location; |
890 | epos.offset = udf_file_entry_alloc_offset(inode); | 891 | epos.offset = udf_file_entry_alloc_offset(inode); |
891 | epos.bh = NULL; | 892 | epos.bh = NULL; |
892 | eloc.logicalBlockNum = block; | 893 | eloc.logicalBlockNum = block; |
893 | eloc.partitionReferenceNum = | 894 | eloc.partitionReferenceNum = |
894 | iinfo->i_location.partitionReferenceNum; | 895 | iinfo->i_location.partitionReferenceNum; |
895 | bsize = sb->s_blocksize; | 896 | bsize = sb->s_blocksize; |
896 | iinfo->i_lenExtents = bsize; | 897 | iinfo->i_lenExtents = bsize; |
897 | udf_add_aext(inode, &epos, &eloc, bsize, 0); | 898 | udf_add_aext(inode, &epos, &eloc, bsize, 0); |
898 | brelse(epos.bh); | 899 | brelse(epos.bh); |
899 | 900 | ||
900 | block = udf_get_pblock(sb, block, | 901 | block = udf_get_pblock(sb, block, |
901 | iinfo->i_location.partitionReferenceNum, | 902 | iinfo->i_location.partitionReferenceNum, |
902 | 0); | 903 | 0); |
903 | epos.bh = udf_tgetblk(sb, block); | 904 | epos.bh = udf_tgetblk(sb, block); |
904 | lock_buffer(epos.bh); | 905 | lock_buffer(epos.bh); |
905 | memset(epos.bh->b_data, 0x00, bsize); | 906 | memset(epos.bh->b_data, 0x00, bsize); |
906 | set_buffer_uptodate(epos.bh); | 907 | set_buffer_uptodate(epos.bh); |
907 | unlock_buffer(epos.bh); | 908 | unlock_buffer(epos.bh); |
908 | mark_buffer_dirty_inode(epos.bh, inode); | 909 | mark_buffer_dirty_inode(epos.bh, inode); |
909 | ea = epos.bh->b_data + udf_ext0_offset(inode); | 910 | ea = epos.bh->b_data + udf_ext0_offset(inode); |
910 | } else | 911 | } else |
911 | ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr; | 912 | ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr; |
912 | 913 | ||
913 | eoffset = sb->s_blocksize - udf_ext0_offset(inode); | 914 | eoffset = sb->s_blocksize - udf_ext0_offset(inode); |
914 | pc = (struct pathComponent *)ea; | 915 | pc = (struct pathComponent *)ea; |
915 | 916 | ||
916 | if (*symname == '/') { | 917 | if (*symname == '/') { |
917 | do { | 918 | do { |
918 | symname++; | 919 | symname++; |
919 | } while (*symname == '/'); | 920 | } while (*symname == '/'); |
920 | 921 | ||
921 | pc->componentType = 1; | 922 | pc->componentType = 1; |
922 | pc->lengthComponentIdent = 0; | 923 | pc->lengthComponentIdent = 0; |
923 | pc->componentFileVersionNum = 0; | 924 | pc->componentFileVersionNum = 0; |
924 | elen += sizeof(struct pathComponent); | 925 | elen += sizeof(struct pathComponent); |
925 | } | 926 | } |
926 | 927 | ||
927 | err = -ENAMETOOLONG; | 928 | err = -ENAMETOOLONG; |
928 | 929 | ||
929 | while (*symname) { | 930 | while (*symname) { |
930 | if (elen + sizeof(struct pathComponent) > eoffset) | 931 | if (elen + sizeof(struct pathComponent) > eoffset) |
931 | goto out_no_entry; | 932 | goto out_no_entry; |
932 | 933 | ||
933 | pc = (struct pathComponent *)(ea + elen); | 934 | pc = (struct pathComponent *)(ea + elen); |
934 | 935 | ||
935 | compstart = symname; | 936 | compstart = symname; |
936 | 937 | ||
937 | do { | 938 | do { |
938 | symname++; | 939 | symname++; |
939 | } while (*symname && *symname != '/'); | 940 | } while (*symname && *symname != '/'); |
940 | 941 | ||
941 | pc->componentType = 5; | 942 | pc->componentType = 5; |
942 | pc->lengthComponentIdent = 0; | 943 | pc->lengthComponentIdent = 0; |
943 | pc->componentFileVersionNum = 0; | 944 | pc->componentFileVersionNum = 0; |
944 | if (compstart[0] == '.') { | 945 | if (compstart[0] == '.') { |
945 | if ((symname - compstart) == 1) | 946 | if ((symname - compstart) == 1) |
946 | pc->componentType = 4; | 947 | pc->componentType = 4; |
947 | else if ((symname - compstart) == 2 && | 948 | else if ((symname - compstart) == 2 && |
948 | compstart[1] == '.') | 949 | compstart[1] == '.') |
949 | pc->componentType = 3; | 950 | pc->componentType = 3; |
950 | } | 951 | } |
951 | 952 | ||
952 | if (pc->componentType == 5) { | 953 | if (pc->componentType == 5) { |
953 | namelen = udf_put_filename(sb, compstart, name, | 954 | namelen = udf_put_filename(sb, compstart, name, |
954 | symname - compstart); | 955 | symname - compstart); |
955 | if (!namelen) | 956 | if (!namelen) |
956 | goto out_no_entry; | 957 | goto out_no_entry; |
957 | 958 | ||
958 | if (elen + sizeof(struct pathComponent) + namelen > | 959 | if (elen + sizeof(struct pathComponent) + namelen > |
959 | eoffset) | 960 | eoffset) |
960 | goto out_no_entry; | 961 | goto out_no_entry; |
961 | else | 962 | else |
962 | pc->lengthComponentIdent = namelen; | 963 | pc->lengthComponentIdent = namelen; |
963 | 964 | ||
964 | memcpy(pc->componentIdent, name, namelen); | 965 | memcpy(pc->componentIdent, name, namelen); |
965 | } | 966 | } |
966 | 967 | ||
967 | elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; | 968 | elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; |
968 | 969 | ||
969 | if (*symname) { | 970 | if (*symname) { |
970 | do { | 971 | do { |
971 | symname++; | 972 | symname++; |
972 | } while (*symname == '/'); | 973 | } while (*symname == '/'); |
973 | } | 974 | } |
974 | } | 975 | } |
975 | 976 | ||
976 | brelse(epos.bh); | 977 | brelse(epos.bh); |
977 | inode->i_size = elen; | 978 | inode->i_size = elen; |
978 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 979 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
979 | iinfo->i_lenAlloc = inode->i_size; | 980 | iinfo->i_lenAlloc = inode->i_size; |
980 | else | 981 | else |
981 | udf_truncate_tail_extent(inode); | 982 | udf_truncate_tail_extent(inode); |
982 | mark_inode_dirty(inode); | 983 | mark_inode_dirty(inode); |
983 | up_write(&iinfo->i_data_sem); | 984 | up_write(&iinfo->i_data_sem); |
984 | 985 | ||
985 | err = udf_add_nondir(dentry, inode); | 986 | err = udf_add_nondir(dentry, inode); |
986 | out: | 987 | out: |
987 | kfree(name); | 988 | kfree(name); |
988 | return err; | 989 | return err; |
989 | 990 | ||
990 | out_no_entry: | 991 | out_no_entry: |
991 | up_write(&iinfo->i_data_sem); | 992 | up_write(&iinfo->i_data_sem); |
992 | inode_dec_link_count(inode); | 993 | inode_dec_link_count(inode); |
993 | unlock_new_inode(inode); | 994 | unlock_new_inode(inode); |
994 | iput(inode); | 995 | iput(inode); |
995 | goto out; | 996 | goto out; |
996 | } | 997 | } |
997 | 998 | ||
998 | static int udf_link(struct dentry *old_dentry, struct inode *dir, | 999 | static int udf_link(struct dentry *old_dentry, struct inode *dir, |
999 | struct dentry *dentry) | 1000 | struct dentry *dentry) |
1000 | { | 1001 | { |
1001 | struct inode *inode = old_dentry->d_inode; | 1002 | struct inode *inode = old_dentry->d_inode; |
1002 | struct udf_fileident_bh fibh; | 1003 | struct udf_fileident_bh fibh; |
1003 | struct fileIdentDesc cfi, *fi; | 1004 | struct fileIdentDesc cfi, *fi; |
1004 | int err; | 1005 | int err; |
1005 | 1006 | ||
1006 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 1007 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
1007 | if (!fi) { | 1008 | if (!fi) { |
1008 | return err; | 1009 | return err; |
1009 | } | 1010 | } |
1010 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 1011 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); |
1011 | cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location); | 1012 | cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location); |
1012 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { | 1013 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { |
1013 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | 1014 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = |
1014 | cpu_to_le32(lvid_get_unique_id(inode->i_sb)); | 1015 | cpu_to_le32(lvid_get_unique_id(inode->i_sb)); |
1015 | } | 1016 | } |
1016 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 1017 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
1017 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1018 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
1018 | mark_inode_dirty(dir); | 1019 | mark_inode_dirty(dir); |
1019 | 1020 | ||
1020 | if (fibh.sbh != fibh.ebh) | 1021 | if (fibh.sbh != fibh.ebh) |
1021 | brelse(fibh.ebh); | 1022 | brelse(fibh.ebh); |
1022 | brelse(fibh.sbh); | 1023 | brelse(fibh.sbh); |
1023 | inc_nlink(inode); | 1024 | inc_nlink(inode); |
1024 | inode->i_ctime = current_fs_time(inode->i_sb); | 1025 | inode->i_ctime = current_fs_time(inode->i_sb); |
1025 | mark_inode_dirty(inode); | 1026 | mark_inode_dirty(inode); |
1026 | ihold(inode); | 1027 | ihold(inode); |
1027 | d_instantiate(dentry, inode); | 1028 | d_instantiate(dentry, inode); |
1028 | 1029 | ||
1029 | return 0; | 1030 | return 0; |
1030 | } | 1031 | } |
1031 | 1032 | ||
1032 | /* Anybody can rename anything with this: the permission checks are left to the | 1033 | /* Anybody can rename anything with this: the permission checks are left to the |
1033 | * higher-level routines. | 1034 | * higher-level routines. |
1034 | */ | 1035 | */ |
1035 | static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | 1036 | static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, |
1036 | struct inode *new_dir, struct dentry *new_dentry) | 1037 | struct inode *new_dir, struct dentry *new_dentry) |
1037 | { | 1038 | { |
1038 | struct inode *old_inode = old_dentry->d_inode; | 1039 | struct inode *old_inode = old_dentry->d_inode; |
1039 | struct inode *new_inode = new_dentry->d_inode; | 1040 | struct inode *new_inode = new_dentry->d_inode; |
1040 | struct udf_fileident_bh ofibh, nfibh; | 1041 | struct udf_fileident_bh ofibh, nfibh; |
1041 | struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL; | 1042 | struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL; |
1042 | struct fileIdentDesc ocfi, ncfi; | 1043 | struct fileIdentDesc ocfi, ncfi; |
1043 | struct buffer_head *dir_bh = NULL; | 1044 | struct buffer_head *dir_bh = NULL; |
1044 | int retval = -ENOENT; | 1045 | int retval = -ENOENT; |
1045 | struct kernel_lb_addr tloc; | 1046 | struct kernel_lb_addr tloc; |
1046 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); | 1047 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); |
1047 | 1048 | ||
1048 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); | 1049 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1049 | if (ofi) { | 1050 | if (ofi) { |
1050 | if (ofibh.sbh != ofibh.ebh) | 1051 | if (ofibh.sbh != ofibh.ebh) |
1051 | brelse(ofibh.ebh); | 1052 | brelse(ofibh.ebh); |
1052 | brelse(ofibh.sbh); | 1053 | brelse(ofibh.sbh); |
1053 | } | 1054 | } |
1054 | tloc = lelb_to_cpu(ocfi.icb.extLocation); | 1055 | tloc = lelb_to_cpu(ocfi.icb.extLocation); |
1055 | if (!ofi || udf_get_lb_pblock(old_dir->i_sb, &tloc, 0) | 1056 | if (!ofi || udf_get_lb_pblock(old_dir->i_sb, &tloc, 0) |
1056 | != old_inode->i_ino) | 1057 | != old_inode->i_ino) |
1057 | goto end_rename; | 1058 | goto end_rename; |
1058 | 1059 | ||
1059 | nfi = udf_find_entry(new_dir, &new_dentry->d_name, &nfibh, &ncfi); | 1060 | nfi = udf_find_entry(new_dir, &new_dentry->d_name, &nfibh, &ncfi); |
1060 | if (nfi) { | 1061 | if (nfi) { |
1061 | if (!new_inode) { | 1062 | if (!new_inode) { |
1062 | if (nfibh.sbh != nfibh.ebh) | 1063 | if (nfibh.sbh != nfibh.ebh) |
1063 | brelse(nfibh.ebh); | 1064 | brelse(nfibh.ebh); |
1064 | brelse(nfibh.sbh); | 1065 | brelse(nfibh.sbh); |
1065 | nfi = NULL; | 1066 | nfi = NULL; |
1066 | } | 1067 | } |
1067 | } | 1068 | } |
1068 | if (S_ISDIR(old_inode->i_mode)) { | 1069 | if (S_ISDIR(old_inode->i_mode)) { |
1069 | int offset = udf_ext0_offset(old_inode); | 1070 | int offset = udf_ext0_offset(old_inode); |
1070 | 1071 | ||
1071 | if (new_inode) { | 1072 | if (new_inode) { |
1072 | retval = -ENOTEMPTY; | 1073 | retval = -ENOTEMPTY; |
1073 | if (!empty_dir(new_inode)) | 1074 | if (!empty_dir(new_inode)) |
1074 | goto end_rename; | 1075 | goto end_rename; |
1075 | } | 1076 | } |
1076 | retval = -EIO; | 1077 | retval = -EIO; |
1077 | if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1078 | if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1078 | dir_fi = udf_get_fileident( | 1079 | dir_fi = udf_get_fileident( |
1079 | old_iinfo->i_ext.i_data - | 1080 | old_iinfo->i_ext.i_data - |
1080 | (old_iinfo->i_efe ? | 1081 | (old_iinfo->i_efe ? |
1081 | sizeof(struct extendedFileEntry) : | 1082 | sizeof(struct extendedFileEntry) : |
1082 | sizeof(struct fileEntry)), | 1083 | sizeof(struct fileEntry)), |
1083 | old_inode->i_sb->s_blocksize, &offset); | 1084 | old_inode->i_sb->s_blocksize, &offset); |
1084 | } else { | 1085 | } else { |
1085 | dir_bh = udf_bread(old_inode, 0, 0, &retval); | 1086 | dir_bh = udf_bread(old_inode, 0, 0, &retval); |
1086 | if (!dir_bh) | 1087 | if (!dir_bh) |
1087 | goto end_rename; | 1088 | goto end_rename; |
1088 | dir_fi = udf_get_fileident(dir_bh->b_data, | 1089 | dir_fi = udf_get_fileident(dir_bh->b_data, |
1089 | old_inode->i_sb->s_blocksize, &offset); | 1090 | old_inode->i_sb->s_blocksize, &offset); |
1090 | } | 1091 | } |
1091 | if (!dir_fi) | 1092 | if (!dir_fi) |
1092 | goto end_rename; | 1093 | goto end_rename; |
1093 | tloc = lelb_to_cpu(dir_fi->icb.extLocation); | 1094 | tloc = lelb_to_cpu(dir_fi->icb.extLocation); |
1094 | if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) != | 1095 | if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) != |
1095 | old_dir->i_ino) | 1096 | old_dir->i_ino) |
1096 | goto end_rename; | 1097 | goto end_rename; |
1097 | } | 1098 | } |
1098 | if (!nfi) { | 1099 | if (!nfi) { |
1099 | nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, | 1100 | nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, |
1100 | &retval); | 1101 | &retval); |
1101 | if (!nfi) | 1102 | if (!nfi) |
1102 | goto end_rename; | 1103 | goto end_rename; |
1103 | } | 1104 | } |
1104 | 1105 | ||
1105 | /* | 1106 | /* |
1106 | * Like most other Unix systems, set the ctime for inodes on a | 1107 | * Like most other Unix systems, set the ctime for inodes on a |
1107 | * rename. | 1108 | * rename. |
1108 | */ | 1109 | */ |
1109 | old_inode->i_ctime = current_fs_time(old_inode->i_sb); | 1110 | old_inode->i_ctime = current_fs_time(old_inode->i_sb); |
1110 | mark_inode_dirty(old_inode); | 1111 | mark_inode_dirty(old_inode); |
1111 | 1112 | ||
1112 | /* | 1113 | /* |
1113 | * ok, that's it | 1114 | * ok, that's it |
1114 | */ | 1115 | */ |
1115 | ncfi.fileVersionNum = ocfi.fileVersionNum; | 1116 | ncfi.fileVersionNum = ocfi.fileVersionNum; |
1116 | ncfi.fileCharacteristics = ocfi.fileCharacteristics; | 1117 | ncfi.fileCharacteristics = ocfi.fileCharacteristics; |
1117 | memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(struct long_ad)); | 1118 | memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(struct long_ad)); |
1118 | udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL); | 1119 | udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL); |
1119 | 1120 | ||
1120 | /* The old fid may have moved - find it again */ | 1121 | /* The old fid may have moved - find it again */ |
1121 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); | 1122 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1122 | udf_delete_entry(old_dir, ofi, &ofibh, &ocfi); | 1123 | udf_delete_entry(old_dir, ofi, &ofibh, &ocfi); |
1123 | 1124 | ||
1124 | if (new_inode) { | 1125 | if (new_inode) { |
1125 | new_inode->i_ctime = current_fs_time(new_inode->i_sb); | 1126 | new_inode->i_ctime = current_fs_time(new_inode->i_sb); |
1126 | inode_dec_link_count(new_inode); | 1127 | inode_dec_link_count(new_inode); |
1127 | } | 1128 | } |
1128 | old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb); | 1129 | old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb); |
1129 | mark_inode_dirty(old_dir); | 1130 | mark_inode_dirty(old_dir); |
1130 | 1131 | ||
1131 | if (dir_fi) { | 1132 | if (dir_fi) { |
1132 | dir_fi->icb.extLocation = cpu_to_lelb(UDF_I(new_dir)->i_location); | 1133 | dir_fi->icb.extLocation = cpu_to_lelb(UDF_I(new_dir)->i_location); |
1133 | udf_update_tag((char *)dir_fi, | 1134 | udf_update_tag((char *)dir_fi, |
1134 | (sizeof(struct fileIdentDesc) + | 1135 | (sizeof(struct fileIdentDesc) + |
1135 | le16_to_cpu(dir_fi->lengthOfImpUse) + 3) & ~3); | 1136 | le16_to_cpu(dir_fi->lengthOfImpUse) + 3) & ~3); |
1136 | if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1137 | if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
1137 | mark_inode_dirty(old_inode); | 1138 | mark_inode_dirty(old_inode); |
1138 | else | 1139 | else |
1139 | mark_buffer_dirty_inode(dir_bh, old_inode); | 1140 | mark_buffer_dirty_inode(dir_bh, old_inode); |
1140 | 1141 | ||
1141 | inode_dec_link_count(old_dir); | 1142 | inode_dec_link_count(old_dir); |
1142 | if (new_inode) | 1143 | if (new_inode) |
1143 | inode_dec_link_count(new_inode); | 1144 | inode_dec_link_count(new_inode); |
1144 | else { | 1145 | else { |
1145 | inc_nlink(new_dir); | 1146 | inc_nlink(new_dir); |
1146 | mark_inode_dirty(new_dir); | 1147 | mark_inode_dirty(new_dir); |
1147 | } | 1148 | } |
1148 | } | 1149 | } |
1149 | 1150 | ||
1150 | if (ofi) { | 1151 | if (ofi) { |
1151 | if (ofibh.sbh != ofibh.ebh) | 1152 | if (ofibh.sbh != ofibh.ebh) |
1152 | brelse(ofibh.ebh); | 1153 | brelse(ofibh.ebh); |
1153 | brelse(ofibh.sbh); | 1154 | brelse(ofibh.sbh); |
1154 | } | 1155 | } |
1155 | 1156 | ||
1156 | retval = 0; | 1157 | retval = 0; |
1157 | 1158 | ||
1158 | end_rename: | 1159 | end_rename: |
1159 | brelse(dir_bh); | 1160 | brelse(dir_bh); |
1160 | if (nfi) { | 1161 | if (nfi) { |
1161 | if (nfibh.sbh != nfibh.ebh) | 1162 | if (nfibh.sbh != nfibh.ebh) |
1162 | brelse(nfibh.ebh); | 1163 | brelse(nfibh.ebh); |
1163 | brelse(nfibh.sbh); | 1164 | brelse(nfibh.sbh); |
1164 | } | 1165 | } |
1165 | 1166 | ||
1166 | return retval; | 1167 | return retval; |
1167 | } | 1168 | } |
1168 | 1169 | ||
1169 | static struct dentry *udf_get_parent(struct dentry *child) | 1170 | static struct dentry *udf_get_parent(struct dentry *child) |
1170 | { | 1171 | { |
1171 | struct kernel_lb_addr tloc; | 1172 | struct kernel_lb_addr tloc; |
1172 | struct inode *inode = NULL; | 1173 | struct inode *inode = NULL; |
1173 | struct qstr dotdot = QSTR_INIT("..", 2); | 1174 | struct qstr dotdot = QSTR_INIT("..", 2); |
1174 | struct fileIdentDesc cfi; | 1175 | struct fileIdentDesc cfi; |
1175 | struct udf_fileident_bh fibh; | 1176 | struct udf_fileident_bh fibh; |
1176 | 1177 | ||
1177 | if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) | 1178 | if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) |
1178 | return ERR_PTR(-EACCES); | 1179 | return ERR_PTR(-EACCES); |
1179 | 1180 | ||
1180 | if (fibh.sbh != fibh.ebh) | 1181 | if (fibh.sbh != fibh.ebh) |
1181 | brelse(fibh.ebh); | 1182 | brelse(fibh.ebh); |
1182 | brelse(fibh.sbh); | 1183 | brelse(fibh.sbh); |
1183 | 1184 | ||
1184 | tloc = lelb_to_cpu(cfi.icb.extLocation); | 1185 | tloc = lelb_to_cpu(cfi.icb.extLocation); |
1185 | inode = udf_iget(child->d_inode->i_sb, &tloc); | 1186 | inode = udf_iget(child->d_inode->i_sb, &tloc); |
1186 | if (IS_ERR(inode)) | 1187 | if (IS_ERR(inode)) |
1187 | return ERR_CAST(inode); | 1188 | return ERR_CAST(inode); |
1188 | 1189 | ||
1189 | return d_obtain_alias(inode); | 1190 | return d_obtain_alias(inode); |
1190 | } | 1191 | } |
1191 | 1192 | ||
1192 | 1193 | ||
1193 | static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block, | 1194 | static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block, |
1194 | u16 partref, __u32 generation) | 1195 | u16 partref, __u32 generation) |
1195 | { | 1196 | { |
1196 | struct inode *inode; | 1197 | struct inode *inode; |
1197 | struct kernel_lb_addr loc; | 1198 | struct kernel_lb_addr loc; |
1198 | 1199 | ||
1199 | if (block == 0) | 1200 | if (block == 0) |
1200 | return ERR_PTR(-ESTALE); | 1201 | return ERR_PTR(-ESTALE); |
1201 | 1202 | ||
1202 | loc.logicalBlockNum = block; | 1203 | loc.logicalBlockNum = block; |
1203 | loc.partitionReferenceNum = partref; | 1204 | loc.partitionReferenceNum = partref; |
1204 | inode = udf_iget(sb, &loc); | 1205 | inode = udf_iget(sb, &loc); |
1205 | 1206 | ||
1206 | if (IS_ERR(inode)) | 1207 | if (IS_ERR(inode)) |
1207 | return ERR_CAST(inode); | 1208 | return ERR_CAST(inode); |
1208 | 1209 | ||
1209 | if (generation && inode->i_generation != generation) { | 1210 | if (generation && inode->i_generation != generation) { |
1210 | iput(inode); | 1211 | iput(inode); |
1211 | return ERR_PTR(-ESTALE); | 1212 | return ERR_PTR(-ESTALE); |
1212 | } | 1213 | } |
1213 | return d_obtain_alias(inode); | 1214 | return d_obtain_alias(inode); |
1214 | } | 1215 | } |
1215 | 1216 | ||
1216 | static struct dentry *udf_fh_to_dentry(struct super_block *sb, | 1217 | static struct dentry *udf_fh_to_dentry(struct super_block *sb, |
1217 | struct fid *fid, int fh_len, int fh_type) | 1218 | struct fid *fid, int fh_len, int fh_type) |
1218 | { | 1219 | { |
1219 | if ((fh_len != 3 && fh_len != 5) || | 1220 | if ((fh_len != 3 && fh_len != 5) || |
1220 | (fh_type != FILEID_UDF_WITH_PARENT && | 1221 | (fh_type != FILEID_UDF_WITH_PARENT && |
1221 | fh_type != FILEID_UDF_WITHOUT_PARENT)) | 1222 | fh_type != FILEID_UDF_WITHOUT_PARENT)) |
1222 | return NULL; | 1223 | return NULL; |
1223 | 1224 | ||
1224 | return udf_nfs_get_inode(sb, fid->udf.block, fid->udf.partref, | 1225 | return udf_nfs_get_inode(sb, fid->udf.block, fid->udf.partref, |
1225 | fid->udf.generation); | 1226 | fid->udf.generation); |
1226 | } | 1227 | } |
1227 | 1228 | ||
1228 | static struct dentry *udf_fh_to_parent(struct super_block *sb, | 1229 | static struct dentry *udf_fh_to_parent(struct super_block *sb, |
1229 | struct fid *fid, int fh_len, int fh_type) | 1230 | struct fid *fid, int fh_len, int fh_type) |
1230 | { | 1231 | { |
1231 | if (fh_len != 5 || fh_type != FILEID_UDF_WITH_PARENT) | 1232 | if (fh_len != 5 || fh_type != FILEID_UDF_WITH_PARENT) |
1232 | return NULL; | 1233 | return NULL; |
1233 | 1234 | ||
1234 | return udf_nfs_get_inode(sb, fid->udf.parent_block, | 1235 | return udf_nfs_get_inode(sb, fid->udf.parent_block, |
1235 | fid->udf.parent_partref, | 1236 | fid->udf.parent_partref, |
1236 | fid->udf.parent_generation); | 1237 | fid->udf.parent_generation); |
1237 | } | 1238 | } |
1238 | static int udf_encode_fh(struct inode *inode, __u32 *fh, int *lenp, | 1239 | static int udf_encode_fh(struct inode *inode, __u32 *fh, int *lenp, |
1239 | struct inode *parent) | 1240 | struct inode *parent) |
1240 | { | 1241 | { |
1241 | int len = *lenp; | 1242 | int len = *lenp; |
1242 | struct kernel_lb_addr location = UDF_I(inode)->i_location; | 1243 | struct kernel_lb_addr location = UDF_I(inode)->i_location; |
1243 | struct fid *fid = (struct fid *)fh; | 1244 | struct fid *fid = (struct fid *)fh; |
1244 | int type = FILEID_UDF_WITHOUT_PARENT; | 1245 | int type = FILEID_UDF_WITHOUT_PARENT; |
1245 | 1246 | ||
1246 | if (parent && (len < 5)) { | 1247 | if (parent && (len < 5)) { |
1247 | *lenp = 5; | 1248 | *lenp = 5; |
1248 | return FILEID_INVALID; | 1249 | return FILEID_INVALID; |
1249 | } else if (len < 3) { | 1250 | } else if (len < 3) { |
1250 | *lenp = 3; | 1251 | *lenp = 3; |
1251 | return FILEID_INVALID; | 1252 | return FILEID_INVALID; |
1252 | } | 1253 | } |
1253 | 1254 | ||
1254 | *lenp = 3; | 1255 | *lenp = 3; |
1255 | fid->udf.block = location.logicalBlockNum; | 1256 | fid->udf.block = location.logicalBlockNum; |
1256 | fid->udf.partref = location.partitionReferenceNum; | 1257 | fid->udf.partref = location.partitionReferenceNum; |
1257 | fid->udf.parent_partref = 0; | 1258 | fid->udf.parent_partref = 0; |
1258 | fid->udf.generation = inode->i_generation; | 1259 | fid->udf.generation = inode->i_generation; |
1259 | 1260 | ||
1260 | if (parent) { | 1261 | if (parent) { |
1261 | location = UDF_I(parent)->i_location; | 1262 | location = UDF_I(parent)->i_location; |
1262 | fid->udf.parent_block = location.logicalBlockNum; | 1263 | fid->udf.parent_block = location.logicalBlockNum; |
1263 | fid->udf.parent_partref = location.partitionReferenceNum; | 1264 | fid->udf.parent_partref = location.partitionReferenceNum; |
1264 | fid->udf.parent_generation = inode->i_generation; | 1265 | fid->udf.parent_generation = inode->i_generation; |
1265 | *lenp = 5; | 1266 | *lenp = 5; |
1266 | type = FILEID_UDF_WITH_PARENT; | 1267 | type = FILEID_UDF_WITH_PARENT; |
1267 | } | 1268 | } |
1268 | 1269 | ||
1269 | return type; | 1270 | return type; |
1270 | } | 1271 | } |
1271 | 1272 | ||
1272 | const struct export_operations udf_export_ops = { | 1273 | const struct export_operations udf_export_ops = { |
1273 | .encode_fh = udf_encode_fh, | 1274 | .encode_fh = udf_encode_fh, |
1274 | .fh_to_dentry = udf_fh_to_dentry, | 1275 | .fh_to_dentry = udf_fh_to_dentry, |
1275 | .fh_to_parent = udf_fh_to_parent, | 1276 | .fh_to_parent = udf_fh_to_parent, |
1276 | .get_parent = udf_get_parent, | 1277 | .get_parent = udf_get_parent, |
1277 | }; | 1278 | }; |
1278 | 1279 | ||
1279 | const struct inode_operations udf_dir_inode_operations = { | 1280 | const struct inode_operations udf_dir_inode_operations = { |
1280 | .lookup = udf_lookup, | 1281 | .lookup = udf_lookup, |
1281 | .create = udf_create, | 1282 | .create = udf_create, |
1282 | .link = udf_link, | 1283 | .link = udf_link, |
1283 | .unlink = udf_unlink, | 1284 | .unlink = udf_unlink, |
1284 | .symlink = udf_symlink, | 1285 | .symlink = udf_symlink, |
1285 | .mkdir = udf_mkdir, | 1286 | .mkdir = udf_mkdir, |
1286 | .rmdir = udf_rmdir, | 1287 | .rmdir = udf_rmdir, |
1287 | .mknod = udf_mknod, | 1288 | .mknod = udf_mknod, |
1288 | .rename = udf_rename, | 1289 | .rename = udf_rename, |
1289 | .tmpfile = udf_tmpfile, | 1290 | .tmpfile = udf_tmpfile, |
1290 | }; | 1291 | }; |
1291 | const struct inode_operations udf_symlink_inode_operations = { | 1292 | const struct inode_operations udf_symlink_inode_operations = { |
1292 | .readlink = generic_readlink, | 1293 | .readlink = generic_readlink, |
1293 | .follow_link = page_follow_link_light, | 1294 | .follow_link = page_follow_link_light, |
1294 | .put_link = page_put_link, | 1295 | .put_link = page_put_link, |
1295 | }; | 1296 | }; |
1296 | 1297 |
fs/udf/symlink.c
1 | /* | 1 | /* |
2 | * symlink.c | 2 | * symlink.c |
3 | * | 3 | * |
4 | * PURPOSE | 4 | * PURPOSE |
5 | * Symlink handling routines for the OSTA-UDF(tm) filesystem. | 5 | * Symlink handling routines for the OSTA-UDF(tm) filesystem. |
6 | * | 6 | * |
7 | * COPYRIGHT | 7 | * COPYRIGHT |
8 | * This file is distributed under the terms of the GNU General Public | 8 | * This file is distributed under the terms of the GNU General Public |
9 | * License (GPL). Copies of the GPL can be obtained from: | 9 | * License (GPL). Copies of the GPL can be obtained from: |
10 | * ftp://prep.ai.mit.edu/pub/gnu/GPL | 10 | * ftp://prep.ai.mit.edu/pub/gnu/GPL |
11 | * Each contributing author retains all rights to their own work. | 11 | * Each contributing author retains all rights to their own work. |
12 | * | 12 | * |
13 | * (C) 1998-2001 Ben Fennema | 13 | * (C) 1998-2001 Ben Fennema |
14 | * (C) 1999 Stelias Computing Inc | 14 | * (C) 1999 Stelias Computing Inc |
15 | * | 15 | * |
16 | * HISTORY | 16 | * HISTORY |
17 | * | 17 | * |
18 | * 04/16/99 blf Created. | 18 | * 04/16/99 blf Created. |
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include "udfdecl.h" | 22 | #include "udfdecl.h" |
23 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/stat.h> | 28 | #include <linux/stat.h> |
29 | #include <linux/pagemap.h> | 29 | #include <linux/pagemap.h> |
30 | #include <linux/buffer_head.h> | 30 | #include <linux/buffer_head.h> |
31 | #include "udf_i.h" | 31 | #include "udf_i.h" |
32 | 32 | ||
33 | static void udf_pc_to_char(struct super_block *sb, unsigned char *from, | 33 | static int udf_pc_to_char(struct super_block *sb, unsigned char *from, |
34 | int fromlen, unsigned char *to) | 34 | int fromlen, unsigned char *to, int tolen) |
35 | { | 35 | { |
36 | struct pathComponent *pc; | 36 | struct pathComponent *pc; |
37 | int elen = 0; | 37 | int elen = 0; |
38 | int comp_len; | ||
38 | unsigned char *p = to; | 39 | unsigned char *p = to; |
39 | 40 | ||
41 | /* Reserve one byte for terminating \0 */ | ||
42 | tolen--; | ||
40 | while (elen < fromlen) { | 43 | while (elen < fromlen) { |
41 | pc = (struct pathComponent *)(from + elen); | 44 | pc = (struct pathComponent *)(from + elen); |
45 | elen += sizeof(struct pathComponent); | ||
42 | switch (pc->componentType) { | 46 | switch (pc->componentType) { |
43 | case 1: | 47 | case 1: |
44 | /* | 48 | /* |
45 | * Symlink points to some place which should be agreed | 49 | * Symlink points to some place which should be agreed |
46 | * upon between originator and receiver of the media. Ignore. | 50 | * upon between originator and receiver of the media. Ignore. |
47 | */ | 51 | */ |
48 | if (pc->lengthComponentIdent > 0) | 52 | if (pc->lengthComponentIdent > 0) { |
53 | elen += pc->lengthComponentIdent; | ||
49 | break; | 54 | break; |
55 | } | ||
50 | /* Fall through */ | 56 | /* Fall through */ |
51 | case 2: | 57 | case 2: |
58 | if (tolen == 0) | ||
59 | return -ENAMETOOLONG; | ||
52 | p = to; | 60 | p = to; |
53 | *p++ = '/'; | 61 | *p++ = '/'; |
62 | tolen--; | ||
54 | break; | 63 | break; |
55 | case 3: | 64 | case 3: |
65 | if (tolen < 3) | ||
66 | return -ENAMETOOLONG; | ||
56 | memcpy(p, "../", 3); | 67 | memcpy(p, "../", 3); |
57 | p += 3; | 68 | p += 3; |
69 | tolen -= 3; | ||
58 | break; | 70 | break; |
59 | case 4: | 71 | case 4: |
72 | if (tolen < 2) | ||
73 | return -ENAMETOOLONG; | ||
60 | memcpy(p, "./", 2); | 74 | memcpy(p, "./", 2); |
61 | p += 2; | 75 | p += 2; |
76 | tolen -= 2; | ||
62 | /* that would be . - just ignore */ | 77 | /* that would be . - just ignore */ |
63 | break; | 78 | break; |
64 | case 5: | 79 | case 5: |
65 | p += udf_get_filename(sb, pc->componentIdent, p, | 80 | elen += pc->lengthComponentIdent; |
66 | pc->lengthComponentIdent); | 81 | if (elen > fromlen) |
82 | return -EIO; | ||
83 | comp_len = udf_get_filename(sb, pc->componentIdent, | ||
84 | pc->lengthComponentIdent, | ||
85 | p, tolen); | ||
86 | p += comp_len; | ||
87 | tolen -= comp_len; | ||
88 | if (tolen == 0) | ||
89 | return -ENAMETOOLONG; | ||
67 | *p++ = '/'; | 90 | *p++ = '/'; |
91 | tolen--; | ||
68 | break; | 92 | break; |
69 | } | 93 | } |
70 | elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; | ||
71 | } | 94 | } |
72 | if (p > to + 1) | 95 | if (p > to + 1) |
73 | p[-1] = '\0'; | 96 | p[-1] = '\0'; |
74 | else | 97 | else |
75 | p[0] = '\0'; | 98 | p[0] = '\0'; |
99 | return 0; | ||
76 | } | 100 | } |
77 | 101 | ||
78 | static int udf_symlink_filler(struct file *file, struct page *page) | 102 | static int udf_symlink_filler(struct file *file, struct page *page) |
79 | { | 103 | { |
80 | struct inode *inode = page->mapping->host; | 104 | struct inode *inode = page->mapping->host; |
81 | struct buffer_head *bh = NULL; | 105 | struct buffer_head *bh = NULL; |
82 | unsigned char *symlink; | 106 | unsigned char *symlink; |
83 | int err = -EIO; | 107 | int err; |
84 | unsigned char *p = kmap(page); | 108 | unsigned char *p = kmap(page); |
85 | struct udf_inode_info *iinfo; | 109 | struct udf_inode_info *iinfo; |
86 | uint32_t pos; | 110 | uint32_t pos; |
87 | 111 | ||
112 | /* We don't support symlinks longer than one block */ | ||
113 | if (inode->i_size > inode->i_sb->s_blocksize) { | ||
114 | err = -ENAMETOOLONG; | ||
115 | goto out_unmap; | ||
116 | } | ||
117 | |||
88 | iinfo = UDF_I(inode); | 118 | iinfo = UDF_I(inode); |
89 | pos = udf_block_map(inode, 0); | 119 | pos = udf_block_map(inode, 0); |
90 | 120 | ||
91 | down_read(&iinfo->i_data_sem); | 121 | down_read(&iinfo->i_data_sem); |
92 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 122 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
93 | symlink = iinfo->i_ext.i_data + iinfo->i_lenEAttr; | 123 | symlink = iinfo->i_ext.i_data + iinfo->i_lenEAttr; |
94 | } else { | 124 | } else { |
95 | bh = sb_bread(inode->i_sb, pos); | 125 | bh = sb_bread(inode->i_sb, pos); |
96 | 126 | ||
97 | if (!bh) | 127 | if (!bh) { |
98 | goto out; | 128 | err = -EIO; |
129 | goto out_unlock_inode; | ||
130 | } | ||
99 | 131 | ||
100 | symlink = bh->b_data; | 132 | symlink = bh->b_data; |
101 | } | 133 | } |
102 | 134 | ||
103 | udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); | 135 | err = udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p, PAGE_SIZE); |
104 | brelse(bh); | 136 | brelse(bh); |
137 | if (err) | ||
138 | goto out_unlock_inode; | ||
105 | 139 | ||
106 | up_read(&iinfo->i_data_sem); | 140 | up_read(&iinfo->i_data_sem); |
107 | SetPageUptodate(page); | 141 | SetPageUptodate(page); |
108 | kunmap(page); | 142 | kunmap(page); |
109 | unlock_page(page); | 143 | unlock_page(page); |
110 | return 0; | 144 | return 0; |
111 | 145 | ||
112 | out: | 146 | out_unlock_inode: |
113 | up_read(&iinfo->i_data_sem); | 147 | up_read(&iinfo->i_data_sem); |
114 | SetPageError(page); | 148 | SetPageError(page); |
149 | out_unmap: | ||
115 | kunmap(page); | 150 | kunmap(page); |
116 | unlock_page(page); | 151 | unlock_page(page); |
117 | return err; | 152 | return err; |
118 | } | 153 | } |
119 | 154 | ||
120 | /* | 155 | /* |
121 | * symlinks can't do much... | 156 | * symlinks can't do much... |
122 | */ | 157 | */ |
123 | const struct address_space_operations udf_symlink_aops = { | 158 | const struct address_space_operations udf_symlink_aops = { |
124 | .readpage = udf_symlink_filler, | 159 | .readpage = udf_symlink_filler, |
125 | }; | 160 | }; |
fs/udf/udfdecl.h
1 | #ifndef __UDF_DECL_H | 1 | #ifndef __UDF_DECL_H |
2 | #define __UDF_DECL_H | 2 | #define __UDF_DECL_H |
3 | 3 | ||
4 | #define pr_fmt(fmt) "UDF-fs: " fmt | 4 | #define pr_fmt(fmt) "UDF-fs: " fmt |
5 | 5 | ||
6 | #include "ecma_167.h" | 6 | #include "ecma_167.h" |
7 | #include "osta_udf.h" | 7 | #include "osta_udf.h" |
8 | 8 | ||
9 | #include <linux/fs.h> | 9 | #include <linux/fs.h> |
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/buffer_head.h> | 11 | #include <linux/buffer_head.h> |
12 | #include <linux/udf_fs_i.h> | 12 | #include <linux/udf_fs_i.h> |
13 | 13 | ||
14 | #include "udf_sb.h" | 14 | #include "udf_sb.h" |
15 | #include "udfend.h" | 15 | #include "udfend.h" |
16 | #include "udf_i.h" | 16 | #include "udf_i.h" |
17 | 17 | ||
18 | #define UDF_PREALLOCATE | 18 | #define UDF_PREALLOCATE |
19 | #define UDF_DEFAULT_PREALLOC_BLOCKS 8 | 19 | #define UDF_DEFAULT_PREALLOC_BLOCKS 8 |
20 | 20 | ||
21 | extern __printf(3, 4) void _udf_err(struct super_block *sb, | 21 | extern __printf(3, 4) void _udf_err(struct super_block *sb, |
22 | const char *function, const char *fmt, ...); | 22 | const char *function, const char *fmt, ...); |
23 | #define udf_err(sb, fmt, ...) \ | 23 | #define udf_err(sb, fmt, ...) \ |
24 | _udf_err(sb, __func__, fmt, ##__VA_ARGS__) | 24 | _udf_err(sb, __func__, fmt, ##__VA_ARGS__) |
25 | 25 | ||
26 | extern __printf(3, 4) void _udf_warn(struct super_block *sb, | 26 | extern __printf(3, 4) void _udf_warn(struct super_block *sb, |
27 | const char *function, const char *fmt, ...); | 27 | const char *function, const char *fmt, ...); |
28 | #define udf_warn(sb, fmt, ...) \ | 28 | #define udf_warn(sb, fmt, ...) \ |
29 | _udf_warn(sb, __func__, fmt, ##__VA_ARGS__) | 29 | _udf_warn(sb, __func__, fmt, ##__VA_ARGS__) |
30 | 30 | ||
31 | #define udf_info(fmt, ...) \ | 31 | #define udf_info(fmt, ...) \ |
32 | pr_info("INFO " fmt, ##__VA_ARGS__) | 32 | pr_info("INFO " fmt, ##__VA_ARGS__) |
33 | 33 | ||
34 | #undef UDFFS_DEBUG | 34 | #undef UDFFS_DEBUG |
35 | 35 | ||
36 | #ifdef UDFFS_DEBUG | 36 | #ifdef UDFFS_DEBUG |
37 | #define udf_debug(fmt, ...) \ | 37 | #define udf_debug(fmt, ...) \ |
38 | printk(KERN_DEBUG pr_fmt("%s:%d:%s: " fmt), \ | 38 | printk(KERN_DEBUG pr_fmt("%s:%d:%s: " fmt), \ |
39 | __FILE__, __LINE__, __func__, ##__VA_ARGS__) | 39 | __FILE__, __LINE__, __func__, ##__VA_ARGS__) |
40 | #else | 40 | #else |
41 | #define udf_debug(fmt, ...) \ | 41 | #define udf_debug(fmt, ...) \ |
42 | no_printk(fmt, ##__VA_ARGS__) | 42 | no_printk(fmt, ##__VA_ARGS__) |
43 | #endif | 43 | #endif |
44 | 44 | ||
45 | #define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) ) | 45 | #define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) ) |
46 | #define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) ) | 46 | #define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) ) |
47 | 47 | ||
48 | #define UDF_EXTENT_LENGTH_MASK 0x3FFFFFFF | 48 | #define UDF_EXTENT_LENGTH_MASK 0x3FFFFFFF |
49 | #define UDF_EXTENT_FLAG_MASK 0xC0000000 | 49 | #define UDF_EXTENT_FLAG_MASK 0xC0000000 |
50 | 50 | ||
51 | #define UDF_NAME_PAD 4 | 51 | #define UDF_NAME_PAD 4 |
52 | #define UDF_NAME_LEN 256 | 52 | #define UDF_NAME_LEN 256 |
53 | #define UDF_PATH_LEN 1023 | 53 | #define UDF_PATH_LEN 1023 |
54 | 54 | ||
55 | static inline size_t udf_file_entry_alloc_offset(struct inode *inode) | 55 | static inline size_t udf_file_entry_alloc_offset(struct inode *inode) |
56 | { | 56 | { |
57 | struct udf_inode_info *iinfo = UDF_I(inode); | 57 | struct udf_inode_info *iinfo = UDF_I(inode); |
58 | if (iinfo->i_use) | 58 | if (iinfo->i_use) |
59 | return sizeof(struct unallocSpaceEntry); | 59 | return sizeof(struct unallocSpaceEntry); |
60 | else if (iinfo->i_efe) | 60 | else if (iinfo->i_efe) |
61 | return sizeof(struct extendedFileEntry) + iinfo->i_lenEAttr; | 61 | return sizeof(struct extendedFileEntry) + iinfo->i_lenEAttr; |
62 | else | 62 | else |
63 | return sizeof(struct fileEntry) + iinfo->i_lenEAttr; | 63 | return sizeof(struct fileEntry) + iinfo->i_lenEAttr; |
64 | } | 64 | } |
65 | 65 | ||
66 | static inline size_t udf_ext0_offset(struct inode *inode) | 66 | static inline size_t udf_ext0_offset(struct inode *inode) |
67 | { | 67 | { |
68 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 68 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
69 | return udf_file_entry_alloc_offset(inode); | 69 | return udf_file_entry_alloc_offset(inode); |
70 | else | 70 | else |
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | /* computes tag checksum */ | 74 | /* computes tag checksum */ |
75 | u8 udf_tag_checksum(const struct tag *t); | 75 | u8 udf_tag_checksum(const struct tag *t); |
76 | 76 | ||
77 | struct dentry; | 77 | struct dentry; |
78 | struct inode; | 78 | struct inode; |
79 | struct task_struct; | 79 | struct task_struct; |
80 | struct buffer_head; | 80 | struct buffer_head; |
81 | struct super_block; | 81 | struct super_block; |
82 | 82 | ||
83 | extern const struct export_operations udf_export_ops; | 83 | extern const struct export_operations udf_export_ops; |
84 | extern const struct inode_operations udf_dir_inode_operations; | 84 | extern const struct inode_operations udf_dir_inode_operations; |
85 | extern const struct file_operations udf_dir_operations; | 85 | extern const struct file_operations udf_dir_operations; |
86 | extern const struct inode_operations udf_file_inode_operations; | 86 | extern const struct inode_operations udf_file_inode_operations; |
87 | extern const struct file_operations udf_file_operations; | 87 | extern const struct file_operations udf_file_operations; |
88 | extern const struct inode_operations udf_symlink_inode_operations; | 88 | extern const struct inode_operations udf_symlink_inode_operations; |
89 | extern const struct address_space_operations udf_aops; | 89 | extern const struct address_space_operations udf_aops; |
90 | extern const struct address_space_operations udf_adinicb_aops; | 90 | extern const struct address_space_operations udf_adinicb_aops; |
91 | extern const struct address_space_operations udf_symlink_aops; | 91 | extern const struct address_space_operations udf_symlink_aops; |
92 | 92 | ||
93 | struct udf_fileident_bh { | 93 | struct udf_fileident_bh { |
94 | struct buffer_head *sbh; | 94 | struct buffer_head *sbh; |
95 | struct buffer_head *ebh; | 95 | struct buffer_head *ebh; |
96 | int soffset; | 96 | int soffset; |
97 | int eoffset; | 97 | int eoffset; |
98 | }; | 98 | }; |
99 | 99 | ||
100 | struct udf_vds_record { | 100 | struct udf_vds_record { |
101 | uint32_t block; | 101 | uint32_t block; |
102 | uint32_t volDescSeqNum; | 102 | uint32_t volDescSeqNum; |
103 | }; | 103 | }; |
104 | 104 | ||
105 | struct generic_desc { | 105 | struct generic_desc { |
106 | struct tag descTag; | 106 | struct tag descTag; |
107 | __le32 volDescSeqNum; | 107 | __le32 volDescSeqNum; |
108 | }; | 108 | }; |
109 | 109 | ||
110 | struct ustr { | 110 | struct ustr { |
111 | uint8_t u_cmpID; | 111 | uint8_t u_cmpID; |
112 | uint8_t u_name[UDF_NAME_LEN - 2]; | 112 | uint8_t u_name[UDF_NAME_LEN - 2]; |
113 | uint8_t u_len; | 113 | uint8_t u_len; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | 116 | ||
117 | /* super.c */ | 117 | /* super.c */ |
118 | 118 | ||
119 | static inline void udf_updated_lvid(struct super_block *sb) | 119 | static inline void udf_updated_lvid(struct super_block *sb) |
120 | { | 120 | { |
121 | struct buffer_head *bh = UDF_SB(sb)->s_lvid_bh; | 121 | struct buffer_head *bh = UDF_SB(sb)->s_lvid_bh; |
122 | 122 | ||
123 | BUG_ON(!bh); | 123 | BUG_ON(!bh); |
124 | WARN_ON_ONCE(((struct logicalVolIntegrityDesc *) | 124 | WARN_ON_ONCE(((struct logicalVolIntegrityDesc *) |
125 | bh->b_data)->integrityType != | 125 | bh->b_data)->integrityType != |
126 | cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN)); | 126 | cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN)); |
127 | UDF_SB(sb)->s_lvid_dirty = 1; | 127 | UDF_SB(sb)->s_lvid_dirty = 1; |
128 | } | 128 | } |
129 | extern u64 lvid_get_unique_id(struct super_block *sb); | 129 | extern u64 lvid_get_unique_id(struct super_block *sb); |
130 | struct inode *udf_find_metadata_inode_efe(struct super_block *sb, | 130 | struct inode *udf_find_metadata_inode_efe(struct super_block *sb, |
131 | u32 meta_file_loc, u32 partition_num); | 131 | u32 meta_file_loc, u32 partition_num); |
132 | 132 | ||
133 | /* namei.c */ | 133 | /* namei.c */ |
134 | extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, | 134 | extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, |
135 | struct fileIdentDesc *, struct udf_fileident_bh *, | 135 | struct fileIdentDesc *, struct udf_fileident_bh *, |
136 | uint8_t *, uint8_t *); | 136 | uint8_t *, uint8_t *); |
137 | 137 | ||
138 | /* file.c */ | 138 | /* file.c */ |
139 | extern long udf_ioctl(struct file *, unsigned int, unsigned long); | 139 | extern long udf_ioctl(struct file *, unsigned int, unsigned long); |
140 | /* inode.c */ | 140 | /* inode.c */ |
141 | extern struct inode *__udf_iget(struct super_block *, struct kernel_lb_addr *, | 141 | extern struct inode *__udf_iget(struct super_block *, struct kernel_lb_addr *, |
142 | bool hidden_inode); | 142 | bool hidden_inode); |
143 | static inline struct inode *udf_iget_special(struct super_block *sb, | 143 | static inline struct inode *udf_iget_special(struct super_block *sb, |
144 | struct kernel_lb_addr *ino) | 144 | struct kernel_lb_addr *ino) |
145 | { | 145 | { |
146 | return __udf_iget(sb, ino, true); | 146 | return __udf_iget(sb, ino, true); |
147 | } | 147 | } |
148 | static inline struct inode *udf_iget(struct super_block *sb, | 148 | static inline struct inode *udf_iget(struct super_block *sb, |
149 | struct kernel_lb_addr *ino) | 149 | struct kernel_lb_addr *ino) |
150 | { | 150 | { |
151 | return __udf_iget(sb, ino, false); | 151 | return __udf_iget(sb, ino, false); |
152 | } | 152 | } |
153 | extern int udf_expand_file_adinicb(struct inode *); | 153 | extern int udf_expand_file_adinicb(struct inode *); |
154 | extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *); | 154 | extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *); |
155 | extern struct buffer_head *udf_bread(struct inode *, int, int, int *); | 155 | extern struct buffer_head *udf_bread(struct inode *, int, int, int *); |
156 | extern int udf_setsize(struct inode *, loff_t); | 156 | extern int udf_setsize(struct inode *, loff_t); |
157 | extern void udf_evict_inode(struct inode *); | 157 | extern void udf_evict_inode(struct inode *); |
158 | extern int udf_write_inode(struct inode *, struct writeback_control *wbc); | 158 | extern int udf_write_inode(struct inode *, struct writeback_control *wbc); |
159 | extern long udf_block_map(struct inode *, sector_t); | 159 | extern long udf_block_map(struct inode *, sector_t); |
160 | extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, | 160 | extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, |
161 | struct kernel_lb_addr *, uint32_t *, sector_t *); | 161 | struct kernel_lb_addr *, uint32_t *, sector_t *); |
162 | extern int udf_add_aext(struct inode *, struct extent_position *, | 162 | extern int udf_add_aext(struct inode *, struct extent_position *, |
163 | struct kernel_lb_addr *, uint32_t, int); | 163 | struct kernel_lb_addr *, uint32_t, int); |
164 | extern void udf_write_aext(struct inode *, struct extent_position *, | 164 | extern void udf_write_aext(struct inode *, struct extent_position *, |
165 | struct kernel_lb_addr *, uint32_t, int); | 165 | struct kernel_lb_addr *, uint32_t, int); |
166 | extern int8_t udf_delete_aext(struct inode *, struct extent_position, | 166 | extern int8_t udf_delete_aext(struct inode *, struct extent_position, |
167 | struct kernel_lb_addr, uint32_t); | 167 | struct kernel_lb_addr, uint32_t); |
168 | extern int8_t udf_next_aext(struct inode *, struct extent_position *, | 168 | extern int8_t udf_next_aext(struct inode *, struct extent_position *, |
169 | struct kernel_lb_addr *, uint32_t *, int); | 169 | struct kernel_lb_addr *, uint32_t *, int); |
170 | extern int8_t udf_current_aext(struct inode *, struct extent_position *, | 170 | extern int8_t udf_current_aext(struct inode *, struct extent_position *, |
171 | struct kernel_lb_addr *, uint32_t *, int); | 171 | struct kernel_lb_addr *, uint32_t *, int); |
172 | 172 | ||
173 | /* misc.c */ | 173 | /* misc.c */ |
174 | extern struct buffer_head *udf_tgetblk(struct super_block *, int); | 174 | extern struct buffer_head *udf_tgetblk(struct super_block *, int); |
175 | extern struct buffer_head *udf_tread(struct super_block *, int); | 175 | extern struct buffer_head *udf_tread(struct super_block *, int); |
176 | extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t, | 176 | extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t, |
177 | uint32_t, uint8_t); | 177 | uint32_t, uint8_t); |
178 | extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, | 178 | extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, |
179 | uint8_t); | 179 | uint8_t); |
180 | extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, | 180 | extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, |
181 | uint32_t, uint16_t *); | 181 | uint32_t, uint16_t *); |
182 | extern struct buffer_head *udf_read_ptagged(struct super_block *, | 182 | extern struct buffer_head *udf_read_ptagged(struct super_block *, |
183 | struct kernel_lb_addr *, uint32_t, | 183 | struct kernel_lb_addr *, uint32_t, |
184 | uint16_t *); | 184 | uint16_t *); |
185 | extern void udf_update_tag(char *, int); | 185 | extern void udf_update_tag(char *, int); |
186 | extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int); | 186 | extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int); |
187 | 187 | ||
188 | /* lowlevel.c */ | 188 | /* lowlevel.c */ |
189 | extern unsigned int udf_get_last_session(struct super_block *); | 189 | extern unsigned int udf_get_last_session(struct super_block *); |
190 | extern unsigned long udf_get_last_block(struct super_block *); | 190 | extern unsigned long udf_get_last_block(struct super_block *); |
191 | 191 | ||
192 | /* partition.c */ | 192 | /* partition.c */ |
193 | extern uint32_t udf_get_pblock(struct super_block *, uint32_t, uint16_t, | 193 | extern uint32_t udf_get_pblock(struct super_block *, uint32_t, uint16_t, |
194 | uint32_t); | 194 | uint32_t); |
195 | extern uint32_t udf_get_pblock_virt15(struct super_block *, uint32_t, uint16_t, | 195 | extern uint32_t udf_get_pblock_virt15(struct super_block *, uint32_t, uint16_t, |
196 | uint32_t); | 196 | uint32_t); |
197 | extern uint32_t udf_get_pblock_virt20(struct super_block *, uint32_t, uint16_t, | 197 | extern uint32_t udf_get_pblock_virt20(struct super_block *, uint32_t, uint16_t, |
198 | uint32_t); | 198 | uint32_t); |
199 | extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t, | 199 | extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t, |
200 | uint32_t); | 200 | uint32_t); |
201 | extern uint32_t udf_get_pblock_meta25(struct super_block *, uint32_t, uint16_t, | 201 | extern uint32_t udf_get_pblock_meta25(struct super_block *, uint32_t, uint16_t, |
202 | uint32_t); | 202 | uint32_t); |
203 | extern int udf_relocate_blocks(struct super_block *, long, long *); | 203 | extern int udf_relocate_blocks(struct super_block *, long, long *); |
204 | 204 | ||
205 | static inline uint32_t | 205 | static inline uint32_t |
206 | udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc, | 206 | udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc, |
207 | uint32_t offset) | 207 | uint32_t offset) |
208 | { | 208 | { |
209 | return udf_get_pblock(sb, loc->logicalBlockNum, | 209 | return udf_get_pblock(sb, loc->logicalBlockNum, |
210 | loc->partitionReferenceNum, offset); | 210 | loc->partitionReferenceNum, offset); |
211 | } | 211 | } |
212 | 212 | ||
213 | /* unicode.c */ | 213 | /* unicode.c */ |
214 | extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int); | 214 | extern int udf_get_filename(struct super_block *, uint8_t *, int, uint8_t *, |
215 | int); | ||
215 | extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, | 216 | extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, |
216 | int); | 217 | int); |
217 | extern int udf_build_ustr(struct ustr *, dstring *, int); | 218 | extern int udf_build_ustr(struct ustr *, dstring *, int); |
218 | extern int udf_CS0toUTF8(struct ustr *, const struct ustr *); | 219 | extern int udf_CS0toUTF8(struct ustr *, const struct ustr *); |
219 | 220 | ||
220 | /* ialloc.c */ | 221 | /* ialloc.c */ |
221 | extern void udf_free_inode(struct inode *); | 222 | extern void udf_free_inode(struct inode *); |
222 | extern struct inode *udf_new_inode(struct inode *, umode_t); | 223 | extern struct inode *udf_new_inode(struct inode *, umode_t); |
223 | 224 | ||
224 | /* truncate.c */ | 225 | /* truncate.c */ |
225 | extern void udf_truncate_tail_extent(struct inode *); | 226 | extern void udf_truncate_tail_extent(struct inode *); |
226 | extern void udf_discard_prealloc(struct inode *); | 227 | extern void udf_discard_prealloc(struct inode *); |
227 | extern void udf_truncate_extents(struct inode *); | 228 | extern void udf_truncate_extents(struct inode *); |
228 | 229 | ||
229 | /* balloc.c */ | 230 | /* balloc.c */ |
230 | extern void udf_free_blocks(struct super_block *, struct inode *, | 231 | extern void udf_free_blocks(struct super_block *, struct inode *, |
231 | struct kernel_lb_addr *, uint32_t, uint32_t); | 232 | struct kernel_lb_addr *, uint32_t, uint32_t); |
232 | extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t, | 233 | extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t, |
233 | uint32_t, uint32_t); | 234 | uint32_t, uint32_t); |
234 | extern int udf_new_block(struct super_block *, struct inode *, uint16_t, | 235 | extern int udf_new_block(struct super_block *, struct inode *, uint16_t, |
235 | uint32_t, int *); | 236 | uint32_t, int *); |
236 | 237 | ||
237 | /* directory.c */ | 238 | /* directory.c */ |
238 | extern struct fileIdentDesc *udf_fileident_read(struct inode *, loff_t *, | 239 | extern struct fileIdentDesc *udf_fileident_read(struct inode *, loff_t *, |
239 | struct udf_fileident_bh *, | 240 | struct udf_fileident_bh *, |
240 | struct fileIdentDesc *, | 241 | struct fileIdentDesc *, |
241 | struct extent_position *, | 242 | struct extent_position *, |
242 | struct kernel_lb_addr *, uint32_t *, | 243 | struct kernel_lb_addr *, uint32_t *, |
243 | sector_t *); | 244 | sector_t *); |
244 | extern struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, | 245 | extern struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, |
245 | int *offset); | 246 | int *offset); |
246 | extern struct long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int); | 247 | extern struct long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int); |
247 | extern struct short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int); | 248 | extern struct short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int); |
248 | 249 | ||
249 | /* udftime.c */ | 250 | /* udftime.c */ |
250 | extern struct timespec *udf_disk_stamp_to_time(struct timespec *dest, | 251 | extern struct timespec *udf_disk_stamp_to_time(struct timespec *dest, |
251 | struct timestamp src); | 252 | struct timestamp src); |
252 | extern struct timestamp *udf_time_to_disk_stamp(struct timestamp *dest, struct timespec src); | 253 | extern struct timestamp *udf_time_to_disk_stamp(struct timestamp *dest, struct timespec src); |
253 | 254 | ||
254 | #endif /* __UDF_DECL_H */ | 255 | #endif /* __UDF_DECL_H */ |
255 | 256 |
fs/udf/unicode.c
1 | /* | 1 | /* |
2 | * unicode.c | 2 | * unicode.c |
3 | * | 3 | * |
4 | * PURPOSE | 4 | * PURPOSE |
5 | * Routines for converting between UTF-8 and OSTA Compressed Unicode. | 5 | * Routines for converting between UTF-8 and OSTA Compressed Unicode. |
6 | * Also handles filename mangling | 6 | * Also handles filename mangling |
7 | * | 7 | * |
8 | * DESCRIPTION | 8 | * DESCRIPTION |
9 | * OSTA Compressed Unicode is explained in the OSTA UDF specification. | 9 | * OSTA Compressed Unicode is explained in the OSTA UDF specification. |
10 | * http://www.osta.org/ | 10 | * http://www.osta.org/ |
11 | * UTF-8 is explained in the IETF RFC XXXX. | 11 | * UTF-8 is explained in the IETF RFC XXXX. |
12 | * ftp://ftp.internic.net/rfc/rfcxxxx.txt | 12 | * ftp://ftp.internic.net/rfc/rfcxxxx.txt |
13 | * | 13 | * |
14 | * COPYRIGHT | 14 | * COPYRIGHT |
15 | * This file is distributed under the terms of the GNU General Public | 15 | * This file is distributed under the terms of the GNU General Public |
16 | * License (GPL). Copies of the GPL can be obtained from: | 16 | * License (GPL). Copies of the GPL can be obtained from: |
17 | * ftp://prep.ai.mit.edu/pub/gnu/GPL | 17 | * ftp://prep.ai.mit.edu/pub/gnu/GPL |
18 | * Each contributing author retains all rights to their own work. | 18 | * Each contributing author retains all rights to their own work. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include "udfdecl.h" | 21 | #include "udfdecl.h" |
22 | 22 | ||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/string.h> /* for memset */ | 24 | #include <linux/string.h> /* for memset */ |
25 | #include <linux/nls.h> | 25 | #include <linux/nls.h> |
26 | #include <linux/crc-itu-t.h> | 26 | #include <linux/crc-itu-t.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | 28 | ||
29 | #include "udf_sb.h" | 29 | #include "udf_sb.h" |
30 | 30 | ||
31 | static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int); | 31 | static int udf_translate_to_linux(uint8_t *, int, uint8_t *, int, uint8_t *, |
32 | int); | ||
32 | 33 | ||
33 | static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) | 34 | static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) |
34 | { | 35 | { |
35 | if ((!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN - 2)) | 36 | if ((!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN - 2)) |
36 | return 0; | 37 | return 0; |
37 | 38 | ||
38 | memset(dest, 0, sizeof(struct ustr)); | 39 | memset(dest, 0, sizeof(struct ustr)); |
39 | memcpy(dest->u_name, src, strlen); | 40 | memcpy(dest->u_name, src, strlen); |
40 | dest->u_cmpID = 0x08; | 41 | dest->u_cmpID = 0x08; |
41 | dest->u_len = strlen; | 42 | dest->u_len = strlen; |
42 | 43 | ||
43 | return strlen; | 44 | return strlen; |
44 | } | 45 | } |
45 | 46 | ||
46 | /* | 47 | /* |
47 | * udf_build_ustr | 48 | * udf_build_ustr |
48 | */ | 49 | */ |
49 | int udf_build_ustr(struct ustr *dest, dstring *ptr, int size) | 50 | int udf_build_ustr(struct ustr *dest, dstring *ptr, int size) |
50 | { | 51 | { |
51 | int usesize; | 52 | int usesize; |
52 | 53 | ||
53 | if (!dest || !ptr || !size) | 54 | if (!dest || !ptr || !size) |
54 | return -1; | 55 | return -1; |
55 | BUG_ON(size < 2); | 56 | BUG_ON(size < 2); |
56 | 57 | ||
57 | usesize = min_t(size_t, ptr[size - 1], sizeof(dest->u_name)); | 58 | usesize = min_t(size_t, ptr[size - 1], sizeof(dest->u_name)); |
58 | usesize = min(usesize, size - 2); | 59 | usesize = min(usesize, size - 2); |
59 | dest->u_cmpID = ptr[0]; | 60 | dest->u_cmpID = ptr[0]; |
60 | dest->u_len = usesize; | 61 | dest->u_len = usesize; |
61 | memcpy(dest->u_name, ptr + 1, usesize); | 62 | memcpy(dest->u_name, ptr + 1, usesize); |
62 | memset(dest->u_name + usesize, 0, sizeof(dest->u_name) - usesize); | 63 | memset(dest->u_name + usesize, 0, sizeof(dest->u_name) - usesize); |
63 | 64 | ||
64 | return 0; | 65 | return 0; |
65 | } | 66 | } |
66 | 67 | ||
67 | /* | 68 | /* |
68 | * udf_build_ustr_exact | 69 | * udf_build_ustr_exact |
69 | */ | 70 | */ |
70 | static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) | 71 | static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) |
71 | { | 72 | { |
72 | if ((!dest) || (!ptr) || (!exactsize)) | 73 | if ((!dest) || (!ptr) || (!exactsize)) |
73 | return -1; | 74 | return -1; |
74 | 75 | ||
75 | memset(dest, 0, sizeof(struct ustr)); | 76 | memset(dest, 0, sizeof(struct ustr)); |
76 | dest->u_cmpID = ptr[0]; | 77 | dest->u_cmpID = ptr[0]; |
77 | dest->u_len = exactsize - 1; | 78 | dest->u_len = exactsize - 1; |
78 | memcpy(dest->u_name, ptr + 1, exactsize - 1); | 79 | memcpy(dest->u_name, ptr + 1, exactsize - 1); |
79 | 80 | ||
80 | return 0; | 81 | return 0; |
81 | } | 82 | } |
82 | 83 | ||
83 | /* | 84 | /* |
84 | * udf_ocu_to_utf8 | 85 | * udf_ocu_to_utf8 |
85 | * | 86 | * |
86 | * PURPOSE | 87 | * PURPOSE |
87 | * Convert OSTA Compressed Unicode to the UTF-8 equivalent. | 88 | * Convert OSTA Compressed Unicode to the UTF-8 equivalent. |
88 | * | 89 | * |
89 | * PRE-CONDITIONS | 90 | * PRE-CONDITIONS |
90 | * utf Pointer to UTF-8 output buffer. | 91 | * utf Pointer to UTF-8 output buffer. |
91 | * ocu Pointer to OSTA Compressed Unicode input buffer | 92 | * ocu Pointer to OSTA Compressed Unicode input buffer |
92 | * of size UDF_NAME_LEN bytes. | 93 | * of size UDF_NAME_LEN bytes. |
93 | * both of type "struct ustr *" | 94 | * both of type "struct ustr *" |
94 | * | 95 | * |
95 | * POST-CONDITIONS | 96 | * POST-CONDITIONS |
96 | * <return> Zero on success. | 97 | * <return> Zero on success. |
97 | * | 98 | * |
98 | * HISTORY | 99 | * HISTORY |
99 | * November 12, 1997 - Andrew E. Mileski | 100 | * November 12, 1997 - Andrew E. Mileski |
100 | * Written, tested, and released. | 101 | * Written, tested, and released. |
101 | */ | 102 | */ |
102 | int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) | 103 | int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) |
103 | { | 104 | { |
104 | const uint8_t *ocu; | 105 | const uint8_t *ocu; |
105 | uint8_t cmp_id, ocu_len; | 106 | uint8_t cmp_id, ocu_len; |
106 | int i; | 107 | int i; |
107 | 108 | ||
108 | ocu_len = ocu_i->u_len; | 109 | ocu_len = ocu_i->u_len; |
109 | if (ocu_len == 0) { | 110 | if (ocu_len == 0) { |
110 | memset(utf_o, 0, sizeof(struct ustr)); | 111 | memset(utf_o, 0, sizeof(struct ustr)); |
111 | return 0; | 112 | return 0; |
112 | } | 113 | } |
113 | 114 | ||
114 | cmp_id = ocu_i->u_cmpID; | 115 | cmp_id = ocu_i->u_cmpID; |
115 | if (cmp_id != 8 && cmp_id != 16) { | 116 | if (cmp_id != 8 && cmp_id != 16) { |
116 | memset(utf_o, 0, sizeof(struct ustr)); | 117 | memset(utf_o, 0, sizeof(struct ustr)); |
117 | pr_err("unknown compression code (%d) stri=%s\n", | 118 | pr_err("unknown compression code (%d) stri=%s\n", |
118 | cmp_id, ocu_i->u_name); | 119 | cmp_id, ocu_i->u_name); |
119 | return 0; | 120 | return 0; |
120 | } | 121 | } |
121 | 122 | ||
122 | ocu = ocu_i->u_name; | 123 | ocu = ocu_i->u_name; |
123 | utf_o->u_len = 0; | 124 | utf_o->u_len = 0; |
124 | for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { | 125 | for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { |
125 | 126 | ||
126 | /* Expand OSTA compressed Unicode to Unicode */ | 127 | /* Expand OSTA compressed Unicode to Unicode */ |
127 | uint32_t c = ocu[i++]; | 128 | uint32_t c = ocu[i++]; |
128 | if (cmp_id == 16) | 129 | if (cmp_id == 16) |
129 | c = (c << 8) | ocu[i++]; | 130 | c = (c << 8) | ocu[i++]; |
130 | 131 | ||
131 | /* Compress Unicode to UTF-8 */ | 132 | /* Compress Unicode to UTF-8 */ |
132 | if (c < 0x80U) | 133 | if (c < 0x80U) |
133 | utf_o->u_name[utf_o->u_len++] = (uint8_t)c; | 134 | utf_o->u_name[utf_o->u_len++] = (uint8_t)c; |
134 | else if (c < 0x800U) { | 135 | else if (c < 0x800U) { |
135 | utf_o->u_name[utf_o->u_len++] = | 136 | utf_o->u_name[utf_o->u_len++] = |
136 | (uint8_t)(0xc0 | (c >> 6)); | 137 | (uint8_t)(0xc0 | (c >> 6)); |
137 | utf_o->u_name[utf_o->u_len++] = | 138 | utf_o->u_name[utf_o->u_len++] = |
138 | (uint8_t)(0x80 | (c & 0x3f)); | 139 | (uint8_t)(0x80 | (c & 0x3f)); |
139 | } else { | 140 | } else { |
140 | utf_o->u_name[utf_o->u_len++] = | 141 | utf_o->u_name[utf_o->u_len++] = |
141 | (uint8_t)(0xe0 | (c >> 12)); | 142 | (uint8_t)(0xe0 | (c >> 12)); |
142 | utf_o->u_name[utf_o->u_len++] = | 143 | utf_o->u_name[utf_o->u_len++] = |
143 | (uint8_t)(0x80 | | 144 | (uint8_t)(0x80 | |
144 | ((c >> 6) & 0x3f)); | 145 | ((c >> 6) & 0x3f)); |
145 | utf_o->u_name[utf_o->u_len++] = | 146 | utf_o->u_name[utf_o->u_len++] = |
146 | (uint8_t)(0x80 | (c & 0x3f)); | 147 | (uint8_t)(0x80 | (c & 0x3f)); |
147 | } | 148 | } |
148 | } | 149 | } |
149 | utf_o->u_cmpID = 8; | 150 | utf_o->u_cmpID = 8; |
150 | 151 | ||
151 | return utf_o->u_len; | 152 | return utf_o->u_len; |
152 | } | 153 | } |
153 | 154 | ||
154 | /* | 155 | /* |
155 | * | 156 | * |
156 | * udf_utf8_to_ocu | 157 | * udf_utf8_to_ocu |
157 | * | 158 | * |
158 | * PURPOSE | 159 | * PURPOSE |
159 | * Convert UTF-8 to the OSTA Compressed Unicode equivalent. | 160 | * Convert UTF-8 to the OSTA Compressed Unicode equivalent. |
160 | * | 161 | * |
161 | * DESCRIPTION | 162 | * DESCRIPTION |
162 | * This routine is only called by udf_lookup(). | 163 | * This routine is only called by udf_lookup(). |
163 | * | 164 | * |
164 | * PRE-CONDITIONS | 165 | * PRE-CONDITIONS |
165 | * ocu Pointer to OSTA Compressed Unicode output | 166 | * ocu Pointer to OSTA Compressed Unicode output |
166 | * buffer of size UDF_NAME_LEN bytes. | 167 | * buffer of size UDF_NAME_LEN bytes. |
167 | * utf Pointer to UTF-8 input buffer. | 168 | * utf Pointer to UTF-8 input buffer. |
168 | * utf_len Length of UTF-8 input buffer in bytes. | 169 | * utf_len Length of UTF-8 input buffer in bytes. |
169 | * | 170 | * |
170 | * POST-CONDITIONS | 171 | * POST-CONDITIONS |
171 | * <return> Zero on success. | 172 | * <return> Zero on success. |
172 | * | 173 | * |
173 | * HISTORY | 174 | * HISTORY |
174 | * November 12, 1997 - Andrew E. Mileski | 175 | * November 12, 1997 - Andrew E. Mileski |
175 | * Written, tested, and released. | 176 | * Written, tested, and released. |
176 | */ | 177 | */ |
177 | static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) | 178 | static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) |
178 | { | 179 | { |
179 | unsigned c, i, max_val, utf_char; | 180 | unsigned c, i, max_val, utf_char; |
180 | int utf_cnt, u_len; | 181 | int utf_cnt, u_len; |
181 | 182 | ||
182 | memset(ocu, 0, sizeof(dstring) * length); | 183 | memset(ocu, 0, sizeof(dstring) * length); |
183 | ocu[0] = 8; | 184 | ocu[0] = 8; |
184 | max_val = 0xffU; | 185 | max_val = 0xffU; |
185 | 186 | ||
186 | try_again: | 187 | try_again: |
187 | u_len = 0U; | 188 | u_len = 0U; |
188 | utf_char = 0U; | 189 | utf_char = 0U; |
189 | utf_cnt = 0U; | 190 | utf_cnt = 0U; |
190 | for (i = 0U; i < utf->u_len; i++) { | 191 | for (i = 0U; i < utf->u_len; i++) { |
191 | c = (uint8_t)utf->u_name[i]; | 192 | c = (uint8_t)utf->u_name[i]; |
192 | 193 | ||
193 | /* Complete a multi-byte UTF-8 character */ | 194 | /* Complete a multi-byte UTF-8 character */ |
194 | if (utf_cnt) { | 195 | if (utf_cnt) { |
195 | utf_char = (utf_char << 6) | (c & 0x3fU); | 196 | utf_char = (utf_char << 6) | (c & 0x3fU); |
196 | if (--utf_cnt) | 197 | if (--utf_cnt) |
197 | continue; | 198 | continue; |
198 | } else { | 199 | } else { |
199 | /* Check for a multi-byte UTF-8 character */ | 200 | /* Check for a multi-byte UTF-8 character */ |
200 | if (c & 0x80U) { | 201 | if (c & 0x80U) { |
201 | /* Start a multi-byte UTF-8 character */ | 202 | /* Start a multi-byte UTF-8 character */ |
202 | if ((c & 0xe0U) == 0xc0U) { | 203 | if ((c & 0xe0U) == 0xc0U) { |
203 | utf_char = c & 0x1fU; | 204 | utf_char = c & 0x1fU; |
204 | utf_cnt = 1; | 205 | utf_cnt = 1; |
205 | } else if ((c & 0xf0U) == 0xe0U) { | 206 | } else if ((c & 0xf0U) == 0xe0U) { |
206 | utf_char = c & 0x0fU; | 207 | utf_char = c & 0x0fU; |
207 | utf_cnt = 2; | 208 | utf_cnt = 2; |
208 | } else if ((c & 0xf8U) == 0xf0U) { | 209 | } else if ((c & 0xf8U) == 0xf0U) { |
209 | utf_char = c & 0x07U; | 210 | utf_char = c & 0x07U; |
210 | utf_cnt = 3; | 211 | utf_cnt = 3; |
211 | } else if ((c & 0xfcU) == 0xf8U) { | 212 | } else if ((c & 0xfcU) == 0xf8U) { |
212 | utf_char = c & 0x03U; | 213 | utf_char = c & 0x03U; |
213 | utf_cnt = 4; | 214 | utf_cnt = 4; |
214 | } else if ((c & 0xfeU) == 0xfcU) { | 215 | } else if ((c & 0xfeU) == 0xfcU) { |
215 | utf_char = c & 0x01U; | 216 | utf_char = c & 0x01U; |
216 | utf_cnt = 5; | 217 | utf_cnt = 5; |
217 | } else { | 218 | } else { |
218 | goto error_out; | 219 | goto error_out; |
219 | } | 220 | } |
220 | continue; | 221 | continue; |
221 | } else { | 222 | } else { |
222 | /* Single byte UTF-8 character (most common) */ | 223 | /* Single byte UTF-8 character (most common) */ |
223 | utf_char = c; | 224 | utf_char = c; |
224 | } | 225 | } |
225 | } | 226 | } |
226 | 227 | ||
227 | /* Choose no compression if necessary */ | 228 | /* Choose no compression if necessary */ |
228 | if (utf_char > max_val) { | 229 | if (utf_char > max_val) { |
229 | if (max_val == 0xffU) { | 230 | if (max_val == 0xffU) { |
230 | max_val = 0xffffU; | 231 | max_val = 0xffffU; |
231 | ocu[0] = (uint8_t)0x10U; | 232 | ocu[0] = (uint8_t)0x10U; |
232 | goto try_again; | 233 | goto try_again; |
233 | } | 234 | } |
234 | goto error_out; | 235 | goto error_out; |
235 | } | 236 | } |
236 | 237 | ||
237 | if (max_val == 0xffffU) | 238 | if (max_val == 0xffffU) |
238 | ocu[++u_len] = (uint8_t)(utf_char >> 8); | 239 | ocu[++u_len] = (uint8_t)(utf_char >> 8); |
239 | ocu[++u_len] = (uint8_t)(utf_char & 0xffU); | 240 | ocu[++u_len] = (uint8_t)(utf_char & 0xffU); |
240 | } | 241 | } |
241 | 242 | ||
242 | if (utf_cnt) { | 243 | if (utf_cnt) { |
243 | error_out: | 244 | error_out: |
244 | ocu[++u_len] = '?'; | 245 | ocu[++u_len] = '?'; |
245 | printk(KERN_DEBUG pr_fmt("bad UTF-8 character\n")); | 246 | printk(KERN_DEBUG pr_fmt("bad UTF-8 character\n")); |
246 | } | 247 | } |
247 | 248 | ||
248 | ocu[length - 1] = (uint8_t)u_len + 1; | 249 | ocu[length - 1] = (uint8_t)u_len + 1; |
249 | 250 | ||
250 | return u_len + 1; | 251 | return u_len + 1; |
251 | } | 252 | } |
252 | 253 | ||
253 | static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, | 254 | static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, |
254 | const struct ustr *ocu_i) | 255 | const struct ustr *ocu_i) |
255 | { | 256 | { |
256 | const uint8_t *ocu; | 257 | const uint8_t *ocu; |
257 | uint8_t cmp_id, ocu_len; | 258 | uint8_t cmp_id, ocu_len; |
258 | int i, len; | 259 | int i, len; |
259 | 260 | ||
260 | 261 | ||
261 | ocu_len = ocu_i->u_len; | 262 | ocu_len = ocu_i->u_len; |
262 | if (ocu_len == 0) { | 263 | if (ocu_len == 0) { |
263 | memset(utf_o, 0, sizeof(struct ustr)); | 264 | memset(utf_o, 0, sizeof(struct ustr)); |
264 | return 0; | 265 | return 0; |
265 | } | 266 | } |
266 | 267 | ||
267 | cmp_id = ocu_i->u_cmpID; | 268 | cmp_id = ocu_i->u_cmpID; |
268 | if (cmp_id != 8 && cmp_id != 16) { | 269 | if (cmp_id != 8 && cmp_id != 16) { |
269 | memset(utf_o, 0, sizeof(struct ustr)); | 270 | memset(utf_o, 0, sizeof(struct ustr)); |
270 | pr_err("unknown compression code (%d) stri=%s\n", | 271 | pr_err("unknown compression code (%d) stri=%s\n", |
271 | cmp_id, ocu_i->u_name); | 272 | cmp_id, ocu_i->u_name); |
272 | return 0; | 273 | return 0; |
273 | } | 274 | } |
274 | 275 | ||
275 | ocu = ocu_i->u_name; | 276 | ocu = ocu_i->u_name; |
276 | utf_o->u_len = 0; | 277 | utf_o->u_len = 0; |
277 | for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { | 278 | for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { |
278 | /* Expand OSTA compressed Unicode to Unicode */ | 279 | /* Expand OSTA compressed Unicode to Unicode */ |
279 | uint32_t c = ocu[i++]; | 280 | uint32_t c = ocu[i++]; |
280 | if (cmp_id == 16) | 281 | if (cmp_id == 16) |
281 | c = (c << 8) | ocu[i++]; | 282 | c = (c << 8) | ocu[i++]; |
282 | 283 | ||
283 | len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len], | 284 | len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len], |
284 | UDF_NAME_LEN - utf_o->u_len); | 285 | UDF_NAME_LEN - utf_o->u_len); |
285 | /* Valid character? */ | 286 | /* Valid character? */ |
286 | if (len >= 0) | 287 | if (len >= 0) |
287 | utf_o->u_len += len; | 288 | utf_o->u_len += len; |
288 | else | 289 | else |
289 | utf_o->u_name[utf_o->u_len++] = '?'; | 290 | utf_o->u_name[utf_o->u_len++] = '?'; |
290 | } | 291 | } |
291 | utf_o->u_cmpID = 8; | 292 | utf_o->u_cmpID = 8; |
292 | 293 | ||
293 | return utf_o->u_len; | 294 | return utf_o->u_len; |
294 | } | 295 | } |
295 | 296 | ||
296 | static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, | 297 | static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, |
297 | int length) | 298 | int length) |
298 | { | 299 | { |
299 | int len; | 300 | int len; |
300 | unsigned i, max_val; | 301 | unsigned i, max_val; |
301 | uint16_t uni_char; | 302 | uint16_t uni_char; |
302 | int u_len; | 303 | int u_len; |
303 | 304 | ||
304 | memset(ocu, 0, sizeof(dstring) * length); | 305 | memset(ocu, 0, sizeof(dstring) * length); |
305 | ocu[0] = 8; | 306 | ocu[0] = 8; |
306 | max_val = 0xffU; | 307 | max_val = 0xffU; |
307 | 308 | ||
308 | try_again: | 309 | try_again: |
309 | u_len = 0U; | 310 | u_len = 0U; |
310 | for (i = 0U; i < uni->u_len; i++) { | 311 | for (i = 0U; i < uni->u_len; i++) { |
311 | len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char); | 312 | len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char); |
312 | if (!len) | 313 | if (!len) |
313 | continue; | 314 | continue; |
314 | /* Invalid character, deal with it */ | 315 | /* Invalid character, deal with it */ |
315 | if (len < 0) { | 316 | if (len < 0) { |
316 | len = 1; | 317 | len = 1; |
317 | uni_char = '?'; | 318 | uni_char = '?'; |
318 | } | 319 | } |
319 | 320 | ||
320 | if (uni_char > max_val) { | 321 | if (uni_char > max_val) { |
321 | max_val = 0xffffU; | 322 | max_val = 0xffffU; |
322 | ocu[0] = (uint8_t)0x10U; | 323 | ocu[0] = (uint8_t)0x10U; |
323 | goto try_again; | 324 | goto try_again; |
324 | } | 325 | } |
325 | 326 | ||
326 | if (max_val == 0xffffU) | 327 | if (max_val == 0xffffU) |
327 | ocu[++u_len] = (uint8_t)(uni_char >> 8); | 328 | ocu[++u_len] = (uint8_t)(uni_char >> 8); |
328 | ocu[++u_len] = (uint8_t)(uni_char & 0xffU); | 329 | ocu[++u_len] = (uint8_t)(uni_char & 0xffU); |
329 | i += len - 1; | 330 | i += len - 1; |
330 | } | 331 | } |
331 | 332 | ||
332 | ocu[length - 1] = (uint8_t)u_len + 1; | 333 | ocu[length - 1] = (uint8_t)u_len + 1; |
333 | return u_len + 1; | 334 | return u_len + 1; |
334 | } | 335 | } |
335 | 336 | ||
336 | int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, | 337 | int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, |
337 | int flen) | 338 | uint8_t *dname, int dlen) |
338 | { | 339 | { |
339 | struct ustr *filename, *unifilename; | 340 | struct ustr *filename, *unifilename; |
340 | int len = 0; | 341 | int len = 0; |
341 | 342 | ||
342 | filename = kmalloc(sizeof(struct ustr), GFP_NOFS); | 343 | filename = kmalloc(sizeof(struct ustr), GFP_NOFS); |
343 | if (!filename) | 344 | if (!filename) |
344 | return 0; | 345 | return 0; |
345 | 346 | ||
346 | unifilename = kmalloc(sizeof(struct ustr), GFP_NOFS); | 347 | unifilename = kmalloc(sizeof(struct ustr), GFP_NOFS); |
347 | if (!unifilename) | 348 | if (!unifilename) |
348 | goto out1; | 349 | goto out1; |
349 | 350 | ||
350 | if (udf_build_ustr_exact(unifilename, sname, flen)) | 351 | if (udf_build_ustr_exact(unifilename, sname, slen)) |
351 | goto out2; | 352 | goto out2; |
352 | 353 | ||
353 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { | 354 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { |
354 | if (!udf_CS0toUTF8(filename, unifilename)) { | 355 | if (!udf_CS0toUTF8(filename, unifilename)) { |
355 | udf_debug("Failed in udf_get_filename: sname = %s\n", | 356 | udf_debug("Failed in udf_get_filename: sname = %s\n", |
356 | sname); | 357 | sname); |
357 | goto out2; | 358 | goto out2; |
358 | } | 359 | } |
359 | } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { | 360 | } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { |
360 | if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, filename, | 361 | if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, filename, |
361 | unifilename)) { | 362 | unifilename)) { |
362 | udf_debug("Failed in udf_get_filename: sname = %s\n", | 363 | udf_debug("Failed in udf_get_filename: sname = %s\n", |
363 | sname); | 364 | sname); |
364 | goto out2; | 365 | goto out2; |
365 | } | 366 | } |
366 | } else | 367 | } else |
367 | goto out2; | 368 | goto out2; |
368 | 369 | ||
369 | len = udf_translate_to_linux(dname, filename->u_name, filename->u_len, | 370 | len = udf_translate_to_linux(dname, dlen, |
371 | filename->u_name, filename->u_len, | ||
370 | unifilename->u_name, unifilename->u_len); | 372 | unifilename->u_name, unifilename->u_len); |
371 | out2: | 373 | out2: |
372 | kfree(unifilename); | 374 | kfree(unifilename); |
373 | out1: | 375 | out1: |
374 | kfree(filename); | 376 | kfree(filename); |
375 | return len; | 377 | return len; |
376 | } | 378 | } |
377 | 379 | ||
378 | int udf_put_filename(struct super_block *sb, const uint8_t *sname, | 380 | int udf_put_filename(struct super_block *sb, const uint8_t *sname, |
379 | uint8_t *dname, int flen) | 381 | uint8_t *dname, int flen) |
380 | { | 382 | { |
381 | struct ustr unifilename; | 383 | struct ustr unifilename; |
382 | int namelen; | 384 | int namelen; |
383 | 385 | ||
384 | if (!udf_char_to_ustr(&unifilename, sname, flen)) | 386 | if (!udf_char_to_ustr(&unifilename, sname, flen)) |
385 | return 0; | 387 | return 0; |
386 | 388 | ||
387 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { | 389 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { |
388 | namelen = udf_UTF8toCS0(dname, &unifilename, UDF_NAME_LEN); | 390 | namelen = udf_UTF8toCS0(dname, &unifilename, UDF_NAME_LEN); |
389 | if (!namelen) | 391 | if (!namelen) |
390 | return 0; | 392 | return 0; |
391 | } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { | 393 | } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { |
392 | namelen = udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname, | 394 | namelen = udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname, |
393 | &unifilename, UDF_NAME_LEN); | 395 | &unifilename, UDF_NAME_LEN); |
394 | if (!namelen) | 396 | if (!namelen) |
395 | return 0; | 397 | return 0; |
396 | } else | 398 | } else |
397 | return 0; | 399 | return 0; |
398 | 400 | ||
399 | return namelen; | 401 | return namelen; |
400 | } | 402 | } |
401 | 403 | ||
402 | #define ILLEGAL_CHAR_MARK '_' | 404 | #define ILLEGAL_CHAR_MARK '_' |
403 | #define EXT_MARK '.' | 405 | #define EXT_MARK '.' |
404 | #define CRC_MARK '#' | 406 | #define CRC_MARK '#' |
405 | #define EXT_SIZE 5 | 407 | #define EXT_SIZE 5 |
408 | /* Number of chars we need to store generated CRC to make filename unique */ | ||
409 | #define CRC_LEN 5 | ||
406 | 410 | ||
407 | static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, | 411 | static int udf_translate_to_linux(uint8_t *newName, int newLen, |
408 | int udfLen, uint8_t *fidName, | 412 | uint8_t *udfName, int udfLen, |
409 | int fidNameLen) | 413 | uint8_t *fidName, int fidNameLen) |
410 | { | 414 | { |
411 | int index, newIndex = 0, needsCRC = 0; | 415 | int index, newIndex = 0, needsCRC = 0; |
412 | int extIndex = 0, newExtIndex = 0, hasExt = 0; | 416 | int extIndex = 0, newExtIndex = 0, hasExt = 0; |
413 | unsigned short valueCRC; | 417 | unsigned short valueCRC; |
414 | uint8_t curr; | 418 | uint8_t curr; |
415 | 419 | ||
416 | if (udfName[0] == '.' && | 420 | if (udfName[0] == '.' && |
417 | (udfLen == 1 || (udfLen == 2 && udfName[1] == '.'))) { | 421 | (udfLen == 1 || (udfLen == 2 && udfName[1] == '.'))) { |
418 | needsCRC = 1; | 422 | needsCRC = 1; |
419 | newIndex = udfLen; | 423 | newIndex = udfLen; |
420 | memcpy(newName, udfName, udfLen); | 424 | memcpy(newName, udfName, udfLen); |
421 | } else { | 425 | } else { |
422 | for (index = 0; index < udfLen; index++) { | 426 | for (index = 0; index < udfLen; index++) { |
423 | curr = udfName[index]; | 427 | curr = udfName[index]; |
424 | if (curr == '/' || curr == 0) { | 428 | if (curr == '/' || curr == 0) { |
425 | needsCRC = 1; | 429 | needsCRC = 1; |
426 | curr = ILLEGAL_CHAR_MARK; | 430 | curr = ILLEGAL_CHAR_MARK; |
427 | while (index + 1 < udfLen && | 431 | while (index + 1 < udfLen && |
428 | (udfName[index + 1] == '/' || | 432 | (udfName[index + 1] == '/' || |
429 | udfName[index + 1] == 0)) | 433 | udfName[index + 1] == 0)) |
430 | index++; | 434 | index++; |
431 | } | 435 | } |
432 | if (curr == EXT_MARK && | 436 | if (curr == EXT_MARK && |
433 | (udfLen - index - 1) <= EXT_SIZE) { | 437 | (udfLen - index - 1) <= EXT_SIZE) { |
434 | if (udfLen == index + 1) | 438 | if (udfLen == index + 1) |
435 | hasExt = 0; | 439 | hasExt = 0; |
436 | else { | 440 | else { |
437 | hasExt = 1; | 441 | hasExt = 1; |
438 | extIndex = index; | 442 | extIndex = index; |
439 | newExtIndex = newIndex; | 443 | newExtIndex = newIndex; |
440 | } | 444 | } |
441 | } | 445 | } |
442 | if (newIndex < 256) | 446 | if (newIndex < newLen) |
443 | newName[newIndex++] = curr; | 447 | newName[newIndex++] = curr; |
444 | else | 448 | else |
445 | needsCRC = 1; | 449 | needsCRC = 1; |
446 | } | 450 | } |
447 | } | 451 | } |
448 | if (needsCRC) { | 452 | if (needsCRC) { |
449 | uint8_t ext[EXT_SIZE]; | 453 | uint8_t ext[EXT_SIZE]; |
450 | int localExtIndex = 0; | 454 | int localExtIndex = 0; |
451 | 455 | ||
452 | if (hasExt) { | 456 | if (hasExt) { |
453 | int maxFilenameLen; | 457 | int maxFilenameLen; |
454 | for (index = 0; | 458 | for (index = 0; |
455 | index < EXT_SIZE && extIndex + index + 1 < udfLen; | 459 | index < EXT_SIZE && extIndex + index + 1 < udfLen; |
456 | index++) { | 460 | index++) { |
457 | curr = udfName[extIndex + index + 1]; | 461 | curr = udfName[extIndex + index + 1]; |
458 | 462 | ||
459 | if (curr == '/' || curr == 0) { | 463 | if (curr == '/' || curr == 0) { |
460 | needsCRC = 1; | 464 | needsCRC = 1; |
461 | curr = ILLEGAL_CHAR_MARK; | 465 | curr = ILLEGAL_CHAR_MARK; |
462 | while (extIndex + index + 2 < udfLen && | 466 | while (extIndex + index + 2 < udfLen && |
463 | (index + 1 < EXT_SIZE && | 467 | (index + 1 < EXT_SIZE && |
464 | (udfName[extIndex + index + 2] == '/' || | 468 | (udfName[extIndex + index + 2] == '/' || |
465 | udfName[extIndex + index + 2] == 0))) | 469 | udfName[extIndex + index + 2] == 0))) |
466 | index++; | 470 | index++; |
467 | } | 471 | } |
468 | ext[localExtIndex++] = curr; | 472 | ext[localExtIndex++] = curr; |
469 | } | 473 | } |
470 | maxFilenameLen = 250 - localExtIndex; | 474 | maxFilenameLen = newLen - CRC_LEN - localExtIndex; |
471 | if (newIndex > maxFilenameLen) | 475 | if (newIndex > maxFilenameLen) |
472 | newIndex = maxFilenameLen; | 476 | newIndex = maxFilenameLen; |
473 | else | 477 | else |
474 | newIndex = newExtIndex; | 478 | newIndex = newExtIndex; |
475 | } else if (newIndex > 250) | 479 | } else if (newIndex > newLen - CRC_LEN) |
476 | newIndex = 250; | 480 | newIndex = newLen - CRC_LEN; |
477 | newName[newIndex++] = CRC_MARK; | 481 | newName[newIndex++] = CRC_MARK; |
478 | valueCRC = crc_itu_t(0, fidName, fidNameLen); | 482 | valueCRC = crc_itu_t(0, fidName, fidNameLen); |
479 | newName[newIndex++] = hex_asc_upper_hi(valueCRC >> 8); | 483 | newName[newIndex++] = hex_asc_upper_hi(valueCRC >> 8); |
480 | newName[newIndex++] = hex_asc_upper_lo(valueCRC >> 8); | 484 | newName[newIndex++] = hex_asc_upper_lo(valueCRC >> 8); |
481 | newName[newIndex++] = hex_asc_upper_hi(valueCRC); | 485 | newName[newIndex++] = hex_asc_upper_hi(valueCRC); |
482 | newName[newIndex++] = hex_asc_upper_lo(valueCRC); | 486 | newName[newIndex++] = hex_asc_upper_lo(valueCRC); |
483 | 487 | ||
484 | if (hasExt) { | 488 | if (hasExt) { |
485 | newName[newIndex++] = EXT_MARK; | 489 | newName[newIndex++] = EXT_MARK; |
486 | for (index = 0; index < localExtIndex; index++) | 490 | for (index = 0; index < localExtIndex; index++) |
487 | newName[newIndex++] = ext[index]; | 491 | newName[newIndex++] = ext[index]; |
488 | } | 492 | } |
489 | } | 493 | } |
490 | 494 | ||
491 | return newIndex; | 495 | return newIndex; |
492 | } | 496 | } |
493 | 497 |