namei.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:32k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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