- pre5:
[davej-history.git] / fs / udf / namei.c
blob9cc2f3d29760f1b08d4ef50289ffe87cb5690765
1 /*
2 * namei.c
4 * PURPOSE
5 * Inode name handling routines for the OSTA-UDF(tm) filesystem.
7 * CONTACTS
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
12 * COPYRIGHT
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
21 * HISTORY
23 * 12/12/98 blf Created. Split out the lookup code from dir.c
24 * 04/19/99 blf link, mknod, symlink support
27 #include "udfdecl.h"
29 #include "udf_i.h"
30 #include "udf_sb.h"
31 #include <linux/string.h>
32 #include <linux/errno.h>
33 #include <linux/mm.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)
40 if (len != qs->len)
41 return 0;
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);
50 Uint16 crc;
51 Uint8 checksum = 0;
52 int i;
53 int offset;
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);
62 if (impuse)
64 if (offset + liu < 0)
65 memcpy((Uint8 *)sfi->impUse, impuse, liu);
66 else if (offset >= 0)
67 memcpy(fibh->ebh->b_data + offset, impuse, liu);
68 else
70 memcpy((Uint8 *)sfi->impUse, impuse, -offset);
71 memcpy(fibh->ebh->b_data, impuse - offset, liu + offset);
75 offset += liu;
77 if (fileident)
79 if (offset + lfi < 0)
80 memcpy((Uint8 *)sfi->fileIdent + liu, fileident, lfi);
81 else if (offset >= 0)
82 memcpy(fibh->ebh->b_data + offset, fileident, lfi);
83 else
85 memcpy((Uint8 *)sfi->fileIdent + liu, fileident, -offset);
86 memcpy(fibh->ebh->b_data, fileident - offset, lfi + offset);
90 offset += lfi;
92 if (offset + padlen < 0)
93 memset((Uint8 *)sfi->padding + liu + lfi, 0x00, padlen);
94 else if (offset >= 0)
95 memset(fibh->ebh->b_data + offset, 0x00, padlen);
96 else
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) -
103 sizeof(tag), 0);
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);
111 else
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);
121 for (i=0; i<16; i++)
122 if (i != 4)
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));
128 else
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);
138 return 0;
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;
147 loff_t f_pos;
148 int block, flen;
149 char fname[255];
150 char *nameptr;
151 Uint8 lfi;
152 Uint16 liu;
153 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
154 lb_addr bloc, eloc;
155 Uint32 extoffset, elen, offset;
156 struct buffer_head *bh = NULL;
158 if (!dir)
159 return 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);
175 else
176 offset = 0;
178 else
180 udf_release_data(bh);
181 return NULL;
184 if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
186 udf_release_data(bh);
187 return NULL;
190 while ( (f_pos < size) )
192 fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
194 if (!fi)
196 if (fibh->sbh != fibh->ebh)
197 udf_release_data(fibh->ebh);
198 udf_release_data(fibh->sbh);
199 udf_release_data(bh);
200 return NULL;
203 liu = le16_to_cpu(cfi->lengthOfImpUse);
204 lfi = cfi->lengthFileIdent;
206 if (fibh->sbh == fibh->ebh)
208 nameptr = fi->fileIdent + liu;
210 else
212 int poffset; /* Unpaded ending offset */
214 poffset = fibh->soffset + sizeof(struct FileIdentDesc) + liu + lfi;
216 if (poffset >= lfi)
217 nameptr = (Uint8 *)(fibh->ebh->b_data + poffset - lfi);
218 else
220 nameptr = fname;
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) )
229 continue;
232 if ( (cfi->fileCharacteristics & FILE_HIDDEN) != 0 )
234 if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE) )
235 continue;
238 if (!lfi)
239 continue;
241 if ((flen = udf_get_filename(nameptr, fname, lfi)))
243 if (udf_match(flen, fname, &(dentry->d_name)))
245 udf_release_data(bh);
246 return fi;
250 if (fibh->sbh != fibh->ebh)
251 udf_release_data(fibh->ebh);
252 udf_release_data(fibh->sbh);
253 udf_release_data(bh);
254 return NULL;
258 * udf_lookup
260 * PURPOSE
261 * Look-up the inode for a given name.
263 * DESCRIPTION
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() -> .
277 * PRE-CONDITIONS
278 * dir Pointer to inode of parent directory.
279 * dentry Pointer to dentry to complete.
281 * POST-CONDITIONS
282 * <return> Zero on success.
284 * HISTORY
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);
299 #ifdef UDF_RECOVERY
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);
305 if (!inode)
306 return ERR_PTR(-EACCES);
308 else
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));
318 if ( !inode )
319 return ERR_PTR(-EACCES);
321 d_add(dentry, inode);
322 return NULL;
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];
334 int namelen;
335 loff_t f_pos;
336 int flen;
337 char *nameptr;
338 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
339 int nfidlen;
340 Uint8 lfi;
341 Uint16 liu;
342 int block;
343 lb_addr bloc, eloc;
344 Uint32 extoffset, elen, offset;
345 struct buffer_head *bh = NULL;
347 sb = dir->i_sb;
349 if (dentry)
351 if ( !(udf_char_to_ustr(&unifilename, dentry->d_name.name, dentry->d_name.len)) )
353 *err = -ENAMETOOLONG;
354 return NULL;
357 if ( !(namelen = udf_UTF8toCS0(name, &unifilename, UDF_NAME_LEN)) )
359 *err = -ENAMETOOLONG;
360 return NULL;
363 else if (dir->i_size != 0)
365 /* WTF??? */
366 *err = -ENOENT;
367 return NULL;
369 else /* .. */
370 namelen = 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);
388 else
389 offset = 0;
391 if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
393 udf_release_data(bh);
394 return NULL;
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);
403 if (!fi)
405 if (fibh->sbh != fibh->ebh)
406 udf_release_data(fibh->ebh);
407 udf_release_data(fibh->sbh);
408 udf_release_data(bh);
409 return NULL;
412 liu = le16_to_cpu(cfi->lengthOfImpUse);
413 lfi = cfi->lengthFileIdent;
415 if (fibh->sbh == fibh->ebh)
416 nameptr = fi->fileIdent + liu;
417 else
419 int poffset; /* Unpaded ending offset */
421 poffset = fibh->soffset + sizeof(struct FileIdentDesc) + liu + lfi;
423 if (poffset >= lfi)
424 nameptr = (char *)(fibh->ebh->b_data + poffset - lfi);
425 else
427 nameptr = fname;
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))
444 return fi;
445 else
446 return NULL;
450 if (!lfi || !dentry)
451 continue;
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);
459 *err = -EEXIST;
460 return NULL;
464 else
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);
472 else
474 fibh->sbh = fibh->ebh = NULL;
475 fibh->soffset = fibh->eoffset = sb->s_blocksize;
479 f_pos += nfidlen;
481 if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB &&
482 sb->s_blocksize - fibh->eoffset < nfidlen)
484 udf_release_data(bh);
485 bh = NULL;
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)))
493 return NULL;
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);
518 else
519 block = UDF_I_LOCATION(dir).logicalBlockNum;
521 fi = (struct FileIdentDesc *)(fibh->sbh->b_data + fibh->soffset);
523 else
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);
536 *err = -ENOSPC;
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);
541 return NULL;
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);
552 else
553 block ++;
555 udf_release_data(fibh->sbh);
556 fibh->sbh = fibh->ebh;
557 fi = (struct FileIdentDesc *)(fibh->sbh->b_data);
559 else
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);
579 return fi;
581 else
583 udf_release_data(bh);
584 if (fibh->sbh != fibh->ebh)
585 udf_release_data(fibh->ebh);
586 udf_release_data(fibh->sbh);
587 return NULL;
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;
602 struct inode *inode;
603 struct FileIdentDesc cfi, *fi;
604 int err;
606 inode = udf_new_inode(dir, mode, &err);
607 if (!inode)
608 return err;
610 if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
611 inode->i_data.a_ops = &udf_adinicb_aops;
612 else
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)))
621 inode->i_nlink --;
622 mark_inode_dirty(inode);
623 iput(inode);
624 return err;
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);
640 return 0;
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;
647 int err;
648 struct FileIdentDesc cfi, *fi;
650 err = -EIO;
651 inode = udf_new_inode(dir, mode, &err);
652 if (!inode)
653 goto out;
655 inode->i_uid = current->fsuid;
656 init_special_inode(inode, mode, rdev);
657 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
659 inode->i_nlink --;
660 mark_inode_dirty(inode);
661 iput(inode);
662 return err;
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);
680 err = 0;
681 out:
682 return err;
685 static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
687 struct inode * inode;
688 struct udf_fileident_bh fibh;
689 int err;
690 struct FileIdentDesc cfi, *fi;
692 err = -EMLINK;
693 if (dir->i_nlink >= (256<<sizeof(dir->i_nlink))-1)
694 goto out;
696 err = -EIO;
697 inode = udf_new_inode(dir, S_IFDIR, &err);
698 if (!inode)
699 goto out;
701 inode->i_op = &udf_dir_inode_operations;
702 inode->i_fop = &udf_dir_operations;
703 inode->i_size = 0;
704 if (!(fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err)))
706 inode->i_nlink--;
707 mark_inode_dirty(inode);
708 iput(inode);
709 goto out;
711 inode->i_nlink = 2;
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)))
726 inode->i_nlink = 0;
727 mark_inode_dirty(inode);
728 iput(inode);
729 goto out;
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;
738 dir->i_nlink++;
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);
744 err = 0;
745 out:
746 return err;
749 static int empty_dir(struct inode *dir)
751 struct FileIdentDesc *fi, cfi;
752 struct udf_fileident_bh fibh;
753 loff_t f_pos;
754 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
755 int block;
756 lb_addr bloc, eloc;
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);
774 else
775 offset = 0;
777 else
779 udf_release_data(bh);
780 return 0;
783 if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
784 return 0;
786 while ( (f_pos < size) )
788 fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
790 if (!fi)
792 if (fibh.sbh != fibh.ebh)
793 udf_release_data(fibh.ebh);
794 udf_release_data(fibh.sbh);
795 udf_release_data(bh);
796 return 0;
799 if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FILE_DELETED) == 0)
801 udf_release_data(bh);
802 return 0;
805 if (fibh.sbh != fibh.ebh)
806 udf_release_data(fibh.ebh);
807 udf_release_data(fibh.sbh);
808 udf_release_data(bh);
809 return 1;
812 static int udf_rmdir(struct inode * dir, struct dentry * dentry)
814 int retval;
815 struct inode * inode;
816 struct udf_fileident_bh fibh;
817 struct FileIdentDesc *fi, cfi;
819 retval = -ENOENT;
820 fi = udf_find_entry(dir, dentry, &fibh, &cfi);
821 if (!fi)
822 goto out;
824 inode = dentry->d_inode;
825 DQUOT_INIT(inode);
827 retval = -EIO;
828 if (udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0) != inode->i_ino)
829 goto end_rmdir;
830 retval = -ENOTEMPTY;
831 if (!empty_dir(inode))
832 goto end_rmdir;
833 retval = udf_delete_entry(fi, &fibh, &cfi);
834 dir->i_version = ++event;
835 if (retval)
836 goto end_rmdir;
837 if (inode->i_nlink != 2)
838 udf_warning(inode->i_sb, "udf_rmdir",
839 "empty directory has nlink != 2 (%d)",
840 inode->i_nlink);
841 inode->i_version = ++event;
842 inode->i_nlink = 0;
843 inode->i_size = 0;
844 mark_inode_dirty(inode);
845 dir->i_nlink --;
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);
850 end_rmdir:
851 if (fibh.sbh != fibh.ebh)
852 udf_release_data(fibh.ebh);
853 udf_release_data(fibh.sbh);
854 out:
855 return retval;
858 static int udf_unlink(struct inode * dir, struct dentry * dentry)
860 int retval;
861 struct inode * inode;
862 struct udf_fileident_bh fibh;
863 struct FileIdentDesc *fi;
864 struct FileIdentDesc cfi;
866 retval = -ENOENT;
867 fi = udf_find_entry(dir, dentry, &fibh, &cfi);
868 if (!fi)
869 goto out;
871 inode = dentry->d_inode;
872 DQUOT_INIT(inode);
874 retval = -EIO;
876 if (udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0) !=
877 inode->i_ino)
879 goto end_unlink;
882 if (!inode->i_nlink)
884 udf_debug("Deleting nonexistent file (%lu), %d\n",
885 inode->i_ino, inode->i_nlink);
886 inode->i_nlink = 1;
888 retval = udf_delete_entry(fi, &fibh, &cfi);
889 if (retval)
890 goto end_unlink;
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);
894 inode->i_nlink--;
895 mark_inode_dirty(inode);
896 inode->i_ctime = dir->i_ctime;
897 retval = 0;
899 end_unlink:
900 if (fibh.sbh != fibh.ebh)
901 udf_release_data(fibh.ebh);
902 udf_release_data(fibh.sbh);
903 out:
904 return retval;
907 static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * symname)
909 struct inode * inode;
910 struct PathComponent *pc;
911 char *compstart;
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;
917 char *ea;
918 int err;
919 int block;
921 if (!(inode = udf_new_inode(dir, S_IFLNK, &err)))
922 goto out;
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;
931 lb_addr bloc, eloc;
932 Uint32 elen, extoffset;
934 block = udf_new_block(inode,
935 UDF_I_LOCATION(inode).partitionReferenceNum,
936 UDF_I_LOCATION(inode).logicalBlockNum, &err);
937 if (!block)
938 goto out_no_entry;
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);
951 else
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;
960 if (*symname == '/')
964 symname++;
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);
974 err = -ENAMETOOLONG;
976 while (*symname)
978 if (elen + sizeof(struct PathComponent) > eoffset)
979 goto out_no_entry;
981 pc = (struct PathComponent *)(ea + elen);
983 compstart = (char *)symname;
987 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)
1004 goto out_no_entry;
1005 else
1006 pc->lengthComponentIdent = symname - compstart;
1008 memcpy(pc->componentIdent, compstart, pc->lengthComponentIdent);
1011 elen += sizeof(struct PathComponent) + pc->lengthComponentIdent;
1013 if (*symname)
1017 symname++;
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)))
1029 goto out_no_entry;
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;
1035 Uint64 uniqueID;
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))
1041 uniqueID += 16;
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);
1055 err = 0;
1057 out:
1058 return err;
1060 out_no_entry:
1061 inode->i_nlink--;
1062 mark_inode_dirty(inode);
1063 iput(inode);
1064 goto out;
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;
1072 int err;
1073 struct FileIdentDesc cfi, *fi;
1075 if (S_ISDIR(inode->i_mode))
1076 return -EPERM;
1078 if (inode->i_nlink >= (256<<sizeof(inode->i_nlink))-1)
1079 return -EMLINK;
1081 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
1082 return 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;
1088 Uint64 uniqueID;
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))
1094 uniqueID += 16;
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);
1107 inode->i_nlink ++;
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);
1113 return 0;
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) !=
1131 old_inode->i_ino)
1133 goto end_rename;
1136 new_inode = new_dentry->d_inode;
1137 nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi);
1138 if (nfi)
1140 if (!new_inode)
1142 if (nfibh.sbh != nfibh.ebh)
1143 udf_release_data(nfibh.ebh);
1144 udf_release_data(nfibh.sbh);
1145 nfi = NULL;
1147 else
1149 DQUOT_INIT(new_inode);
1152 if (S_ISDIR(old_inode->i_mode))
1154 Uint32 offset = udf_ext0_offset(old_inode);
1156 if (new_inode)
1158 retval = -ENOTEMPTY;
1159 if (!empty_dir(new_inode))
1160 goto end_rename;
1162 retval = -EIO;
1163 dir_bh = udf_bread(old_inode, 0, 0, &retval);
1164 if (!dir_bh)
1165 goto end_rename;
1166 dir_fi = udf_get_fileident(dir_bh->b_data, old_inode->i_sb->s_blocksize, &offset);
1167 if (!dir_fi)
1168 goto end_rename;
1169 if (udf_get_lb_pblock(old_inode->i_sb, cpu_to_lelb(dir_fi->icb.extLocation), 0) !=
1170 old_dir->i_ino)
1172 goto end_rename;
1174 retval = -EMLINK;
1175 if (!new_inode && new_dir->i_nlink >= (256<<sizeof(new_dir->i_nlink))-1)
1176 goto end_rename;
1178 if (!nfi)
1180 nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, &retval);
1181 if (!nfi)
1182 goto end_rename;
1184 new_dir->i_version = ++event;
1187 * Like most other Unix systems, set the ctime for inodes on a
1188 * rename.
1190 old_inode->i_ctime = CURRENT_TIME;
1191 UDF_I_UCTIME(old_inode) = CURRENT_UTIME;
1192 mark_inode_dirty(old_inode);
1195 * ok, that's it
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;
1205 if (new_inode)
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);
1216 if (dir_bh)
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;
1226 else
1227 mark_buffer_dirty(dir_bh);
1228 old_dir->i_nlink --;
1229 mark_inode_dirty(old_dir);
1230 if (new_inode)
1232 new_inode->i_nlink --;
1233 mark_inode_dirty(new_inode);
1235 else
1237 new_dir->i_nlink ++;
1238 mark_inode_dirty(new_dir);
1242 retval = 0;
1244 end_rename:
1245 udf_release_data(dir_bh);
1246 if (ofi)
1248 if (ofibh.sbh != ofibh.ebh)
1249 udf_release_data(ofibh.ebh);
1250 udf_release_data(ofibh.sbh);
1252 if (nfi)
1254 if (nfibh.sbh != nfibh.ebh)
1255 udf_release_data(nfibh.ebh);
1256 udf_release_data(nfibh.sbh);
1258 return retval;
1261 struct inode_operations udf_dir_inode_operations = {
1262 lookup: udf_lookup,
1263 create: udf_create,
1264 link: udf_link,
1265 unlink: udf_unlink,
1266 symlink: udf_symlink,
1267 mkdir: udf_mkdir,
1268 rmdir: udf_rmdir,
1269 mknod: udf_mknod,
1270 rename: udf_rename,