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