namei.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:33k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *   Copyright (c) International Business Machines Corp., 2000-2002
  3.  *   Portions Copyright (c) Christoph Hellwig, 2001-2002
  4.  *
  5.  *   This program is free software;  you can redistribute it and/or modify
  6.  *   it under the terms of the GNU General Public License as published by
  7.  *   the Free Software Foundation; either version 2 of the License, or 
  8.  *   (at your option) any later version.
  9.  * 
  10.  *   This program is distributed in the hope that it will be useful,
  11.  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  12.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  13.  *   the GNU General Public License for more details.
  14.  *
  15.  *   You should have received a copy of the GNU General Public License
  16.  *   along with this program;  if not, write to the Free Software 
  17.  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18.  */
  19. #include <linux/fs.h>
  20. #include "jfs_incore.h"
  21. #include "jfs_inode.h"
  22. #include "jfs_dinode.h"
  23. #include "jfs_dmap.h"
  24. #include "jfs_unicode.h"
  25. #include "jfs_metapage.h"
  26. #include "jfs_xattr.h"
  27. #include "jfs_debug.h"
  28. extern struct inode_operations jfs_file_inode_operations;
  29. extern struct inode_operations jfs_symlink_inode_operations;
  30. extern struct file_operations jfs_file_operations;
  31. extern struct address_space_operations jfs_aops;
  32. extern int jfs_fsync(struct file *, struct dentry *, int);
  33. extern void jfs_truncate_nolock(struct inode *, loff_t);
  34. /*
  35.  * forward references
  36.  */
  37. struct inode_operations jfs_dir_inode_operations;
  38. struct file_operations jfs_dir_operations;
  39. s64 commitZeroLink(tid_t, struct inode *);
  40. /*
  41.  * NAME: jfs_create(dip, dentry, mode)
  42.  *
  43.  * FUNCTION: create a regular file in the parent directory <dip>
  44.  * with name = <from dentry> and mode = <mode>
  45.  *
  46.  * PARAMETER: dip  - parent directory vnode
  47.  * dentry - dentry of new file
  48.  * mode - create mode (rwxrwxrwx).
  49.  *
  50.  * RETURN: Errors from subroutines
  51.  *
  52.  */
  53. int jfs_create(struct inode *dip, struct dentry *dentry, int mode)
  54. {
  55. int rc = 0;
  56. tid_t tid; /* transaction id */
  57. struct inode *ip = NULL; /* child directory inode */
  58. ino_t ino;
  59. struct component_name dname; /* child directory name */
  60. struct btstack btstack;
  61. struct inode *iplist[2];
  62. struct tblock *tblk;
  63. jFYI(1, ("jfs_create: dip:0x%p name:%sn", dip, dentry->d_name.name));
  64. /*
  65.  * search parent directory for entry/freespace
  66.  * (dtSearch() returns parent directory page pinned)
  67.  */
  68. if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
  69. goto out1;
  70. /*
  71.  * Either iAlloc() or txBegin() may block.  Deadlock can occur if we
  72.  * block there while holding dtree page, so we allocate the inode &
  73.  * begin the transaction before we search the directory.
  74.  */
  75. ip = ialloc(dip, mode);
  76. if (ip == NULL) {
  77. rc = ENOSPC;
  78. goto out2;
  79. }
  80. tid = txBegin(dip->i_sb, 0);
  81. down(&JFS_IP(dip)->commit_sem);
  82. down(&JFS_IP(ip)->commit_sem);
  83. if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
  84. jERROR(1, ("jfs_create: dtSearch returned %dn", rc));
  85. goto out3;
  86. }
  87. tblk = tid_to_tblock(tid);
  88. tblk->xflag |= COMMIT_CREATE;
  89. tblk->ip = ip;
  90. iplist[0] = dip;
  91. iplist[1] = ip;
  92. /*
  93.  * initialize the child XAD tree root in-line in inode
  94.  */
  95. xtInitRoot(tid, ip);
  96. /*
  97.  * create entry in parent directory for child directory
  98.  * (dtInsert() releases parent directory page)
  99.  */
  100. ino = ip->i_ino;
  101. if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
  102. jERROR(1, ("jfs_create: dtInsert returned %dn", rc));
  103. if (rc == EIO)
  104. txAbort(tid, 1); /* Marks Filesystem dirty */
  105. else
  106. txAbort(tid, 0); /* Filesystem full */
  107. goto out3;
  108. }
  109. ip->i_op = &jfs_file_inode_operations;
  110. ip->i_fop = &jfs_file_operations;
  111. ip->i_mapping->a_ops = &jfs_aops;
  112. insert_inode_hash(ip);
  113. mark_inode_dirty(ip);
  114. d_instantiate(dentry, ip);
  115. dip->i_ctime = dip->i_mtime = CURRENT_TIME;
  116. mark_inode_dirty(dip);
  117. rc = txCommit(tid, 2, &iplist[0], 0);
  118.       out3:
  119. txEnd(tid);
  120. up(&JFS_IP(dip)->commit_sem);
  121. up(&JFS_IP(ip)->commit_sem);
  122. if (rc) {
  123. ip->i_nlink = 0;
  124. iput(ip);
  125. }
  126.       out2:
  127. free_UCSname(&dname);
  128.       out1:
  129. jFYI(1, ("jfs_create: rc:%dn", -rc));
  130. return -rc;
  131. }
  132. /*
  133.  * NAME: jfs_mkdir(dip, dentry, mode)
  134.  *
  135.  * FUNCTION: create a child directory in the parent directory <dip>
  136.  * with name = <from dentry> and mode = <mode>
  137.  *
  138.  * PARAMETER: dip  - parent directory vnode
  139.  * dentry - dentry of child directory
  140.  * mode - create mode (rwxrwxrwx).
  141.  *
  142.  * RETURN: Errors from subroutines
  143.  *
  144.  * note:
  145.  * EACCESS: user needs search+write permission on the parent directory
  146.  */
  147. int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
  148. {
  149. int rc = 0;
  150. tid_t tid; /* transaction id */
  151. struct inode *ip = NULL; /* child directory inode */
  152. ino_t ino;
  153. struct component_name dname; /* child directory name */
  154. struct btstack btstack;
  155. struct inode *iplist[2];
  156. struct tblock *tblk;
  157. jFYI(1, ("jfs_mkdir: dip:0x%p name:%sn", dip, dentry->d_name.name));
  158. /* link count overflow on parent directory ? */
  159. if (dip->i_nlink == JFS_LINK_MAX) {
  160. rc = EMLINK;
  161. goto out1;
  162. }
  163. /*
  164.  * search parent directory for entry/freespace
  165.  * (dtSearch() returns parent directory page pinned)
  166.  */
  167. if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
  168. goto out1;
  169. /*
  170.  * Either iAlloc() or txBegin() may block.  Deadlock can occur if we
  171.  * block there while holding dtree page, so we allocate the inode &
  172.  * begin the transaction before we search the directory.
  173.  */
  174. ip = ialloc(dip, S_IFDIR | mode);
  175. if (ip == NULL) {
  176. rc = ENOSPC;
  177. goto out2;
  178. }
  179. tid = txBegin(dip->i_sb, 0);
  180. down(&JFS_IP(dip)->commit_sem);
  181. down(&JFS_IP(ip)->commit_sem);
  182. if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
  183. jERROR(1, ("jfs_mkdir: dtSearch returned %dn", rc));
  184. goto out3;
  185. }
  186. tblk = tid_to_tblock(tid);
  187. tblk->xflag |= COMMIT_CREATE;
  188. tblk->ip = ip;
  189. iplist[0] = dip;
  190. iplist[1] = ip;
  191. /*
  192.  * initialize the child directory in-line in inode
  193.  */
  194. dtInitRoot(tid, ip, dip->i_ino);
  195. /*
  196.  * create entry in parent directory for child directory
  197.  * (dtInsert() releases parent directory page)
  198.  */
  199. ino = ip->i_ino;
  200. if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
  201. jERROR(1, ("jfs_mkdir: dtInsert returned %dn", rc));
  202. if (rc == EIO)
  203. txAbort(tid, 1); /* Marks Filesystem dirty */
  204. else
  205. txAbort(tid, 0); /* Filesystem full */
  206. goto out3;
  207. }
  208. ip->i_nlink = 2; /* for '.' */
  209. ip->i_op = &jfs_dir_inode_operations;
  210. ip->i_fop = &jfs_dir_operations;
  211. ip->i_mapping->a_ops = &jfs_aops;
  212. ip->i_mapping->gfp_mask = GFP_NOFS;
  213. insert_inode_hash(ip);
  214. mark_inode_dirty(ip);
  215. d_instantiate(dentry, ip);
  216. /* update parent directory inode */
  217. dip->i_nlink++; /* for '..' from child directory */
  218. dip->i_ctime = dip->i_mtime = CURRENT_TIME;
  219. mark_inode_dirty(dip);
  220. rc = txCommit(tid, 2, &iplist[0], 0);
  221.       out3:
  222. txEnd(tid);
  223. up(&JFS_IP(dip)->commit_sem);
  224. up(&JFS_IP(ip)->commit_sem);
  225. if (rc) {
  226. ip->i_nlink = 0;
  227. iput(ip);
  228. }
  229.       out2:
  230. free_UCSname(&dname);
  231.       out1:
  232. jFYI(1, ("jfs_mkdir: rc:%dn", -rc));
  233. return -rc;
  234. }
  235. /*
  236.  * NAME: jfs_rmdir(dip, dentry)
  237.  *
  238.  * FUNCTION: remove a link to child directory
  239.  *
  240.  * PARAMETER: dip  - parent inode
  241.  * dentry - child directory dentry
  242.  *
  243.  * RETURN: EINVAL - if name is . or ..
  244.  * EINVAL  - if . or .. exist but are invalid.
  245.  * errors from subroutines
  246.  *
  247.  * note:
  248.  * if other threads have the directory open when the last link 
  249.  * is removed, the "." and ".." entries, if present, are removed before 
  250.  * rmdir() returns and no new entries may be created in the directory, 
  251.  * but the directory is not removed until the last reference to 
  252.  * the directory is released (cf.unlink() of regular file).
  253.  */
  254. int jfs_rmdir(struct inode *dip, struct dentry *dentry)
  255. {
  256. int rc;
  257. tid_t tid; /* transaction id */
  258. struct inode *ip = dentry->d_inode;
  259. ino_t ino;
  260. struct component_name dname;
  261. struct inode *iplist[2];
  262. struct tblock *tblk;
  263. jFYI(1, ("jfs_rmdir: dip:0x%p name:%sn", dip, dentry->d_name.name));
  264. /* directory must be empty to be removed */
  265. if (!dtEmpty(ip)) {
  266. rc = ENOTEMPTY;
  267. goto out;
  268. }
  269. if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) {
  270. goto out;
  271. }
  272. tid = txBegin(dip->i_sb, 0);
  273. down(&JFS_IP(dip)->commit_sem);
  274. down(&JFS_IP(ip)->commit_sem);
  275. iplist[0] = dip;
  276. iplist[1] = ip;
  277. tblk = tid_to_tblock(tid);
  278. tblk->xflag |= COMMIT_DELETE;
  279. tblk->ip = ip;
  280. /*
  281.  * delete the entry of target directory from parent directory
  282.  */
  283. ino = ip->i_ino;
  284. if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
  285. jERROR(1, ("jfs_rmdir: dtDelete returned %dn", rc));
  286. if (rc == EIO)
  287. txAbort(tid, 1);
  288. txEnd(tid);
  289. up(&JFS_IP(dip)->commit_sem);
  290. up(&JFS_IP(ip)->commit_sem);
  291. goto out2;
  292. }
  293. /* update parent directory's link count corresponding
  294.  * to ".." entry of the target directory deleted
  295.  */
  296. dip->i_nlink--;
  297. dip->i_ctime = dip->i_mtime = CURRENT_TIME;
  298. mark_inode_dirty(dip);
  299. /*
  300.  * OS/2 could have created EA and/or ACL
  301.  */
  302. /* free EA from both persistent and working map */
  303. if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
  304. /* free EA pages */
  305. txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
  306. }
  307. JFS_IP(ip)->ea.flag = 0;
  308. /* free ACL from both persistent and working map */
  309. if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
  310. /* free ACL pages */
  311. txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
  312. }
  313. JFS_IP(ip)->acl.flag = 0;
  314. /* mark the target directory as deleted */
  315. ip->i_nlink = 0;
  316. mark_inode_dirty(ip);
  317. rc = txCommit(tid, 2, &iplist[0], 0);
  318. txEnd(tid);
  319. up(&JFS_IP(dip)->commit_sem);
  320. up(&JFS_IP(ip)->commit_sem);
  321. /*
  322.  * Truncating the directory index table is not guaranteed.  It
  323.  * may need to be done iteratively
  324.  */
  325. if (test_cflag(COMMIT_Stale, dip)) {
  326. if (dip->i_size > 1)
  327. jfs_truncate_nolock(dip, 0);
  328. clear_cflag(COMMIT_Stale, dip);
  329. }
  330.       out2:
  331. free_UCSname(&dname);
  332.       out:
  333. jFYI(1, ("jfs_rmdir: rc:%dn", rc));
  334. return -rc;
  335. }
  336. /*
  337.  * NAME: jfs_unlink(dip, dentry)
  338.  *
  339.  * FUNCTION: remove a link to object <vp> named by <name> 
  340.  * from parent directory <dvp>
  341.  *
  342.  * PARAMETER: dip  - inode of parent directory
  343.  * dentry  - dentry of object to be removed
  344.  *
  345.  * RETURN: errors from subroutines
  346.  *
  347.  * note:
  348.  * temporary file: if one or more processes have the file open
  349.  * when the last link is removed, the link will be removed before
  350.  * unlink() returns, but the removal of the file contents will be
  351.  * postponed until all references to the files are closed.
  352.  *
  353.  * JFS does NOT support unlink() on directories.
  354.  *
  355.  */
  356. int jfs_unlink(struct inode *dip, struct dentry *dentry)
  357. {
  358. int rc;
  359. tid_t tid; /* transaction id */
  360. struct inode *ip = dentry->d_inode;
  361. ino_t ino;
  362. struct component_name dname; /* object name */
  363. struct inode *iplist[2];
  364. struct tblock *tblk;
  365. s64 new_size = 0;
  366. int commit_flag;
  367. jFYI(1, ("jfs_unlink: dip:0x%p name:%sn", dip, dentry->d_name.name));
  368. if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
  369. goto out;
  370. IWRITE_LOCK(ip);
  371. tid = txBegin(dip->i_sb, 0);
  372. down(&JFS_IP(dip)->commit_sem);
  373. down(&JFS_IP(ip)->commit_sem);
  374. iplist[0] = dip;
  375. iplist[1] = ip;
  376. /*
  377.  * delete the entry of target file from parent directory
  378.  */
  379. ino = ip->i_ino;
  380. if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
  381. jERROR(1, ("jfs_unlink: dtDelete returned %dn", rc));
  382. if (rc == EIO)
  383. txAbort(tid, 1); /* Marks FS Dirty */
  384. txEnd(tid);
  385. up(&JFS_IP(dip)->commit_sem);
  386. up(&JFS_IP(ip)->commit_sem);
  387. IWRITE_UNLOCK(ip);
  388. goto out1;
  389. }
  390. ASSERT(ip->i_nlink);
  391. ip->i_ctime = dip->i_ctime = dip->i_mtime = CURRENT_TIME;
  392. mark_inode_dirty(dip);
  393. /* update target's inode */
  394. ip->i_nlink--;
  395. mark_inode_dirty(ip);
  396. /*
  397.  *      commit zero link count object
  398.  */
  399. if (ip->i_nlink == 0) {
  400. assert(!test_cflag(COMMIT_Nolink, ip));
  401. /* free block resources */
  402. if ((new_size = commitZeroLink(tid, ip)) < 0) {
  403. txAbort(tid, 1); /* Marks FS Dirty */
  404. txEnd(tid);
  405. up(&JFS_IP(dip)->commit_sem);
  406. up(&JFS_IP(ip)->commit_sem);
  407. IWRITE_UNLOCK(ip);
  408. rc = -new_size; /* We return -rc */
  409. goto out1;
  410. }
  411. tblk = tid_to_tblock(tid);
  412. tblk->xflag |= COMMIT_DELETE;
  413. tblk->ip = ip;
  414. }
  415. /*
  416.  * Incomplete truncate of file data can
  417.  * result in timing problems unless we synchronously commit the
  418.  * transaction.
  419.  */
  420. if (new_size)
  421. commit_flag = COMMIT_SYNC;
  422. else
  423. commit_flag = 0;
  424. /*
  425.  * If xtTruncate was incomplete, commit synchronously to avoid
  426.  * timing complications
  427.  */
  428. rc = txCommit(tid, 2, &iplist[0], commit_flag);
  429. txEnd(tid);
  430. up(&JFS_IP(dip)->commit_sem);
  431. up(&JFS_IP(ip)->commit_sem);
  432. while (new_size && (rc == 0)) {
  433. tid = txBegin(dip->i_sb, 0);
  434. down(&JFS_IP(ip)->commit_sem);
  435. new_size = xtTruncate_pmap(tid, ip, new_size);
  436. if (new_size < 0) {
  437. txAbort(tid, 1); /* Marks FS Dirty */
  438. rc = -new_size; /* We return -rc */
  439. } else
  440. rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
  441. txEnd(tid);
  442. up(&JFS_IP(ip)->commit_sem);
  443. }
  444. if (ip->i_nlink == 0)
  445. set_cflag(COMMIT_Nolink, ip);
  446. if (!test_cflag(COMMIT_Holdlock, ip))
  447. IWRITE_UNLOCK(ip);
  448. /*
  449.  * Truncating the directory index table is not guaranteed.  It
  450.  * may need to be done iteratively
  451.  */
  452. if (test_cflag(COMMIT_Stale, dip)) {
  453. if (dip->i_size > 1)
  454. jfs_truncate_nolock(dip, 0);
  455. clear_cflag(COMMIT_Stale, dip);
  456. }
  457.       out1:
  458. free_UCSname(&dname);
  459.       out:
  460. jFYI(1, ("jfs_unlink: rc:%dn", -rc));
  461. return -rc;
  462. }
  463. /*
  464.  * NAME: commitZeroLink()
  465.  *
  466.  * FUNCTION:    for non-directory, called by jfs_remove(),
  467.  * truncate a regular file, directory or symbolic
  468.  * link to zero length. return 0 if type is not 
  469.  * one of these.
  470.  *
  471.  * if the file is currently associated with a VM segment
  472.  * only permanent disk and inode map resources are freed,
  473.  * and neither the inode nor indirect blocks are modified
  474.  * so that the resources can be later freed in the work
  475.  * map by ctrunc1.
  476.  * if there is no VM segment on entry, the resources are
  477.  * freed in both work and permanent map.
  478.  * (? for temporary file - memory object is cached even 
  479.  * after no reference:
  480.  * reference count > 0 -   )
  481.  *
  482.  * PARAMETERS: cd - pointer to commit data structure.
  483.  *   current inode is the one to truncate.
  484.  *
  485.  * RETURN : Errors from subroutines
  486.  */
  487. s64 commitZeroLink(tid_t tid, struct inode *ip)
  488. {
  489. int filetype;
  490. struct tblock *tblk;
  491. jFYI(1, ("commitZeroLink: tid = %d, ip = 0x%pn", tid, ip));
  492. filetype = ip->i_mode & S_IFMT;
  493. switch (filetype) {
  494. case S_IFREG:
  495. break;
  496. case S_IFLNK:
  497. /* fast symbolic link */
  498. if (ip->i_size <= 256) {
  499. ip->i_size = 0;
  500. return 0;
  501. }
  502. break;
  503. default:
  504. assert(filetype != S_IFDIR);
  505. return 0;
  506. }
  507. set_cflag(COMMIT_Freewmap, ip);
  508. /* mark transaction of block map update type */
  509. tblk = tid_to_tblock(tid);
  510. tblk->xflag |= COMMIT_PMAP;
  511. /*
  512.  * free EA
  513.  */
  514. if (JFS_IP(ip)->ea.flag & DXD_EXTENT)
  515. /* acquire maplock on EA to be freed from block map */
  516. txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
  517. /*
  518.  * free ACL
  519.  */
  520. if (JFS_IP(ip)->acl.flag & DXD_EXTENT)
  521. /* acquire maplock on EA to be freed from block map */
  522. txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
  523. /*
  524.  * free xtree/data (truncate to zero length):
  525.  * free xtree/data pages from cache if COMMIT_PWMAP, 
  526.  * free xtree/data blocks from persistent block map, and
  527.  * free xtree/data blocks from working block map if COMMIT_PWMAP;
  528.  */
  529. if (ip->i_size)
  530. return xtTruncate_pmap(tid, ip, 0);
  531. return 0;
  532. }
  533. /*
  534.  * NAME: freeZeroLink()
  535.  *
  536.  * FUNCTION:    for non-directory, called by iClose(),
  537.  * free resources of a file from cache and WORKING map 
  538.  * for a file previously committed with zero link count
  539.  * while associated with a pager object,
  540.  *
  541.  * PARAMETER: ip - pointer to inode of file.
  542.  *
  543.  * RETURN: 0 -ok
  544.  */
  545. int freeZeroLink(struct inode *ip)
  546. {
  547. int rc = 0;
  548. int type;
  549. jFYI(1, ("freeZeroLink: ip = 0x%pn", ip));
  550. /* return if not reg or symbolic link or if size is
  551.  * already ok.
  552.  */
  553. type = ip->i_mode & S_IFMT;
  554. switch (type) {
  555. case S_IFREG:
  556. break;
  557. case S_IFLNK:
  558. /* if its contained in inode nothing to do */
  559. if (ip->i_size <= 256)
  560. return 0;
  561. break;
  562. default:
  563. return 0;
  564. }
  565. /*
  566.  * free EA
  567.  */
  568. if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
  569. s64 xaddr = addressDXD(&JFS_IP(ip)->ea);
  570. int xlen = lengthDXD(&JFS_IP(ip)->ea);
  571. struct maplock maplock; /* maplock for COMMIT_WMAP */
  572. struct pxd_lock *pxdlock; /* maplock for COMMIT_WMAP */
  573. /* free EA pages from cache */
  574. invalidate_dxd_metapages(ip, JFS_IP(ip)->ea);
  575. /* free EA extent from working block map */
  576. maplock.index = 1;
  577. pxdlock = (struct pxd_lock *) & maplock;
  578. pxdlock->flag = mlckFREEPXD;
  579. PXDaddress(&pxdlock->pxd, xaddr);
  580. PXDlength(&pxdlock->pxd, xlen);
  581. txFreeMap(ip, pxdlock, 0, COMMIT_WMAP);
  582. }
  583. /*
  584.  * free ACL
  585.  */
  586. if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
  587. s64 xaddr = addressDXD(&JFS_IP(ip)->acl);
  588. int xlen = lengthDXD(&JFS_IP(ip)->acl);
  589. struct maplock maplock; /* maplock for COMMIT_WMAP */
  590. struct pxd_lock *pxdlock; /* maplock for COMMIT_WMAP */
  591. invalidate_dxd_metapages(ip, JFS_IP(ip)->acl);
  592. /* free ACL extent from working block map */
  593. maplock.index = 1;
  594. pxdlock = (struct pxd_lock *) & maplock;
  595. pxdlock->flag = mlckFREEPXD;
  596. PXDaddress(&pxdlock->pxd, xaddr);
  597. PXDlength(&pxdlock->pxd, xlen);
  598. txFreeMap(ip, pxdlock, 0, COMMIT_WMAP);
  599. }
  600. /*
  601.  * free xtree/data (truncate to zero length):
  602.  * free xtree/data pages from cache, and
  603.  * free xtree/data blocks from working block map;
  604.  */
  605. if (ip->i_size)
  606. rc = xtTruncate(0, ip, 0, COMMIT_WMAP);
  607. return rc;
  608. }
  609. /*
  610.  * NAME: jfs_link(vp, dvp, name, crp)
  611.  *
  612.  * FUNCTION: create a link to <vp> by the name = <name>
  613.  * in the parent directory <dvp>
  614.  *
  615.  * PARAMETER: vp  - target object
  616.  * dvp - parent directory of new link
  617.  * name - name of new link to target object
  618.  * crp - credential
  619.  *
  620.  * RETURN: Errors from subroutines
  621.  *
  622.  * note:
  623.  * JFS does NOT support link() on directories (to prevent circular
  624.  * path in the directory hierarchy);
  625.  * EPERM: the target object is a directory, and either the caller
  626.  * does not have appropriate privileges or the implementation prohibits
  627.  * using link() on directories [XPG4.2].
  628.  *
  629.  * JFS does NOT support links between file systems:
  630.  * EXDEV: target object and new link are on different file systems and
  631.  * implementation does not support links between file systems [XPG4.2].
  632.  */
  633. int jfs_link(struct dentry *old_dentry,
  634.      struct inode *dir, struct dentry *dentry)
  635. {
  636. int rc;
  637. tid_t tid;
  638. struct inode *ip = old_dentry->d_inode;
  639. ino_t ino;
  640. struct component_name dname;
  641. struct btstack btstack;
  642. struct inode *iplist[2];
  643. jFYI(1,
  644.      ("jfs_link: %s %sn", old_dentry->d_name.name,
  645.       dentry->d_name.name));
  646. /* JFS does NOT support link() on directories */
  647. if (S_ISDIR(ip->i_mode))
  648. return -EPERM;
  649. tid = txBegin(ip->i_sb, 0);
  650. down(&JFS_IP(dir)->commit_sem);
  651. down(&JFS_IP(ip)->commit_sem);
  652. if (ip->i_nlink == JFS_LINK_MAX) {
  653. rc = EMLINK;
  654. goto out;
  655. }
  656. /*
  657.  * scan parent directory for entry/freespace
  658.  */
  659. if ((rc = get_UCSname(&dname, dentry, JFS_SBI(ip->i_sb)->nls_tab)))
  660. goto out;
  661. if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
  662. goto out;
  663. /*
  664.  * create entry for new link in parent directory
  665.  */
  666. ino = ip->i_ino;
  667. if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
  668. goto out;
  669. /* update object inode */
  670. ip->i_nlink++; /* for new link */
  671. ip->i_ctime = CURRENT_TIME;
  672. mark_inode_dirty(dir);
  673. atomic_inc(&ip->i_count);
  674. d_instantiate(dentry, ip);
  675. iplist[0] = ip;
  676. iplist[1] = dir;
  677. rc = txCommit(tid, 2, &iplist[0], 0);
  678.       out:
  679. txEnd(tid);
  680. up(&JFS_IP(dir)->commit_sem);
  681. up(&JFS_IP(ip)->commit_sem);
  682. jFYI(1, ("jfs_link: rc:%dn", rc));
  683. return -rc;
  684. }
  685. /*
  686.  * NAME: jfs_symlink(dip, dentry, name)
  687.  *
  688.  * FUNCTION: creates a symbolic link to <symlink> by name <name>
  689.  *         in directory <dip>
  690.  *
  691.  * PARAMETER: dip     - parent directory vnode
  692.  *         dentry  - dentry of symbolic link
  693.  *         name    - the path name of the existing object 
  694.  *               that will be the source of the link
  695.  *
  696.  * RETURN: errors from subroutines
  697.  *
  698.  * note:
  699.  * ENAMETOOLONG: pathname resolution of a symbolic link produced
  700.  * an intermediate result whose length exceeds PATH_MAX [XPG4.2]
  701. */
  702. int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name)
  703. {
  704. int rc;
  705. tid_t tid;
  706. ino_t ino = 0;
  707. struct component_name dname;
  708. int ssize; /* source pathname size */
  709. struct btstack btstack;
  710. struct inode *ip = dentry->d_inode;
  711. unchar *i_fastsymlink;
  712. s64 xlen = 0;
  713. int bmask = 0, xsize;
  714. s64 xaddr;
  715. struct metapage *mp;
  716. struct super_block *sb;
  717. struct tblock *tblk;
  718. struct inode *iplist[2];
  719. jFYI(1, ("jfs_symlink: dip:0x%p name:%sn", dip, name));
  720. ssize = strlen(name) + 1;
  721. /*
  722.  * search parent directory for entry/freespace
  723.  * (dtSearch() returns parent directory page pinned)
  724.  */
  725. if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
  726. goto out1;
  727. /*
  728.  * allocate on-disk/in-memory inode for symbolic link:
  729.  * (iAlloc() returns new, locked inode)
  730.  */
  731. ip = ialloc(dip, S_IFLNK | 0777);
  732. if (ip == NULL) {
  733. rc = ENOSPC;
  734. goto out2;
  735. }
  736. tid = txBegin(dip->i_sb, 0);
  737. down(&JFS_IP(dip)->commit_sem);
  738. down(&JFS_IP(ip)->commit_sem);
  739. if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE)))
  740. goto out3;
  741. tblk = tid_to_tblock(tid);
  742. tblk->xflag |= COMMIT_CREATE;
  743. tblk->ip = ip;
  744. /*
  745.  * create entry for symbolic link in parent directory
  746.  */
  747. ino = ip->i_ino;
  748. if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
  749. jERROR(1, ("jfs_symlink: dtInsert returned %dn", rc));
  750. /* discard ne inode */
  751. goto out3;
  752. }
  753. /* fix symlink access permission
  754.  * (dir_create() ANDs in the u.u_cmask, 
  755.  * but symlinks really need to be 777 access)
  756.  */
  757. ip->i_mode |= 0777;
  758. /*
  759.    *       write symbolic link target path name
  760.  */
  761. xtInitRoot(tid, ip);
  762. /*
  763.  * write source path name inline in on-disk inode (fast symbolic link)
  764.  */
  765. if (ssize <= IDATASIZE) {
  766. ip->i_op = &jfs_symlink_inode_operations;
  767. i_fastsymlink = JFS_IP(ip)->i_inline;
  768. memcpy(i_fastsymlink, name, ssize);
  769. ip->i_size = ssize - 1;
  770. /*
  771.  * if symlink is > 128 bytes, we don't have the space to
  772.  * store inline extended attributes
  773.  */
  774. if (ssize > sizeof (JFS_IP(ip)->i_inline))
  775. JFS_IP(ip)->mode2 &= ~INLINEEA;
  776. jFYI(1,
  777.      ("jfs_symlink: fast symlink added  ssize:%d name:%s n",
  778.       ssize, name));
  779. }
  780. /*
  781.  * write source path name in a single extent
  782.  */
  783. else {
  784. jFYI(1, ("jfs_symlink: allocate extent ip:0x%pn", ip));
  785. ip->i_op = &page_symlink_inode_operations;
  786. ip->i_mapping->a_ops = &jfs_aops;
  787. /*
  788.  * even though the data of symlink object (source 
  789.  * path name) is treated as non-journaled user data,
  790.  * it is read/written thru buffer cache for performance.
  791.  */
  792. sb = ip->i_sb;
  793. bmask = JFS_SBI(sb)->bsize - 1;
  794. xsize = (ssize + bmask) & ~bmask;
  795. xaddr = 0;
  796. xlen = xsize >> JFS_SBI(sb)->l2bsize;
  797. if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0)) == 0) {
  798. ip->i_size = ssize - 1;
  799. while (ssize) {
  800. int copy_size = min(ssize, PSIZE);
  801. mp = get_metapage(ip, xaddr, PSIZE, 1);
  802. if (mp == NULL) {
  803. dtDelete(tid, dip, &dname, &ino,
  804.  JFS_REMOVE);
  805. rc = EIO;
  806. goto out3;
  807. }
  808. memcpy(mp->data, name, copy_size);
  809. flush_metapage(mp);
  810. #if 0
  811. mark_buffer_uptodate(bp, 1);
  812. mark_buffer_dirty(bp, 1);
  813. if (IS_SYNC(dip)) {
  814. ll_rw_block(WRITE, 1, &bp);
  815. wait_on_buffer(bp);
  816. }
  817. brelse(bp);
  818. #endif /* 0 */
  819. ssize -= copy_size;
  820. xaddr += JFS_SBI(sb)->nbperpage;
  821. }
  822. ip->i_blocks = LBLK2PBLK(sb, xlen);
  823. } else {
  824. dtDelete(tid, dip, &dname, &ino, JFS_REMOVE);
  825. rc = ENOSPC;
  826. goto out3;
  827. }
  828. }
  829. insert_inode_hash(ip);
  830. mark_inode_dirty(ip);
  831. d_instantiate(dentry, ip);
  832. /*
  833.  * commit update of parent directory and link object
  834.  *
  835.  * if extent allocation failed (ENOSPC),
  836.  * the parent inode is committed regardless to avoid
  837.  * backing out parent directory update (by dtInsert())
  838.  * and subsequent dtDelete() which is harmless wrt 
  839.  * integrity concern.  
  840.  * the symlink inode will be freed by iput() at exit
  841.  * as it has a zero link count (by dtDelete()) and 
  842.  * no permanant resources. 
  843.  */
  844. iplist[0] = dip;
  845. if (rc == 0) {
  846. iplist[1] = ip;
  847. rc = txCommit(tid, 2, &iplist[0], 0);
  848. } else
  849. rc = txCommit(tid, 1, &iplist[0], 0);
  850.       out3:
  851. txEnd(tid);
  852. up(&JFS_IP(dip)->commit_sem);
  853. up(&JFS_IP(ip)->commit_sem);
  854. if (rc) {
  855. ip->i_nlink = 0;
  856. iput(ip);
  857. }
  858.       out2:
  859. free_UCSname(&dname);
  860.       out1:
  861. jFYI(1, ("jfs_symlink: rc:%dn", -rc));
  862. return -rc;
  863. }
  864. /*
  865.  * NAME:        jfs_rename
  866.  *
  867.  * FUNCTION:    rename a file or directory
  868.  */
  869. int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
  870.        struct inode *new_dir, struct dentry *new_dentry)
  871. {
  872. struct btstack btstack;
  873. ino_t ino;
  874. struct component_name new_dname;
  875. struct inode *new_ip;
  876. struct component_name old_dname;
  877. struct inode *old_ip;
  878. int rc;
  879. tid_t tid;
  880. struct tlock *tlck;
  881. struct dt_lock *dtlck;
  882. struct lv *lv;
  883. int ipcount;
  884. struct inode *iplist[4];
  885. struct tblock *tblk;
  886. s64 new_size = 0;
  887. int commit_flag;
  888. jFYI(1,
  889.      ("jfs_rename: %s %sn", old_dentry->d_name.name,
  890.       new_dentry->d_name.name));
  891. old_ip = old_dentry->d_inode;
  892. new_ip = new_dentry->d_inode;
  893. if ((rc = get_UCSname(&old_dname, old_dentry,
  894.       JFS_SBI(old_dir->i_sb)->nls_tab)))
  895. goto out1;
  896. if ((rc = get_UCSname(&new_dname, new_dentry,
  897.       JFS_SBI(old_dir->i_sb)->nls_tab)))
  898. goto out2;
  899. /*
  900.  * Make sure source inode number is what we think it is
  901.  */
  902. rc = dtSearch(old_dir, &old_dname, &ino, &btstack, JFS_LOOKUP);
  903. if (rc || (ino != old_ip->i_ino)) {
  904. rc = ENOENT;
  905. goto out3;
  906. }
  907. /*
  908.  * Make sure dest inode number (if any) is what we think it is
  909.  */
  910. rc = dtSearch(new_dir, &new_dname, &ino, &btstack, JFS_LOOKUP);
  911. if (rc == 0) {
  912. if ((new_ip == 0) || (ino != new_ip->i_ino)) {
  913. rc = ESTALE;
  914. goto out3;
  915. }
  916. } else if (rc != ENOENT)
  917. goto out3;
  918. else if (new_ip) {
  919. /* no entry exists, but one was expected */
  920. rc = ESTALE;
  921. goto out3;
  922. }
  923. if (S_ISDIR(old_ip->i_mode)) {
  924. if (new_ip) {
  925. if (!dtEmpty(new_ip)) {
  926. rc = ENOTEMPTY;
  927. goto out3;
  928. }
  929. } else if ((new_dir != old_dir) &&
  930.    (new_dir->i_nlink == JFS_LINK_MAX)) {
  931. rc = EMLINK;
  932. goto out3;
  933. }
  934. } else if (new_ip)
  935. IWRITE_LOCK(new_ip);
  936. /*
  937.  * The real work starts here
  938.  */
  939. tid = txBegin(new_dir->i_sb, 0);
  940. down(&JFS_IP(new_dir)->commit_sem);
  941. down(&JFS_IP(old_ip)->commit_sem);
  942. if (old_dir != new_dir)
  943. down(&JFS_IP(old_dir)->commit_sem);
  944. if (new_ip) {
  945. down(&JFS_IP(new_ip)->commit_sem);
  946. /*
  947.  * Change existing directory entry to new inode number
  948.  */
  949. ino = new_ip->i_ino;
  950. rc = dtModify(tid, new_dir, &new_dname, &ino,
  951.       old_ip->i_ino, JFS_RENAME);
  952. if (rc)
  953. goto out4;
  954. new_ip->i_nlink--;
  955. if (S_ISDIR(new_ip->i_mode)) {
  956. new_ip->i_nlink--;
  957. assert(new_ip->i_nlink == 0);
  958. tblk = tid_to_tblock(tid);
  959. tblk->xflag |= COMMIT_DELETE;
  960. tblk->ip = new_ip;
  961. } else if (new_ip->i_nlink == 0) {
  962. assert(!test_cflag(COMMIT_Nolink, new_ip));
  963. /* free block resources */
  964. if ((new_size = commitZeroLink(tid, new_ip)) < 0) {
  965. txAbort(tid, 1); /* Marks FS Dirty */
  966. rc = -new_size; /* We return -rc */
  967. goto out4;
  968. }
  969. tblk = tid_to_tblock(tid);
  970. tblk->xflag |= COMMIT_DELETE;
  971. tblk->ip = new_ip;
  972. } else {
  973. new_ip->i_ctime = CURRENT_TIME;
  974. mark_inode_dirty(new_ip);
  975. }
  976. } else {
  977. /*
  978.  * Add new directory entry
  979.  */
  980. rc = dtSearch(new_dir, &new_dname, &ino, &btstack,
  981.       JFS_CREATE);
  982. if (rc) {
  983. jERROR(1,
  984.        ("jfs_rename didn't expect dtSearch to fail w/rc = %dn",
  985. rc));
  986. goto out4;
  987. }
  988. ino = old_ip->i_ino;
  989. rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack);
  990. if (rc) {
  991. jERROR(1,
  992.        ("jfs_rename: dtInsert failed w/rc = %dn",
  993. rc));
  994. goto out4;
  995. }
  996. if (S_ISDIR(old_ip->i_mode))
  997. new_dir->i_nlink++;
  998. }
  999. /*
  1000.  * Remove old directory entry
  1001.  */
  1002. ino = old_ip->i_ino;
  1003. rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE);
  1004. if (rc) {
  1005. jERROR(1,
  1006.        ("jfs_rename did not expect dtDelete to return rc = %dn",
  1007. rc));
  1008. txAbort(tid, 1); /* Marks Filesystem dirty */
  1009. goto out4;
  1010. }
  1011. if (S_ISDIR(old_ip->i_mode)) {
  1012. old_dir->i_nlink--;
  1013. if (old_dir != new_dir) {
  1014. /*
  1015.  * Change inode number of parent for moved directory
  1016.  */
  1017. JFS_IP(old_ip)->i_dtroot.header.idotdot =
  1018. cpu_to_le32(new_dir->i_ino);
  1019. /* Linelock header of dtree */
  1020. tlck = txLock(tid, old_ip,
  1021.     (struct metapage *) &JFS_IP(old_ip)->bxflag,
  1022.       tlckDTREE | tlckBTROOT);
  1023. dtlck = (struct dt_lock *) & tlck->lock;
  1024. ASSERT(dtlck->index == 0);
  1025. lv = & dtlck->lv[0];
  1026. lv->offset = 0;
  1027. lv->length = 1;
  1028. dtlck->index++;
  1029. }
  1030. }
  1031. /*
  1032.  * Update ctime on changed/moved inodes & mark dirty
  1033.  */
  1034. old_ip->i_ctime = CURRENT_TIME;
  1035. mark_inode_dirty(old_ip);
  1036. new_dir->i_ctime = CURRENT_TIME;
  1037. mark_inode_dirty(new_dir);
  1038. /* Build list of inodes modified by this transaction */
  1039. ipcount = 0;
  1040. iplist[ipcount++] = old_ip;
  1041. if (new_ip)
  1042. iplist[ipcount++] = new_ip;
  1043. iplist[ipcount++] = old_dir;
  1044. if (old_dir != new_dir) {
  1045. iplist[ipcount++] = new_dir;
  1046. old_dir->i_ctime = CURRENT_TIME;
  1047. mark_inode_dirty(old_dir);
  1048. }
  1049. /*
  1050.  * Incomplete truncate of file data can
  1051.  * result in timing problems unless we synchronously commit the
  1052.  * transaction.
  1053.  */
  1054. if (new_size)
  1055. commit_flag = COMMIT_SYNC;
  1056. else
  1057. commit_flag = 0;
  1058. rc = txCommit(tid, ipcount, iplist, commit_flag);
  1059. /*
  1060.  * Don't unlock new_ip if COMMIT_HOLDLOCK is set
  1061.  */
  1062. if (new_ip && test_cflag(COMMIT_Holdlock, new_ip)) {
  1063. up(&JFS_IP(new_ip)->commit_sem);
  1064. new_ip = 0;
  1065. }
  1066.       out4:
  1067. txEnd(tid);
  1068. up(&JFS_IP(new_dir)->commit_sem);
  1069. up(&JFS_IP(old_ip)->commit_sem);
  1070. if (old_dir != new_dir)
  1071. up(&JFS_IP(old_dir)->commit_sem);
  1072. if (new_ip)
  1073. up(&JFS_IP(new_ip)->commit_sem);
  1074. while (new_size && (rc == 0)) {
  1075. tid = txBegin(new_ip->i_sb, 0);
  1076. down(&JFS_IP(new_ip)->commit_sem);
  1077. new_size = xtTruncate_pmap(tid, new_ip, new_size);
  1078. if (new_size < 0) {
  1079. txAbort(tid, 1);
  1080. rc = -new_size; /* We return -rc */
  1081. } else
  1082. rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
  1083. txEnd(tid);
  1084. up(&JFS_IP(new_ip)->commit_sem);
  1085. }
  1086. if (new_ip && (new_ip->i_nlink == 0))
  1087. set_cflag(COMMIT_Nolink, new_ip);
  1088.       out3:
  1089. free_UCSname(&new_dname);
  1090.       out2:
  1091. free_UCSname(&old_dname);
  1092.       out1:
  1093. if (new_ip && !S_ISDIR(new_ip->i_mode))
  1094. IWRITE_UNLOCK(new_ip);
  1095. /*
  1096.  * Truncating the directory index table is not guaranteed.  It
  1097.  * may need to be done iteratively
  1098.  */
  1099. if (test_cflag(COMMIT_Stale, old_dir)) {
  1100. if (old_dir->i_size > 1)
  1101. jfs_truncate_nolock(old_dir, 0);
  1102. clear_cflag(COMMIT_Stale, old_dir);
  1103. }
  1104. jFYI(1, ("jfs_rename: returning %dn", rc));
  1105. return -rc;
  1106. }
  1107. /*
  1108.  * NAME:        jfs_mknod
  1109.  *
  1110.  * FUNCTION:    Create a special file (device)
  1111.  */
  1112. int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
  1113. {
  1114. struct btstack btstack;
  1115. struct component_name dname;
  1116. ino_t ino;
  1117. struct inode *ip;
  1118. struct inode *iplist[2];
  1119. int rc;
  1120. tid_t tid;
  1121. struct tblock *tblk;
  1122. jFYI(1, ("jfs_mknod: %sn", dentry->d_name.name));
  1123. if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab)))
  1124. goto out;
  1125. ip = ialloc(dir, mode);
  1126. if (ip == NULL) {
  1127. rc = ENOSPC;
  1128. goto out1;
  1129. }
  1130. tid = txBegin(dir->i_sb, 0);
  1131. down(&JFS_IP(dir)->commit_sem);
  1132. down(&JFS_IP(ip)->commit_sem);
  1133. if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
  1134. goto out3;
  1135. tblk = tid_to_tblock(tid);
  1136. tblk->xflag |= COMMIT_CREATE;
  1137. tblk->ip = ip;
  1138. ino = ip->i_ino;
  1139. if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
  1140. goto out3;
  1141. ip->i_op = &jfs_file_inode_operations;
  1142. init_special_inode(ip, ip->i_mode, rdev);
  1143. insert_inode_hash(ip);
  1144. mark_inode_dirty(ip);
  1145. d_instantiate(dentry, ip);
  1146. dir->i_ctime = dir->i_mtime = CURRENT_TIME;
  1147. mark_inode_dirty(dir);
  1148. iplist[0] = dir;
  1149. iplist[1] = ip;
  1150. rc = txCommit(tid, 2, iplist, 0);
  1151.       out3:
  1152. txEnd(tid);
  1153. up(&JFS_IP(ip)->commit_sem);
  1154. up(&JFS_IP(dir)->commit_sem);
  1155. if (rc) {
  1156. ip->i_nlink = 0;
  1157. iput(ip);
  1158. }
  1159.       out1:
  1160. free_UCSname(&dname);
  1161.       out:
  1162. jFYI(1, ("jfs_mknod: returning %dn", rc));
  1163. return -rc;
  1164. }
  1165. static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry)
  1166. {
  1167. struct btstack btstack;
  1168. ino_t inum;
  1169. struct inode *ip;
  1170. struct component_name key;
  1171. const char *name = dentry->d_name.name;
  1172. int len = dentry->d_name.len;
  1173. int rc;
  1174. jFYI(1, ("jfs_lookup: name = %sn", name));
  1175. if ((name[0] == '.') && (len == 1))
  1176. inum = dip->i_ino;
  1177. else if (strcmp(name, "..") == 0)
  1178. inum = PARENT(dip);
  1179. else {
  1180. if ((rc =
  1181.      get_UCSname(&key, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
  1182. return ERR_PTR(-rc);
  1183. rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP);
  1184. free_UCSname(&key);
  1185. if (rc == ENOENT) {
  1186. d_add(dentry, NULL);
  1187. return ERR_PTR(0);
  1188. } else if (rc) {
  1189. jERROR(1,
  1190.        ("jfs_lookup: dtSearch returned %dn", rc));
  1191. return ERR_PTR(-rc);
  1192. }
  1193. }
  1194. ip = iget(dip->i_sb, inum);
  1195. if (ip == NULL) {
  1196. jERROR(1,
  1197.        ("jfs_lookup: iget failed on inum %dn",
  1198. (uint) inum));
  1199. return ERR_PTR(-EACCES);
  1200. }
  1201. d_add(dentry, ip);
  1202. return ERR_PTR(0);
  1203. }
  1204. struct inode_operations jfs_dir_inode_operations = {
  1205. .create = jfs_create,
  1206. .lookup = jfs_lookup,
  1207. .link = jfs_link,
  1208. .unlink = jfs_unlink,
  1209. .symlink = jfs_symlink,
  1210. .mkdir = jfs_mkdir,
  1211. .rmdir = jfs_rmdir,
  1212. .mknod = jfs_mknod,
  1213. .rename = jfs_rename,
  1214. .setxattr = jfs_setxattr,
  1215. .getxattr = jfs_getxattr,
  1216. .listxattr = jfs_listxattr,
  1217. .removexattr = jfs_removexattr,
  1218. };
  1219. struct file_operations jfs_dir_operations = {
  1220. .read = generic_read_dir,
  1221. .readdir = jfs_readdir,
  1222. .fsync = jfs_fsync,
  1223. };