diff options
Diffstat (limited to 'fs/udf/namei.c')
| -rw-r--r-- | fs/udf/namei.c | 218 |
1 files changed, 76 insertions, 142 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 112a5fb0b27b..ba5537d4bc15 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
| 32 | #include <linux/buffer_head.h> | 32 | #include <linux/buffer_head.h> |
| 33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
| 34 | #include <linux/crc-itu-t.h> | ||
| 34 | 35 | ||
| 35 | static inline int udf_match(int len1, const char *name1, int len2, | 36 | static inline int udf_match(int len1, const char *name1, int len2, |
| 36 | const char *name2) | 37 | const char *name2) |
| @@ -97,25 +98,23 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, | |||
| 97 | memset(fibh->ebh->b_data, 0x00, padlen + offset); | 98 | memset(fibh->ebh->b_data, 0x00, padlen + offset); |
| 98 | } | 99 | } |
| 99 | 100 | ||
| 100 | crc = udf_crc((uint8_t *)cfi + sizeof(tag), | 101 | crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(tag), |
| 101 | sizeof(struct fileIdentDesc) - sizeof(tag), 0); | 102 | sizeof(struct fileIdentDesc) - sizeof(tag)); |
| 102 | 103 | ||
| 103 | if (fibh->sbh == fibh->ebh) { | 104 | if (fibh->sbh == fibh->ebh) { |
| 104 | crc = udf_crc((uint8_t *)sfi->impUse, | 105 | crc = crc_itu_t(crc, (uint8_t *)sfi->impUse, |
| 105 | crclen + sizeof(tag) - | 106 | crclen + sizeof(tag) - |
| 106 | sizeof(struct fileIdentDesc), crc); | 107 | sizeof(struct fileIdentDesc)); |
| 107 | } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) { | 108 | } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) { |
| 108 | crc = udf_crc(fibh->ebh->b_data + | 109 | crc = crc_itu_t(crc, fibh->ebh->b_data + |
| 109 | sizeof(struct fileIdentDesc) + | 110 | sizeof(struct fileIdentDesc) + |
| 110 | fibh->soffset, | 111 | fibh->soffset, |
| 111 | crclen + sizeof(tag) - | 112 | crclen + sizeof(tag) - |
| 112 | sizeof(struct fileIdentDesc), | 113 | sizeof(struct fileIdentDesc)); |
| 113 | crc); | ||
| 114 | } else { | 114 | } else { |
| 115 | crc = udf_crc((uint8_t *)sfi->impUse, | 115 | crc = crc_itu_t(crc, (uint8_t *)sfi->impUse, |
| 116 | -fibh->soffset - sizeof(struct fileIdentDesc), | 116 | -fibh->soffset - sizeof(struct fileIdentDesc)); |
| 117 | crc); | 117 | crc = crc_itu_t(crc, fibh->ebh->b_data, fibh->eoffset); |
| 118 | crc = udf_crc(fibh->ebh->b_data, fibh->eoffset, crc); | ||
| 119 | } | 118 | } |
| 120 | 119 | ||
| 121 | cfi->descTag.descCRC = cpu_to_le16(crc); | 120 | cfi->descTag.descCRC = cpu_to_le16(crc); |
| @@ -149,7 +148,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
| 149 | struct fileIdentDesc *fi = NULL; | 148 | struct fileIdentDesc *fi = NULL; |
| 150 | loff_t f_pos; | 149 | loff_t f_pos; |
| 151 | int block, flen; | 150 | int block, flen; |
| 152 | char fname[UDF_NAME_LEN]; | 151 | char *fname = NULL; |
| 153 | char *nameptr; | 152 | char *nameptr; |
| 154 | uint8_t lfi; | 153 | uint8_t lfi; |
| 155 | uint16_t liu; | 154 | uint16_t liu; |
| @@ -163,12 +162,12 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
| 163 | size = udf_ext0_offset(dir) + dir->i_size; | 162 | size = udf_ext0_offset(dir) + dir->i_size; |
| 164 | f_pos = udf_ext0_offset(dir); | 163 | f_pos = udf_ext0_offset(dir); |
| 165 | 164 | ||
| 165 | fibh->sbh = fibh->ebh = NULL; | ||
| 166 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); | 166 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); |
| 167 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 167 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
| 168 | fibh->sbh = fibh->ebh = NULL; | 168 | if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos, |
| 169 | else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, | 169 | &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) |
| 170 | &epos, &eloc, &elen, &offset) == | 170 | goto out_err; |
| 171 | (EXT_RECORDED_ALLOCATED >> 30)) { | ||
| 172 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 171 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
| 173 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 172 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { |
| 174 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 173 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
| @@ -179,25 +178,19 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
| 179 | offset = 0; | 178 | offset = 0; |
| 180 | 179 | ||
| 181 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); | 180 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); |
| 182 | if (!fibh->sbh) { | 181 | if (!fibh->sbh) |
| 183 | brelse(epos.bh); | 182 | goto out_err; |
| 184 | return NULL; | ||
| 185 | } | ||
| 186 | } else { | ||
| 187 | brelse(epos.bh); | ||
| 188 | return NULL; | ||
| 189 | } | 183 | } |
| 190 | 184 | ||
| 185 | fname = kmalloc(UDF_NAME_LEN, GFP_NOFS); | ||
| 186 | if (!fname) | ||
| 187 | goto out_err; | ||
| 188 | |||
| 191 | while (f_pos < size) { | 189 | while (f_pos < size) { |
| 192 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, | 190 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, |
| 193 | &elen, &offset); | 191 | &elen, &offset); |
| 194 | if (!fi) { | 192 | if (!fi) |
| 195 | if (fibh->sbh != fibh->ebh) | 193 | goto out_err; |
| 196 | brelse(fibh->ebh); | ||
| 197 | brelse(fibh->sbh); | ||
| 198 | brelse(epos.bh); | ||
| 199 | return NULL; | ||
| 200 | } | ||
| 201 | 194 | ||
| 202 | liu = le16_to_cpu(cfi->lengthOfImpUse); | 195 | liu = le16_to_cpu(cfi->lengthOfImpUse); |
| 203 | lfi = cfi->lengthFileIdent; | 196 | lfi = cfi->lengthFileIdent; |
| @@ -237,53 +230,22 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
| 237 | 230 | ||
| 238 | flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); | 231 | flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); |
| 239 | if (flen && udf_match(flen, fname, dentry->d_name.len, | 232 | if (flen && udf_match(flen, fname, dentry->d_name.len, |
| 240 | dentry->d_name.name)) { | 233 | dentry->d_name.name)) |
| 241 | brelse(epos.bh); | 234 | goto out_ok; |
| 242 | return fi; | ||
| 243 | } | ||
| 244 | } | 235 | } |
| 245 | 236 | ||
| 237 | out_err: | ||
| 238 | fi = NULL; | ||
| 246 | if (fibh->sbh != fibh->ebh) | 239 | if (fibh->sbh != fibh->ebh) |
| 247 | brelse(fibh->ebh); | 240 | brelse(fibh->ebh); |
| 248 | brelse(fibh->sbh); | 241 | brelse(fibh->sbh); |
| 242 | out_ok: | ||
| 249 | brelse(epos.bh); | 243 | brelse(epos.bh); |
| 244 | kfree(fname); | ||
| 250 | 245 | ||
| 251 | return NULL; | 246 | return fi; |
| 252 | } | 247 | } |
| 253 | 248 | ||
| 254 | /* | ||
| 255 | * udf_lookup | ||
| 256 | * | ||
| 257 | * PURPOSE | ||
| 258 | * Look-up the inode for a given name. | ||
| 259 | * | ||
| 260 | * DESCRIPTION | ||
| 261 | * Required - lookup_dentry() will return -ENOTDIR if this routine is not | ||
| 262 | * available for a directory. The filesystem is useless if this routine is | ||
| 263 | * not available for at least the filesystem's root directory. | ||
| 264 | * | ||
| 265 | * This routine is passed an incomplete dentry - it must be completed by | ||
| 266 | * calling d_add(dentry, inode). If the name does not exist, then the | ||
| 267 | * specified inode must be set to null. An error should only be returned | ||
| 268 | * when the lookup fails for a reason other than the name not existing. | ||
| 269 | * Note that the directory inode semaphore is held during the call. | ||
| 270 | * | ||
| 271 | * Refer to lookup_dentry() in fs/namei.c | ||
| 272 | * lookup_dentry() -> lookup() -> real_lookup() -> . | ||
| 273 | * | ||
| 274 | * PRE-CONDITIONS | ||
| 275 | * dir Pointer to inode of parent directory. | ||
| 276 | * dentry Pointer to dentry to complete. | ||
| 277 | * nd Pointer to lookup nameidata | ||
| 278 | * | ||
| 279 | * POST-CONDITIONS | ||
| 280 | * <return> Zero on success. | ||
| 281 | * | ||
| 282 | * HISTORY | ||
| 283 | * July 1, 1997 - Andrew E. Mileski | ||
| 284 | * Written, tested, and released. | ||
| 285 | */ | ||
| 286 | |||
| 287 | static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | 249 | static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, |
| 288 | struct nameidata *nd) | 250 | struct nameidata *nd) |
| 289 | { | 251 | { |
| @@ -336,11 +298,9 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
| 336 | { | 298 | { |
| 337 | struct super_block *sb = dir->i_sb; | 299 | struct super_block *sb = dir->i_sb; |
| 338 | struct fileIdentDesc *fi = NULL; | 300 | struct fileIdentDesc *fi = NULL; |
| 339 | char name[UDF_NAME_LEN], fname[UDF_NAME_LEN]; | 301 | char *name = NULL; |
| 340 | int namelen; | 302 | int namelen; |
| 341 | loff_t f_pos; | 303 | loff_t f_pos; |
| 342 | int flen; | ||
| 343 | char *nameptr; | ||
| 344 | loff_t size = udf_ext0_offset(dir) + dir->i_size; | 304 | loff_t size = udf_ext0_offset(dir) + dir->i_size; |
| 345 | int nfidlen; | 305 | int nfidlen; |
| 346 | uint8_t lfi; | 306 | uint8_t lfi; |
| @@ -352,16 +312,23 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
| 352 | struct extent_position epos = {}; | 312 | struct extent_position epos = {}; |
| 353 | struct udf_inode_info *dinfo; | 313 | struct udf_inode_info *dinfo; |
| 354 | 314 | ||
| 315 | fibh->sbh = fibh->ebh = NULL; | ||
| 316 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); | ||
| 317 | if (!name) { | ||
| 318 | *err = -ENOMEM; | ||
| 319 | goto out_err; | ||
| 320 | } | ||
| 321 | |||
| 355 | if (dentry) { | 322 | if (dentry) { |
| 356 | if (!dentry->d_name.len) { | 323 | if (!dentry->d_name.len) { |
| 357 | *err = -EINVAL; | 324 | *err = -EINVAL; |
| 358 | return NULL; | 325 | goto out_err; |
| 359 | } | 326 | } |
| 360 | namelen = udf_put_filename(sb, dentry->d_name.name, name, | 327 | namelen = udf_put_filename(sb, dentry->d_name.name, name, |
| 361 | dentry->d_name.len); | 328 | dentry->d_name.len); |
| 362 | if (!namelen) { | 329 | if (!namelen) { |
| 363 | *err = -ENAMETOOLONG; | 330 | *err = -ENAMETOOLONG; |
| 364 | return NULL; | 331 | goto out_err; |
| 365 | } | 332 | } |
| 366 | } else { | 333 | } else { |
| 367 | namelen = 0; | 334 | namelen = 0; |
| @@ -373,11 +340,14 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
| 373 | 340 | ||
| 374 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); | 341 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); |
| 375 | dinfo = UDF_I(dir); | 342 | dinfo = UDF_I(dir); |
| 376 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 343 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
| 377 | fibh->sbh = fibh->ebh = NULL; | 344 | if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos, |
| 378 | else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, | 345 | &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) { |
| 379 | &epos, &eloc, &elen, &offset) == | 346 | block = udf_get_lb_pblock(dir->i_sb, |
| 380 | (EXT_RECORDED_ALLOCATED >> 30)) { | 347 | dinfo->i_location, 0); |
| 348 | fibh->soffset = fibh->eoffset = sb->s_blocksize; | ||
| 349 | goto add; | ||
| 350 | } | ||
| 381 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 351 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
| 382 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 352 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { |
| 383 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 353 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
| @@ -389,17 +359,11 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
| 389 | 359 | ||
| 390 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); | 360 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); |
| 391 | if (!fibh->sbh) { | 361 | if (!fibh->sbh) { |
| 392 | brelse(epos.bh); | ||
| 393 | *err = -EIO; | 362 | *err = -EIO; |
| 394 | return NULL; | 363 | goto out_err; |
| 395 | } | 364 | } |
| 396 | 365 | ||
| 397 | block = dinfo->i_location.logicalBlockNum; | 366 | block = dinfo->i_location.logicalBlockNum; |
| 398 | } else { | ||
| 399 | block = udf_get_lb_pblock(dir->i_sb, dinfo->i_location, 0); | ||
| 400 | fibh->sbh = fibh->ebh = NULL; | ||
| 401 | fibh->soffset = fibh->eoffset = sb->s_blocksize; | ||
| 402 | goto add; | ||
| 403 | } | 367 | } |
| 404 | 368 | ||
| 405 | while (f_pos < size) { | 369 | while (f_pos < size) { |
| @@ -407,41 +371,16 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
| 407 | &elen, &offset); | 371 | &elen, &offset); |
| 408 | 372 | ||
| 409 | if (!fi) { | 373 | if (!fi) { |
| 410 | if (fibh->sbh != fibh->ebh) | ||
| 411 | brelse(fibh->ebh); | ||
| 412 | brelse(fibh->sbh); | ||
| 413 | brelse(epos.bh); | ||
| 414 | *err = -EIO; | 374 | *err = -EIO; |
| 415 | return NULL; | 375 | goto out_err; |
| 416 | } | 376 | } |
| 417 | 377 | ||
| 418 | liu = le16_to_cpu(cfi->lengthOfImpUse); | 378 | liu = le16_to_cpu(cfi->lengthOfImpUse); |
| 419 | lfi = cfi->lengthFileIdent; | 379 | lfi = cfi->lengthFileIdent; |
| 420 | 380 | ||
| 421 | if (fibh->sbh == fibh->ebh) | ||
| 422 | nameptr = fi->fileIdent + liu; | ||
| 423 | else { | ||
| 424 | int poffset; /* Unpaded ending offset */ | ||
| 425 | |||
| 426 | poffset = fibh->soffset + sizeof(struct fileIdentDesc) + | ||
| 427 | liu + lfi; | ||
| 428 | |||
| 429 | if (poffset >= lfi) | ||
| 430 | nameptr = (char *)(fibh->ebh->b_data + | ||
| 431 | poffset - lfi); | ||
| 432 | else { | ||
| 433 | nameptr = fname; | ||
| 434 | memcpy(nameptr, fi->fileIdent + liu, | ||
| 435 | lfi - poffset); | ||
| 436 | memcpy(nameptr + lfi - poffset, | ||
| 437 | fibh->ebh->b_data, poffset); | ||
| 438 | } | ||
| 439 | } | ||
| 440 | |||
| 441 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { | 381 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { |
| 442 | if (((sizeof(struct fileIdentDesc) + | 382 | if (((sizeof(struct fileIdentDesc) + |
| 443 | liu + lfi + 3) & ~3) == nfidlen) { | 383 | liu + lfi + 3) & ~3) == nfidlen) { |
| 444 | brelse(epos.bh); | ||
| 445 | cfi->descTag.tagSerialNum = cpu_to_le16(1); | 384 | cfi->descTag.tagSerialNum = cpu_to_le16(1); |
| 446 | cfi->fileVersionNum = cpu_to_le16(1); | 385 | cfi->fileVersionNum = cpu_to_le16(1); |
| 447 | cfi->fileCharacteristics = 0; | 386 | cfi->fileCharacteristics = 0; |
| @@ -449,27 +388,13 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
| 449 | cfi->lengthOfImpUse = cpu_to_le16(0); | 388 | cfi->lengthOfImpUse = cpu_to_le16(0); |
| 450 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, | 389 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, |
| 451 | name)) | 390 | name)) |
| 452 | return fi; | 391 | goto out_ok; |
| 453 | else { | 392 | else { |
| 454 | *err = -EIO; | 393 | *err = -EIO; |
| 455 | return NULL; | 394 | goto out_err; |
| 456 | } | 395 | } |
| 457 | } | 396 | } |
| 458 | } | 397 | } |
| 459 | |||
| 460 | if (!lfi || !dentry) | ||
| 461 | continue; | ||
| 462 | |||
| 463 | flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); | ||
| 464 | if (flen && udf_match(flen, fname, dentry->d_name.len, | ||
| 465 | dentry->d_name.name)) { | ||
| 466 | if (fibh->sbh != fibh->ebh) | ||
| 467 | brelse(fibh->ebh); | ||
| 468 | brelse(fibh->sbh); | ||
| 469 | brelse(epos.bh); | ||
| 470 | *err = -EEXIST; | ||
| 471 | return NULL; | ||
| 472 | } | ||
| 473 | } | 398 | } |
| 474 | 399 | ||
| 475 | add: | 400 | add: |
| @@ -496,7 +421,7 @@ add: | |||
| 496 | fibh->sbh = fibh->ebh = | 421 | fibh->sbh = fibh->ebh = |
| 497 | udf_expand_dir_adinicb(dir, &block, err); | 422 | udf_expand_dir_adinicb(dir, &block, err); |
| 498 | if (!fibh->sbh) | 423 | if (!fibh->sbh) |
| 499 | return NULL; | 424 | goto out_err; |
| 500 | epos.block = dinfo->i_location; | 425 | epos.block = dinfo->i_location; |
| 501 | epos.offset = udf_file_entry_alloc_offset(dir); | 426 | epos.offset = udf_file_entry_alloc_offset(dir); |
| 502 | /* Load extent udf_expand_dir_adinicb() has created */ | 427 | /* Load extent udf_expand_dir_adinicb() has created */ |
| @@ -537,11 +462,8 @@ add: | |||
| 537 | dir->i_sb->s_blocksize_bits); | 462 | dir->i_sb->s_blocksize_bits); |
| 538 | fibh->ebh = udf_bread(dir, | 463 | fibh->ebh = udf_bread(dir, |
| 539 | f_pos >> dir->i_sb->s_blocksize_bits, 1, err); | 464 | f_pos >> dir->i_sb->s_blocksize_bits, 1, err); |
| 540 | if (!fibh->ebh) { | 465 | if (!fibh->ebh) |
| 541 | brelse(epos.bh); | 466 | goto out_err; |
| 542 | brelse(fibh->sbh); | ||
| 543 | return NULL; | ||
| 544 | } | ||
| 545 | 467 | ||
| 546 | if (!fibh->soffset) { | 468 | if (!fibh->soffset) { |
| 547 | if (udf_next_aext(dir, &epos, &eloc, &elen, 1) == | 469 | if (udf_next_aext(dir, &epos, &eloc, &elen, 1) == |
| @@ -572,20 +494,25 @@ add: | |||
| 572 | cfi->lengthFileIdent = namelen; | 494 | cfi->lengthFileIdent = namelen; |
| 573 | cfi->lengthOfImpUse = cpu_to_le16(0); | 495 | cfi->lengthOfImpUse = cpu_to_le16(0); |
| 574 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) { | 496 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) { |
| 575 | brelse(epos.bh); | ||
| 576 | dir->i_size += nfidlen; | 497 | dir->i_size += nfidlen; |
| 577 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 498 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
| 578 | dinfo->i_lenAlloc += nfidlen; | 499 | dinfo->i_lenAlloc += nfidlen; |
| 579 | mark_inode_dirty(dir); | 500 | mark_inode_dirty(dir); |
| 580 | return fi; | 501 | goto out_ok; |
| 581 | } else { | 502 | } else { |
| 582 | brelse(epos.bh); | ||
| 583 | if (fibh->sbh != fibh->ebh) | ||
| 584 | brelse(fibh->ebh); | ||
| 585 | brelse(fibh->sbh); | ||
| 586 | *err = -EIO; | 503 | *err = -EIO; |
| 587 | return NULL; | 504 | goto out_err; |
| 588 | } | 505 | } |
| 506 | |||
| 507 | out_err: | ||
| 508 | fi = NULL; | ||
| 509 | if (fibh->sbh != fibh->ebh) | ||
| 510 | brelse(fibh->ebh); | ||
| 511 | brelse(fibh->sbh); | ||
| 512 | out_ok: | ||
| 513 | brelse(epos.bh); | ||
| 514 | kfree(name); | ||
| 515 | return fi; | ||
| 589 | } | 516 | } |
| 590 | 517 | ||
| 591 | static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, | 518 | static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, |
| @@ -940,7 +867,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
| 940 | char *ea; | 867 | char *ea; |
| 941 | int err; | 868 | int err; |
| 942 | int block; | 869 | int block; |
| 943 | char name[UDF_NAME_LEN]; | 870 | char *name = NULL; |
| 944 | int namelen; | 871 | int namelen; |
| 945 | struct buffer_head *bh; | 872 | struct buffer_head *bh; |
| 946 | struct udf_inode_info *iinfo; | 873 | struct udf_inode_info *iinfo; |
| @@ -950,6 +877,12 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
| 950 | if (!inode) | 877 | if (!inode) |
| 951 | goto out; | 878 | goto out; |
| 952 | 879 | ||
| 880 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); | ||
| 881 | if (!name) { | ||
| 882 | err = -ENOMEM; | ||
| 883 | goto out_no_entry; | ||
| 884 | } | ||
| 885 | |||
| 953 | iinfo = UDF_I(inode); | 886 | iinfo = UDF_I(inode); |
| 954 | inode->i_mode = S_IFLNK | S_IRWXUGO; | 887 | inode->i_mode = S_IFLNK | S_IRWXUGO; |
| 955 | inode->i_data.a_ops = &udf_symlink_aops; | 888 | inode->i_data.a_ops = &udf_symlink_aops; |
| @@ -1089,6 +1022,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
| 1089 | err = 0; | 1022 | err = 0; |
| 1090 | 1023 | ||
| 1091 | out: | 1024 | out: |
| 1025 | kfree(name); | ||
| 1092 | unlock_kernel(); | 1026 | unlock_kernel(); |
| 1093 | return err; | 1027 | return err; |
| 1094 | 1028 | ||
