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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Cache operations for Coda.
  3.  * For Linux 2.1: (C) 1997 Carnegie Mellon University
  4.  * For Linux 2.3: (C) 2000 Carnegie Mellon University
  5.  *
  6.  * Carnegie Mellon encourages users of this code to contribute improvements
  7.  * to the Coda project http://www.coda.cs.cmu.edu/ <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/stat.h>
  14. #include <linux/errno.h>
  15. #include <linux/locks.h>
  16. #include <asm/uaccess.h>
  17. #include <linux/string.h>
  18. #include <linux/list.h>
  19. #include <linux/coda.h>
  20. #include <linux/coda_linux.h>
  21. #include <linux/coda_psdev.h>
  22. #include <linux/coda_fs_i.h>
  23. #include <linux/coda_cache.h>
  24. /* replace or extend an acl cache hit */
  25. void coda_cache_enter(struct inode *inode, int mask)
  26. {
  27. struct coda_inode_info *cii = ITOC(inode);
  28.         if ( !coda_cred_ok(&cii->c_cached_cred) ) {
  29.                 coda_load_creds(&cii->c_cached_cred);
  30.                 cii->c_cached_perm = mask;
  31.         } else
  32.                 cii->c_cached_perm |= mask;
  33. }
  34. /* remove cached acl from an inode */
  35. void coda_cache_clear_inode(struct inode *inode)
  36. {
  37. struct coda_inode_info *cii = ITOC(inode);
  38.         cii->c_cached_perm = 0;
  39. }
  40. /* remove all acl caches for a principal (or all principals when cred == NULL)*/
  41. void coda_cache_clear_all(struct super_block *sb, struct coda_cred *cred)
  42. {
  43.         struct coda_sb_info *sbi;
  44.         struct coda_inode_info *cii;
  45.         struct list_head *tmp;
  46.         sbi = coda_sbp(sb);
  47.         if (!sbi) BUG();
  48.         list_for_each(tmp, &sbi->sbi_cihead)
  49.         {
  50. cii = list_entry(tmp, struct coda_inode_info, c_cilist);
  51.                 if (!cred || coda_cred_eq(cred, &cii->c_cached_cred))
  52.                         cii->c_cached_perm = 0;
  53. }
  54. }
  55. /* check if the mask has been matched against the acl already */
  56. int coda_cache_check(struct inode *inode, int mask)
  57. {
  58. struct coda_inode_info *cii = ITOC(inode);
  59.         int hit;
  60.         hit = ((mask & cii->c_cached_perm) == mask) &&
  61.                 coda_cred_ok(&cii->c_cached_cred);
  62.         CDEBUG(D_CACHE, "%s for ino %ldn", hit ? "HIT" : "MISS", inode->i_ino);
  63.         return hit;
  64. }
  65. /* Purging dentries and children */
  66. /* The following routines drop dentries which are not
  67.    in use and flag dentries which are in use to be 
  68.    zapped later.
  69.    The flags are detected by:
  70.    - coda_dentry_revalidate (for lookups) if the flag is C_PURGE
  71.    - coda_dentry_delete: to remove dentry from the cache when d_count
  72.      falls to zero
  73.    - an inode method coda_revalidate (for attributes) if the 
  74.      flag is C_VATTR
  75. */
  76. /* this won't do any harm: just flag all children */
  77. static void coda_flag_children(struct dentry *parent, int flag)
  78. {
  79. struct list_head *child;
  80. struct dentry *de;
  81. spin_lock(&dcache_lock);
  82. list_for_each(child, &parent->d_subdirs)
  83. {
  84. de = list_entry(child, struct dentry, d_child);
  85. /* don't know what to do with negative dentries */
  86. if ( ! de->d_inode ) 
  87. continue;
  88. CDEBUG(D_DOWNCALL, "%d for %*s/%*sn", flag, 
  89.        de->d_name.len, de->d_name.name, 
  90.        de->d_parent->d_name.len, de->d_parent->d_name.name);
  91. coda_flag_inode(de->d_inode, flag);
  92. }
  93. spin_unlock(&dcache_lock);
  94. return; 
  95. }
  96. void coda_flag_inode_children(struct inode *inode, int flag)
  97. {
  98. struct dentry *alias_de;
  99. if ( !inode || !S_ISDIR(inode->i_mode)) 
  100. return; 
  101. alias_de = d_find_alias(inode);
  102. if (!alias_de)
  103. return;
  104. coda_flag_children(alias_de, flag);
  105. shrink_dcache_parent(alias_de);
  106. dput(alias_de);
  107. }