5 * Inode name handling routines for the OSTA-UDF(tm) filesystem.
8 * E-mail regarding any portion of the Linux UDF file system should be
9 * directed to the development team mailing list (run by majordomo):
10 * linux_udf@hootie.lvld.hp.com
13 * This file is distributed under the terms of the GNU General Public
14 * License (GPL). Copies of the GPL can be obtained from:
15 * ftp://prep.ai.mit.edu/pub/gnu/GPL
16 * Each contributing author retains all rights to their own work.
18 * (C) 1998-2000 Ben Fennema
19 * (C) 1999-2000 Stelias Computing Inc
23 * 12/12/98 blf Created. Split out the lookup code from dir.c
24 * 04/19/99 blf link, mknod, symlink support
31 #include <linux/string.h>
32 #include <linux/errno.h>
34 #include <linux/malloc.h>
35 #include <linux/quotaops.h>
36 #include <linux/udf_fs.h>
38 static inline int udf_match(int len
, const char * const name
, struct qstr
*qs
)
42 return !memcmp(name
, qs
->name
, len
);
45 int udf_write_fi(struct FileIdentDesc
*cfi
, struct FileIdentDesc
*sfi
,
46 struct udf_fileident_bh
*fibh
,
47 Uint8
*impuse
, Uint8
*fileident
)
49 Uint16 crclen
= fibh
->eoffset
- fibh
->soffset
- sizeof(tag
);
54 Uint16 liu
= le16_to_cpu(cfi
->lengthOfImpUse
);
55 Uint8 lfi
= cfi
->lengthFileIdent
;
56 int padlen
= fibh
->eoffset
- fibh
->soffset
- liu
- lfi
-
57 sizeof(struct FileIdentDesc
);
60 offset
= fibh
->soffset
+ sizeof(struct FileIdentDesc
);
65 memcpy((Uint8
*)sfi
->impUse
, impuse
, liu
);
67 memcpy(fibh
->ebh
->b_data
+ offset
, impuse
, liu
);
70 memcpy((Uint8
*)sfi
->impUse
, impuse
, -offset
);
71 memcpy(fibh
->ebh
->b_data
, impuse
- offset
, liu
+ offset
);
80 memcpy((Uint8
*)sfi
->fileIdent
+ liu
, fileident
, lfi
);
82 memcpy(fibh
->ebh
->b_data
+ offset
, fileident
, lfi
);
85 memcpy((Uint8
*)sfi
->fileIdent
+ liu
, fileident
, -offset
);
86 memcpy(fibh
->ebh
->b_data
, fileident
- offset
, lfi
+ offset
);
92 if (offset
+ padlen
< 0)
93 memset((Uint8
*)sfi
->padding
+ liu
+ lfi
, 0x00, padlen
);
95 memset(fibh
->ebh
->b_data
+ offset
, 0x00, padlen
);
98 memset((Uint8
*)sfi
->padding
+ liu
+ lfi
, 0x00, -offset
);
99 memset(fibh
->ebh
->b_data
, 0x00, padlen
+ offset
);
102 crc
= udf_crc((Uint8
*)cfi
+ sizeof(tag
), sizeof(struct FileIdentDesc
) -
105 if (fibh
->sbh
== fibh
->ebh
)
106 crc
= udf_crc((Uint8
*)sfi
->impUse
,
107 crclen
+ sizeof(tag
) - sizeof(struct FileIdentDesc
), crc
);
108 else if (sizeof(struct FileIdentDesc
) >= -fibh
->soffset
)
109 crc
= udf_crc(fibh
->ebh
->b_data
+ sizeof(struct FileIdentDesc
) + fibh
->soffset
,
110 crclen
+ sizeof(tag
) - sizeof(struct FileIdentDesc
), crc
);
113 crc
= udf_crc((Uint8
*)sfi
->impUse
,
114 -fibh
->soffset
- sizeof(struct FileIdentDesc
), crc
);
115 crc
= udf_crc(fibh
->ebh
->b_data
, fibh
->eoffset
, crc
);
118 cfi
->descTag
.descCRC
= cpu_to_le32(crc
);
119 cfi
->descTag
.descCRCLength
= cpu_to_le16(crclen
);
123 checksum
+= ((Uint8
*)&cfi
->descTag
)[i
];
125 cfi
->descTag
.tagChecksum
= checksum
;
126 if (sizeof(struct FileIdentDesc
) <= -fibh
->soffset
)
127 memcpy((Uint8
*)sfi
, (Uint8
*)cfi
, sizeof(struct FileIdentDesc
));
130 memcpy((Uint8
*)sfi
, (Uint8
*)cfi
, -fibh
->soffset
);
131 memcpy(fibh
->ebh
->b_data
, (Uint8
*)cfi
- fibh
->soffset
,
132 sizeof(struct FileIdentDesc
) + fibh
->soffset
);
135 if (fibh
->sbh
!= fibh
->ebh
)
136 mark_buffer_dirty(fibh
->ebh
);
137 mark_buffer_dirty(fibh
->sbh
);
141 static struct FileIdentDesc
*
142 udf_find_entry(struct inode
*dir
, struct dentry
*dentry
,
143 struct udf_fileident_bh
*fibh
,
144 struct FileIdentDesc
*cfi
)
146 struct FileIdentDesc
*fi
=NULL
;
153 loff_t size
= (udf_ext0_offset(dir
) + dir
->i_size
) >> 2;
155 Uint32 extoffset
, elen
, offset
;
156 struct buffer_head
*bh
= NULL
;
161 f_pos
= (udf_ext0_offset(dir
) >> 2);
163 fibh
->soffset
= fibh
->eoffset
= (f_pos
& ((dir
->i_sb
->s_blocksize
- 1) >> 2)) << 2;
164 if (inode_bmap(dir
, f_pos
>> (dir
->i_sb
->s_blocksize_bits
- 2),
165 &bloc
, &extoffset
, &eloc
, &elen
, &offset
, &bh
) == EXTENT_RECORDED_ALLOCATED
)
167 block
= udf_get_lb_pblock(dir
->i_sb
, eloc
, offset
);
168 if ((++offset
<< dir
->i_sb
->s_blocksize_bits
) < elen
)
170 if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_SHORT
)
171 extoffset
-= sizeof(short_ad
);
172 else if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_LONG
)
173 extoffset
-= sizeof(long_ad
);
180 udf_release_data(bh
);
184 if (!(fibh
->sbh
= fibh
->ebh
= udf_tread(dir
->i_sb
, block
, dir
->i_sb
->s_blocksize
)))
186 udf_release_data(bh
);
190 while ( (f_pos
< size
) )
192 fi
= udf_fileident_read(dir
, &f_pos
, fibh
, cfi
, &bloc
, &extoffset
, &eloc
, &elen
, &offset
, &bh
);
196 if (fibh
->sbh
!= fibh
->ebh
)
197 udf_release_data(fibh
->ebh
);
198 udf_release_data(fibh
->sbh
);
199 udf_release_data(bh
);
203 liu
= le16_to_cpu(cfi
->lengthOfImpUse
);
204 lfi
= cfi
->lengthFileIdent
;
206 if (fibh
->sbh
== fibh
->ebh
)
208 nameptr
= fi
->fileIdent
+ liu
;
212 int poffset
; /* Unpaded ending offset */
214 poffset
= fibh
->soffset
+ sizeof(struct FileIdentDesc
) + liu
+ lfi
;
217 nameptr
= (Uint8
*)(fibh
->ebh
->b_data
+ poffset
- lfi
);
221 memcpy(nameptr
, fi
->fileIdent
+ liu
, lfi
- poffset
);
222 memcpy(nameptr
+ lfi
- poffset
, fibh
->ebh
->b_data
, poffset
);
226 if ( (cfi
->fileCharacteristics
& FILE_DELETED
) != 0 )
228 if ( !UDF_QUERY_FLAG(dir
->i_sb
, UDF_FLAG_UNDELETE
) )
232 if ( (cfi
->fileCharacteristics
& FILE_HIDDEN
) != 0 )
234 if ( !UDF_QUERY_FLAG(dir
->i_sb
, UDF_FLAG_UNHIDE
) )
241 if ((flen
= udf_get_filename(nameptr
, fname
, lfi
)))
243 if (udf_match(flen
, fname
, &(dentry
->d_name
)))
245 udf_release_data(bh
);
250 if (fibh
->sbh
!= fibh
->ebh
)
251 udf_release_data(fibh
->ebh
);
252 udf_release_data(fibh
->sbh
);
253 udf_release_data(bh
);
261 * Look-up the inode for a given name.
264 * Required - lookup_dentry() will return -ENOTDIR if this routine is not
265 * available for a directory. The filesystem is useless if this routine is
266 * not available for at least the filesystem's root directory.
268 * This routine is passed an incomplete dentry - it must be completed by
269 * calling d_add(dentry, inode). If the name does not exist, then the
270 * specified inode must be set to null. An error should only be returned
271 * when the lookup fails for a reason other than the name not existing.
272 * Note that the directory inode semaphore is held during the call.
274 * Refer to lookup_dentry() in fs/namei.c
275 * lookup_dentry() -> lookup() -> real_lookup() -> .
278 * dir Pointer to inode of parent directory.
279 * dentry Pointer to dentry to complete.
282 * <return> Zero on success.
285 * July 1, 1997 - Andrew E. Mileski
286 * Written, tested, and released.
289 static struct dentry
*
290 udf_lookup(struct inode
*dir
, struct dentry
*dentry
)
292 struct inode
*inode
= NULL
;
293 struct FileIdentDesc cfi
, *fi
;
294 struct udf_fileident_bh fibh
;
296 if (dentry
->d_name
.len
> UDF_NAME_LEN
)
297 return ERR_PTR(-ENAMETOOLONG
);
300 /* temporary shorthand for specifying files by inode number */
301 if (!strncmp(dentry
->d_name
.name
, ".B=", 3) )
303 lb_addr lb
= { 0, simple_strtoul(dentry
->d_name
.name
+3, NULL
, 0) };
304 inode
= udf_iget(dir
->i_sb
, lb
);
306 return ERR_PTR(-EACCES
);
309 #endif /* UDF_RECOVERY */
311 if ((fi
= udf_find_entry(dir
, dentry
, &fibh
, &cfi
)))
313 if (fibh
.sbh
!= fibh
.ebh
)
314 udf_release_data(fibh
.ebh
);
315 udf_release_data(fibh
.sbh
);
317 inode
= udf_iget(dir
->i_sb
, lelb_to_cpu(cfi
.icb
.extLocation
));
319 return ERR_PTR(-EACCES
);
321 d_add(dentry
, inode
);
325 static struct FileIdentDesc
*
326 udf_add_entry(struct inode
*dir
, struct dentry
*dentry
,
327 struct udf_fileident_bh
*fibh
,
328 struct FileIdentDesc
*cfi
, int *err
)
330 struct super_block
*sb
;
331 struct FileIdentDesc
*fi
=NULL
;
332 struct ustr unifilename
;
333 char name
[UDF_NAME_LEN
], fname
[UDF_NAME_LEN
];
338 loff_t size
= (udf_ext0_offset(dir
) + dir
->i_size
) >> 2;
344 Uint32 extoffset
, elen
, offset
;
345 struct buffer_head
*bh
= NULL
;
351 if ( !(udf_char_to_ustr(&unifilename
, dentry
->d_name
.name
, dentry
->d_name
.len
)) )
353 *err
= -ENAMETOOLONG
;
357 if ( !(namelen
= udf_UTF8toCS0(name
, &unifilename
, UDF_NAME_LEN
)) )
359 *err
= -ENAMETOOLONG
;
363 else if (dir
->i_size
!= 0)
372 nfidlen
= (sizeof(struct FileIdentDesc
) + 0 + namelen
+ 3) & ~3;
374 f_pos
= (udf_ext0_offset(dir
) >> 2);
376 fibh
->soffset
= fibh
->eoffset
= (f_pos
& ((dir
->i_sb
->s_blocksize
- 1) >> 2)) << 2;
377 if (inode_bmap(dir
, f_pos
>> (dir
->i_sb
->s_blocksize_bits
- 2),
378 &bloc
, &extoffset
, &eloc
, &elen
, &offset
, &bh
) == EXTENT_RECORDED_ALLOCATED
)
380 block
= udf_get_lb_pblock(dir
->i_sb
, eloc
, offset
);
381 if ((++offset
<< dir
->i_sb
->s_blocksize_bits
) < elen
)
383 if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_SHORT
)
384 extoffset
-= sizeof(short_ad
);
385 else if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_LONG
)
386 extoffset
-= sizeof(long_ad
);
391 if (!(fibh
->sbh
= fibh
->ebh
= udf_tread(dir
->i_sb
, block
, dir
->i_sb
->s_blocksize
)))
393 udf_release_data(bh
);
397 block
= UDF_I_LOCATION(dir
).logicalBlockNum
;
399 while ( (f_pos
< size
) )
401 fi
= udf_fileident_read(dir
, &f_pos
, fibh
, cfi
, &bloc
, &extoffset
, &eloc
, &elen
, &offset
, &bh
);
405 if (fibh
->sbh
!= fibh
->ebh
)
406 udf_release_data(fibh
->ebh
);
407 udf_release_data(fibh
->sbh
);
408 udf_release_data(bh
);
412 liu
= le16_to_cpu(cfi
->lengthOfImpUse
);
413 lfi
= cfi
->lengthFileIdent
;
415 if (fibh
->sbh
== fibh
->ebh
)
416 nameptr
= fi
->fileIdent
+ liu
;
419 int poffset
; /* Unpaded ending offset */
421 poffset
= fibh
->soffset
+ sizeof(struct FileIdentDesc
) + liu
+ lfi
;
424 nameptr
= (char *)(fibh
->ebh
->b_data
+ poffset
- lfi
);
428 memcpy(nameptr
, fi
->fileIdent
+ liu
, lfi
- poffset
);
429 memcpy(nameptr
+ lfi
- poffset
, fibh
->ebh
->b_data
, poffset
);
433 if ( (cfi
->fileCharacteristics
& FILE_DELETED
) != 0 )
435 if (((sizeof(struct FileIdentDesc
) + liu
+ lfi
+ 3) & ~3) == nfidlen
)
437 udf_release_data(bh
);
438 cfi
->descTag
.tagSerialNum
= cpu_to_le16(1);
439 cfi
->fileVersionNum
= cpu_to_le16(1);
440 cfi
->fileCharacteristics
= 0;
441 cfi
->lengthFileIdent
= namelen
;
442 cfi
->lengthOfImpUse
= cpu_to_le16(0);
443 if (!udf_write_fi(cfi
, fi
, fibh
, NULL
, name
))
453 if ((flen
= udf_get_filename(nameptr
, fname
, lfi
)) &&
454 udf_match(flen
, fname
, &(dentry
->d_name
))) {
455 if (fibh
->sbh
!= fibh
->ebh
)
456 udf_release_data(fibh
->ebh
);
457 udf_release_data(fibh
->sbh
);
458 udf_release_data(bh
);
466 block
= udf_get_lb_pblock(dir
->i_sb
, UDF_I_LOCATION(dir
), 0);
467 if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_IN_ICB
)
469 fibh
->sbh
= fibh
->ebh
= udf_tread(dir
->i_sb
, block
, dir
->i_sb
->s_blocksize
);
470 fibh
->soffset
= fibh
->eoffset
= udf_file_entry_alloc_offset(dir
);
474 fibh
->sbh
= fibh
->ebh
= NULL
;
475 fibh
->soffset
= fibh
->eoffset
= sb
->s_blocksize
;
481 if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_IN_ICB
&&
482 sb
->s_blocksize
- fibh
->eoffset
< nfidlen
)
484 udf_release_data(bh
);
486 fibh
->soffset
-= udf_ext0_offset(dir
);
487 fibh
->eoffset
-= udf_ext0_offset(dir
);
488 f_pos
-= (udf_ext0_offset(dir
) >> 2);
489 if (fibh
->sbh
!= fibh
->ebh
)
490 udf_release_data(fibh
->ebh
);
491 udf_release_data(fibh
->sbh
);
492 if (!(fibh
->sbh
= fibh
->ebh
= udf_expand_dir_adinicb(dir
, &block
, err
)))
494 bloc
= UDF_I_LOCATION(dir
);
495 eloc
.logicalBlockNum
= block
;
496 eloc
.partitionReferenceNum
= UDF_I_LOCATION(dir
).partitionReferenceNum
;
497 elen
= dir
->i_sb
->s_blocksize
;
498 extoffset
= udf_file_entry_alloc_offset(dir
);
499 if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_SHORT
)
500 extoffset
+= sizeof(short_ad
);
501 else if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_LONG
)
502 extoffset
+= sizeof(long_ad
);
505 if (sb
->s_blocksize
- fibh
->eoffset
>= nfidlen
)
507 fibh
->soffset
= fibh
->eoffset
;
508 fibh
->eoffset
+= nfidlen
;
509 if (fibh
->sbh
!= fibh
->ebh
)
511 udf_release_data(fibh
->sbh
);
512 fibh
->sbh
= fibh
->ebh
;
515 if (UDF_I_ALLOCTYPE(dir
) != ICB_FLAG_AD_IN_ICB
)
516 block
= eloc
.logicalBlockNum
+ ((elen
- 1) >>
517 dir
->i_sb
->s_blocksize_bits
);
519 block
= UDF_I_LOCATION(dir
).logicalBlockNum
;
521 fi
= (struct FileIdentDesc
*)(fibh
->sbh
->b_data
+ fibh
->soffset
);
525 fibh
->soffset
= fibh
->eoffset
- sb
->s_blocksize
;
526 fibh
->eoffset
+= nfidlen
- sb
->s_blocksize
;
527 if (fibh
->sbh
!= fibh
->ebh
)
529 udf_release_data(fibh
->sbh
);
530 fibh
->sbh
= fibh
->ebh
;
533 block
= eloc
.logicalBlockNum
+ ((elen
- 1) >>
534 dir
->i_sb
->s_blocksize_bits
);
537 if (!(fibh
->ebh
= udf_bread(dir
, f_pos
>> (dir
->i_sb
->s_blocksize_bits
- 2), 1, err
)))
539 udf_release_data(bh
);
540 udf_release_data(fibh
->sbh
);
544 if (!(fibh
->soffset
))
546 if (udf_next_aext(dir
, &bloc
, &extoffset
, &eloc
, &elen
, &bh
, 1) ==
547 EXTENT_RECORDED_ALLOCATED
)
549 block
= eloc
.logicalBlockNum
+ ((elen
- 1) >>
550 dir
->i_sb
->s_blocksize_bits
);
555 udf_release_data(fibh
->sbh
);
556 fibh
->sbh
= fibh
->ebh
;
557 fi
= (struct FileIdentDesc
*)(fibh
->sbh
->b_data
);
561 fi
= (struct FileIdentDesc
*)
562 (fibh
->sbh
->b_data
+ sb
->s_blocksize
+ fibh
->soffset
);
566 memset(cfi
, 0, sizeof(struct FileIdentDesc
));
567 udf_new_tag((char *)cfi
, TID_FILE_IDENT_DESC
, 2, 1, block
, sizeof(tag
));
568 cfi
->fileVersionNum
= cpu_to_le16(1);
569 cfi
->lengthFileIdent
= namelen
;
570 cfi
->lengthOfImpUse
= cpu_to_le16(0);
571 if (!udf_write_fi(cfi
, fi
, fibh
, NULL
, name
))
573 udf_release_data(bh
);
574 dir
->i_size
+= nfidlen
;
575 if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_IN_ICB
)
576 UDF_I_LENALLOC(dir
) += nfidlen
;
577 dir
->i_version
= ++event
;
578 mark_inode_dirty(dir
);
583 udf_release_data(bh
);
584 if (fibh
->sbh
!= fibh
->ebh
)
585 udf_release_data(fibh
->ebh
);
586 udf_release_data(fibh
->sbh
);
591 static int udf_delete_entry(struct FileIdentDesc
*fi
,
592 struct udf_fileident_bh
*fibh
,
593 struct FileIdentDesc
*cfi
)
595 cfi
->fileCharacteristics
|= FILE_DELETED
;
596 return udf_write_fi(cfi
, fi
, fibh
, NULL
, NULL
);
599 static int udf_create(struct inode
*dir
, struct dentry
*dentry
, int mode
)
601 struct udf_fileident_bh fibh
;
603 struct FileIdentDesc cfi
, *fi
;
606 inode
= udf_new_inode(dir
, mode
, &err
);
610 if (UDF_I_ALLOCTYPE(inode
) == ICB_FLAG_AD_IN_ICB
)
611 inode
->i_data
.a_ops
= &udf_adinicb_aops
;
613 inode
->i_data
.a_ops
= &udf_aops
;
614 inode
->i_op
= &udf_file_inode_operations
;
615 inode
->i_fop
= &udf_file_operations
;
616 inode
->i_mode
= mode
;
617 mark_inode_dirty(inode
);
619 if (!(fi
= udf_add_entry(dir
, dentry
, &fibh
, &cfi
, &err
)))
622 mark_inode_dirty(inode
);
626 cfi
.icb
.extLength
= cpu_to_le32(inode
->i_sb
->s_blocksize
);
627 cfi
.icb
.extLocation
= cpu_to_lelb(UDF_I_LOCATION(inode
));
628 *(Uint32
*)((struct ADImpUse
*)cfi
.icb
.impUse
)->impUse
=
629 cpu_to_le32(UDF_I_UNIQUE(inode
) & 0x00000000FFFFFFFFUL
);
630 udf_write_fi(&cfi
, fi
, &fibh
, NULL
, NULL
);
631 if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_IN_ICB
)
633 mark_inode_dirty(dir
);
634 dir
->i_version
= ++event
;
636 if (fibh
.sbh
!= fibh
.ebh
)
637 udf_release_data(fibh
.ebh
);
638 udf_release_data(fibh
.sbh
);
639 d_instantiate(dentry
, inode
);
643 static int udf_mknod(struct inode
* dir
, struct dentry
* dentry
, int mode
, int rdev
)
645 struct inode
* inode
;
646 struct udf_fileident_bh fibh
;
648 struct FileIdentDesc cfi
, *fi
;
651 inode
= udf_new_inode(dir
, mode
, &err
);
655 inode
->i_uid
= current
->fsuid
;
656 init_special_inode(inode
, mode
, rdev
);
657 if (!(fi
= udf_add_entry(dir
, dentry
, &fibh
, &cfi
, &err
)))
660 mark_inode_dirty(inode
);
664 cfi
.icb
.extLength
= cpu_to_le32(inode
->i_sb
->s_blocksize
);
665 cfi
.icb
.extLocation
= cpu_to_lelb(UDF_I_LOCATION(inode
));
666 *(Uint32
*)((struct ADImpUse
*)cfi
.icb
.impUse
)->impUse
=
667 cpu_to_le32(UDF_I_UNIQUE(inode
) & 0x00000000FFFFFFFFUL
);
668 udf_write_fi(&cfi
, fi
, &fibh
, NULL
, NULL
);
669 if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_IN_ICB
)
671 mark_inode_dirty(dir
);
672 dir
->i_version
= ++event
;
674 mark_inode_dirty(inode
);
676 if (fibh
.sbh
!= fibh
.ebh
)
677 udf_release_data(fibh
.ebh
);
678 udf_release_data(fibh
.sbh
);
679 d_instantiate(dentry
, inode
);
685 static int udf_mkdir(struct inode
* dir
, struct dentry
* dentry
, int mode
)
687 struct inode
* inode
;
688 struct udf_fileident_bh fibh
;
690 struct FileIdentDesc cfi
, *fi
;
693 if (dir
->i_nlink
>= (256<<sizeof(dir
->i_nlink
))-1)
697 inode
= udf_new_inode(dir
, S_IFDIR
, &err
);
701 inode
->i_op
= &udf_dir_inode_operations
;
702 inode
->i_fop
= &udf_dir_operations
;
704 if (!(fi
= udf_add_entry(inode
, NULL
, &fibh
, &cfi
, &err
)))
707 mark_inode_dirty(inode
);
712 cfi
.icb
.extLength
= cpu_to_le32(inode
->i_sb
->s_blocksize
);
713 cfi
.icb
.extLocation
= cpu_to_lelb(UDF_I_LOCATION(dir
));
714 *(Uint32
*)((struct ADImpUse
*)cfi
.icb
.impUse
)->impUse
=
715 cpu_to_le32(UDF_I_UNIQUE(dir
) & 0x00000000FFFFFFFFUL
);
716 cfi
.fileCharacteristics
= FILE_DIRECTORY
| FILE_PARENT
;
717 udf_write_fi(&cfi
, fi
, &fibh
, NULL
, NULL
);
718 udf_release_data(fibh
.sbh
);
719 inode
->i_mode
= S_IFDIR
| mode
;
720 if (dir
->i_mode
& S_ISGID
)
721 inode
->i_mode
|= S_ISGID
;
722 mark_inode_dirty(inode
);
724 if (!(fi
= udf_add_entry(dir
, dentry
, &fibh
, &cfi
, &err
)))
727 mark_inode_dirty(inode
);
731 cfi
.icb
.extLength
= cpu_to_le32(inode
->i_sb
->s_blocksize
);
732 cfi
.icb
.extLocation
= cpu_to_lelb(UDF_I_LOCATION(inode
));
733 *(Uint32
*)((struct ADImpUse
*)cfi
.icb
.impUse
)->impUse
=
734 cpu_to_le32(UDF_I_UNIQUE(inode
) & 0x00000000FFFFFFFFUL
);
735 cfi
.fileCharacteristics
|= FILE_DIRECTORY
;
736 udf_write_fi(&cfi
, fi
, &fibh
, NULL
, NULL
);
737 dir
->i_version
= ++event
;
739 mark_inode_dirty(dir
);
740 d_instantiate(dentry
, inode
);
741 if (fibh
.sbh
!= fibh
.ebh
)
742 udf_release_data(fibh
.ebh
);
743 udf_release_data(fibh
.sbh
);
749 static int empty_dir(struct inode
*dir
)
751 struct FileIdentDesc
*fi
, cfi
;
752 struct udf_fileident_bh fibh
;
754 loff_t size
= (udf_ext0_offset(dir
) + dir
->i_size
) >> 2;
757 Uint32 extoffset
, elen
, offset
;
758 struct buffer_head
*bh
= NULL
;
760 f_pos
= (udf_ext0_offset(dir
) >> 2);
762 fibh
.soffset
= fibh
.eoffset
= (f_pos
& ((dir
->i_sb
->s_blocksize
- 1) >> 2)) << 2;
763 if (inode_bmap(dir
, f_pos
>> (dir
->i_sb
->s_blocksize_bits
- 2),
764 &bloc
, &extoffset
, &eloc
, &elen
, &offset
, &bh
) == EXTENT_RECORDED_ALLOCATED
)
766 block
= udf_get_lb_pblock(dir
->i_sb
, eloc
, offset
);
767 if ((++offset
<< dir
->i_sb
->s_blocksize_bits
) < elen
)
769 if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_SHORT
)
770 extoffset
-= sizeof(short_ad
);
771 else if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_LONG
)
772 extoffset
-= sizeof(long_ad
);
779 udf_release_data(bh
);
783 if (!(fibh
.sbh
= fibh
.ebh
= udf_tread(dir
->i_sb
, block
, dir
->i_sb
->s_blocksize
)))
786 while ( (f_pos
< size
) )
788 fi
= udf_fileident_read(dir
, &f_pos
, &fibh
, &cfi
, &bloc
, &extoffset
, &eloc
, &elen
, &offset
, &bh
);
792 if (fibh
.sbh
!= fibh
.ebh
)
793 udf_release_data(fibh
.ebh
);
794 udf_release_data(fibh
.sbh
);
795 udf_release_data(bh
);
799 if (cfi
.lengthFileIdent
&& (cfi
.fileCharacteristics
& FILE_DELETED
) == 0)
801 udf_release_data(bh
);
805 if (fibh
.sbh
!= fibh
.ebh
)
806 udf_release_data(fibh
.ebh
);
807 udf_release_data(fibh
.sbh
);
808 udf_release_data(bh
);
812 static int udf_rmdir(struct inode
* dir
, struct dentry
* dentry
)
815 struct inode
* inode
;
816 struct udf_fileident_bh fibh
;
817 struct FileIdentDesc
*fi
, cfi
;
820 fi
= udf_find_entry(dir
, dentry
, &fibh
, &cfi
);
824 inode
= dentry
->d_inode
;
828 if (udf_get_lb_pblock(dir
->i_sb
, lelb_to_cpu(cfi
.icb
.extLocation
), 0) != inode
->i_ino
)
831 if (!empty_dir(inode
))
833 retval
= udf_delete_entry(fi
, &fibh
, &cfi
);
834 dir
->i_version
= ++event
;
837 if (inode
->i_nlink
!= 2)
838 udf_warning(inode
->i_sb
, "udf_rmdir",
839 "empty directory has nlink != 2 (%d)",
841 inode
->i_version
= ++event
;
844 mark_inode_dirty(inode
);
846 inode
->i_ctime
= dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
847 UDF_I_UCTIME(inode
) = UDF_I_UCTIME(dir
) = UDF_I_UMTIME(dir
) = CURRENT_UTIME
;
848 mark_inode_dirty(dir
);
851 if (fibh
.sbh
!= fibh
.ebh
)
852 udf_release_data(fibh
.ebh
);
853 udf_release_data(fibh
.sbh
);
858 static int udf_unlink(struct inode
* dir
, struct dentry
* dentry
)
861 struct inode
* inode
;
862 struct udf_fileident_bh fibh
;
863 struct FileIdentDesc
*fi
;
864 struct FileIdentDesc cfi
;
867 fi
= udf_find_entry(dir
, dentry
, &fibh
, &cfi
);
871 inode
= dentry
->d_inode
;
876 if (udf_get_lb_pblock(dir
->i_sb
, lelb_to_cpu(cfi
.icb
.extLocation
), 0) !=
884 udf_debug("Deleting nonexistent file (%lu), %d\n",
885 inode
->i_ino
, inode
->i_nlink
);
888 retval
= udf_delete_entry(fi
, &fibh
, &cfi
);
891 dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
892 UDF_I_UCTIME(dir
) = UDF_I_UMTIME(dir
) = CURRENT_UTIME
;
893 mark_inode_dirty(dir
);
895 mark_inode_dirty(inode
);
896 inode
->i_ctime
= dir
->i_ctime
;
900 if (fibh
.sbh
!= fibh
.ebh
)
901 udf_release_data(fibh
.ebh
);
902 udf_release_data(fibh
.sbh
);
907 static int udf_symlink(struct inode
* dir
, struct dentry
* dentry
, const char * symname
)
909 struct inode
* inode
;
910 struct PathComponent
*pc
;
912 struct udf_fileident_bh fibh
;
913 struct buffer_head
*bh
= NULL
;
914 int eoffset
, elen
= 0;
915 struct FileIdentDesc
*fi
;
916 struct FileIdentDesc cfi
;
921 if (!(inode
= udf_new_inode(dir
, S_IFLNK
, &err
)))
924 inode
->i_mode
= S_IFLNK
| S_IRWXUGO
;
925 inode
->i_data
.a_ops
= &udf_symlink_aops
;
926 inode
->i_op
= &page_symlink_inode_operations
;
928 if (UDF_I_ALLOCTYPE(inode
) != ICB_FLAG_AD_IN_ICB
)
930 struct buffer_head
*bh
= NULL
;
932 Uint32 elen
, extoffset
;
934 block
= udf_new_block(inode
,
935 UDF_I_LOCATION(inode
).partitionReferenceNum
,
936 UDF_I_LOCATION(inode
).logicalBlockNum
, &err
);
939 bloc
= UDF_I_LOCATION(inode
);
940 eloc
.logicalBlockNum
= block
;
941 eloc
.partitionReferenceNum
= UDF_I_LOCATION(inode
).partitionReferenceNum
;
942 elen
= inode
->i_sb
->s_blocksize
;
943 extoffset
= udf_file_entry_alloc_offset(inode
);
944 udf_add_aext(inode
, &bloc
, &extoffset
, eloc
, elen
, &bh
, 0);
945 udf_release_data(bh
);
947 inode
->i_blocks
= inode
->i_sb
->s_blocksize
/ 512;
948 block
= udf_get_pblock(inode
->i_sb
, block
,
949 UDF_I_LOCATION(inode
).partitionReferenceNum
, 0);
952 block
= udf_get_lb_pblock(inode
->i_sb
, UDF_I_LOCATION(inode
), 0);
954 bh
= udf_tread(inode
->i_sb
, block
, inode
->i_sb
->s_blocksize
);
955 ea
= bh
->b_data
+ udf_ext0_offset(inode
);
957 eoffset
= inode
->i_sb
->s_blocksize
- udf_ext0_offset(inode
);
958 pc
= (struct PathComponent
*)ea
;
965 } while (*symname
== '/');
967 pc
->componentType
= 1;
968 pc
->lengthComponentIdent
= 0;
969 pc
->componentFileVersionNum
= 0;
970 pc
+= sizeof(struct PathComponent
);
971 elen
+= sizeof(struct PathComponent
);
978 if (elen
+ sizeof(struct PathComponent
) > eoffset
)
981 pc
= (struct PathComponent
*)(ea
+ elen
);
983 compstart
= (char *)symname
;
988 } while (*symname
&& *symname
!= '/');
990 pc
->componentType
= 5;
991 pc
->lengthComponentIdent
= 0;
992 pc
->componentFileVersionNum
= 0;
993 if (pc
->componentIdent
[0] == '.')
995 if (pc
->lengthComponentIdent
== 1)
996 pc
->componentType
= 4;
997 else if (pc
->lengthComponentIdent
== 2 && pc
->componentIdent
[1] == '.')
998 pc
->componentType
= 3;
1001 if (pc
->componentType
== 5)
1003 if (elen
+ sizeof(struct PathComponent
) + symname
- compstart
> eoffset
)
1006 pc
->lengthComponentIdent
= symname
- compstart
;
1008 memcpy(pc
->componentIdent
, compstart
, pc
->lengthComponentIdent
);
1011 elen
+= sizeof(struct PathComponent
) + pc
->lengthComponentIdent
;
1018 } while (*symname
== '/');
1022 udf_release_data(bh
);
1023 inode
->i_size
= elen
;
1024 if (UDF_I_ALLOCTYPE(inode
) == ICB_FLAG_AD_IN_ICB
)
1025 UDF_I_LENALLOC(inode
) = inode
->i_size
;
1026 mark_inode_dirty(inode
);
1028 if (!(fi
= udf_add_entry(dir
, dentry
, &fibh
, &cfi
, &err
)))
1030 cfi
.icb
.extLength
= cpu_to_le32(inode
->i_sb
->s_blocksize
);
1031 cfi
.icb
.extLocation
= cpu_to_lelb(UDF_I_LOCATION(inode
));
1032 if (UDF_SB_LVIDBH(inode
->i_sb
))
1034 struct LogicalVolHeaderDesc
*lvhd
;
1036 lvhd
= (struct LogicalVolHeaderDesc
*)(UDF_SB_LVID(inode
->i_sb
)->logicalVolContentsUse
);
1037 uniqueID
= le64_to_cpu(lvhd
->uniqueID
);
1038 *(Uint32
*)((struct ADImpUse
*)cfi
.icb
.impUse
)->impUse
=
1039 cpu_to_le32(uniqueID
& 0x00000000FFFFFFFFUL
);
1040 if (!(++uniqueID
& 0x00000000FFFFFFFFUL
))
1042 lvhd
->uniqueID
= cpu_to_le64(uniqueID
);
1043 mark_buffer_dirty(UDF_SB_LVIDBH(inode
->i_sb
));
1045 udf_write_fi(&cfi
, fi
, &fibh
, NULL
, NULL
);
1046 if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_IN_ICB
)
1048 mark_inode_dirty(dir
);
1049 dir
->i_version
= ++event
;
1051 if (fibh
.sbh
!= fibh
.ebh
)
1052 udf_release_data(fibh
.ebh
);
1053 udf_release_data(fibh
.sbh
);
1054 d_instantiate(dentry
, inode
);
1062 mark_inode_dirty(inode
);
1067 static int udf_link(struct dentry
* old_dentry
, struct inode
* dir
,
1068 struct dentry
*dentry
)
1070 struct inode
*inode
= old_dentry
->d_inode
;
1071 struct udf_fileident_bh fibh
;
1073 struct FileIdentDesc cfi
, *fi
;
1075 if (S_ISDIR(inode
->i_mode
))
1078 if (inode
->i_nlink
>= (256<<sizeof(inode
->i_nlink
))-1)
1081 if (!(fi
= udf_add_entry(dir
, dentry
, &fibh
, &cfi
, &err
)))
1083 cfi
.icb
.extLength
= cpu_to_le32(inode
->i_sb
->s_blocksize
);
1084 cfi
.icb
.extLocation
= cpu_to_lelb(UDF_I_LOCATION(inode
));
1085 if (UDF_SB_LVIDBH(inode
->i_sb
))
1087 struct LogicalVolHeaderDesc
*lvhd
;
1089 lvhd
= (struct LogicalVolHeaderDesc
*)(UDF_SB_LVID(inode
->i_sb
)->logicalVolContentsUse
);
1090 uniqueID
= le64_to_cpu(lvhd
->uniqueID
);
1091 *(Uint32
*)((struct ADImpUse
*)cfi
.icb
.impUse
)->impUse
=
1092 cpu_to_le32(uniqueID
& 0x00000000FFFFFFFFUL
);
1093 if (!(++uniqueID
& 0x00000000FFFFFFFFUL
))
1095 lvhd
->uniqueID
= cpu_to_le64(uniqueID
);
1096 mark_buffer_dirty(UDF_SB_LVIDBH(inode
->i_sb
));
1098 udf_write_fi(&cfi
, fi
, &fibh
, NULL
, NULL
);
1099 if (UDF_I_ALLOCTYPE(dir
) == ICB_FLAG_AD_IN_ICB
)
1101 mark_inode_dirty(dir
);
1102 dir
->i_version
= ++event
;
1104 if (fibh
.sbh
!= fibh
.ebh
)
1105 udf_release_data(fibh
.ebh
);
1106 udf_release_data(fibh
.sbh
);
1108 inode
->i_ctime
= CURRENT_TIME
;
1109 UDF_I_UCTIME(inode
) = CURRENT_UTIME
;
1110 mark_inode_dirty(inode
);
1111 atomic_inc(&inode
->i_count
);
1112 d_instantiate(dentry
, inode
);
1116 /* Anybody can rename anything with this: the permission checks are left to the
1117 * higher-level routines.
1119 static int udf_rename (struct inode
* old_dir
, struct dentry
* old_dentry
,
1120 struct inode
* new_dir
, struct dentry
* new_dentry
)
1122 struct inode
* old_inode
, * new_inode
;
1123 struct udf_fileident_bh ofibh
, nfibh
;
1124 struct FileIdentDesc
*ofi
= NULL
, *nfi
= NULL
, *dir_fi
= NULL
, ocfi
, ncfi
;
1125 struct buffer_head
*dir_bh
= NULL
;
1126 int retval
= -ENOENT
;
1128 old_inode
= old_dentry
->d_inode
;
1129 ofi
= udf_find_entry(old_dir
, old_dentry
, &ofibh
, &ocfi
);
1130 if (!ofi
|| udf_get_lb_pblock(old_dir
->i_sb
, lelb_to_cpu(ocfi
.icb
.extLocation
), 0) !=
1136 new_inode
= new_dentry
->d_inode
;
1137 nfi
= udf_find_entry(new_dir
, new_dentry
, &nfibh
, &ncfi
);
1142 if (nfibh
.sbh
!= nfibh
.ebh
)
1143 udf_release_data(nfibh
.ebh
);
1144 udf_release_data(nfibh
.sbh
);
1149 DQUOT_INIT(new_inode
);
1152 if (S_ISDIR(old_inode
->i_mode
))
1154 Uint32 offset
= udf_ext0_offset(old_inode
);
1158 retval
= -ENOTEMPTY
;
1159 if (!empty_dir(new_inode
))
1163 dir_bh
= udf_bread(old_inode
, 0, 0, &retval
);
1166 dir_fi
= udf_get_fileident(dir_bh
->b_data
, old_inode
->i_sb
->s_blocksize
, &offset
);
1169 if (udf_get_lb_pblock(old_inode
->i_sb
, cpu_to_lelb(dir_fi
->icb
.extLocation
), 0) !=
1175 if (!new_inode
&& new_dir
->i_nlink
>= (256<<sizeof(new_dir
->i_nlink
))-1)
1180 nfi
= udf_add_entry(new_dir
, new_dentry
, &nfibh
, &ncfi
, &retval
);
1184 new_dir
->i_version
= ++event
;
1187 * Like most other Unix systems, set the ctime for inodes on a
1190 old_inode
->i_ctime
= CURRENT_TIME
;
1191 UDF_I_UCTIME(old_inode
) = CURRENT_UTIME
;
1192 mark_inode_dirty(old_inode
);
1197 ncfi
.fileVersionNum
= ocfi
.fileVersionNum
;
1198 ncfi
.fileCharacteristics
= ocfi
.fileCharacteristics
;
1199 memcpy(&(ncfi
.icb
), &(ocfi
.icb
), sizeof(long_ad
));
1200 udf_write_fi(&ncfi
, nfi
, &nfibh
, NULL
, NULL
);
1202 udf_delete_entry(ofi
, &ofibh
, &ocfi
);
1204 old_dir
->i_version
= ++event
;
1207 new_inode
->i_nlink
--;
1208 new_inode
->i_ctime
= CURRENT_TIME
;
1209 UDF_I_UCTIME(new_inode
) = CURRENT_UTIME
;
1210 mark_inode_dirty(new_inode
);
1212 old_dir
->i_ctime
= old_dir
->i_mtime
= CURRENT_TIME
;
1213 UDF_I_UCTIME(old_dir
) = UDF_I_UMTIME(old_dir
) = CURRENT_UTIME
;
1214 mark_inode_dirty(old_dir
);
1218 dir_fi
->icb
.extLocation
= lelb_to_cpu(UDF_I_LOCATION(new_dir
));
1219 udf_update_tag((char *)dir_fi
, sizeof(struct FileIdentDesc
) +
1220 cpu_to_le16(dir_fi
->lengthOfImpUse
));
1221 if (UDF_I_ALLOCTYPE(old_inode
) == ICB_FLAG_AD_IN_ICB
)
1223 mark_inode_dirty(old_inode
);
1224 old_inode
->i_version
= ++event
;
1227 mark_buffer_dirty(dir_bh
);
1228 old_dir
->i_nlink
--;
1229 mark_inode_dirty(old_dir
);
1232 new_inode
->i_nlink
--;
1233 mark_inode_dirty(new_inode
);
1237 new_dir
->i_nlink
++;
1238 mark_inode_dirty(new_dir
);
1245 udf_release_data(dir_bh
);
1248 if (ofibh
.sbh
!= ofibh
.ebh
)
1249 udf_release_data(ofibh
.ebh
);
1250 udf_release_data(ofibh
.sbh
);
1254 if (nfibh
.sbh
!= nfibh
.ebh
)
1255 udf_release_data(nfibh
.ebh
);
1256 udf_release_data(nfibh
.sbh
);
1261 struct inode_operations udf_dir_inode_operations
= {
1266 symlink
: udf_symlink
,