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