udf: simple cleanup of truncate.c
[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;
1da177e4
LT
306 char name[UDF_NAME_LEN], fname[UDF_NAME_LEN];
307 int namelen;
308 loff_t f_pos;
309 int flen;
310 char *nameptr;
af793295 311 loff_t size = udf_ext0_offset(dir) + dir->i_size;
1da177e4
LT
312 int nfidlen;
313 uint8_t lfi;
314 uint16_t liu;
315 int block;
ff116fc8
JK
316 kernel_lb_addr eloc;
317 uint32_t elen;
60448b1d 318 sector_t offset;
28de7948 319 struct extent_position epos = {};
48d6d8ff 320 struct udf_inode_info *dinfo;
1da177e4 321
cb00ea35
CG
322 if (dentry) {
323 if (!dentry->d_name.len) {
1da177e4
LT
324 *err = -EINVAL;
325 return NULL;
326 }
4b11111a
MS
327 namelen = udf_put_filename(sb, dentry->d_name.name, name,
328 dentry->d_name.len);
329 if (!namelen) {
1da177e4
LT
330 *err = -ENAMETOOLONG;
331 return NULL;
332 }
28de7948 333 } else {
1da177e4 334 namelen = 0;
28de7948 335 }
1da177e4
LT
336
337 nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3;
338
af793295 339 f_pos = udf_ext0_offset(dir);
1da177e4 340
af793295 341 fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1);
48d6d8ff
MS
342 dinfo = UDF_I(dir);
343 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1da177e4 344 fibh->sbh = fibh->ebh = NULL;
af793295 345 else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits,
4b11111a
MS
346 &epos, &eloc, &elen, &offset) ==
347 (EXT_RECORDED_ALLOCATED >> 30)) {
1da177e4 348 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
cb00ea35 349 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
48d6d8ff 350 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
ff116fc8 351 epos.offset -= sizeof(short_ad);
48d6d8ff 352 else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
ff116fc8 353 epos.offset -= sizeof(long_ad);
4b11111a 354 } else
1da177e4
LT
355 offset = 0;
356
4b11111a
MS
357 fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block);
358 if (!fibh->sbh) {
3bf25cb4 359 brelse(epos.bh);
1da177e4
LT
360 *err = -EIO;
361 return NULL;
362 }
363
48d6d8ff 364 block = dinfo->i_location.logicalBlockNum;
cb00ea35 365 } else {
48d6d8ff 366 block = udf_get_lb_pblock(dir->i_sb, dinfo->i_location, 0);
1da177e4
LT
367 fibh->sbh = fibh->ebh = NULL;
368 fibh->soffset = fibh->eoffset = sb->s_blocksize;
369 goto add;
370 }
371
af793295 372 while (f_pos < size) {
cb00ea35
CG
373 fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
374 &elen, &offset);
1da177e4 375
cb00ea35 376 if (!fi) {
1da177e4 377 if (fibh->sbh != fibh->ebh)
3bf25cb4
JK
378 brelse(fibh->ebh);
379 brelse(fibh->sbh);
380 brelse(epos.bh);
1da177e4
LT
381 *err = -EIO;
382 return NULL;
383 }
384
385 liu = le16_to_cpu(cfi->lengthOfImpUse);
386 lfi = cfi->lengthFileIdent;
387
4b11111a 388 if (fibh->sbh == fibh->ebh)
1da177e4 389 nameptr = fi->fileIdent + liu;
4b11111a 390 else {
1da177e4
LT
391 int poffset; /* Unpaded ending offset */
392
4b11111a
MS
393 poffset = fibh->soffset + sizeof(struct fileIdentDesc) +
394 liu + lfi;
1da177e4 395
4b11111a
MS
396 if (poffset >= lfi)
397 nameptr = (char *)(fibh->ebh->b_data +
398 poffset - lfi);
399 else {
1da177e4 400 nameptr = fname;
4b11111a
MS
401 memcpy(nameptr, fi->fileIdent + liu,
402 lfi - poffset);
403 memcpy(nameptr + lfi - poffset,
404 fibh->ebh->b_data, poffset);
1da177e4
LT
405 }
406 }
407
cb00ea35 408 if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) {
4b11111a
MS
409 if (((sizeof(struct fileIdentDesc) +
410 liu + lfi + 3) & ~3) == nfidlen) {
3bf25cb4 411 brelse(epos.bh);
1da177e4
LT
412 cfi->descTag.tagSerialNum = cpu_to_le16(1);
413 cfi->fileVersionNum = cpu_to_le16(1);
414 cfi->fileCharacteristics = 0;
415 cfi->lengthFileIdent = namelen;
416 cfi->lengthOfImpUse = cpu_to_le16(0);
4b11111a
MS
417 if (!udf_write_fi(dir, cfi, fi, fibh, NULL,
418 name))
1da177e4 419 return fi;
4b11111a 420 else {
1da177e4
LT
421 *err = -EIO;
422 return NULL;
423 }
424 }
425 }
426
427 if (!lfi || !dentry)
428 continue;
429
4b11111a
MS
430 flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
431 if (flen && udf_match(flen, fname, dentry->d_name.len,
432 dentry->d_name.name)) {
1da177e4 433 if (fibh->sbh != fibh->ebh)
3bf25cb4
JK
434 brelse(fibh->ebh);
435 brelse(fibh->sbh);
436 brelse(epos.bh);
1da177e4
LT
437 *err = -EEXIST;
438 return NULL;
439 }
440 }
441
28de7948 442add:
05343c4f
JK
443 if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
444 elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1);
445 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
446 epos.offset -= sizeof(short_ad);
447 else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
448 epos.offset -= sizeof(long_ad);
449 udf_write_aext(dir, &epos, eloc, elen, 1);
450 }
1da177e4
LT
451 f_pos += nfidlen;
452
48d6d8ff 453 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB &&
cb00ea35 454 sb->s_blocksize - fibh->eoffset < nfidlen) {
3bf25cb4 455 brelse(epos.bh);
ff116fc8 456 epos.bh = NULL;
1da177e4
LT
457 fibh->soffset -= udf_ext0_offset(dir);
458 fibh->eoffset -= udf_ext0_offset(dir);
af793295 459 f_pos -= udf_ext0_offset(dir);
1da177e4 460 if (fibh->sbh != fibh->ebh)
3bf25cb4
JK
461 brelse(fibh->ebh);
462 brelse(fibh->sbh);
4b11111a
MS
463 fibh->sbh = fibh->ebh =
464 udf_expand_dir_adinicb(dir, &block, err);
465 if (!fibh->sbh)
1da177e4 466 return NULL;
48d6d8ff 467 epos.block = dinfo->i_location;
ff116fc8 468 epos.offset = udf_file_entry_alloc_offset(dir);
05343c4f
JK
469 /* Load extent udf_expand_dir_adinicb() has created */
470 udf_current_aext(dir, &epos, &eloc, &elen, 1);
1da177e4
LT
471 }
472
cb00ea35 473 if (sb->s_blocksize - fibh->eoffset >= nfidlen) {
1da177e4
LT
474 fibh->soffset = fibh->eoffset;
475 fibh->eoffset += nfidlen;
cb00ea35 476 if (fibh->sbh != fibh->ebh) {
3bf25cb4 477 brelse(fibh->sbh);
1da177e4
LT
478 fibh->sbh = fibh->ebh;
479 }
480
48d6d8ff
MS
481 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
482 block = dinfo->i_location.logicalBlockNum;
4b11111a 483 fi = (struct fileIdentDesc *)
48d6d8ff 484 (dinfo->i_ext.i_data +
c0b34438 485 fibh->soffset -
4b11111a 486 udf_ext0_offset(dir) +
48d6d8ff 487 dinfo->i_lenEAttr);
cb00ea35 488 } else {
4b11111a
MS
489 block = eloc.logicalBlockNum +
490 ((elen - 1) >>
491 dir->i_sb->s_blocksize_bits);
492 fi = (struct fileIdentDesc *)
493 (fibh->sbh->b_data + fibh->soffset);
1da177e4 494 }
cb00ea35 495 } else {
1da177e4
LT
496 fibh->soffset = fibh->eoffset - sb->s_blocksize;
497 fibh->eoffset += nfidlen - sb->s_blocksize;
cb00ea35 498 if (fibh->sbh != fibh->ebh) {
3bf25cb4 499 brelse(fibh->sbh);
1da177e4
LT
500 fibh->sbh = fibh->ebh;
501 }
502
503 block = eloc.logicalBlockNum + ((elen - 1) >>
cb00ea35 504 dir->i_sb->s_blocksize_bits);
4b11111a 505 fibh->ebh = udf_bread(dir,
af793295 506 f_pos >> dir->i_sb->s_blocksize_bits, 1, err);
28de7948 507 if (!fibh->ebh) {
3bf25cb4
JK
508 brelse(epos.bh);
509 brelse(fibh->sbh);
1da177e4
LT
510 return NULL;
511 }
512
28de7948 513 if (!fibh->soffset) {
ff116fc8 514 if (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
cb00ea35 515 (EXT_RECORDED_ALLOCATED >> 30)) {
1da177e4 516 block = eloc.logicalBlockNum + ((elen - 1) >>
28de7948 517 dir->i_sb->s_blocksize_bits);
4b11111a 518 } else
cb00ea35 519 block++;
1da177e4 520
3bf25cb4 521 brelse(fibh->sbh);
1da177e4
LT
522 fibh->sbh = fibh->ebh;
523 fi = (struct fileIdentDesc *)(fibh->sbh->b_data);
cb00ea35 524 } else {
1da177e4 525 fi = (struct fileIdentDesc *)
4b11111a
MS
526 (fibh->sbh->b_data + sb->s_blocksize +
527 fibh->soffset);
1da177e4
LT
528 }
529 }
530
531 memset(cfi, 0, sizeof(struct fileIdentDesc));
6c79e987 532 if (UDF_SB(sb)->s_udfrev >= 0x0200)
4b11111a
MS
533 udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block,
534 sizeof(tag));
1da177e4 535 else
4b11111a
MS
536 udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block,
537 sizeof(tag));
1da177e4
LT
538 cfi->fileVersionNum = cpu_to_le16(1);
539 cfi->lengthFileIdent = namelen;
540 cfi->lengthOfImpUse = cpu_to_le16(0);
cb00ea35 541 if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) {
3bf25cb4 542 brelse(epos.bh);
1da177e4 543 dir->i_size += nfidlen;
48d6d8ff
MS
544 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
545 dinfo->i_lenAlloc += nfidlen;
1da177e4
LT
546 mark_inode_dirty(dir);
547 return fi;
cb00ea35 548 } else {
3bf25cb4 549 brelse(epos.bh);
1da177e4 550 if (fibh->sbh != fibh->ebh)
3bf25cb4
JK
551 brelse(fibh->ebh);
552 brelse(fibh->sbh);
1da177e4
LT
553 *err = -EIO;
554 return NULL;
555 }
556}
557
558static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
cb00ea35
CG
559 struct udf_fileident_bh *fibh,
560 struct fileIdentDesc *cfi)
1da177e4
LT
561{
562 cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED;
28de7948 563
1da177e4
LT
564 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
565 memset(&(cfi->icb), 0x00, sizeof(long_ad));
28de7948 566
1da177e4
LT
567 return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
568}
569
cb00ea35
CG
570static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
571 struct nameidata *nd)
1da177e4
LT
572{
573 struct udf_fileident_bh fibh;
574 struct inode *inode;
575 struct fileIdentDesc cfi, *fi;
576 int err;
48d6d8ff 577 struct udf_inode_info *iinfo;
1da177e4
LT
578
579 lock_kernel();
580 inode = udf_new_inode(dir, mode, &err);
cb00ea35 581 if (!inode) {
1da177e4
LT
582 unlock_kernel();
583 return err;
584 }
585
48d6d8ff
MS
586 iinfo = UDF_I(inode);
587 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1da177e4
LT
588 inode->i_data.a_ops = &udf_adinicb_aops;
589 else
590 inode->i_data.a_ops = &udf_aops;
591 inode->i_op = &udf_file_inode_operations;
592 inode->i_fop = &udf_file_operations;
593 inode->i_mode = mode;
594 mark_inode_dirty(inode);
595
4b11111a
MS
596 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
597 if (!fi) {
cb00ea35 598 inode->i_nlink--;
1da177e4
LT
599 mark_inode_dirty(inode);
600 iput(inode);
601 unlock_kernel();
602 return err;
603 }
604 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
48d6d8ff 605 cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location);
28de7948 606 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
48d6d8ff 607 cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL);
1da177e4 608 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
c0b34438 609 if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1da177e4 610 mark_inode_dirty(dir);
1da177e4 611 if (fibh.sbh != fibh.ebh)
3bf25cb4
JK
612 brelse(fibh.ebh);
613 brelse(fibh.sbh);
1da177e4
LT
614 unlock_kernel();
615 d_instantiate(dentry, inode);
28de7948 616
1da177e4
LT
617 return 0;
618}
619
cb00ea35
CG
620static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
621 dev_t rdev)
1da177e4 622{
cb00ea35 623 struct inode *inode;
1da177e4
LT
624 struct udf_fileident_bh fibh;
625 struct fileIdentDesc cfi, *fi;
626 int err;
48d6d8ff 627 struct udf_inode_info *iinfo;
1da177e4
LT
628
629 if (!old_valid_dev(rdev))
630 return -EINVAL;
631
632 lock_kernel();
633 err = -EIO;
634 inode = udf_new_inode(dir, mode, &err);
635 if (!inode)
636 goto out;
637
48d6d8ff 638 iinfo = UDF_I(inode);
1da177e4
LT
639 inode->i_uid = current->fsuid;
640 init_special_inode(inode, mode, rdev);
4b11111a
MS
641 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
642 if (!fi) {
cb00ea35 643 inode->i_nlink--;
1da177e4
LT
644 mark_inode_dirty(inode);
645 iput(inode);
646 unlock_kernel();
647 return err;
648 }
649 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
48d6d8ff 650 cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location);
28de7948 651 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
48d6d8ff 652 cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL);
1da177e4 653 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
c0b34438 654 if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1da177e4 655 mark_inode_dirty(dir);
1da177e4
LT
656 mark_inode_dirty(inode);
657
658 if (fibh.sbh != fibh.ebh)
3bf25cb4
JK
659 brelse(fibh.ebh);
660 brelse(fibh.sbh);
1da177e4
LT
661 d_instantiate(dentry, inode);
662 err = 0;
28de7948
CG
663
664out:
1da177e4
LT
665 unlock_kernel();
666 return err;
667}
668
cb00ea35 669static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1da177e4 670{
cb00ea35 671 struct inode *inode;
1da177e4
LT
672 struct udf_fileident_bh fibh;
673 struct fileIdentDesc cfi, *fi;
674 int err;
48d6d8ff
MS
675 struct udf_inode_info *dinfo = UDF_I(dir);
676 struct udf_inode_info *iinfo;
1da177e4
LT
677
678 lock_kernel();
679 err = -EMLINK;
cb00ea35 680 if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1)
1da177e4
LT
681 goto out;
682
683 err = -EIO;
684 inode = udf_new_inode(dir, S_IFDIR, &err);
685 if (!inode)
686 goto out;
687
48d6d8ff 688 iinfo = UDF_I(inode);
1da177e4
LT
689 inode->i_op = &udf_dir_inode_operations;
690 inode->i_fop = &udf_dir_operations;
4b11111a
MS
691 fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err);
692 if (!fi) {
1da177e4
LT
693 inode->i_nlink--;
694 mark_inode_dirty(inode);
695 iput(inode);
696 goto out;
697 }
698 inode->i_nlink = 2;
699 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
48d6d8ff 700 cfi.icb.extLocation = cpu_to_lelb(dinfo->i_location);
28de7948 701 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
48d6d8ff 702 cpu_to_le32(dinfo->i_unique & 0x00000000FFFFFFFFUL);
4b11111a
MS
703 cfi.fileCharacteristics =
704 FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
1da177e4 705 udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL);
3bf25cb4 706 brelse(fibh.sbh);
1da177e4
LT
707 inode->i_mode = S_IFDIR | mode;
708 if (dir->i_mode & S_ISGID)
709 inode->i_mode |= S_ISGID;
710 mark_inode_dirty(inode);
711
4b11111a
MS
712 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
713 if (!fi) {
1da177e4
LT
714 inode->i_nlink = 0;
715 mark_inode_dirty(inode);
716 iput(inode);
717 goto out;
718 }
719 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
48d6d8ff 720 cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location);
28de7948 721 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
48d6d8ff 722 cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL);
1da177e4
LT
723 cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY;
724 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
d8c76e6f 725 inc_nlink(dir);
1da177e4
LT
726 mark_inode_dirty(dir);
727 d_instantiate(dentry, inode);
728 if (fibh.sbh != fibh.ebh)
3bf25cb4
JK
729 brelse(fibh.ebh);
730 brelse(fibh.sbh);
1da177e4 731 err = 0;
28de7948
CG
732
733out:
1da177e4
LT
734 unlock_kernel();
735 return err;
736}
737
738static int empty_dir(struct inode *dir)
739{
740 struct fileIdentDesc *fi, cfi;
741 struct udf_fileident_bh fibh;
742 loff_t f_pos;
af793295 743 loff_t size = udf_ext0_offset(dir) + dir->i_size;
1da177e4 744 int block;
ff116fc8
JK
745 kernel_lb_addr eloc;
746 uint32_t elen;
60448b1d 747 sector_t offset;
28de7948 748 struct extent_position epos = {};
48d6d8ff 749 struct udf_inode_info *dinfo = UDF_I(dir);
1da177e4 750
af793295
JK
751 f_pos = udf_ext0_offset(dir);
752 fibh.soffset = fibh.eoffset = f_pos & (dir->i_sb->s_blocksize - 1);
1da177e4 753
48d6d8ff 754 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1da177e4 755 fibh.sbh = fibh.ebh = NULL;
af793295 756 else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits,
4b11111a
MS
757 &epos, &eloc, &elen, &offset) ==
758 (EXT_RECORDED_ALLOCATED >> 30)) {
1da177e4 759 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
cb00ea35 760 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
48d6d8ff 761 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
ff116fc8 762 epos.offset -= sizeof(short_ad);
48d6d8ff 763 else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
ff116fc8 764 epos.offset -= sizeof(long_ad);
4b11111a 765 } else
1da177e4
LT
766 offset = 0;
767
4b11111a
MS
768 fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block);
769 if (!fibh.sbh) {
3bf25cb4 770 brelse(epos.bh);
1da177e4
LT
771 return 0;
772 }
cb00ea35 773 } else {
3bf25cb4 774 brelse(epos.bh);
1da177e4
LT
775 return 0;
776 }
777
af793295 778 while (f_pos < size) {
cb00ea35
CG
779 fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc,
780 &elen, &offset);
cb00ea35 781 if (!fi) {
1da177e4 782 if (fibh.sbh != fibh.ebh)
3bf25cb4
JK
783 brelse(fibh.ebh);
784 brelse(fibh.sbh);
785 brelse(epos.bh);
1da177e4
LT
786 return 0;
787 }
788
28de7948
CG
789 if (cfi.lengthFileIdent &&
790 (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) {
1da177e4 791 if (fibh.sbh != fibh.ebh)
3bf25cb4
JK
792 brelse(fibh.ebh);
793 brelse(fibh.sbh);
794 brelse(epos.bh);
1da177e4
LT
795 return 0;
796 }
797 }
28de7948 798
1da177e4 799 if (fibh.sbh != fibh.ebh)
3bf25cb4
JK
800 brelse(fibh.ebh);
801 brelse(fibh.sbh);
802 brelse(epos.bh);
28de7948 803
1da177e4
LT
804 return 1;
805}
806
cb00ea35 807static int udf_rmdir(struct inode *dir, struct dentry *dentry)
1da177e4
LT
808{
809 int retval;
cb00ea35 810 struct inode *inode = dentry->d_inode;
1da177e4
LT
811 struct udf_fileident_bh fibh;
812 struct fileIdentDesc *fi, cfi;
813 kernel_lb_addr tloc;
814
815 retval = -ENOENT;
816 lock_kernel();
817 fi = udf_find_entry(dir, dentry, &fibh, &cfi);
818 if (!fi)
819 goto out;
820
821 retval = -EIO;
822 tloc = lelb_to_cpu(cfi.icb.extLocation);
823 if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino)
824 goto end_rmdir;
825 retval = -ENOTEMPTY;
826 if (!empty_dir(inode))
827 goto end_rmdir;
828 retval = udf_delete_entry(dir, fi, &fibh, &cfi);
829 if (retval)
830 goto end_rmdir;
831 if (inode->i_nlink != 2)
832 udf_warning(inode->i_sb, "udf_rmdir",
cb00ea35
CG
833 "empty directory has nlink != 2 (%d)",
834 inode->i_nlink);
ce71ec36 835 clear_nlink(inode);
1da177e4 836 inode->i_size = 0;
c007c06e 837 inode_dec_link_count(dir);
4b11111a
MS
838 inode->i_ctime = dir->i_ctime = dir->i_mtime =
839 current_fs_time(dir->i_sb);
1da177e4
LT
840 mark_inode_dirty(dir);
841
28de7948 842end_rmdir:
1da177e4 843 if (fibh.sbh != fibh.ebh)
3bf25cb4
JK
844 brelse(fibh.ebh);
845 brelse(fibh.sbh);
28de7948
CG
846
847out:
1da177e4
LT
848 unlock_kernel();
849 return retval;
850}
851
cb00ea35 852static int udf_unlink(struct inode *dir, struct dentry *dentry)
1da177e4
LT
853{
854 int retval;
cb00ea35 855 struct inode *inode = dentry->d_inode;
1da177e4
LT
856 struct udf_fileident_bh fibh;
857 struct fileIdentDesc *fi;
858 struct fileIdentDesc cfi;
859 kernel_lb_addr tloc;
860
861 retval = -ENOENT;
862 lock_kernel();
863 fi = udf_find_entry(dir, dentry, &fibh, &cfi);
864 if (!fi)
865 goto out;
866
867 retval = -EIO;
868 tloc = lelb_to_cpu(cfi.icb.extLocation);
869 if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino)
870 goto end_unlink;
871
cb00ea35 872 if (!inode->i_nlink) {
1da177e4 873 udf_debug("Deleting nonexistent file (%lu), %d\n",
cb00ea35 874 inode->i_ino, inode->i_nlink);
1da177e4
LT
875 inode->i_nlink = 1;
876 }
877 retval = udf_delete_entry(dir, fi, &fibh, &cfi);
878 if (retval)
879 goto end_unlink;
880 dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
881 mark_inode_dirty(dir);
9a53c3a7 882 inode_dec_link_count(inode);
1da177e4
LT
883 inode->i_ctime = dir->i_ctime;
884 retval = 0;
885
28de7948 886end_unlink:
1da177e4 887 if (fibh.sbh != fibh.ebh)
3bf25cb4
JK
888 brelse(fibh.ebh);
889 brelse(fibh.sbh);
28de7948
CG
890
891out:
1da177e4
LT
892 unlock_kernel();
893 return retval;
894}
895
cb00ea35
CG
896static int udf_symlink(struct inode *dir, struct dentry *dentry,
897 const char *symname)
1da177e4 898{
cb00ea35 899 struct inode *inode;
1da177e4
LT
900 struct pathComponent *pc;
901 char *compstart;
902 struct udf_fileident_bh fibh;
28de7948 903 struct extent_position epos = {};
1da177e4
LT
904 int eoffset, elen = 0;
905 struct fileIdentDesc *fi;
906 struct fileIdentDesc cfi;
907 char *ea;
908 int err;
909 int block;
910 char name[UDF_NAME_LEN];
911 int namelen;
6c79e987 912 struct buffer_head *bh;
48d6d8ff 913 struct udf_inode_info *iinfo;
1da177e4
LT
914
915 lock_kernel();
4b11111a
MS
916 inode = udf_new_inode(dir, S_IFLNK, &err);
917 if (!inode)
1da177e4
LT
918 goto out;
919
48d6d8ff 920 iinfo = UDF_I(inode);
1da177e4
LT
921 inode->i_mode = S_IFLNK | S_IRWXUGO;
922 inode->i_data.a_ops = &udf_symlink_aops;
923 inode->i_op = &page_symlink_inode_operations;
924
48d6d8ff 925 if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
ff116fc8
JK
926 kernel_lb_addr eloc;
927 uint32_t elen;
1da177e4
LT
928
929 block = udf_new_block(inode->i_sb, inode,
48d6d8ff
MS
930 iinfo->i_location.partitionReferenceNum,
931 iinfo->i_location.logicalBlockNum, &err);
1da177e4
LT
932 if (!block)
933 goto out_no_entry;
48d6d8ff 934 epos.block = iinfo->i_location;
ff116fc8
JK
935 epos.offset = udf_file_entry_alloc_offset(inode);
936 epos.bh = NULL;
1da177e4 937 eloc.logicalBlockNum = block;
4b11111a 938 eloc.partitionReferenceNum =
48d6d8ff 939 iinfo->i_location.partitionReferenceNum;
1da177e4 940 elen = inode->i_sb->s_blocksize;
48d6d8ff 941 iinfo->i_lenExtents = elen;
ff116fc8 942 udf_add_aext(inode, &epos, eloc, elen, 0);
3bf25cb4 943 brelse(epos.bh);
1da177e4
LT
944
945 block = udf_get_pblock(inode->i_sb, block,
48d6d8ff 946 iinfo->i_location.partitionReferenceNum,
4b11111a 947 0);
ff116fc8
JK
948 epos.bh = udf_tread(inode->i_sb, block);
949 lock_buffer(epos.bh);
950 memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize);
951 set_buffer_uptodate(epos.bh);
952 unlock_buffer(epos.bh);
953 mark_buffer_dirty_inode(epos.bh, inode);
954 ea = epos.bh->b_data + udf_ext0_offset(inode);
48d6d8ff
MS
955 } else
956 ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr;
1da177e4
LT
957
958 eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode);
959 pc = (struct pathComponent *)ea;
960
cb00ea35
CG
961 if (*symname == '/') {
962 do {
1da177e4
LT
963 symname++;
964 } while (*symname == '/');
965
966 pc->componentType = 1;
967 pc->lengthComponentIdent = 0;
968 pc->componentFileVersionNum = 0;
969 pc += sizeof(struct pathComponent);
970 elen += sizeof(struct pathComponent);
971 }
972
973 err = -ENAMETOOLONG;
974
cb00ea35 975 while (*symname) {
1da177e4
LT
976 if (elen + sizeof(struct pathComponent) > eoffset)
977 goto out_no_entry;
978
979 pc = (struct pathComponent *)(ea + elen);
980
981 compstart = (char *)symname;
982
cb00ea35 983 do {
1da177e4
LT
984 symname++;
985 } while (*symname && *symname != '/');
986
987 pc->componentType = 5;
988 pc->lengthComponentIdent = 0;
989 pc->componentFileVersionNum = 0;
cb00ea35
CG
990 if (compstart[0] == '.') {
991 if ((symname - compstart) == 1)
1da177e4 992 pc->componentType = 4;
4b11111a
MS
993 else if ((symname - compstart) == 2 &&
994 compstart[1] == '.')
1da177e4
LT
995 pc->componentType = 3;
996 }
997
cb00ea35 998 if (pc->componentType == 5) {
28de7948
CG
999 namelen = udf_put_filename(inode->i_sb, compstart, name,
1000 symname - compstart);
1001 if (!namelen)
1da177e4
LT
1002 goto out_no_entry;
1003
4b11111a
MS
1004 if (elen + sizeof(struct pathComponent) + namelen >
1005 eoffset)
1da177e4
LT
1006 goto out_no_entry;
1007 else
1008 pc->lengthComponentIdent = namelen;
1009
1010 memcpy(pc->componentIdent, name, namelen);
1011 }
1012
1013 elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
1014
cb00ea35
CG
1015 if (*symname) {
1016 do {
1da177e4
LT
1017 symname++;
1018 } while (*symname == '/');
1019 }
1020 }
1021
3bf25cb4 1022 brelse(epos.bh);
1da177e4 1023 inode->i_size = elen;
48d6d8ff
MS
1024 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1025 iinfo->i_lenAlloc = inode->i_size;
1da177e4
LT
1026 mark_inode_dirty(inode);
1027
4b11111a
MS
1028 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
1029 if (!fi)
1da177e4
LT
1030 goto out_no_entry;
1031 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
48d6d8ff 1032 cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location);
6c79e987
MS
1033 bh = UDF_SB(inode->i_sb)->s_lvid_bh;
1034 if (bh) {
4b11111a
MS
1035 struct logicalVolIntegrityDesc *lvid =
1036 (struct logicalVolIntegrityDesc *)bh->b_data;
1da177e4
LT
1037 struct logicalVolHeaderDesc *lvhd;
1038 uint64_t uniqueID;
4b11111a
MS
1039 lvhd = (struct logicalVolHeaderDesc *)
1040 lvid->logicalVolContentsUse;
1da177e4 1041 uniqueID = le64_to_cpu(lvhd->uniqueID);
28de7948
CG
1042 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
1043 cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
1da177e4
LT
1044 if (!(++uniqueID & 0x00000000FFFFFFFFUL))
1045 uniqueID += 16;
1046 lvhd->uniqueID = cpu_to_le64(uniqueID);
6c79e987 1047 mark_buffer_dirty(bh);
1da177e4
LT
1048 }
1049 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
c0b34438 1050 if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1da177e4 1051 mark_inode_dirty(dir);
1da177e4 1052 if (fibh.sbh != fibh.ebh)
3bf25cb4
JK
1053 brelse(fibh.ebh);
1054 brelse(fibh.sbh);
1da177e4
LT
1055 d_instantiate(dentry, inode);
1056 err = 0;
1057
28de7948 1058out:
1da177e4
LT
1059 unlock_kernel();
1060 return err;
1061
28de7948 1062out_no_entry:
9a53c3a7 1063 inode_dec_link_count(inode);
1da177e4
LT
1064 iput(inode);
1065 goto out;
1066}
1067
cb00ea35
CG
1068static int udf_link(struct dentry *old_dentry, struct inode *dir,
1069 struct dentry *dentry)
1da177e4
LT
1070{
1071 struct inode *inode = old_dentry->d_inode;
1072 struct udf_fileident_bh fibh;
1073 struct fileIdentDesc cfi, *fi;
1074 int err;
6c79e987 1075 struct buffer_head *bh;
1da177e4
LT
1076
1077 lock_kernel();
cb00ea35 1078 if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) {
1da177e4
LT
1079 unlock_kernel();
1080 return -EMLINK;
1081 }
1082
4b11111a
MS
1083 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
1084 if (!fi) {
1da177e4
LT
1085 unlock_kernel();
1086 return err;
1087 }
1088 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
c0b34438 1089 cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location);
6c79e987
MS
1090 bh = UDF_SB(inode->i_sb)->s_lvid_bh;
1091 if (bh) {
4b11111a
MS
1092 struct logicalVolIntegrityDesc *lvid =
1093 (struct logicalVolIntegrityDesc *)bh->b_data;
1da177e4
LT
1094 struct logicalVolHeaderDesc *lvhd;
1095 uint64_t uniqueID;
4b11111a
MS
1096 lvhd = (struct logicalVolHeaderDesc *)
1097 (lvid->logicalVolContentsUse);
1da177e4 1098 uniqueID = le64_to_cpu(lvhd->uniqueID);
28de7948
CG
1099 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
1100 cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
1da177e4
LT
1101 if (!(++uniqueID & 0x00000000FFFFFFFFUL))
1102 uniqueID += 16;
1103 lvhd->uniqueID = cpu_to_le64(uniqueID);
6c79e987 1104 mark_buffer_dirty(bh);
1da177e4
LT
1105 }
1106 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
c0b34438 1107 if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1da177e4 1108 mark_inode_dirty(dir);
28de7948 1109
1da177e4 1110 if (fibh.sbh != fibh.ebh)
3bf25cb4
JK
1111 brelse(fibh.ebh);
1112 brelse(fibh.sbh);
d8c76e6f 1113 inc_nlink(inode);
1da177e4
LT
1114 inode->i_ctime = current_fs_time(inode->i_sb);
1115 mark_inode_dirty(inode);
1116 atomic_inc(&inode->i_count);
1117 d_instantiate(dentry, inode);
1118 unlock_kernel();
28de7948 1119
1da177e4
LT
1120 return 0;
1121}
1122
1123/* Anybody can rename anything with this: the permission checks are left to the
1124 * higher-level routines.
1125 */
cb00ea35
CG
1126static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
1127 struct inode *new_dir, struct dentry *new_dentry)
1da177e4 1128{
cb00ea35
CG
1129 struct inode *old_inode = old_dentry->d_inode;
1130 struct inode *new_inode = new_dentry->d_inode;
1da177e4 1131 struct udf_fileident_bh ofibh, nfibh;
4b11111a
MS
1132 struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL;
1133 struct fileIdentDesc ocfi, ncfi;
1da177e4
LT
1134 struct buffer_head *dir_bh = NULL;
1135 int retval = -ENOENT;
1136 kernel_lb_addr tloc;
48d6d8ff 1137 struct udf_inode_info *old_iinfo = UDF_I(old_inode);
1da177e4
LT
1138
1139 lock_kernel();
4b11111a
MS
1140 ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
1141 if (ofi) {
1da177e4 1142 if (ofibh.sbh != ofibh.ebh)
3bf25cb4
JK
1143 brelse(ofibh.ebh);
1144 brelse(ofibh.sbh);
1da177e4
LT
1145 }
1146 tloc = lelb_to_cpu(ocfi.icb.extLocation);
1147 if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0)
cb00ea35 1148 != old_inode->i_ino)
1da177e4
LT
1149 goto end_rename;
1150
1151 nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi);
cb00ea35
CG
1152 if (nfi) {
1153 if (!new_inode) {
1da177e4 1154 if (nfibh.sbh != nfibh.ebh)
3bf25cb4
JK
1155 brelse(nfibh.ebh);
1156 brelse(nfibh.sbh);
1da177e4
LT
1157 nfi = NULL;
1158 }
1159 }
cb00ea35 1160 if (S_ISDIR(old_inode->i_mode)) {
7f3fbd08 1161 int offset = udf_ext0_offset(old_inode);
1da177e4 1162
cb00ea35 1163 if (new_inode) {
1da177e4
LT
1164 retval = -ENOTEMPTY;
1165 if (!empty_dir(new_inode))
1166 goto end_rename;
1167 }
1168 retval = -EIO;
48d6d8ff 1169 if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
4b11111a 1170 dir_fi = udf_get_fileident(
48d6d8ff
MS
1171 old_iinfo->i_ext.i_data -
1172 (old_iinfo->i_efe ?
4b11111a
MS
1173 sizeof(struct extendedFileEntry) :
1174 sizeof(struct fileEntry)),
1175 old_inode->i_sb->s_blocksize, &offset);
cb00ea35 1176 } else {
1da177e4
LT
1177 dir_bh = udf_bread(old_inode, 0, 0, &retval);
1178 if (!dir_bh)
1179 goto end_rename;
4b11111a
MS
1180 dir_fi = udf_get_fileident(dir_bh->b_data,
1181 old_inode->i_sb->s_blocksize, &offset);
1da177e4
LT
1182 }
1183 if (!dir_fi)
1184 goto end_rename;
1185 tloc = lelb_to_cpu(dir_fi->icb.extLocation);
4b11111a
MS
1186 if (udf_get_lb_pblock(old_inode->i_sb, tloc, 0) !=
1187 old_dir->i_ino)
1da177e4
LT
1188 goto end_rename;
1189
1190 retval = -EMLINK;
4b11111a
MS
1191 if (!new_inode &&
1192 new_dir->i_nlink >=
1193 (256 << sizeof(new_dir->i_nlink)) - 1)
1da177e4
LT
1194 goto end_rename;
1195 }
cb00ea35 1196 if (!nfi) {
4b11111a
MS
1197 nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi,
1198 &retval);
1da177e4
LT
1199 if (!nfi)
1200 goto end_rename;
1201 }
1202
1203 /*
1204 * Like most other Unix systems, set the ctime for inodes on a
1205 * rename.
1206 */
1207 old_inode->i_ctime = current_fs_time(old_inode->i_sb);
1208 mark_inode_dirty(old_inode);
1209
1210 /*
1211 * ok, that's it
1212 */
1213 ncfi.fileVersionNum = ocfi.fileVersionNum;
1214 ncfi.fileCharacteristics = ocfi.fileCharacteristics;
1215 memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(long_ad));
1216 udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL);
1217
1218 /* The old fid may have moved - find it again */
1219 ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
1220 udf_delete_entry(old_dir, ofi, &ofibh, &ocfi);
1221
cb00ea35 1222 if (new_inode) {
1da177e4 1223 new_inode->i_ctime = current_fs_time(new_inode->i_sb);
9a53c3a7 1224 inode_dec_link_count(new_inode);
1da177e4
LT
1225 }
1226 old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb);
1227 mark_inode_dirty(old_dir);
1228
cb00ea35 1229 if (dir_fi) {
c0b34438 1230 dir_fi->icb.extLocation = cpu_to_lelb(UDF_I(new_dir)->i_location);
4b11111a
MS
1231 udf_update_tag((char *)dir_fi,
1232 (sizeof(struct fileIdentDesc) +
1233 le16_to_cpu(dir_fi->lengthOfImpUse) + 3) & ~3);
48d6d8ff 1234 if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1da177e4 1235 mark_inode_dirty(old_inode);
4b11111a 1236 else
1da177e4 1237 mark_buffer_dirty_inode(dir_bh, old_inode);
4b11111a 1238
9a53c3a7 1239 inode_dec_link_count(old_dir);
4b11111a 1240 if (new_inode)
9a53c3a7 1241 inode_dec_link_count(new_inode);
4b11111a 1242 else {
d8c76e6f 1243 inc_nlink(new_dir);
1da177e4
LT
1244 mark_inode_dirty(new_dir);
1245 }
1246 }
1247
cb00ea35 1248 if (ofi) {
1da177e4 1249 if (ofibh.sbh != ofibh.ebh)
3bf25cb4
JK
1250 brelse(ofibh.ebh);
1251 brelse(ofibh.sbh);
1da177e4
LT
1252 }
1253
1254 retval = 0;
1255
28de7948 1256end_rename:
3bf25cb4 1257 brelse(dir_bh);
cb00ea35 1258 if (nfi) {
1da177e4 1259 if (nfibh.sbh != nfibh.ebh)
3bf25cb4
JK
1260 brelse(nfibh.ebh);
1261 brelse(nfibh.sbh);
1da177e4
LT
1262 }
1263 unlock_kernel();
28de7948 1264
1da177e4
LT
1265 return retval;
1266}
1267
c5ef1c42 1268const struct inode_operations udf_dir_inode_operations = {
28de7948
CG
1269 .lookup = udf_lookup,
1270 .create = udf_create,
1271 .link = udf_link,
1272 .unlink = udf_unlink,
1273 .symlink = udf_symlink,
1274 .mkdir = udf_mkdir,
1275 .rmdir = udf_rmdir,
1276 .mknod = udf_mknod,
1277 .rename = udf_rename,
1da177e4 1278};