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