dirhash.c 6.4 KB

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