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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Directory operations for Coda filesystem
  3.  * Original version: (C) 1996 P. Braam and M. Callahan
  4.  * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University
  5.  * 
  6.  * Carnegie Mellon encourages users to contribute improvements to
  7.  * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
  8.  */
  9. #include <linux/types.h>
  10. #include <linux/kernel.h>
  11. #include <linux/sched.h>
  12. #include <linux/fs.h>
  13. #include <linux/file.h>
  14. #include <linux/stat.h>
  15. #include <linux/errno.h>
  16. #include <linux/locks.h>
  17. #include <linux/string.h>
  18. #include <linux/smp_lock.h>
  19. #include <asm/uaccess.h>
  20. #include <linux/coda.h>
  21. #include <linux/coda_linux.h>
  22. #include <linux/coda_psdev.h>
  23. #include <linux/coda_fs_i.h>
  24. #include <linux/coda_cache.h>
  25. #include <linux/coda_proc.h>
  26. /* dir inode-ops */
  27. static int coda_create(struct inode *dir, struct dentry *new, int mode);
  28. static int coda_mknod(struct inode *dir, struct dentry *new, int mode, int rdev);
  29. static struct dentry *coda_lookup(struct inode *dir, struct dentry *target);
  30. static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, 
  31.      struct dentry *entry);
  32. static int coda_unlink(struct inode *dir_inode, struct dentry *entry);
  33. static int coda_symlink(struct inode *dir_inode, struct dentry *entry,
  34. const char *symname);
  35. static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, int mode);
  36. static int coda_rmdir(struct inode *dir_inode, struct dentry *entry);
  37. static int coda_rename(struct inode *old_inode, struct dentry *old_dentry, 
  38.                        struct inode *new_inode, struct dentry *new_dentry);
  39. /* dir file-ops */
  40. static int coda_readdir(struct file *file, void *dirent, filldir_t filldir);
  41. /* dentry ops */
  42. static int coda_dentry_revalidate(struct dentry *de, int);
  43. static int coda_dentry_delete(struct dentry *);
  44. /* support routines */
  45. static int coda_venus_readdir(struct file *filp, filldir_t filldir,
  46.       void *dirent, struct dentry *dir);
  47. int coda_fsync(struct file *, struct dentry *dentry, int datasync);
  48. int coda_hasmknod;
  49. struct dentry_operations coda_dentry_operations =
  50. {
  51. d_revalidate: coda_dentry_revalidate,
  52. d_delete: coda_dentry_delete,
  53. };
  54. struct inode_operations coda_dir_inode_operations =
  55. {
  56. create: coda_create,
  57. lookup: coda_lookup,
  58. link: coda_link,
  59. unlink: coda_unlink,
  60. symlink: coda_symlink,
  61. mkdir: coda_mkdir,
  62. rmdir: coda_rmdir,
  63. mknod: coda_mknod,
  64. rename: coda_rename,
  65. permission: coda_permission,
  66.         revalidate: coda_revalidate_inode,
  67. setattr: coda_notify_change,
  68. };
  69. struct file_operations coda_dir_operations = {
  70. read: generic_read_dir,
  71. readdir: coda_readdir,
  72. open: coda_open,
  73. flush:   coda_flush,
  74. release: coda_release,
  75. fsync: coda_fsync,
  76. };
  77. /* inode operations for directories */
  78. /* access routines: lookup, readlink, permission */
  79. static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
  80. {
  81. struct inode *res_inode = NULL;
  82. struct ViceFid resfid = {0,0,0};
  83. int dropme = 0; /* to indicate entry should not be cached */
  84. int type = 0;
  85. int error = 0;
  86. const char *name = entry->d_name.name;
  87. size_t length = entry->d_name.len;
  88. if ( length > CODA_MAXNAMLEN ) {
  89.         printk("name too long: lookup, %s (%*s)n", 
  90.        coda_i2s(dir), (int)length, name);
  91. return ERR_PTR(-ENAMETOOLONG);
  92. }
  93.         CDEBUG(D_INODE, "name %s, len %ld in ino %ld, fid %sn", 
  94.        name, (long)length, dir->i_ino, coda_i2s(dir));
  95.         /* control object, create inode on the fly */
  96.         if (coda_isroot(dir) && coda_iscontrol(name, length)) {
  97.         error = coda_cnode_makectl(&res_inode, dir->i_sb);
  98. CDEBUG(D_SPECIAL, 
  99.        "Lookup on CTL object; dir ino %ld, count %dn", 
  100.        dir->i_ino, atomic_read(&dir->i_count));
  101. dropme = 1;
  102.                 goto exit;
  103.         }
  104. error = venus_lookup(dir->i_sb, coda_i2f(dir), 
  105.      (const char *)name, length, &type, &resfid);
  106. res_inode = NULL;
  107. if (!error) {
  108. if (type & CODA_NOCACHE) {
  109. type &= (~CODA_NOCACHE);
  110. CDEBUG(D_INODE, "dropme set for %sn", 
  111.        coda_f2s(&resfid));
  112. dropme = 1;
  113. }
  114.      error = coda_cnode_make(&res_inode, &resfid, dir->i_sb);
  115. if (error) return ERR_PTR(error);
  116. } else if (error != -ENOENT) {
  117.         CDEBUG(D_INODE, "error for %s(%*s)%dn",
  118.        coda_i2s(dir), (int)length, name, error);
  119. return ERR_PTR(error);
  120. }
  121. CDEBUG(D_INODE, "lookup: %s is (%s), type %d result %d, dropme %dn",
  122.        name, coda_f2s(&resfid), type, error, dropme);
  123. exit:
  124. entry->d_time = 0;
  125. entry->d_op = &coda_dentry_operations;
  126. d_add(entry, res_inode);
  127. if ( dropme ) {
  128. d_drop(entry);
  129. coda_flag_inode(res_inode, C_VATTR);
  130. }
  131.         return NULL;
  132. }
  133. int coda_permission(struct inode *inode, int mask)
  134. {
  135.         int error;
  136.  
  137. coda_vfs_stat.permission++;
  138.         if ( mask == 0 )
  139.                 return 0;
  140. if ( coda_access_cache ) {
  141. coda_permission_stat.count++;
  142. if ( coda_cache_check(inode, mask) ) {
  143. coda_permission_stat.hit_count++;
  144. return 0; 
  145. }
  146. }
  147.         CDEBUG(D_INODE, "mask is %on", mask);
  148.         error = venus_access(inode->i_sb, coda_i2f(inode), mask);
  149.     
  150.         CDEBUG(D_INODE, "fid: %s, ino: %ld (mask: %o) error: %dn", 
  151.        coda_i2s(inode), inode->i_ino, mask, error);
  152. if (!error)
  153. coda_cache_enter(inode, mask);
  154.         return error; 
  155. }
  156. static inline void coda_dir_changed(struct inode *dir, int link)
  157. {
  158. #ifdef REQUERY_VENUS_FOR_MTIME
  159. /* invalidate the directory cnode's attributes so we refetch the
  160.  * attributes from venus next time the inode is referenced */
  161. coda_flag_inode(dir, C_VATTR);
  162. #else
  163. /* optimistically we can also act as if our nose bleeds. The
  164.          * granularity of the mtime is coarse anyways so we might actually be
  165.          * right most of the time. Note: we only do this for directories. */
  166. dir->i_mtime = dir->i_ctime = CURRENT_TIME;
  167. #endif
  168. if (link)
  169. dir->i_nlink += link;
  170. }
  171. /* creation routines: create, mknod, mkdir, link, symlink */
  172. static int coda_create(struct inode *dir, struct dentry *de, int mode)
  173. {
  174.         int error=0;
  175. const char *name=de->d_name.name;
  176. int length=de->d_name.len;
  177. struct inode *inode;
  178. struct ViceFid newfid;
  179. struct coda_vattr attrs;
  180. coda_vfs_stat.create++;
  181. CDEBUG(D_INODE, "name: %s, length %d, mode %on", name, length, mode);
  182. if (coda_isroot(dir) && coda_iscontrol(name, length))
  183. return -EPERM;
  184. error = venus_create(dir->i_sb, coda_i2f(dir), name, length, 
  185. 0, mode, 0, &newfid, &attrs);
  186.         if ( error ) {
  187. CDEBUG(D_INODE, "create: %s, result %dn",
  188.        coda_f2s(&newfid), error); 
  189. d_drop(de);
  190. return error;
  191. }
  192. inode = coda_iget(dir->i_sb, &newfid, &attrs);
  193. if ( IS_ERR(inode) ) {
  194. d_drop(de);
  195. return PTR_ERR(inode);
  196. }
  197. /* invalidate the directory cnode's attributes */
  198. coda_dir_changed(dir, 0);
  199. d_instantiate(de, inode);
  200.         return 0;
  201. }
  202. static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
  203. {
  204.         int error=0;
  205. const char *name=de->d_name.name;
  206. int length=de->d_name.len;
  207. struct inode *inode;
  208. struct ViceFid newfid;
  209. struct coda_vattr attrs;
  210. if ( coda_hasmknod == 0 )
  211. return -EIO;
  212. coda_vfs_stat.create++;
  213. CDEBUG(D_INODE, "name: %s, length %d, mode %o, rdev %xn",
  214.        name, length, mode, rdev);
  215. if (coda_isroot(dir) && coda_iscontrol(name, length))
  216. return -EPERM;
  217. error = venus_create(dir->i_sb, coda_i2f(dir), name, length, 
  218. 0, mode, rdev, &newfid, &attrs);
  219.         if ( error ) {
  220. CDEBUG(D_INODE, "mknod: %s, result %dn",
  221.        coda_f2s(&newfid), error); 
  222. d_drop(de);
  223. return error;
  224. }
  225. inode = coda_iget(dir->i_sb, &newfid, &attrs);
  226. if ( IS_ERR(inode) ) {
  227. d_drop(de);
  228. return PTR_ERR(inode);
  229. }
  230. /* invalidate the directory cnode's attributes */
  231. coda_dir_changed(dir, 0);
  232. d_instantiate(de, inode);
  233.         return 0;
  234. }      
  235. static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
  236. {
  237. struct inode *inode;
  238. struct coda_vattr attrs;
  239. const char *name = de->d_name.name;
  240. int len = de->d_name.len;
  241. int error;
  242. struct ViceFid newfid;
  243. coda_vfs_stat.mkdir++;
  244. if (coda_isroot(dir) && coda_iscontrol(name, len))
  245. return -EPERM;
  246. CDEBUG(D_INODE, "mkdir %s (len %d) in %s, mode %o.n", 
  247.        name, len, coda_i2s(dir), mode);
  248. attrs.va_mode = mode;
  249. error = venus_mkdir(dir->i_sb, coda_i2f(dir), 
  250.        name, len, &newfid, &attrs);
  251.         
  252.         if ( error ) {
  253.         CDEBUG(D_INODE, "mkdir error: %s result %dn", 
  254.        coda_f2s(&newfid), error); 
  255. d_drop(de);
  256.                 return error;
  257.         }
  258.          
  259. CDEBUG(D_INODE, "mkdir: new dir has fid %s.n", 
  260.        coda_f2s(&newfid)); 
  261. inode = coda_iget(dir->i_sb, &newfid, &attrs);
  262. if ( IS_ERR(inode) ) {
  263. d_drop(de);
  264. return PTR_ERR(inode);
  265. }
  266. /* invalidate the directory cnode's attributes */
  267. coda_dir_changed(dir, 1);
  268. d_instantiate(de, inode);
  269.         return 0;
  270. }
  271. /* try to make de an entry in dir_inodde linked to source_de */ 
  272. static int coda_link(struct dentry *source_de, struct inode *dir_inode, 
  273.   struct dentry *de)
  274. {
  275. struct inode *inode = source_de->d_inode;
  276.         const char * name = de->d_name.name;
  277. int len = de->d_name.len;
  278. int error;
  279. coda_vfs_stat.link++;
  280. if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
  281. return -EPERM;
  282. CDEBUG(D_INODE, "old: fid: %sn", coda_i2s(inode));
  283. CDEBUG(D_INODE, "directory: %sn", coda_i2s(dir_inode));
  284. error = venus_link(dir_inode->i_sb, coda_i2f(inode),
  285.    coda_i2f(dir_inode), (const char *)name, len);
  286. if (error) { 
  287. d_drop(de);
  288. goto out;
  289. }
  290. coda_dir_changed(dir_inode, 0);
  291. atomic_inc(&inode->i_count);
  292. d_instantiate(de, inode);
  293. inode->i_nlink++;
  294.         
  295. out:
  296. CDEBUG(D_INODE, "link result %dn",error);
  297. return(error);
  298. }
  299. static int coda_symlink(struct inode *dir_inode, struct dentry *de,
  300. const char *symname)
  301. {
  302.         const char *name = de->d_name.name;
  303. int len = de->d_name.len;
  304. int symlen;
  305.         int error=0;
  306.         
  307. coda_vfs_stat.symlink++;
  308. if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
  309. return -EPERM;
  310. symlen = strlen(symname);
  311. if ( symlen > CODA_MAXPATHLEN )
  312.                 return -ENAMETOOLONG;
  313.         CDEBUG(D_INODE, "symname: %s, length: %dn", symname, symlen);
  314. /*
  315.  * This entry is now negative. Since we do not create
  316.  * an inode for the entry we have to drop it. 
  317.  */
  318. d_drop(de);
  319. error = venus_symlink(dir_inode->i_sb, coda_i2f(dir_inode), name, len, 
  320.       symname, symlen);
  321. /* mtime is no good anymore */
  322. if ( !error )
  323. coda_dir_changed(dir_inode, 0);
  324.         CDEBUG(D_INODE, "in symlink result %dn",error);
  325.         return error;
  326. }
  327. /* destruction routines: unlink, rmdir */
  328. int coda_unlink(struct inode *dir, struct dentry *de)
  329. {
  330.         int error;
  331. const char *name = de->d_name.name;
  332. int len = de->d_name.len;
  333. coda_vfs_stat.unlink++;
  334.         CDEBUG(D_INODE, " %s in %s, dirino %ldn", name , 
  335.        coda_i2s(dir), dir->i_ino);
  336.         error = venus_remove(dir->i_sb, coda_i2f(dir), name, len);
  337.         if ( error ) {
  338.                 CDEBUG(D_INODE, "upc returned error %dn", error);
  339.                 return error;
  340.         }
  341. coda_dir_changed(dir, 0);
  342. de->d_inode->i_nlink--;
  343.         return 0;
  344. }
  345. int coda_rmdir(struct inode *dir, struct dentry *de)
  346. {
  347. const char *name = de->d_name.name;
  348. int len = de->d_name.len;
  349.         int error;
  350. coda_vfs_stat.rmdir++;
  351. if (!d_unhashed(de))
  352. return -EBUSY;
  353. error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
  354.         if ( error ) {
  355.                 CDEBUG(D_INODE, "upc returned error %dn", error);
  356.                 return error;
  357.         }
  358. coda_dir_changed(dir, -1);
  359. de->d_inode->i_nlink--;
  360. d_delete(de);
  361.         return 0;
  362. }
  363. /* rename */
  364. static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, 
  365.        struct inode *new_dir, struct dentry *new_dentry)
  366. {
  367.         const char *old_name = old_dentry->d_name.name;
  368.         const char *new_name = new_dentry->d_name.name;
  369. int old_length = old_dentry->d_name.len;
  370. int new_length = new_dentry->d_name.len;
  371.         int link_adjust = 0;
  372.         int error;
  373. coda_vfs_stat.rename++;
  374.         CDEBUG(D_INODE, "old: %s, (%d length), new: %s"
  375.        "(%d length). old:d_count: %d, new:d_count: %dn", 
  376.        old_name, old_length, new_name, new_length,
  377.        atomic_read(&old_dentry->d_count), atomic_read(&new_dentry->d_count));
  378.         error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), 
  379.      coda_i2f(new_dir), old_length, new_length, 
  380.      (const char *) old_name, (const char *)new_name);
  381.         if ( !error ) {
  382. if ( new_dentry->d_inode ) {
  383. if ( S_ISDIR(new_dentry->d_inode->i_mode) )
  384.                          link_adjust = 1;
  385.                         coda_dir_changed(old_dir, -link_adjust);
  386.                         coda_dir_changed(new_dir,  link_adjust);
  387. coda_flag_inode(new_dentry->d_inode, C_VATTR);
  388. } else {
  389. coda_flag_inode(old_dir, C_VATTR);
  390. coda_flag_inode(new_dir, C_VATTR);
  391.                 }
  392. }
  393. CDEBUG(D_INODE, "result %dn", error); 
  394. return error;
  395. }
  396. /* file operations for directories */
  397. int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir)
  398. {
  399. struct dentry *coda_dentry = coda_file->f_dentry;
  400. struct coda_file_info *cfi;
  401. struct file *host_file;
  402. int ret;
  403. cfi = CODA_FTOC(coda_file);
  404. if (!cfi || cfi->cfi_magic != CODA_MAGIC) BUG();
  405. host_file = cfi->cfi_container;
  406. coda_vfs_stat.readdir++;
  407. down(&host_file->f_dentry->d_inode->i_sem);
  408. host_file->f_pos = coda_file->f_pos;
  409. if ( !host_file->f_op->readdir ) {
  410. /* Venus: we must read Venus dirents from the file */
  411. ret = coda_venus_readdir(host_file, filldir, dirent, coda_dentry);
  412. } else {
  413. /* potemkin case: we were handed a directory inode */
  414. ret = vfs_readdir(host_file, filldir, dirent);
  415. }
  416. coda_file->f_pos = host_file->f_pos;
  417. up(&host_file->f_dentry->d_inode->i_sem);
  418. return ret;
  419. }
  420. static inline unsigned int CDT2DT(unsigned char cdt)
  421. {
  422. unsigned int dt;
  423. switch(cdt) {
  424. case CDT_UNKNOWN: dt = DT_UNKNOWN; break;
  425. case CDT_FIFO:   dt = DT_FIFO;    break;
  426. case CDT_CHR:   dt = DT_CHR;     break;
  427. case CDT_DIR:   dt = DT_DIR;     break;
  428. case CDT_BLK:   dt = DT_BLK;     break;
  429. case CDT_REG:   dt = DT_REG;     break;
  430. case CDT_LNK:   dt = DT_LNK;     break;
  431. case CDT_SOCK:   dt = DT_SOCK;    break;
  432. case CDT_WHT:   dt = DT_WHT;     break;
  433. default:   dt = DT_UNKNOWN; break;
  434. }
  435. return dt;
  436. }
  437. /* support routines */
  438. static int coda_venus_readdir(struct file *filp, filldir_t filldir,
  439.       void *dirent, struct dentry *dir)
  440. {
  441. int result = 0; /* # of entries returned */
  442. struct venus_dirent *vdir;
  443. unsigned long vdir_size =
  444.     (unsigned long)(&((struct venus_dirent *)0)->d_name);
  445. unsigned int type;
  446. struct qstr name;
  447. ino_t ino;
  448. int ret, i;
  449. vdir = (struct venus_dirent *)kmalloc(sizeof(*vdir), GFP_KERNEL);
  450. if (!vdir) return -ENOMEM;
  451. i = filp->f_pos;
  452. switch(i) {
  453. case 0:
  454. ret = filldir(dirent, ".", 1, 0, dir->d_inode->i_ino, DT_DIR);
  455. if (ret < 0) break;
  456. result++;
  457. filp->f_pos++;
  458. /* fallthrough */
  459. case 1:
  460. ret = filldir(dirent, "..", 2, 1, dir->d_parent->d_inode->i_ino, DT_DIR);
  461. if (ret < 0) break;
  462. result++;
  463. filp->f_pos++;
  464. /* fallthrough */
  465. default:
  466. while (1) {
  467. /* read entries from the directory file */
  468. ret = kernel_read(filp, filp->f_pos - 2, (char *)vdir,
  469.   sizeof(*vdir));
  470. if (ret < 0) {
  471. printk("coda_venus_readdir: read dir failed %dn", ret);
  472. break;
  473. }
  474. if (ret == 0) break; /* end of directory file reached */
  475. /* catch truncated reads */
  476. if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) {
  477. printk("coda_venus_readdir: short read: %ldn",
  478.        filp->f_dentry->d_inode->i_ino);
  479. ret = -EBADF;
  480. break;
  481. }
  482. /* validate whether the directory file actually makes sense */
  483. if (vdir->d_reclen < vdir_size + vdir->d_namlen ||
  484.     vdir->d_namlen > CODA_MAXNAMLEN) {
  485. printk("coda_venus_readdir: Invalid dir: %ldn",
  486.        filp->f_dentry->d_inode->i_ino);
  487. ret = -EBADF;
  488. break;
  489. }
  490. name.len = vdir->d_namlen;
  491. name.name = vdir->d_name;
  492. /* Make sure we skip '.' and '..', we already got those */
  493. if (name.name[0] == '.' && (name.len == 1 ||
  494.     (vdir->d_name[1] == '.' && name.len == 2)))
  495. vdir->d_fileno = name.len = 0;
  496. /* skip null entries */
  497. if (vdir->d_fileno && name.len) {
  498. /* try to look up this entry in the dcache, that way
  499.  * userspace doesn't have to worry about breaking
  500.  * getcwd by having mismatched inode numbers for
  501.  * internal volume mountpoints. */
  502. ino = find_inode_number(dir, &name);
  503. if (!ino) ino = vdir->d_fileno;
  504. type = CDT2DT(vdir->d_type);
  505. ret = filldir(dirent, name.name, name.len, filp->f_pos,
  506.       ino, type); 
  507. /* failure means no space for filling in this round */
  508. if (ret < 0) break;
  509. result++;
  510. }
  511. /* we'll always have progress because d_reclen is unsigned and
  512.  * we've already established it is non-zero. */
  513. filp->f_pos += vdir->d_reclen;
  514. }
  515. kfree(vdir);
  516. return result ? result : ret;
  517. }
  518. /* called when a cache lookup succeeds */
  519. static int coda_dentry_revalidate(struct dentry *de, int flags)
  520. {
  521. struct inode *inode = de->d_inode;
  522. struct coda_inode_info *cii;
  523. if (!inode)
  524. return 1;
  525. lock_kernel();
  526. if (coda_isroot(inode))
  527. goto out;
  528. if (is_bad_inode(inode))
  529. goto bad;
  530. cii = ITOC(de->d_inode);
  531. if (!(cii->c_flags & (C_PURGE | C_FLUSH)))
  532. goto out;
  533. shrink_dcache_parent(de);
  534. /* propagate for a flush */
  535. if (cii->c_flags & C_FLUSH) 
  536. coda_flag_inode_children(inode, C_FLUSH);
  537. if (atomic_read(&de->d_count) > 1) {
  538. /* pretend it's valid, but don't change the flags */
  539. CDEBUG(D_DOWNCALL, "BOOM for: ino %ld, %sn",
  540.        de->d_inode->i_ino, coda_f2s(&cii->c_fid));
  541. goto out;
  542. }
  543. /* clear the flags. */
  544. cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
  545. bad:
  546. unlock_kernel();
  547. return 0;
  548. out:
  549. unlock_kernel();
  550. return 1;
  551. }
  552. /*
  553.  * This is the callback from dput() when d_count is going to 0.
  554.  * We use this to unhash dentries with bad inodes.
  555.  */
  556. static int coda_dentry_delete(struct dentry * dentry)
  557. {
  558. int flags;
  559. if (!dentry->d_inode) 
  560. return 0;
  561. flags = (ITOC(dentry->d_inode)->c_flags) & C_PURGE;
  562. if (is_bad_inode(dentry->d_inode) || flags) {
  563. CDEBUG(D_DOWNCALL, "bad inode, unhashing %s/%s, %ldn", 
  564.        dentry->d_parent->d_name.name, dentry->d_name.name,
  565.        dentry->d_inode->i_ino);
  566. return 1;
  567. }
  568. return 0;
  569. }
  570. /*
  571.  * This is called when we want to check if the inode has
  572.  * changed on the server.  Coda makes this easy since the
  573.  * cache manager Venus issues a downcall to the kernel when this 
  574.  * happens 
  575.  */
  576. int coda_revalidate_inode(struct dentry *dentry)
  577. {
  578. struct coda_vattr attr;
  579. int error = 0;
  580. int old_mode;
  581. ino_t old_ino;
  582. struct inode *inode = dentry->d_inode;
  583. struct coda_inode_info *cii = ITOC(inode);
  584. CDEBUG(D_INODE, "revalidating: %*s/%*sn", 
  585.        dentry->d_name.len, dentry->d_name.name,
  586.        dentry->d_parent->d_name.len, dentry->d_parent->d_name.name);
  587. lock_kernel();
  588. if ( !cii->c_flags )
  589. goto ok;
  590. if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
  591. error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
  592. if ( error )
  593. goto return_bad_inode;
  594. /* this inode may be lost if:
  595.    - it's ino changed 
  596.    - type changes must be permitted for repair and
  597.    missing mount points.
  598. */
  599. old_mode = inode->i_mode;
  600. old_ino = inode->i_ino;
  601. coda_vattr_to_iattr(inode, &attr);
  602. if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) {
  603. printk("Coda: inode %ld, fid %s changed type!n",
  604.        inode->i_ino, coda_f2s(&(cii->c_fid)));
  605. }
  606. /* the following can happen when a local fid is replaced 
  607.    with a global one, here we lose and declare the inode bad */
  608. if (inode->i_ino != old_ino)
  609. goto return_bad_inode;
  610. coda_flag_inode_children(inode, C_FLUSH);
  611. cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
  612. }
  613. ok:
  614. unlock_kernel();
  615. return 0;
  616. return_bad_inode:
  617. unlock_kernel();
  618. return -EIO;
  619. }