tmpfs-idr.patch 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. SPDX-License-Identifier: GPL-2.0
  2. diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
  3. index 166158b6e917..0e9606171432 100644
  4. --- a/include/linux/shmem_fs.h
  5. +++ b/include/linux/shmem_fs.h
  6. @@ -28,10 +28,13 @@ struct shmem_inode_info {
  7. };
  8. struct shmem_sb_info {
  9. + struct mutex idr_lock;
  10. + bool idr_nouse;
  11. + struct idr idr; /* manages inode-number */
  12. unsigned long max_blocks; /* How many blocks are allowed */
  13. struct percpu_counter used_blocks; /* How many are allocated */
  14. - unsigned long max_inodes; /* How many inodes are allowed */
  15. - unsigned long free_inodes; /* How many are left for allocation */
  16. + int max_inodes; /* How many inodes are allowed */
  17. + int free_inodes; /* How many are left for allocation */
  18. raw_spinlock_t stat_lock; /* Serialize shmem_sb_info changes */
  19. umode_t mode; /* Mount mode for root directory */
  20. unsigned char huge; /* Whether to try for hugepages */
  21. diff --git a/mm/shmem.c b/mm/shmem.c
  22. index 342d1bc72867..460e4c54483f 100644
  23. --- a/mm/shmem.c
  24. +++ b/mm/shmem.c
  25. @@ -108,7 +108,7 @@ struct shmem_falloc {
  26. struct shmem_options {
  27. unsigned long long blocks;
  28. - unsigned long long inodes;
  29. + int inodes;
  30. struct mempolicy *mpol;
  31. kuid_t uid;
  32. kgid_t gid;
  33. @@ -128,11 +128,14 @@ static unsigned long shmem_default_max_blocks(void)
  34. return totalram_pages() / 2;
  35. }
  36. -static unsigned long shmem_default_max_inodes(void)
  37. +static int shmem_default_max_inodes(void)
  38. {
  39. unsigned long nr_pages = totalram_pages();
  40. + unsigned long ul;
  41. - return min(nr_pages - totalhigh_pages(), nr_pages / 2);
  42. + ul = INT_MAX;
  43. + ul = min3(ul, nr_pages - totalhigh_pages(), nr_pages / 2);
  44. + return ul;
  45. }
  46. #endif
  47. @@ -1165,6 +1168,11 @@ static void shmem_evict_inode(struct inode *inode)
  48. simple_xattrs_free(&info->xattrs);
  49. WARN_ON(inode->i_blocks);
  50. + if (!sbinfo->idr_nouse && inode->i_ino) {
  51. + mutex_lock(&sbinfo->idr_lock);
  52. + idr_remove(&sbinfo->idr, inode->i_ino);
  53. + mutex_unlock(&sbinfo->idr_lock);
  54. + }
  55. shmem_free_inode(inode->i_sb);
  56. clear_inode(inode);
  57. }
  58. @@ -2336,6 +2344,25 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode
  59. break;
  60. }
  61. + if (!sbinfo->idr_nouse) {
  62. + /* inum 0 and 1 are unused */
  63. + mutex_lock(&sbinfo->idr_lock);
  64. + ino = idr_alloc(&sbinfo->idr, inode, 2, INT_MAX,
  65. + GFP_NOFS);
  66. + if (ino > 0) {
  67. + inode->i_ino = ino;
  68. + mutex_unlock(&sbinfo->idr_lock);
  69. + __insert_inode_hash(inode, inode->i_ino);
  70. + } else {
  71. + inode->i_ino = 0;
  72. + mutex_unlock(&sbinfo->idr_lock);
  73. + iput(inode);
  74. + /* shmem_free_inode() will be called */
  75. + inode = NULL;
  76. + }
  77. + } else
  78. + inode->i_ino = ino;
  79. +
  80. lockdep_annotate_inode_mutex_key(inode);
  81. } else
  82. shmem_free_inode(sb);
  83. @@ -3252,8 +3279,7 @@ static struct dentry *shmem_get_parent(struct dentry *child)
  84. static int shmem_match(struct inode *ino, void *vfh)
  85. {
  86. __u32 *fh = vfh;
  87. - __u64 inum = fh[2];
  88. - inum = (inum << 32) | fh[1];
  89. + __u64 inum = fh[1];
  90. return ino->i_ino == inum && fh[0] == ino->i_generation;
  91. }
  92. @@ -3273,14 +3299,11 @@ static struct dentry *shmem_fh_to_dentry(struct super_block *sb,
  93. struct dentry *dentry = NULL;
  94. u64 inum;
  95. - if (fh_len < 3)
  96. + if (fh_len < 2)
  97. return NULL;
  98. - inum = fid->raw[2];
  99. - inum = (inum << 32) | fid->raw[1];
  100. -
  101. - inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]),
  102. - shmem_match, fid->raw);
  103. + inum = fid->raw[1];
  104. + inode = ilookup5(sb, inum, shmem_match, fid->raw);
  105. if (inode) {
  106. dentry = shmem_find_alias(inode);
  107. iput(inode);
  108. @@ -3292,30 +3315,15 @@ static struct dentry *shmem_fh_to_dentry(struct super_block *sb,
  109. static int shmem_encode_fh(struct inode *inode, __u32 *fh, int *len,
  110. struct inode *parent)
  111. {
  112. - if (*len < 3) {
  113. - *len = 3;
  114. + if (*len < 2) {
  115. + *len = 2;
  116. return FILEID_INVALID;
  117. }
  118. - if (inode_unhashed(inode)) {
  119. - /* Unfortunately insert_inode_hash is not idempotent,
  120. - * so as we hash inodes here rather than at creation
  121. - * time, we need a lock to ensure we only try
  122. - * to do it once
  123. - */
  124. - static DEFINE_SPINLOCK(lock);
  125. - spin_lock(&lock);
  126. - if (inode_unhashed(inode))
  127. - __insert_inode_hash(inode,
  128. - inode->i_ino + inode->i_generation);
  129. - spin_unlock(&lock);
  130. - }
  131. -
  132. fh[0] = inode->i_generation;
  133. fh[1] = inode->i_ino;
  134. - fh[2] = ((__u64)inode->i_ino) >> 32;
  135. - *len = 3;
  136. + *len = 2;
  137. return 1;
  138. }
  139. @@ -3394,7 +3402,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
  140. break;
  141. case Opt_nr_inodes:
  142. ctx->inodes = memparse(param->string, &rest);
  143. - if (*rest)
  144. + if (*rest || ctx->inodes < 2)
  145. goto bad_value;
  146. ctx->seen |= SHMEM_SEEN_INODES;
  147. break;
  148. @@ -3504,7 +3512,7 @@ static int shmem_reconfigure(struct fs_context *fc)
  149. {
  150. struct shmem_options *ctx = fc->fs_private;
  151. struct shmem_sb_info *sbinfo = SHMEM_SB(fc->root->d_sb);
  152. - unsigned long inodes;
  153. + int inodes;
  154. struct mempolicy *mpol = NULL;
  155. const char *err;
  156. @@ -3573,7 +3581,7 @@ static int shmem_show_options(struct seq_file *seq, struct dentry *root)
  157. seq_printf(seq, ",size=%luk",
  158. sbinfo->max_blocks << (PAGE_SHIFT - 10));
  159. if (sbinfo->max_inodes != shmem_default_max_inodes())
  160. - seq_printf(seq, ",nr_inodes=%lu", sbinfo->max_inodes);
  161. + seq_printf(seq, ",nr_inodes=%d", sbinfo->max_inodes);
  162. if (sbinfo->mode != (0777 | S_ISVTX))
  163. seq_printf(seq, ",mode=%03ho", sbinfo->mode);
  164. if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID))
  165. @@ -3620,6 +3628,8 @@ static void shmem_put_super(struct super_block *sb)
  166. {
  167. struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
  168. + if (!sbinfo->idr_nouse)
  169. + idr_destroy(&sbinfo->idr);
  170. free_percpu(sbinfo->ino_batch);
  171. percpu_counter_destroy(&sbinfo->used_blocks);
  172. mpol_put(sbinfo->mpol);
  173. @@ -3662,6 +3672,8 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc)
  174. #else
  175. sb->s_flags |= SB_NOUSER;
  176. #endif
  177. + mutex_init(&sbinfo->idr_lock);
  178. + idr_init(&sbinfo->idr);
  179. sbinfo->max_blocks = ctx->blocks;
  180. sbinfo->free_inodes = sbinfo->max_inodes = ctx->inodes;
  181. if (sb->s_flags & SB_KERNMOUNT) {
  182. @@ -3779,6 +3791,15 @@ static void shmem_destroy_inodecache(void)
  183. kmem_cache_destroy(shmem_inode_cachep);
  184. }
  185. +static __init void shmem_no_idr(struct super_block *sb)
  186. +{
  187. + struct shmem_sb_info *sbinfo;
  188. +
  189. + sbinfo = SHMEM_SB(sb);
  190. + sbinfo->idr_nouse = true;
  191. + idr_destroy(&sbinfo->idr);
  192. +}
  193. +
  194. const struct address_space_operations shmem_aops = {
  195. .writepage = shmem_writepage,
  196. .set_page_dirty = __set_page_dirty_no_writeback,
  197. @@ -3920,6 +3941,7 @@ int __init shmem_init(void)
  198. pr_err("Could not kern_mount tmpfs\n");
  199. goto out1;
  200. }
  201. + shmem_no_idr(shm_mnt->mnt_sb);
  202. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  203. if (has_transparent_hugepage() && shmem_huge > SHMEM_HUGE_DENY)