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