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