1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "udfdecl.h"
23
24#include "udf_i.h"
25#include "udf_sb.h"
26#include <linux/string.h>
27#include <linux/errno.h>
28#include <linux/mm.h>
29#include <linux/slab.h>
30#include <linux/quotaops.h>
31#include <linux/smp_lock.h>
32#include <linux/buffer_head.h>
33#include <linux/sched.h>
34
35static inline int udf_match(int len1, const char *name1, int len2,
36 const char *name2)
37{
38 if (len1 != len2)
39 return 0;
40
41 return !memcmp(name1, name2, len1);
42}
43
44int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
45 struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh,
46 uint8_t * impuse, uint8_t * fileident)
47{
48 uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(tag);
49 uint16_t crc;
50 uint8_t checksum = 0;
51 int i;
52 int offset;
53 uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse);
54 uint8_t lfi = cfi->lengthFileIdent;
55 int padlen = fibh->eoffset - fibh->soffset - liu - lfi -
56 sizeof(struct fileIdentDesc);
57 int adinicb = 0;
58
59 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
60 adinicb = 1;
61
62 offset = fibh->soffset + sizeof(struct fileIdentDesc);
63
64 if (impuse) {
65 if (adinicb || (offset + liu < 0)) {
66 memcpy((uint8_t *)sfi->impUse, impuse, liu);
67 } else if (offset >= 0) {
68 memcpy(fibh->ebh->b_data + offset, impuse, liu);
69 } else {
70 memcpy((uint8_t *)sfi->impUse, impuse, -offset);
71 memcpy(fibh->ebh->b_data, impuse - offset, liu + offset);
72 }
73 }
74
75 offset += liu;
76
77 if (fileident) {
78 if (adinicb || (offset + lfi < 0)) {
79 memcpy((uint8_t *)sfi->fileIdent + liu, fileident, lfi);
80 } else if (offset >= 0) {
81 memcpy(fibh->ebh->b_data + offset, fileident, lfi);
82 } else {
83 memcpy((uint8_t *)sfi->fileIdent + liu, fileident, -offset);
84 memcpy(fibh->ebh->b_data, fileident - offset, lfi + offset);
85 }
86 }
87
88 offset += lfi;
89
90 if (adinicb || (offset + padlen < 0)) {
91 memset((uint8_t *)sfi->padding + liu + lfi, 0x00, padlen);
92 } else if (offset >= 0) {
93 memset(fibh->ebh->b_data + offset, 0x00, padlen);
94 } else {
95 memset((uint8_t *)sfi->padding + liu + lfi, 0x00, -offset);
96 memset(fibh->ebh->b_data, 0x00, padlen + offset);
97 }
98
99 crc = udf_crc((uint8_t *)cfi + sizeof(tag),
100 sizeof(struct fileIdentDesc) - sizeof(tag), 0);
101
102 if (fibh->sbh == fibh->ebh) {
103 crc = udf_crc((uint8_t *)sfi->impUse,
104 crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc);
105 } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) {
106 crc = udf_crc(fibh->ebh->b_data + sizeof(struct fileIdentDesc) + fibh->soffset,
107 crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc);
108 } else {
109 crc = udf_crc((uint8_t *)sfi->impUse,
110 -fibh->soffset - sizeof(struct fileIdentDesc), crc);
111 crc = udf_crc(fibh->ebh->b_data, fibh->eoffset, crc);
112 }
113
114 cfi->descTag.descCRC = cpu_to_le16(crc);
115 cfi->descTag.descCRCLength = cpu_to_le16(crclen);
116
117 for (i = 0; i < 16; i++) {
118 if (i != 4)
119 checksum += ((uint8_t *)&cfi->descTag)[i];
120 }
121
122 cfi->descTag.tagChecksum = checksum;
123 if (adinicb || (sizeof(struct fileIdentDesc) <= -fibh->soffset)) {
124 memcpy((uint8_t *)sfi, (uint8_t *)cfi, sizeof(struct fileIdentDesc));
125 } else {
126 memcpy((uint8_t *)sfi, (uint8_t *)cfi, -fibh->soffset);
127 memcpy(fibh->ebh->b_data, (uint8_t *)cfi - fibh->soffset,
128 sizeof(struct fileIdentDesc) + fibh->soffset);
129 }
130
131 if (adinicb) {
132 mark_inode_dirty(inode);
133 } else {
134 if (fibh->sbh != fibh->ebh)
135 mark_buffer_dirty_inode(fibh->ebh, inode);
136 mark_buffer_dirty_inode(fibh->sbh, inode);
137 }
138 return 0;
139}
140
141static struct fileIdentDesc *udf_find_entry(struct inode *dir,
142 struct dentry *dentry,
143 struct udf_fileident_bh *fibh,
144 struct fileIdentDesc *cfi)
145{
146 struct fileIdentDesc *fi = NULL;
147 loff_t f_pos;
148 int block, flen;
149 char fname[UDF_NAME_LEN];
150 char *nameptr;
151 uint8_t lfi;
152 uint16_t liu;
153 loff_t size;
154 kernel_lb_addr eloc;
155 uint32_t elen;
156 sector_t offset;
157 struct extent_position epos = {};
158
159 size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
160 f_pos = (udf_ext0_offset(dir) >> 2);
161
162 fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
163 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
164 fibh->sbh = fibh->ebh = NULL;
165 } else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
166 &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
167 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
168 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
169 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
170 epos.offset -= sizeof(short_ad);
171 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
172 epos.offset -= sizeof(long_ad);
173 } else {
174 offset = 0;
175 }
176
177 if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) {
178 brelse(epos.bh);
179 return NULL;
180 }
181 } else {
182 brelse(epos.bh);
183 return NULL;
184 }
185
186 while ((f_pos < size)) {
187 fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
188 &elen, &offset);
189 if (!fi) {
190 if (fibh->sbh != fibh->ebh)
191 brelse(fibh->ebh);
192 brelse(fibh->sbh);
193 brelse(epos.bh);
194 return NULL;
195 }
196
197 liu = le16_to_cpu(cfi->lengthOfImpUse);
198 lfi = cfi->lengthFileIdent;
199
200 if (fibh->sbh == fibh->ebh) {
201 nameptr = fi->fileIdent + liu;
202 } else {
203 int poffset;
204
205 poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi;
206
207 if (poffset >= lfi) {
208 nameptr = (uint8_t *)(fibh->ebh->b_data + poffset - lfi);
209 } else {
210 nameptr = fname;
211 memcpy(nameptr, fi->fileIdent + liu, lfi - poffset);
212 memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset);
213 }
214 }
215
216 if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) {
217 if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE))
218 continue;
219 }
220
221 if ((cfi->fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) {
222 if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE))
223 continue;
224 }
225
226 if (!lfi)
227 continue;
228
229 if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi))) {
230 if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) {
231 brelse(epos.bh);
232 return fi;
233 }
234 }
235 }
236
237 if (fibh->sbh != fibh->ebh)
238 brelse(fibh->ebh);
239 brelse(fibh->sbh);
240 brelse(epos.bh);
241
242 return NULL;
243}
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
279 struct nameidata *nd)
280{
281 struct inode *inode = NULL;
282 struct fileIdentDesc cfi;
283 struct udf_fileident_bh fibh;
284
285 if (dentry->d_name.len > UDF_NAME_LEN - 2)
286 return ERR_PTR(-ENAMETOOLONG);
287
288 lock_kernel();
289#ifdef UDF_RECOVERY
290
291 if (!strncmp(dentry->d_name.name, ".B=", 3)) {
292 kernel_lb_addr lb = {
293 .logicalBlockNum = 0,
294 .partitionReferenceNum = simple_strtoul(dentry->d_name.name + 3,
295 NULL, 0),
296 };
297 inode = udf_iget(dir->i_sb, lb);
298 if (!inode) {
299 unlock_kernel();
300 return ERR_PTR(-EACCES);
301 }
302 }
303 else
304#endif
305
306 if (udf_find_entry(dir, dentry, &fibh, &cfi)) {
307 if (fibh.sbh != fibh.ebh)
308 brelse(fibh.ebh);
309 brelse(fibh.sbh);
310
311 inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation));
312 if (!inode) {
313 unlock_kernel();
314 return ERR_PTR(-EACCES);
315 }
316 }
317 unlock_kernel();
318 d_add(dentry, inode);
319
320 return NULL;
321}
322
323static struct fileIdentDesc *udf_add_entry(struct inode *dir,
324 struct dentry *dentry,
325 struct udf_fileident_bh *fibh,
326 struct fileIdentDesc *cfi, int *err)
327{
328 struct super_block *sb;
329 struct fileIdentDesc *fi = NULL;
330 char name[UDF_NAME_LEN], fname[UDF_NAME_LEN];
331 int namelen;
332 loff_t f_pos;
333 int flen;
334 char *nameptr;
335 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
336 int nfidlen;
337 uint8_t lfi;
338 uint16_t liu;
339 int block;
340 kernel_lb_addr eloc;
341 uint32_t elen;
342 sector_t offset;
343 struct extent_position epos = {};
344
345 sb = dir->i_sb;
346
347 if (dentry) {
348 if (!dentry->d_name.len) {
349 *err = -EINVAL;
350 return NULL;
351 }
352 if (!(namelen = udf_put_filename(sb, dentry->d_name.name, name,
353 dentry->d_name.len))) {
354 *err = -ENAMETOOLONG;
355 return NULL;
356 }
357 } else {
358 namelen = 0;
359 }
360
361 nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3;
362
363 f_pos = (udf_ext0_offset(dir) >> 2);
364
365 fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
366 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
367 fibh->sbh = fibh->ebh = NULL;
368 } else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
369 &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
370 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
371 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
372 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
373 epos.offset -= sizeof(short_ad);
374 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
375 epos.offset -= sizeof(long_ad);
376 } else {
377 offset = 0;
378 }
379
380 if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) {
381 brelse(epos.bh);
382 *err = -EIO;
383 return NULL;
384 }
385
386 block = UDF_I_LOCATION(dir).logicalBlockNum;
387
388 } else {
389 block = udf_get_lb_pblock(dir->i_sb, UDF_I_LOCATION(dir), 0);
390 fibh->sbh = fibh->ebh = NULL;
391 fibh->soffset = fibh->eoffset = sb->s_blocksize;
392 goto add;
393 }
394
395 while ((f_pos < size)) {
396 fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
397 &elen, &offset);
398
399 if (!fi) {
400 if (fibh->sbh != fibh->ebh)
401 brelse(fibh->ebh);
402 brelse(fibh->sbh);
403 brelse(epos.bh);
404 *err = -EIO;
405 return NULL;
406 }
407
408 liu = le16_to_cpu(cfi->lengthOfImpUse);
409 lfi = cfi->lengthFileIdent;
410
411 if (fibh->sbh == fibh->ebh) {
412 nameptr = fi->fileIdent + liu;
413 } else {
414 int poffset;
415
416 poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi;
417
418 if (poffset >= lfi) {
419 nameptr = (char *)(fibh->ebh->b_data + poffset - lfi);
420 } else {
421 nameptr = fname;
422 memcpy(nameptr, fi->fileIdent + liu, lfi - poffset);
423 memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset);
424 }
425 }
426
427 if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) {
428 if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen) {
429 brelse(epos.bh);
430 cfi->descTag.tagSerialNum = cpu_to_le16(1);
431 cfi->fileVersionNum = cpu_to_le16(1);
432 cfi->fileCharacteristics = 0;
433 cfi->lengthFileIdent = namelen;
434 cfi->lengthOfImpUse = cpu_to_le16(0);
435 if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) {
436 return fi;
437 } else {
438 *err = -EIO;
439 return NULL;
440 }
441 }
442 }
443
444 if (!lfi || !dentry)
445 continue;
446
447 if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi)) &&
448 udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) {
449 if (fibh->sbh != fibh->ebh)
450 brelse(fibh->ebh);
451 brelse(fibh->sbh);
452 brelse(epos.bh);
453 *err = -EEXIST;
454 return NULL;
455 }
456 }
457
458add:
459 f_pos += nfidlen;
460
461 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB &&
462 sb->s_blocksize - fibh->eoffset < nfidlen) {
463 brelse(epos.bh);
464 epos.bh = NULL;
465 fibh->soffset -= udf_ext0_offset(dir);
466 fibh->eoffset -= udf_ext0_offset(dir);
467 f_pos -= (udf_ext0_offset(dir) >> 2);
468 if (fibh->sbh != fibh->ebh)
469 brelse(fibh->ebh);
470 brelse(fibh->sbh);
471 if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err)))
472 return NULL;
473 epos.block = UDF_I_LOCATION(dir);
474 eloc.logicalBlockNum = block;
475 eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
476 elen = dir->i_sb->s_blocksize;
477 epos.offset = udf_file_entry_alloc_offset(dir);
478 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
479 epos.offset += sizeof(short_ad);
480 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
481 epos.offset += sizeof(long_ad);
482 }
483
484 if (sb->s_blocksize - fibh->eoffset >= nfidlen) {
485 fibh->soffset = fibh->eoffset;
486 fibh->eoffset += nfidlen;
487 if (fibh->sbh != fibh->ebh) {
488 brelse(fibh->sbh);
489 fibh->sbh = fibh->ebh;
490 }
491
492 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
493 block = UDF_I_LOCATION(dir).logicalBlockNum;
494 fi = (struct fileIdentDesc *)(UDF_I_DATA(dir) + fibh->soffset -
495 udf_ext0_offset(dir) +
496 UDF_I_LENEATTR(dir));
497 } else {
498 block = eloc.logicalBlockNum + ((elen - 1) >>
499 dir->i_sb->s_blocksize_bits);
500 fi = (struct fileIdentDesc *)(fibh->sbh->b_data + fibh->soffset);
501 }
502 } else {
503 fibh->soffset = fibh->eoffset - sb->s_blocksize;
504 fibh->eoffset += nfidlen - sb->s_blocksize;
505 if (fibh->sbh != fibh->ebh) {
506 brelse(fibh->sbh);
507 fibh->sbh = fibh->ebh;
508 }
509
510 block = eloc.logicalBlockNum + ((elen - 1) >>
511 dir->i_sb->s_blocksize_bits);
512 fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err);
513 if (!fibh->ebh) {
514 brelse(epos.bh);
515 brelse(fibh->sbh);
516 return NULL;
517 }
518
519 if (!fibh->soffset) {
520 if (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
521 (EXT_RECORDED_ALLOCATED >> 30)) {
522 block = eloc.logicalBlockNum + ((elen - 1) >>
523 dir->i_sb->s_blocksize_bits);
524 } else {
525 block++;
526 }
527
528 brelse(fibh->sbh);
529 fibh->sbh = fibh->ebh;
530 fi = (struct fileIdentDesc *)(fibh->sbh->b_data);
531 } else {
532 fi = (struct fileIdentDesc *)
533 (fibh->sbh->b_data + sb->s_blocksize + fibh->soffset);
534 }
535 }
536
537 memset(cfi, 0, sizeof(struct fileIdentDesc));
538 if (UDF_SB_UDFREV(sb) >= 0x0200)
539 udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block, sizeof(tag));
540 else
541 udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block, sizeof(tag));
542 cfi->fileVersionNum = cpu_to_le16(1);
543 cfi->lengthFileIdent = namelen;
544 cfi->lengthOfImpUse = cpu_to_le16(0);
545 if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) {
546 brelse(epos.bh);
547 dir->i_size += nfidlen;
548 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
549 UDF_I_LENALLOC(dir) += nfidlen;
550 mark_inode_dirty(dir);
551 return fi;
552 } else {
553 brelse(epos.bh);
554 if (fibh->sbh != fibh->ebh)
555 brelse(fibh->ebh);
556 brelse(fibh->sbh);
557 *err = -EIO;
558 return NULL;
559 }
560}
561
562static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
563 struct udf_fileident_bh *fibh,
564 struct fileIdentDesc *cfi)
565{
566 cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED;
567
568 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
569 memset(&(cfi->icb), 0x00, sizeof(long_ad));
570
571 return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
572}
573
574static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
575 struct nameidata *nd)
576{
577 struct udf_fileident_bh fibh;
578 struct inode *inode;
579 struct fileIdentDesc cfi, *fi;
580 int err;
581
582 lock_kernel();
583 inode = udf_new_inode(dir, mode, &err);
584 if (!inode) {
585 unlock_kernel();
586 return err;
587 }
588
589 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
590 inode->i_data.a_ops = &udf_adinicb_aops;
591 else
592 inode->i_data.a_ops = &udf_aops;
593 inode->i_op = &udf_file_inode_operations;
594 inode->i_fop = &udf_file_operations;
595 inode->i_mode = mode;
596 mark_inode_dirty(inode);
597
598 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) {
599 inode->i_nlink--;
600 mark_inode_dirty(inode);
601 iput(inode);
602 unlock_kernel();
603 return err;
604 }
605 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
606 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
607 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
608 cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
609 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
610 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
611 mark_inode_dirty(dir);
612 }
613 if (fibh.sbh != fibh.ebh)
614 brelse(fibh.ebh);
615 brelse(fibh.sbh);
616 unlock_kernel();
617 d_instantiate(dentry, inode);
618
619 return 0;
620}
621
622static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
623 dev_t rdev)
624{
625 struct inode *inode;
626 struct udf_fileident_bh fibh;
627 struct fileIdentDesc cfi, *fi;
628 int err;
629
630 if (!old_valid_dev(rdev))
631 return -EINVAL;
632
633 lock_kernel();
634 err = -EIO;
635 inode = udf_new_inode(dir, mode, &err);
636 if (!inode)
637 goto out;
638
639 inode->i_uid = current->fsuid;
640 init_special_inode(inode, mode, rdev);
641 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) {
642 inode->i_nlink--;
643 mark_inode_dirty(inode);
644 iput(inode);
645 unlock_kernel();
646 return err;
647 }
648 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
649 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
650 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
651 cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
652 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
653 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
654 mark_inode_dirty(dir);
655 }
656 mark_inode_dirty(inode);
657
658 if (fibh.sbh != fibh.ebh)
659 brelse(fibh.ebh);
660 brelse(fibh.sbh);
661 d_instantiate(dentry, inode);
662 err = 0;
663
664out:
665 unlock_kernel();
666 return err;
667}
668
669static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
670{
671 struct inode *inode;
672 struct udf_fileident_bh fibh;
673 struct fileIdentDesc cfi, *fi;
674 int err;
675
676 lock_kernel();
677 err = -EMLINK;
678 if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1)
679 goto out;
680
681 err = -EIO;
682 inode = udf_new_inode(dir, S_IFDIR, &err);
683 if (!inode)
684 goto out;
685
686 inode->i_op = &udf_dir_inode_operations;
687 inode->i_fop = &udf_dir_operations;
688 if (!(fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err))) {
689 inode->i_nlink--;
690 mark_inode_dirty(inode);
691 iput(inode);
692 goto out;
693 }
694 inode->i_nlink = 2;
695 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
696 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(dir));
697 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
698 cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL);
699 cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
700 udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL);
701 brelse(fibh.sbh);
702 inode->i_mode = S_IFDIR | mode;
703 if (dir->i_mode & S_ISGID)
704 inode->i_mode |= S_ISGID;
705 mark_inode_dirty(inode);
706
707 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) {
708 inode->i_nlink = 0;
709 mark_inode_dirty(inode);
710 iput(inode);
711 goto out;
712 }
713 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
714 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
715 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
716 cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
717 cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY;
718 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
719 inc_nlink(dir);
720 mark_inode_dirty(dir);
721 d_instantiate(dentry, inode);
722 if (fibh.sbh != fibh.ebh)
723 brelse(fibh.ebh);
724 brelse(fibh.sbh);
725 err = 0;
726
727out:
728 unlock_kernel();
729 return err;
730}
731
732static int empty_dir(struct inode *dir)
733{
734 struct fileIdentDesc *fi, cfi;
735 struct udf_fileident_bh fibh;
736 loff_t f_pos;
737 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
738 int block;
739 kernel_lb_addr eloc;
740 uint32_t elen;
741 sector_t offset;
742 struct extent_position epos = {};
743
744 f_pos = (udf_ext0_offset(dir) >> 2);
745
746 fibh.soffset = fibh.eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
747
748 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
749 fibh.sbh = fibh.ebh = NULL;
750 } else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
751 &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
752 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
753 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
754 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
755 epos.offset -= sizeof(short_ad);
756 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
757 epos.offset -= sizeof(long_ad);
758 } else {
759 offset = 0;
760 }
761
762 if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) {
763 brelse(epos.bh);
764 return 0;
765 }
766 } else {
767 brelse(epos.bh);
768 return 0;
769 }
770
771 while ((f_pos < size)) {
772 fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc,
773 &elen, &offset);
774 if (!fi) {
775 if (fibh.sbh != fibh.ebh)
776 brelse(fibh.ebh);
777 brelse(fibh.sbh);
778 brelse(epos.bh);
779 return 0;
780 }
781
782 if (cfi.lengthFileIdent &&
783 (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) {
784 if (fibh.sbh != fibh.ebh)
785 brelse(fibh.ebh);
786 brelse(fibh.sbh);
787 brelse(epos.bh);
788 return 0;
789 }
790 }
791
792 if (fibh.sbh != fibh.ebh)
793 brelse(fibh.ebh);
794 brelse(fibh.sbh);
795 brelse(epos.bh);
796
797 return 1;
798}
799
800static int udf_rmdir(struct inode *dir, struct dentry *dentry)
801{
802 int retval;
803 struct inode *inode = dentry->d_inode;
804 struct udf_fileident_bh fibh;
805 struct fileIdentDesc *fi, cfi;
806 kernel_lb_addr tloc;
807
808 retval = -ENOENT;
809 lock_kernel();
810 fi = udf_find_entry(dir, dentry, &fibh, &cfi);
811 if (!fi)
812 goto out;
813
814 retval = -EIO;
815 tloc = lelb_to_cpu(cfi.icb.extLocation);
816 if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino)
817 goto end_rmdir;
818 retval = -ENOTEMPTY;
819 if (!empty_dir(inode))
820 goto end_rmdir;
821 retval = udf_delete_entry(dir, fi, &fibh, &cfi);
822 if (retval)
823 goto end_rmdir;
824 if (inode->i_nlink != 2)
825 udf_warning(inode->i_sb, "udf_rmdir",
826 "empty directory has nlink != 2 (%d)",
827 inode->i_nlink);
828 clear_nlink(inode);
829 inode->i_size = 0;
830 inode_dec_link_count(dir);
831 inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
832 mark_inode_dirty(dir);
833
834end_rmdir:
835 if (fibh.sbh != fibh.ebh)
836 brelse(fibh.ebh);
837 brelse(fibh.sbh);
838
839out:
840 unlock_kernel();
841 return retval;
842}
843
844static int udf_unlink(struct inode *dir, struct dentry *dentry)
845{
846 int retval;
847 struct inode *inode = dentry->d_inode;
848 struct udf_fileident_bh fibh;
849 struct fileIdentDesc *fi;
850 struct fileIdentDesc cfi;
851 kernel_lb_addr tloc;
852
853 retval = -ENOENT;
854 lock_kernel();
855 fi = udf_find_entry(dir, dentry, &fibh, &cfi);
856 if (!fi)
857 goto out;
858
859 retval = -EIO;
860 tloc = lelb_to_cpu(cfi.icb.extLocation);
861 if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino)
862 goto end_unlink;
863
864 if (!inode->i_nlink) {
865 udf_debug("Deleting nonexistent file (%lu), %d\n",
866 inode->i_ino, inode->i_nlink);
867 inode->i_nlink = 1;
868 }
869 retval = udf_delete_entry(dir, fi, &fibh, &cfi);
870 if (retval)
871 goto end_unlink;
872 dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
873 mark_inode_dirty(dir);
874 inode_dec_link_count(inode);
875 inode->i_ctime = dir->i_ctime;
876 retval = 0;
877
878end_unlink:
879 if (fibh.sbh != fibh.ebh)
880 brelse(fibh.ebh);
881 brelse(fibh.sbh);
882
883out:
884 unlock_kernel();
885 return retval;
886}
887
888static int udf_symlink(struct inode *dir, struct dentry *dentry,
889 const char *symname)
890{
891 struct inode *inode;
892 struct pathComponent *pc;
893 char *compstart;
894 struct udf_fileident_bh fibh;
895 struct extent_position epos = {};
896 int eoffset, elen = 0;
897 struct fileIdentDesc *fi;
898 struct fileIdentDesc cfi;
899 char *ea;
900 int err;
901 int block;
902 char name[UDF_NAME_LEN];
903 int namelen;
904
905 lock_kernel();
906 if (!(inode = udf_new_inode(dir, S_IFLNK, &err)))
907 goto out;
908
909 inode->i_mode = S_IFLNK | S_IRWXUGO;
910 inode->i_data.a_ops = &udf_symlink_aops;
911 inode->i_op = &page_symlink_inode_operations;
912
913 if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB) {
914 kernel_lb_addr eloc;
915 uint32_t elen;
916
917 block = udf_new_block(inode->i_sb, inode,
918 UDF_I_LOCATION(inode).partitionReferenceNum,
919 UDF_I_LOCATION(inode).logicalBlockNum, &err);
920 if (!block)
921 goto out_no_entry;
922 epos.block = UDF_I_LOCATION(inode);
923 epos.offset = udf_file_entry_alloc_offset(inode);
924 epos.bh = NULL;
925 eloc.logicalBlockNum = block;
926 eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
927 elen = inode->i_sb->s_blocksize;
928 UDF_I_LENEXTENTS(inode) = elen;
929 udf_add_aext(inode, &epos, eloc, elen, 0);
930 brelse(epos.bh);
931
932 block = udf_get_pblock(inode->i_sb, block,
933 UDF_I_LOCATION(inode).partitionReferenceNum, 0);
934 epos.bh = udf_tread(inode->i_sb, block);
935 lock_buffer(epos.bh);
936 memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize);
937 set_buffer_uptodate(epos.bh);
938 unlock_buffer(epos.bh);
939 mark_buffer_dirty_inode(epos.bh, inode);
940 ea = epos.bh->b_data + udf_ext0_offset(inode);
941 } else {
942 ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
943 }
944
945 eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode);
946 pc = (struct pathComponent *)ea;
947
948 if (*symname == '/') {
949 do {
950 symname++;
951 } while (*symname == '/');
952
953 pc->componentType = 1;
954 pc->lengthComponentIdent = 0;
955 pc->componentFileVersionNum = 0;
956 pc += sizeof(struct pathComponent);
957 elen += sizeof(struct pathComponent);
958 }
959
960 err = -ENAMETOOLONG;
961
962 while (*symname) {
963 if (elen + sizeof(struct pathComponent) > eoffset)
964 goto out_no_entry;
965
966 pc = (struct pathComponent *)(ea + elen);
967
968 compstart = (char *)symname;
969
970 do {
971 symname++;
972 } while (*symname && *symname != '/');
973
974 pc->componentType = 5;
975 pc->lengthComponentIdent = 0;
976 pc->componentFileVersionNum = 0;
977 if (compstart[0] == '.') {
978 if ((symname - compstart) == 1)
979 pc->componentType = 4;
980 else if ((symname - compstart) == 2 && compstart[1] == '.')
981 pc->componentType = 3;
982 }
983
984 if (pc->componentType == 5) {
985 namelen = udf_put_filename(inode->i_sb, compstart, name,
986 symname - compstart);
987 if (!namelen)
988 goto out_no_entry;
989
990 if (elen + sizeof(struct pathComponent) + namelen > eoffset)
991 goto out_no_entry;
992 else
993 pc->lengthComponentIdent = namelen;
994
995 memcpy(pc->componentIdent, name, namelen);
996 }
997
998 elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
999
1000 if (*symname) {
1001 do {
1002 symname++;
1003 } while (*symname == '/');
1004 }
1005 }
1006
1007 brelse(epos.bh);
1008 inode->i_size = elen;
1009 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
1010 UDF_I_LENALLOC(inode) = inode->i_size;
1011 mark_inode_dirty(inode);
1012
1013 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
1014 goto out_no_entry;
1015 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
1016 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
1017 if (UDF_SB_LVIDBH(inode->i_sb)) {
1018 struct logicalVolHeaderDesc *lvhd;
1019 uint64_t uniqueID;
1020 lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
1021 uniqueID = le64_to_cpu(lvhd->uniqueID);
1022 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
1023 cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
1024 if (!(++uniqueID & 0x00000000FFFFFFFFUL))
1025 uniqueID += 16;
1026 lvhd->uniqueID = cpu_to_le64(uniqueID);
1027 mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb));
1028 }
1029 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
1030 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
1031 mark_inode_dirty(dir);
1032 }
1033 if (fibh.sbh != fibh.ebh)
1034 brelse(fibh.ebh);
1035 brelse(fibh.sbh);
1036 d_instantiate(dentry, inode);
1037 err = 0;
1038
1039out:
1040 unlock_kernel();
1041 return err;
1042
1043out_no_entry:
1044 inode_dec_link_count(inode);
1045 iput(inode);
1046 goto out;
1047}
1048
1049static int udf_link(struct dentry *old_dentry, struct inode *dir,
1050 struct dentry *dentry)
1051{
1052 struct inode *inode = old_dentry->d_inode;
1053 struct udf_fileident_bh fibh;
1054 struct fileIdentDesc cfi, *fi;
1055 int err;
1056
1057 lock_kernel();
1058 if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) {
1059 unlock_kernel();
1060 return -EMLINK;
1061 }
1062
1063 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) {
1064 unlock_kernel();
1065 return err;
1066 }
1067 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
1068 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
1069 if (UDF_SB_LVIDBH(inode->i_sb)) {
1070 struct logicalVolHeaderDesc *lvhd;
1071 uint64_t uniqueID;
1072 lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
1073 uniqueID = le64_to_cpu(lvhd->uniqueID);
1074 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
1075 cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
1076 if (!(++uniqueID & 0x00000000FFFFFFFFUL))
1077 uniqueID += 16;
1078 lvhd->uniqueID = cpu_to_le64(uniqueID);
1079 mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb));
1080 }
1081 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
1082 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
1083 mark_inode_dirty(dir);
1084 }
1085
1086 if (fibh.sbh != fibh.ebh)
1087 brelse(fibh.ebh);
1088 brelse(fibh.sbh);
1089 inc_nlink(inode);
1090 inode->i_ctime = current_fs_time(inode->i_sb);
1091 mark_inode_dirty(inode);
1092 atomic_inc(&inode->i_count);
1093 d_instantiate(dentry, inode);
1094 unlock_kernel();
1095
1096 return 0;
1097}
1098
1099
1100
1101
1102static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
1103 struct inode *new_dir, struct dentry *new_dentry)
1104{
1105 struct inode *old_inode = old_dentry->d_inode;
1106 struct inode *new_inode = new_dentry->d_inode;
1107 struct udf_fileident_bh ofibh, nfibh;
1108 struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi;
1109 struct buffer_head *dir_bh = NULL;
1110 int retval = -ENOENT;
1111 kernel_lb_addr tloc;
1112
1113 lock_kernel();
1114 if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi))) {
1115 if (ofibh.sbh != ofibh.ebh)
1116 brelse(ofibh.ebh);
1117 brelse(ofibh.sbh);
1118 }
1119 tloc = lelb_to_cpu(ocfi.icb.extLocation);
1120 if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0)
1121 != old_inode->i_ino)
1122 goto end_rename;
1123
1124 nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi);
1125 if (nfi) {
1126 if (!new_inode) {
1127 if (nfibh.sbh != nfibh.ebh)
1128 brelse(nfibh.ebh);
1129 brelse(nfibh.sbh);
1130 nfi = NULL;
1131 }
1132 }
1133 if (S_ISDIR(old_inode->i_mode)) {
1134 uint32_t offset = udf_ext0_offset(old_inode);
1135
1136 if (new_inode) {
1137 retval = -ENOTEMPTY;
1138 if (!empty_dir(new_inode))
1139 goto end_rename;
1140 }
1141 retval = -EIO;
1142 if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB) {
1143 dir_fi = udf_get_fileident(UDF_I_DATA(old_inode) -
1144 (UDF_I_EFE(old_inode) ?
1145 sizeof(struct extendedFileEntry) :
1146 sizeof(struct fileEntry)),
1147 old_inode->i_sb->s_blocksize, &offset);
1148 } else {
1149 dir_bh = udf_bread(old_inode, 0, 0, &retval);
1150 if (!dir_bh)
1151 goto end_rename;
1152 dir_fi = udf_get_fileident(dir_bh->b_data, old_inode->i_sb->s_blocksize, &offset);
1153 }
1154 if (!dir_fi)
1155 goto end_rename;
1156 tloc = lelb_to_cpu(dir_fi->icb.extLocation);
1157 if (udf_get_lb_pblock(old_inode->i_sb, tloc, 0) != old_dir->i_ino)
1158 goto end_rename;
1159
1160 retval = -EMLINK;
1161 if (!new_inode && new_dir->i_nlink >= (256 << sizeof(new_dir->i_nlink)) - 1)
1162 goto end_rename;
1163 }
1164 if (!nfi) {
1165 nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, &retval);
1166 if (!nfi)
1167 goto end_rename;
1168 }
1169
1170
1171
1172
1173
1174 old_inode->i_ctime = current_fs_time(old_inode->i_sb);
1175 mark_inode_dirty(old_inode);
1176
1177
1178
1179
1180 ncfi.fileVersionNum = ocfi.fileVersionNum;
1181 ncfi.fileCharacteristics = ocfi.fileCharacteristics;
1182 memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(long_ad));
1183 udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL);
1184
1185
1186 ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
1187 udf_delete_entry(old_dir, ofi, &ofibh, &ocfi);
1188
1189 if (new_inode) {
1190 new_inode->i_ctime = current_fs_time(new_inode->i_sb);
1191 inode_dec_link_count(new_inode);
1192 }
1193 old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb);
1194 mark_inode_dirty(old_dir);
1195
1196 if (dir_fi) {
1197 dir_fi->icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(new_dir));
1198 udf_update_tag((char *)dir_fi, (sizeof(struct fileIdentDesc) +
1199 le16_to_cpu(dir_fi->lengthOfImpUse) + 3) & ~3);
1200 if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB) {
1201 mark_inode_dirty(old_inode);
1202 } else {
1203 mark_buffer_dirty_inode(dir_bh, old_inode);
1204 }
1205 inode_dec_link_count(old_dir);
1206 if (new_inode) {
1207 inode_dec_link_count(new_inode);
1208 } else {
1209 inc_nlink(new_dir);
1210 mark_inode_dirty(new_dir);
1211 }
1212 }
1213
1214 if (ofi) {
1215 if (ofibh.sbh != ofibh.ebh)
1216 brelse(ofibh.ebh);
1217 brelse(ofibh.sbh);
1218 }
1219
1220 retval = 0;
1221
1222end_rename:
1223 brelse(dir_bh);
1224 if (nfi) {
1225 if (nfibh.sbh != nfibh.ebh)
1226 brelse(nfibh.ebh);
1227 brelse(nfibh.sbh);
1228 }
1229 unlock_kernel();
1230
1231 return retval;
1232}
1233
1234const struct inode_operations udf_dir_inode_operations = {
1235 .lookup = udf_lookup,
1236 .create = udf_create,
1237 .link = udf_link,
1238 .unlink = udf_unlink,
1239 .symlink = udf_symlink,
1240 .mkdir = udf_mkdir,
1241 .rmdir = udf_rmdir,
1242 .mknod = udf_mknod,
1243 .rename = udf_rename,
1244};
1245