dentry.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * fs/sdcardfs/dentry.c
  3. *
  4. * Copyright (c) 2013 Samsung Electronics Co. Ltd
  5. * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun,
  6. * Sunghwan Yun, Sungjong Seo
  7. *
  8. * This program has been developed as a stackable file system based on
  9. * the WrapFS which written by
  10. *
  11. * Copyright (c) 1998-2011 Erez Zadok
  12. * Copyright (c) 2009 Shrikar Archak
  13. * Copyright (c) 2003-2011 Stony Brook University
  14. * Copyright (c) 2003-2011 The Research Foundation of SUNY
  15. *
  16. * This file is dual licensed. It may be redistributed and/or modified
  17. * under the terms of the Apache 2.0 License OR version 2 of the GNU
  18. * General Public License.
  19. */
  20. #include "sdcardfs.h"
  21. #include "linux/ctype.h"
  22. /*
  23. * returns: -ERRNO if error (returned to user)
  24. * 0: tell VFS to invalidate dentry
  25. * 1: dentry is valid
  26. */
  27. static int sdcardfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
  28. {
  29. int err = 1;
  30. struct path parent_lower_path, lower_path;
  31. struct dentry *parent_dentry = NULL;
  32. struct dentry *parent_lower_dentry = NULL;
  33. struct dentry *lower_cur_parent_dentry = NULL;
  34. struct dentry *lower_dentry = NULL;
  35. struct inode *inode;
  36. struct sdcardfs_inode_data *data;
  37. if (nd && nd->flags & LOOKUP_RCU)
  38. return -ECHILD;
  39. spin_lock(&dentry->d_lock);
  40. if (IS_ROOT(dentry)) {
  41. spin_unlock(&dentry->d_lock);
  42. return 1;
  43. }
  44. spin_unlock(&dentry->d_lock);
  45. /* check uninitialized obb_dentry and
  46. * whether the base obbpath has been changed or not
  47. */
  48. if (is_obbpath_invalid(dentry)) {
  49. return 0;
  50. }
  51. parent_dentry = dget_parent(dentry);
  52. sdcardfs_get_lower_path(parent_dentry, &parent_lower_path);
  53. sdcardfs_get_real_lower(dentry, &lower_path);
  54. parent_lower_dentry = parent_lower_path.dentry;
  55. lower_dentry = lower_path.dentry;
  56. lower_cur_parent_dentry = dget_parent(lower_dentry);
  57. if ((lower_dentry->d_flags & DCACHE_OP_REVALIDATE)) {
  58. struct path ptmp;
  59. if (nd) {
  60. pathcpy(&ptmp, &nd->path);
  61. pathcpy(&nd->path, &lower_path);
  62. }
  63. err = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
  64. if (nd)
  65. pathcpy(&nd->path, &ptmp);
  66. if (err == 0) {
  67. goto out;
  68. }
  69. }
  70. spin_lock(&lower_dentry->d_lock);
  71. if (d_unhashed(lower_dentry)) {
  72. spin_unlock(&lower_dentry->d_lock);
  73. err = 0;
  74. goto out;
  75. }
  76. spin_unlock(&lower_dentry->d_lock);
  77. if (parent_lower_dentry != lower_cur_parent_dentry) {
  78. err = 0;
  79. goto out;
  80. }
  81. if (dentry < lower_dentry) {
  82. spin_lock(&dentry->d_lock);
  83. spin_lock_nested(&lower_dentry->d_lock, DENTRY_D_LOCK_NESTED);
  84. } else {
  85. spin_lock(&lower_dentry->d_lock);
  86. spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
  87. }
  88. if (!qstr_case_eq(&dentry->d_name, &lower_dentry->d_name)) {
  89. err = 0;
  90. }
  91. if (dentry < lower_dentry) {
  92. spin_unlock(&lower_dentry->d_lock);
  93. spin_unlock(&dentry->d_lock);
  94. } else {
  95. spin_unlock(&dentry->d_lock);
  96. spin_unlock(&lower_dentry->d_lock);
  97. }
  98. if (!err)
  99. goto out;
  100. /* If our top's inode is gone, we may be out of date */
  101. inode = igrab(dentry->d_inode);
  102. if (inode) {
  103. data = top_data_get(SDCARDFS_I(inode));
  104. if (!data || data->abandoned) {
  105. err = 0;
  106. }
  107. if (data)
  108. data_put(data);
  109. iput(inode);
  110. }
  111. out:
  112. dput(parent_dentry);
  113. dput(lower_cur_parent_dentry);
  114. sdcardfs_put_lower_path(parent_dentry, &parent_lower_path);
  115. sdcardfs_put_real_lower(dentry, &lower_path);
  116. return err;
  117. }
  118. /* 1 = delete, 0 = cache */
  119. static int sdcardfs_d_delete(const struct dentry *d)
  120. {
  121. return SDCARDFS_SB(d->d_sb)->options.nocache ? 1 : 0;
  122. }
  123. static void sdcardfs_d_release(struct dentry *dentry)
  124. {
  125. if (!dentry || !dentry->d_fsdata)
  126. return;
  127. /* release and reset the lower paths */
  128. if (has_graft_path(dentry))
  129. sdcardfs_put_reset_orig_path(dentry);
  130. sdcardfs_put_reset_lower_path(dentry);
  131. free_dentry_private_data(dentry);
  132. }
  133. static int sdcardfs_hash_ci(const struct dentry *dentry,
  134. const struct inode *inode, struct qstr *qstr)
  135. {
  136. /*
  137. * This function is copy of vfat_hashi.
  138. * FIXME Should we support national language?
  139. * Refer to vfat_hashi()
  140. * struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io;
  141. */
  142. const unsigned char *name;
  143. unsigned int len;
  144. unsigned long hash;
  145. name = qstr->name;
  146. len = qstr->len;
  147. hash = init_name_hash();
  148. while (len--)
  149. hash = partial_name_hash(tolower(*name++), hash);
  150. qstr->hash = end_name_hash(hash);
  151. return 0;
  152. }
  153. /*
  154. * Case insensitive compare of two vfat names.
  155. */
  156. static int sdcardfs_cmp_ci(const struct dentry *parent,
  157. const struct inode *pinode,
  158. const struct dentry *dentry, const struct inode *inode,
  159. unsigned int len, const char *str, const struct qstr *name)
  160. {
  161. /* FIXME Should we support national language? */
  162. if (name->len == len) {
  163. if (str_n_case_eq(name->name, str, len))
  164. return 0;
  165. }
  166. return 1;
  167. }
  168. static void sdcardfs_canonical_path(const struct path *path,
  169. struct path *actual_path)
  170. {
  171. sdcardfs_get_real_lower(path->dentry, actual_path);
  172. }
  173. const struct dentry_operations sdcardfs_ci_dops = {
  174. .d_revalidate = sdcardfs_d_revalidate,
  175. .d_delete = sdcardfs_d_delete,
  176. .d_release = sdcardfs_d_release,
  177. .d_hash = sdcardfs_hash_ci,
  178. .d_compare = sdcardfs_cmp_ci,
  179. .d_canonical_path = sdcardfs_canonical_path,
  180. };