aboutsummaryrefslogtreecommitdiffstats
path: root/mm/shmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/shmem.c')
-rw-r--r--mm/shmem.c198
1 files changed, 134 insertions, 64 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index 85bed948fafc..90b576cbc06e 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -49,6 +49,7 @@
49#include <linux/ctype.h> 49#include <linux/ctype.h>
50#include <linux/migrate.h> 50#include <linux/migrate.h>
51#include <linux/highmem.h> 51#include <linux/highmem.h>
52#include <linux/seq_file.h>
52 53
53#include <asm/uaccess.h> 54#include <asm/uaccess.h>
54#include <asm/div64.h> 55#include <asm/div64.h>
@@ -84,6 +85,18 @@ enum sgp_type {
84 SGP_WRITE, /* may exceed i_size, may allocate page */ 85 SGP_WRITE, /* may exceed i_size, may allocate page */
85}; 86};
86 87
88#ifdef CONFIG_TMPFS
89static unsigned long shmem_default_max_blocks(void)
90{
91 return totalram_pages / 2;
92}
93
94static unsigned long shmem_default_max_inodes(void)
95{
96 return min(totalram_pages - totalhigh_pages, totalram_pages / 2);
97}
98#endif
99
87static int shmem_getpage(struct inode *inode, unsigned long idx, 100static int shmem_getpage(struct inode *inode, unsigned long idx,
88 struct page **pagep, enum sgp_type sgp, int *type); 101 struct page **pagep, enum sgp_type sgp, int *type);
89 102
@@ -1068,7 +1081,8 @@ redirty:
1068} 1081}
1069 1082
1070#ifdef CONFIG_NUMA 1083#ifdef CONFIG_NUMA
1071static inline int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_nodes) 1084#ifdef CONFIG_TMPFS
1085static int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_nodes)
1072{ 1086{
1073 char *nodelist = strchr(value, ':'); 1087 char *nodelist = strchr(value, ':');
1074 int err = 1; 1088 int err = 1;
@@ -1117,6 +1131,42 @@ out:
1117 return err; 1131 return err;
1118} 1132}
1119 1133
1134static void shmem_show_mpol(struct seq_file *seq, int policy,
1135 const nodemask_t policy_nodes)
1136{
1137 char *policy_string;
1138
1139 switch (policy) {
1140 case MPOL_PREFERRED:
1141 policy_string = "prefer";
1142 break;
1143 case MPOL_BIND:
1144 policy_string = "bind";
1145 break;
1146 case MPOL_INTERLEAVE:
1147 policy_string = "interleave";
1148 break;
1149 default:
1150 /* MPOL_DEFAULT */
1151 return;
1152 }
1153
1154 seq_printf(seq, ",mpol=%s", policy_string);
1155
1156 if (policy != MPOL_INTERLEAVE ||
1157 !nodes_equal(policy_nodes, node_states[N_HIGH_MEMORY])) {
1158 char buffer[64];
1159 int len;
1160
1161 len = nodelist_scnprintf(buffer, sizeof(buffer), policy_nodes);
1162 if (len < sizeof(buffer))
1163 seq_printf(seq, ":%s", buffer);
1164 else
1165 seq_printf(seq, ":?");
1166 }
1167}
1168#endif /* CONFIG_TMPFS */
1169
1120static struct page *shmem_swapin(swp_entry_t entry, gfp_t gfp, 1170static struct page *shmem_swapin(swp_entry_t entry, gfp_t gfp,
1121 struct shmem_inode_info *info, unsigned long idx) 1171 struct shmem_inode_info *info, unsigned long idx)
1122{ 1172{
@@ -1148,13 +1198,20 @@ static struct page *shmem_alloc_page(gfp_t gfp,
1148 mpol_free(pvma.vm_policy); 1198 mpol_free(pvma.vm_policy);
1149 return page; 1199 return page;
1150} 1200}
1151#else 1201#else /* !CONFIG_NUMA */
1202#ifdef CONFIG_TMPFS
1152static inline int shmem_parse_mpol(char *value, int *policy, 1203static inline int shmem_parse_mpol(char *value, int *policy,
1153 nodemask_t *policy_nodes) 1204 nodemask_t *policy_nodes)
1154{ 1205{
1155 return 1; 1206 return 1;
1156} 1207}
1157 1208
1209static inline void shmem_show_mpol(struct seq_file *seq, int policy,
1210 const nodemask_t policy_nodes)
1211{
1212}
1213#endif /* CONFIG_TMPFS */
1214
1158static inline struct page *shmem_swapin(swp_entry_t entry, gfp_t gfp, 1215static inline struct page *shmem_swapin(swp_entry_t entry, gfp_t gfp,
1159 struct shmem_inode_info *info, unsigned long idx) 1216 struct shmem_inode_info *info, unsigned long idx)
1160{ 1217{
@@ -1166,7 +1223,7 @@ static inline struct page *shmem_alloc_page(gfp_t gfp,
1166{ 1223{
1167 return alloc_page(gfp); 1224 return alloc_page(gfp);
1168} 1225}
1169#endif 1226#endif /* CONFIG_NUMA */
1170 1227
1171/* 1228/*
1172 * shmem_getpage - either get the page from swap or allocate a new one 1229 * shmem_getpage - either get the page from swap or allocate a new one
@@ -2077,9 +2134,8 @@ static const struct export_operations shmem_export_ops = {
2077 .fh_to_dentry = shmem_fh_to_dentry, 2134 .fh_to_dentry = shmem_fh_to_dentry,
2078}; 2135};
2079 2136
2080static int shmem_parse_options(char *options, int *mode, uid_t *uid, 2137static int shmem_parse_options(char *options, struct shmem_sb_info *sbinfo,
2081 gid_t *gid, unsigned long *blocks, unsigned long *inodes, 2138 bool remount)
2082 int *policy, nodemask_t *policy_nodes)
2083{ 2139{
2084 char *this_char, *value, *rest; 2140 char *this_char, *value, *rest;
2085 2141
@@ -2122,35 +2178,37 @@ static int shmem_parse_options(char *options, int *mode, uid_t *uid,
2122 } 2178 }
2123 if (*rest) 2179 if (*rest)
2124 goto bad_val; 2180 goto bad_val;
2125 *blocks = DIV_ROUND_UP(size, PAGE_CACHE_SIZE); 2181 sbinfo->max_blocks =
2182 DIV_ROUND_UP(size, PAGE_CACHE_SIZE);
2126 } else if (!strcmp(this_char,"nr_blocks")) { 2183 } else if (!strcmp(this_char,"nr_blocks")) {
2127 *blocks = memparse(value,&rest); 2184 sbinfo->max_blocks = memparse(value, &rest);
2128 if (*rest) 2185 if (*rest)
2129 goto bad_val; 2186 goto bad_val;
2130 } else if (!strcmp(this_char,"nr_inodes")) { 2187 } else if (!strcmp(this_char,"nr_inodes")) {
2131 *inodes = memparse(value,&rest); 2188 sbinfo->max_inodes = memparse(value, &rest);
2132 if (*rest) 2189 if (*rest)
2133 goto bad_val; 2190 goto bad_val;
2134 } else if (!strcmp(this_char,"mode")) { 2191 } else if (!strcmp(this_char,"mode")) {
2135 if (!mode) 2192 if (remount)
2136 continue; 2193 continue;
2137 *mode = simple_strtoul(value,&rest,8); 2194 sbinfo->mode = simple_strtoul(value, &rest, 8) & 07777;
2138 if (*rest) 2195 if (*rest)
2139 goto bad_val; 2196 goto bad_val;
2140 } else if (!strcmp(this_char,"uid")) { 2197 } else if (!strcmp(this_char,"uid")) {
2141 if (!uid) 2198 if (remount)
2142 continue; 2199 continue;
2143 *uid = simple_strtoul(value,&rest,0); 2200 sbinfo->uid = simple_strtoul(value, &rest, 0);
2144 if (*rest) 2201 if (*rest)
2145 goto bad_val; 2202 goto bad_val;
2146 } else if (!strcmp(this_char,"gid")) { 2203 } else if (!strcmp(this_char,"gid")) {
2147 if (!gid) 2204 if (remount)
2148 continue; 2205 continue;
2149 *gid = simple_strtoul(value,&rest,0); 2206 sbinfo->gid = simple_strtoul(value, &rest, 0);
2150 if (*rest) 2207 if (*rest)
2151 goto bad_val; 2208 goto bad_val;
2152 } else if (!strcmp(this_char,"mpol")) { 2209 } else if (!strcmp(this_char,"mpol")) {
2153 if (shmem_parse_mpol(value,policy,policy_nodes)) 2210 if (shmem_parse_mpol(value, &sbinfo->policy,
2211 &sbinfo->policy_nodes))
2154 goto bad_val; 2212 goto bad_val;
2155 } else { 2213 } else {
2156 printk(KERN_ERR "tmpfs: Bad mount option %s\n", 2214 printk(KERN_ERR "tmpfs: Bad mount option %s\n",
@@ -2170,24 +2228,20 @@ bad_val:
2170static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) 2228static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
2171{ 2229{
2172 struct shmem_sb_info *sbinfo = SHMEM_SB(sb); 2230 struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
2173 unsigned long max_blocks = sbinfo->max_blocks; 2231 struct shmem_sb_info config = *sbinfo;
2174 unsigned long max_inodes = sbinfo->max_inodes;
2175 int policy = sbinfo->policy;
2176 nodemask_t policy_nodes = sbinfo->policy_nodes;
2177 unsigned long blocks; 2232 unsigned long blocks;
2178 unsigned long inodes; 2233 unsigned long inodes;
2179 int error = -EINVAL; 2234 int error = -EINVAL;
2180 2235
2181 if (shmem_parse_options(data, NULL, NULL, NULL, &max_blocks, 2236 if (shmem_parse_options(data, &config, true))
2182 &max_inodes, &policy, &policy_nodes))
2183 return error; 2237 return error;
2184 2238
2185 spin_lock(&sbinfo->stat_lock); 2239 spin_lock(&sbinfo->stat_lock);
2186 blocks = sbinfo->max_blocks - sbinfo->free_blocks; 2240 blocks = sbinfo->max_blocks - sbinfo->free_blocks;
2187 inodes = sbinfo->max_inodes - sbinfo->free_inodes; 2241 inodes = sbinfo->max_inodes - sbinfo->free_inodes;
2188 if (max_blocks < blocks) 2242 if (config.max_blocks < blocks)
2189 goto out; 2243 goto out;
2190 if (max_inodes < inodes) 2244 if (config.max_inodes < inodes)
2191 goto out; 2245 goto out;
2192 /* 2246 /*
2193 * Those tests also disallow limited->unlimited while any are in 2247 * Those tests also disallow limited->unlimited while any are in
@@ -2195,23 +2249,42 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
2195 * but we must separately disallow unlimited->limited, because 2249 * but we must separately disallow unlimited->limited, because
2196 * in that case we have no record of how much is already in use. 2250 * in that case we have no record of how much is already in use.
2197 */ 2251 */
2198 if (max_blocks && !sbinfo->max_blocks) 2252 if (config.max_blocks && !sbinfo->max_blocks)
2199 goto out; 2253 goto out;
2200 if (max_inodes && !sbinfo->max_inodes) 2254 if (config.max_inodes && !sbinfo->max_inodes)
2201 goto out; 2255 goto out;
2202 2256
2203 error = 0; 2257 error = 0;
2204 sbinfo->max_blocks = max_blocks; 2258 sbinfo->max_blocks = config.max_blocks;
2205 sbinfo->free_blocks = max_blocks - blocks; 2259 sbinfo->free_blocks = config.max_blocks - blocks;
2206 sbinfo->max_inodes = max_inodes; 2260 sbinfo->max_inodes = config.max_inodes;
2207 sbinfo->free_inodes = max_inodes - inodes; 2261 sbinfo->free_inodes = config.max_inodes - inodes;
2208 sbinfo->policy = policy; 2262 sbinfo->policy = config.policy;
2209 sbinfo->policy_nodes = policy_nodes; 2263 sbinfo->policy_nodes = config.policy_nodes;
2210out: 2264out:
2211 spin_unlock(&sbinfo->stat_lock); 2265 spin_unlock(&sbinfo->stat_lock);
2212 return error; 2266 return error;
2213} 2267}
2214#endif 2268
2269static int shmem_show_options(struct seq_file *seq, struct vfsmount *vfs)
2270{
2271 struct shmem_sb_info *sbinfo = SHMEM_SB(vfs->mnt_sb);
2272
2273 if (sbinfo->max_blocks != shmem_default_max_blocks())
2274 seq_printf(seq, ",size=%luk",
2275 sbinfo->max_blocks << (PAGE_CACHE_SHIFT - 10));
2276 if (sbinfo->max_inodes != shmem_default_max_inodes())
2277 seq_printf(seq, ",nr_inodes=%lu", sbinfo->max_inodes);
2278 if (sbinfo->mode != (S_IRWXUGO | S_ISVTX))
2279 seq_printf(seq, ",mode=%03o", sbinfo->mode);
2280 if (sbinfo->uid != 0)
2281 seq_printf(seq, ",uid=%u", sbinfo->uid);
2282 if (sbinfo->gid != 0)
2283 seq_printf(seq, ",gid=%u", sbinfo->gid);
2284 shmem_show_mpol(seq, sbinfo->policy, sbinfo->policy_nodes);
2285 return 0;
2286}
2287#endif /* CONFIG_TMPFS */
2215 2288
2216static void shmem_put_super(struct super_block *sb) 2289static void shmem_put_super(struct super_block *sb)
2217{ 2290{
@@ -2224,15 +2297,23 @@ static int shmem_fill_super(struct super_block *sb,
2224{ 2297{
2225 struct inode *inode; 2298 struct inode *inode;
2226 struct dentry *root; 2299 struct dentry *root;
2227 int mode = S_IRWXUGO | S_ISVTX;
2228 uid_t uid = current->fsuid;
2229 gid_t gid = current->fsgid;
2230 int err = -ENOMEM;
2231 struct shmem_sb_info *sbinfo; 2300 struct shmem_sb_info *sbinfo;
2232 unsigned long blocks = 0; 2301 int err = -ENOMEM;
2233 unsigned long inodes = 0; 2302
2234 int policy = MPOL_DEFAULT; 2303 /* Round up to L1_CACHE_BYTES to resist false sharing */
2235 nodemask_t policy_nodes = node_states[N_HIGH_MEMORY]; 2304 sbinfo = kmalloc(max((int)sizeof(struct shmem_sb_info),
2305 L1_CACHE_BYTES), GFP_KERNEL);
2306 if (!sbinfo)
2307 return -ENOMEM;
2308
2309 sbinfo->max_blocks = 0;
2310 sbinfo->max_inodes = 0;
2311 sbinfo->mode = S_IRWXUGO | S_ISVTX;
2312 sbinfo->uid = current->fsuid;
2313 sbinfo->gid = current->fsgid;
2314 sbinfo->policy = MPOL_DEFAULT;
2315 sbinfo->policy_nodes = node_states[N_HIGH_MEMORY];
2316 sb->s_fs_info = sbinfo;
2236 2317
2237#ifdef CONFIG_TMPFS 2318#ifdef CONFIG_TMPFS
2238 /* 2319 /*
@@ -2241,34 +2322,22 @@ static int shmem_fill_super(struct super_block *sb,
2241 * but the internal instance is left unlimited. 2322 * but the internal instance is left unlimited.
2242 */ 2323 */
2243 if (!(sb->s_flags & MS_NOUSER)) { 2324 if (!(sb->s_flags & MS_NOUSER)) {
2244 blocks = totalram_pages / 2; 2325 sbinfo->max_blocks = shmem_default_max_blocks();
2245 inodes = totalram_pages - totalhigh_pages; 2326 sbinfo->max_inodes = shmem_default_max_inodes();
2246 if (inodes > blocks) 2327 if (shmem_parse_options(data, sbinfo, false)) {
2247 inodes = blocks; 2328 err = -EINVAL;
2248 if (shmem_parse_options(data, &mode, &uid, &gid, &blocks, 2329 goto failed;
2249 &inodes, &policy, &policy_nodes)) 2330 }
2250 return -EINVAL;
2251 } 2331 }
2252 sb->s_export_op = &shmem_export_ops; 2332 sb->s_export_op = &shmem_export_ops;
2253#else 2333#else
2254 sb->s_flags |= MS_NOUSER; 2334 sb->s_flags |= MS_NOUSER;
2255#endif 2335#endif
2256 2336
2257 /* Round up to L1_CACHE_BYTES to resist false sharing */
2258 sbinfo = kmalloc(max((int)sizeof(struct shmem_sb_info),
2259 L1_CACHE_BYTES), GFP_KERNEL);
2260 if (!sbinfo)
2261 return -ENOMEM;
2262
2263 spin_lock_init(&sbinfo->stat_lock); 2337 spin_lock_init(&sbinfo->stat_lock);
2264 sbinfo->max_blocks = blocks; 2338 sbinfo->free_blocks = sbinfo->max_blocks;
2265 sbinfo->free_blocks = blocks; 2339 sbinfo->free_inodes = sbinfo->max_inodes;
2266 sbinfo->max_inodes = inodes;
2267 sbinfo->free_inodes = inodes;
2268 sbinfo->policy = policy;
2269 sbinfo->policy_nodes = policy_nodes;
2270 2340
2271 sb->s_fs_info = sbinfo;
2272 sb->s_maxbytes = SHMEM_MAX_BYTES; 2341 sb->s_maxbytes = SHMEM_MAX_BYTES;
2273 sb->s_blocksize = PAGE_CACHE_SIZE; 2342 sb->s_blocksize = PAGE_CACHE_SIZE;
2274 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 2343 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -2280,11 +2349,11 @@ static int shmem_fill_super(struct super_block *sb,
2280 sb->s_flags |= MS_POSIXACL; 2349 sb->s_flags |= MS_POSIXACL;
2281#endif 2350#endif
2282 2351
2283 inode = shmem_get_inode(sb, S_IFDIR | mode, 0); 2352 inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0);
2284 if (!inode) 2353 if (!inode)
2285 goto failed; 2354 goto failed;
2286 inode->i_uid = uid; 2355 inode->i_uid = sbinfo->uid;
2287 inode->i_gid = gid; 2356 inode->i_gid = sbinfo->gid;
2288 root = d_alloc_root(inode); 2357 root = d_alloc_root(inode);
2289 if (!root) 2358 if (!root)
2290 goto failed_iput; 2359 goto failed_iput;
@@ -2420,6 +2489,7 @@ static const struct super_operations shmem_ops = {
2420#ifdef CONFIG_TMPFS 2489#ifdef CONFIG_TMPFS
2421 .statfs = shmem_statfs, 2490 .statfs = shmem_statfs,
2422 .remount_fs = shmem_remount_fs, 2491 .remount_fs = shmem_remount_fs,
2492 .show_options = shmem_show_options,
2423#endif 2493#endif
2424 .delete_inode = shmem_delete_inode, 2494 .delete_inode = shmem_delete_inode,
2425 .drop_inode = generic_delete_inode, 2495 .drop_inode = generic_delete_inode,