dirhash.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /* -*- linux-c -*- --------------------------------------------------------- *
  2. *
  3. * linux/fs/autofs/dirhash.c
  4. *
  5. * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
  6. *
  7. * This file is part of the Linux kernel and is made available under
  8. * the terms of the GNU General Public License, version 2, or at your
  9. * option, any later version, incorporated herein by reference.
  10. *
  11. * ------------------------------------------------------------------------- */
  12. #include "autofs_i.h"
  13. /* Functions for maintenance of expiry queue */
  14. static void autofs_init_usage(struct autofs_dirhash *dh,
  15. struct autofs_dir_ent *ent)
  16. {
  17. list_add_tail(&ent->exp, &dh->expiry_head);
  18. ent->last_usage = jiffies;
  19. }
  20. static void autofs_delete_usage(struct autofs_dir_ent *ent)
  21. {
  22. list_del(&ent->exp);
  23. }
  24. void autofs_update_usage(struct autofs_dirhash *dh,
  25. struct autofs_dir_ent *ent)
  26. {
  27. autofs_delete_usage(ent); /* Unlink from current position */
  28. autofs_init_usage(dh,ent); /* Relink at queue tail */
  29. }
  30. struct autofs_dir_ent *autofs_expire(struct super_block *sb,
  31. struct autofs_sb_info *sbi,
  32. struct vfsmount *mnt)
  33. {
  34. struct autofs_dirhash *dh = &sbi->dirhash;
  35. struct autofs_dir_ent *ent;
  36. struct dentry *dentry;
  37. unsigned long timeout = sbi->exp_timeout;
  38. while (1) {
  39. if ( list_empty(&dh->expiry_head) || sbi->catatonic )
  40. return NULL; /* No entries */
  41. /* We keep the list sorted by last_usage and want old stuff */
  42. ent = list_entry(dh->expiry_head.next, struct autofs_dir_ent, exp);
  43. if (jiffies - ent->last_usage < timeout)
  44. break;
  45. /* Move to end of list in case expiry isn't desirable */
  46. autofs_update_usage(dh, ent);
  47. /* Check to see that entry is expirable */
  48. if ( ent->ino < AUTOFS_FIRST_DIR_INO )
  49. return ent; /* Symlinks are always expirable */
  50. /* Get the dentry for the autofs subdirectory */
  51. dentry = ent->dentry;
  52. if ( !dentry ) {
  53. /* Should only happen in catatonic mode */
  54. printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name);
  55. autofs_delete_usage(ent);
  56. continue;
  57. }
  58. if ( !dentry->d_inode ) {
  59. dput(dentry);
  60. printk("autofs: negative dentry on expiry queue: %s\n",
  61. ent->name);
  62. autofs_delete_usage(ent);
  63. continue;
  64. }
  65. /* Make sure entry is mounted and unused; note that dentry will
  66. point to the mounted-on-top root. */
  67. if (!S_ISDIR(dentry->d_inode->i_mode)||!d_mountpoint(dentry)) {
  68. DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
  69. continue;
  70. }
  71. mntget(mnt);
  72. dget(dentry);
  73. if (!follow_down(&mnt, &dentry)) {
  74. dput(dentry);
  75. mntput(mnt);
  76. DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
  77. continue;
  78. }
  79. while (d_mountpoint(dentry) && follow_down(&mnt, &dentry))
  80. ;
  81. dput(dentry);
  82. if ( may_umount(mnt) ) {
  83. mntput(mnt);
  84. DPRINTK(("autofs: signaling expire on %s\n", ent->name));
  85. return ent; /* Expirable! */
  86. }
  87. DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name));
  88. mntput(mnt);
  89. }
  90. return NULL; /* No expirable entries */
  91. }
  92. void autofs_initialize_hash(struct autofs_dirhash *dh) {
  93. memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *));
  94. INIT_LIST_HEAD(&dh->expiry_head);
  95. }
  96. struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, struct qstr *name)
  97. {
  98. struct autofs_dir_ent *dhn;
  99. DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", name->hash));
  100. autofs_say(name->name,name->len);
  101. for ( dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE] ; dhn ; dhn = dhn->next ) {
  102. if ( name->hash == dhn->hash &&
  103. name->len == dhn->len &&
  104. !memcmp(name->name, dhn->name, name->len) )
  105. break;
  106. }
  107. return dhn;
  108. }
  109. void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent)
  110. {
  111. struct autofs_dir_ent **dhnp;
  112. DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash));
  113. autofs_say(ent->name,ent->len);
  114. autofs_init_usage(dh,ent);
  115. if (ent->dentry)
  116. dget(ent->dentry);
  117. dhnp = &dh->h[(unsigned) ent->hash % AUTOFS_HASH_SIZE];
  118. ent->next = *dhnp;
  119. ent->back = dhnp;
  120. *dhnp = ent;
  121. if ( ent->next )
  122. ent->next->back = &(ent->next);
  123. }
  124. void autofs_hash_delete(struct autofs_dir_ent *ent)
  125. {
  126. *(ent->back) = ent->next;
  127. if ( ent->next )
  128. ent->next->back = ent->back;
  129. autofs_delete_usage(ent);
  130. if ( ent->dentry )
  131. dput(ent->dentry);
  132. kfree(ent->name);
  133. kfree(ent);
  134. }
  135. /*
  136. * Used by readdir(). We must validate "ptr", so we can't simply make it
  137. * a pointer. Values below 0xffff are reserved; calling with any value
  138. * <= 0x10000 will return the first entry found.
  139. *
  140. * "last" can be NULL or the value returned by the last search *if* we
  141. * want the next sequential entry.
  142. */
  143. struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh,
  144. off_t *ptr, struct autofs_dir_ent *last)
  145. {
  146. int bucket, ecount, i;
  147. struct autofs_dir_ent *ent;
  148. bucket = (*ptr >> 16) - 1;
  149. ecount = *ptr & 0xffff;
  150. if ( bucket < 0 ) {
  151. bucket = ecount = 0;
  152. }
  153. DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount));
  154. ent = last ? last->next : NULL;
  155. if ( ent ) {
  156. ecount++;
  157. } else {
  158. while ( bucket < AUTOFS_HASH_SIZE ) {
  159. ent = dh->h[bucket];
  160. for ( i = ecount ; ent && i ; i-- )
  161. ent = ent->next;
  162. if (ent) {
  163. ecount++; /* Point to *next* entry */
  164. break;
  165. }
  166. bucket++; ecount = 0;
  167. }
  168. }
  169. #ifdef DEBUG
  170. if ( !ent )
  171. printk("autofs_hash_enum: nothing found\n");
  172. else {
  173. printk("autofs_hash_enum: found hash %08x, name", ent->hash);
  174. autofs_say(ent->name,ent->len);
  175. }
  176. #endif
  177. *ptr = ((bucket+1) << 16) + ecount;
  178. return ent;
  179. }
  180. /* Iterate over all the ents, and remove all dentry pointers. Used on
  181. entering catatonic mode, in order to make the filesystem unmountable. */
  182. void autofs_hash_dputall(struct autofs_dirhash *dh)
  183. {
  184. int i;
  185. struct autofs_dir_ent *ent;
  186. for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
  187. for ( ent = dh->h[i] ; ent ; ent = ent->next ) {
  188. if ( ent->dentry ) {
  189. dput(ent->dentry);
  190. ent->dentry = NULL;
  191. }
  192. }
  193. }
  194. }
  195. /* Delete everything. This is used on filesystem destruction, so we
  196. make no attempt to keep the pointers valid */
  197. void autofs_hash_nuke(struct autofs_sb_info *sbi)
  198. {
  199. int i;
  200. struct autofs_dir_ent *ent, *nent;
  201. for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
  202. for ( ent = sbi->dirhash.h[i] ; ent ; ent = nent ) {
  203. nent = ent->next;
  204. if ( ent->dentry )
  205. dput(ent->dentry);
  206. kfree(ent->name);
  207. kfree(ent);
  208. }
  209. }
  210. }