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