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
udf_match(int len,const char * const name,struct qstr * qs)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
udf_write_fi(struct inode * inode,struct fileIdentDesc * cfi,struct fileIdentDesc * sfi,struct udf_fileident_bh * fibh,uint8_t * impuse,uint8_t * fileident)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 *
udf_find_entry(struct inode * dir,struct dentry * dentry,struct udf_fileident_bh * fibh,struct fileIdentDesc * cfi)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 *
udf_lookup(struct inode * dir,struct dentry * 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 *
udf_add_entry(struct inode * dir,struct dentry * dentry,struct udf_fileident_bh * fibh,struct fileIdentDesc * cfi,int * err)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
udf_delete_entry(struct inode * inode,struct fileIdentDesc * fi,struct udf_fileident_bh * fibh,struct fileIdentDesc * cfi)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
udf_create(struct inode * dir,struct dentry * dentry,int mode)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
udf_mknod(struct inode * dir,struct dentry * dentry,int mode,int rdev)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
udf_mkdir(struct inode * dir,struct dentry * dentry,int mode)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
empty_dir(struct inode * dir)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
udf_rmdir(struct inode * dir,struct dentry * dentry)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
udf_unlink(struct inode * dir,struct dentry * dentry)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
udf_symlink(struct inode * dir,struct dentry * dentry,const char * symname)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
udf_link(struct dentry * old_dentry,struct inode * dir,struct dentry * dentry)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 */
udf_rename(struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry)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 };
1301