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