shmem.c (2361f738b67ab7f1152187fa3d321a09b7c95c09) | shmem.c (38f38657444d15e1a8574eae80ed3de9f501737a) |
---|---|
1/* 2 * Resizable virtual memory filesystem for Linux. 3 * 4 * Copyright (C) 2000 Linus Torvalds. 5 * 2000 Transmeta Corp. 6 * 2000-2001 Christoph Rohland 7 * 2000-2001 SAP AG 8 * 2002 Red Hat Inc. --- 63 unchanged lines hidden (view full) --- 72#define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT) 73 74/* Pretend that each entry is of this size in directory's i_size */ 75#define BOGO_DIRENT_SIZE 20 76 77/* Symlink up to this size is kmalloc'ed instead of using a swappable page */ 78#define SHORT_SYMLINK_LEN 128 79 | 1/* 2 * Resizable virtual memory filesystem for Linux. 3 * 4 * Copyright (C) 2000 Linus Torvalds. 5 * 2000 Transmeta Corp. 6 * 2000-2001 Christoph Rohland 7 * 2000-2001 SAP AG 8 * 2002 Red Hat Inc. --- 63 unchanged lines hidden (view full) --- 72#define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT) 73 74/* Pretend that each entry is of this size in directory's i_size */ 75#define BOGO_DIRENT_SIZE 20 76 77/* Symlink up to this size is kmalloc'ed instead of using a swappable page */ 78#define SHORT_SYMLINK_LEN 128 79 |
80struct shmem_xattr { 81 struct list_head list; /* anchored by shmem_inode_info->xattr_list */ 82 char *name; /* xattr name */ 83 size_t size; 84 char value[0]; 85}; 86 | |
87/* 88 * shmem_fallocate and shmem_writepage communicate via inode->i_private 89 * (with i_mutex making sure that it has only one user at a time): 90 * we would prefer not to enlarge the shmem inode just for that. 91 */ 92struct shmem_falloc { 93 pgoff_t start; /* start of range currently being fallocated */ 94 pgoff_t next; /* the next page offset to be fallocated */ --- 536 unchanged lines hidden (view full) --- 631 error = generic_acl_chmod(inode); 632#endif 633 return error; 634} 635 636static void shmem_evict_inode(struct inode *inode) 637{ 638 struct shmem_inode_info *info = SHMEM_I(inode); | 80/* 81 * shmem_fallocate and shmem_writepage communicate via inode->i_private 82 * (with i_mutex making sure that it has only one user at a time): 83 * we would prefer not to enlarge the shmem inode just for that. 84 */ 85struct shmem_falloc { 86 pgoff_t start; /* start of range currently being fallocated */ 87 pgoff_t next; /* the next page offset to be fallocated */ --- 536 unchanged lines hidden (view full) --- 624 error = generic_acl_chmod(inode); 625#endif 626 return error; 627} 628 629static void shmem_evict_inode(struct inode *inode) 630{ 631 struct shmem_inode_info *info = SHMEM_I(inode); |
639 struct shmem_xattr *xattr, *nxattr; | |
640 641 if (inode->i_mapping->a_ops == &shmem_aops) { 642 shmem_unacct_size(info->flags, inode->i_size); 643 inode->i_size = 0; 644 shmem_truncate_range(inode, 0, (loff_t)-1); 645 if (!list_empty(&info->swaplist)) { 646 mutex_lock(&shmem_swaplist_mutex); 647 list_del_init(&info->swaplist); 648 mutex_unlock(&shmem_swaplist_mutex); 649 } 650 } else 651 kfree(info->symlink); 652 | 632 633 if (inode->i_mapping->a_ops == &shmem_aops) { 634 shmem_unacct_size(info->flags, inode->i_size); 635 inode->i_size = 0; 636 shmem_truncate_range(inode, 0, (loff_t)-1); 637 if (!list_empty(&info->swaplist)) { 638 mutex_lock(&shmem_swaplist_mutex); 639 list_del_init(&info->swaplist); 640 mutex_unlock(&shmem_swaplist_mutex); 641 } 642 } else 643 kfree(info->symlink); 644 |
653 list_for_each_entry_safe(xattr, nxattr, &info->xattr_list, list) { 654 kfree(xattr->name); 655 kfree(xattr); 656 } | 645 simple_xattrs_free(&info->xattrs); |
657 BUG_ON(inode->i_blocks); 658 shmem_free_inode(inode->i_sb); 659 clear_inode(inode); 660} 661 662/* 663 * If swap found in inode, free it and move page from swapcache to filecache. 664 */ --- 707 unchanged lines hidden (view full) --- 1372 inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; 1373 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 1374 inode->i_generation = get_seconds(); 1375 info = SHMEM_I(inode); 1376 memset(info, 0, (char *)inode - (char *)info); 1377 spin_lock_init(&info->lock); 1378 info->flags = flags & VM_NORESERVE; 1379 INIT_LIST_HEAD(&info->swaplist); | 646 BUG_ON(inode->i_blocks); 647 shmem_free_inode(inode->i_sb); 648 clear_inode(inode); 649} 650 651/* 652 * If swap found in inode, free it and move page from swapcache to filecache. 653 */ --- 707 unchanged lines hidden (view full) --- 1361 inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; 1362 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 1363 inode->i_generation = get_seconds(); 1364 info = SHMEM_I(inode); 1365 memset(info, 0, (char *)inode - (char *)info); 1366 spin_lock_init(&info->lock); 1367 info->flags = flags & VM_NORESERVE; 1368 INIT_LIST_HEAD(&info->swaplist); |
1380 INIT_LIST_HEAD(&info->xattr_list); | 1369 simple_xattrs_init(&info->xattrs); |
1381 cache_no_acl(inode); 1382 1383 switch (mode & S_IFMT) { 1384 default: 1385 inode->i_op = &shmem_special_inode_operations; 1386 init_special_inode(inode, mode, dev); 1387 break; 1388 case S_IFREG: --- 666 unchanged lines hidden (view full) --- 2055/* 2056 * Superblocks without xattr inode operations may get some security.* xattr 2057 * support from the LSM "for free". As soon as we have any other xattrs 2058 * like ACLs, we also need to implement the security.* handlers at 2059 * filesystem level, though. 2060 */ 2061 2062/* | 1370 cache_no_acl(inode); 1371 1372 switch (mode & S_IFMT) { 1373 default: 1374 inode->i_op = &shmem_special_inode_operations; 1375 init_special_inode(inode, mode, dev); 1376 break; 1377 case S_IFREG: --- 666 unchanged lines hidden (view full) --- 2044/* 2045 * Superblocks without xattr inode operations may get some security.* xattr 2046 * support from the LSM "for free". As soon as we have any other xattrs 2047 * like ACLs, we also need to implement the security.* handlers at 2048 * filesystem level, though. 2049 */ 2050 2051/* |
2063 * Allocate new xattr and copy in the value; but leave the name to callers. 2064 */ 2065static struct shmem_xattr *shmem_xattr_alloc(const void *value, size_t size) 2066{ 2067 struct shmem_xattr *new_xattr; 2068 size_t len; 2069 2070 /* wrap around? */ 2071 len = sizeof(*new_xattr) + size; 2072 if (len <= sizeof(*new_xattr)) 2073 return NULL; 2074 2075 new_xattr = kmalloc(len, GFP_KERNEL); 2076 if (!new_xattr) 2077 return NULL; 2078 2079 new_xattr->size = size; 2080 memcpy(new_xattr->value, value, size); 2081 return new_xattr; 2082} 2083 2084/* | |
2085 * Callback for security_inode_init_security() for acquiring xattrs. 2086 */ 2087static int shmem_initxattrs(struct inode *inode, 2088 const struct xattr *xattr_array, 2089 void *fs_info) 2090{ 2091 struct shmem_inode_info *info = SHMEM_I(inode); 2092 const struct xattr *xattr; | 2052 * Callback for security_inode_init_security() for acquiring xattrs. 2053 */ 2054static int shmem_initxattrs(struct inode *inode, 2055 const struct xattr *xattr_array, 2056 void *fs_info) 2057{ 2058 struct shmem_inode_info *info = SHMEM_I(inode); 2059 const struct xattr *xattr; |
2093 struct shmem_xattr *new_xattr; | 2060 struct simple_xattr *new_xattr; |
2094 size_t len; 2095 2096 for (xattr = xattr_array; xattr->name != NULL; xattr++) { | 2061 size_t len; 2062 2063 for (xattr = xattr_array; xattr->name != NULL; xattr++) { |
2097 new_xattr = shmem_xattr_alloc(xattr->value, xattr->value_len); | 2064 new_xattr = simple_xattr_alloc(xattr->value, xattr->value_len); |
2098 if (!new_xattr) 2099 return -ENOMEM; 2100 2101 len = strlen(xattr->name) + 1; 2102 new_xattr->name = kmalloc(XATTR_SECURITY_PREFIX_LEN + len, 2103 GFP_KERNEL); 2104 if (!new_xattr->name) { 2105 kfree(new_xattr); 2106 return -ENOMEM; 2107 } 2108 2109 memcpy(new_xattr->name, XATTR_SECURITY_PREFIX, 2110 XATTR_SECURITY_PREFIX_LEN); 2111 memcpy(new_xattr->name + XATTR_SECURITY_PREFIX_LEN, 2112 xattr->name, len); 2113 | 2065 if (!new_xattr) 2066 return -ENOMEM; 2067 2068 len = strlen(xattr->name) + 1; 2069 new_xattr->name = kmalloc(XATTR_SECURITY_PREFIX_LEN + len, 2070 GFP_KERNEL); 2071 if (!new_xattr->name) { 2072 kfree(new_xattr); 2073 return -ENOMEM; 2074 } 2075 2076 memcpy(new_xattr->name, XATTR_SECURITY_PREFIX, 2077 XATTR_SECURITY_PREFIX_LEN); 2078 memcpy(new_xattr->name + XATTR_SECURITY_PREFIX_LEN, 2079 xattr->name, len); 2080 |
2114 spin_lock(&info->lock); 2115 list_add(&new_xattr->list, &info->xattr_list); 2116 spin_unlock(&info->lock); | 2081 simple_xattr_list_add(&info->xattrs, new_xattr); |
2117 } 2118 2119 return 0; 2120} 2121 | 2082 } 2083 2084 return 0; 2085} 2086 |
2122static int shmem_xattr_get(struct dentry *dentry, const char *name, 2123 void *buffer, size_t size) 2124{ 2125 struct shmem_inode_info *info; 2126 struct shmem_xattr *xattr; 2127 int ret = -ENODATA; 2128 2129 info = SHMEM_I(dentry->d_inode); 2130 2131 spin_lock(&info->lock); 2132 list_for_each_entry(xattr, &info->xattr_list, list) { 2133 if (strcmp(name, xattr->name)) 2134 continue; 2135 2136 ret = xattr->size; 2137 if (buffer) { 2138 if (size < xattr->size) 2139 ret = -ERANGE; 2140 else 2141 memcpy(buffer, xattr->value, xattr->size); 2142 } 2143 break; 2144 } 2145 spin_unlock(&info->lock); 2146 return ret; 2147} 2148 2149static int shmem_xattr_set(struct inode *inode, const char *name, 2150 const void *value, size_t size, int flags) 2151{ 2152 struct shmem_inode_info *info = SHMEM_I(inode); 2153 struct shmem_xattr *xattr; 2154 struct shmem_xattr *new_xattr = NULL; 2155 int err = 0; 2156 2157 /* value == NULL means remove */ 2158 if (value) { 2159 new_xattr = shmem_xattr_alloc(value, size); 2160 if (!new_xattr) 2161 return -ENOMEM; 2162 2163 new_xattr->name = kstrdup(name, GFP_KERNEL); 2164 if (!new_xattr->name) { 2165 kfree(new_xattr); 2166 return -ENOMEM; 2167 } 2168 } 2169 2170 spin_lock(&info->lock); 2171 list_for_each_entry(xattr, &info->xattr_list, list) { 2172 if (!strcmp(name, xattr->name)) { 2173 if (flags & XATTR_CREATE) { 2174 xattr = new_xattr; 2175 err = -EEXIST; 2176 } else if (new_xattr) { 2177 list_replace(&xattr->list, &new_xattr->list); 2178 } else { 2179 list_del(&xattr->list); 2180 } 2181 goto out; 2182 } 2183 } 2184 if (flags & XATTR_REPLACE) { 2185 xattr = new_xattr; 2186 err = -ENODATA; 2187 } else { 2188 list_add(&new_xattr->list, &info->xattr_list); 2189 xattr = NULL; 2190 } 2191out: 2192 spin_unlock(&info->lock); 2193 if (xattr) 2194 kfree(xattr->name); 2195 kfree(xattr); 2196 return err; 2197} 2198 | |
2199static const struct xattr_handler *shmem_xattr_handlers[] = { 2200#ifdef CONFIG_TMPFS_POSIX_ACL 2201 &generic_acl_access_handler, 2202 &generic_acl_default_handler, 2203#endif 2204 NULL 2205}; 2206 --- 14 unchanged lines hidden (view full) --- 2221 } 2222 } 2223 return -EOPNOTSUPP; 2224} 2225 2226static ssize_t shmem_getxattr(struct dentry *dentry, const char *name, 2227 void *buffer, size_t size) 2228{ | 2087static const struct xattr_handler *shmem_xattr_handlers[] = { 2088#ifdef CONFIG_TMPFS_POSIX_ACL 2089 &generic_acl_access_handler, 2090 &generic_acl_default_handler, 2091#endif 2092 NULL 2093}; 2094 --- 14 unchanged lines hidden (view full) --- 2109 } 2110 } 2111 return -EOPNOTSUPP; 2112} 2113 2114static ssize_t shmem_getxattr(struct dentry *dentry, const char *name, 2115 void *buffer, size_t size) 2116{ |
2117 struct shmem_inode_info *info = SHMEM_I(dentry->d_inode); |
|
2229 int err; 2230 2231 /* 2232 * If this is a request for a synthetic attribute in the system.* 2233 * namespace use the generic infrastructure to resolve a handler 2234 * for it via sb->s_xattr. 2235 */ 2236 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 2237 return generic_getxattr(dentry, name, buffer, size); 2238 2239 err = shmem_xattr_validate(name); 2240 if (err) 2241 return err; 2242 | 2118 int err; 2119 2120 /* 2121 * If this is a request for a synthetic attribute in the system.* 2122 * namespace use the generic infrastructure to resolve a handler 2123 * for it via sb->s_xattr. 2124 */ 2125 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 2126 return generic_getxattr(dentry, name, buffer, size); 2127 2128 err = shmem_xattr_validate(name); 2129 if (err) 2130 return err; 2131 |
2243 return shmem_xattr_get(dentry, name, buffer, size); | 2132 return simple_xattr_get(&info->xattrs, name, buffer, size); |
2244} 2245 2246static int shmem_setxattr(struct dentry *dentry, const char *name, 2247 const void *value, size_t size, int flags) 2248{ | 2133} 2134 2135static int shmem_setxattr(struct dentry *dentry, const char *name, 2136 const void *value, size_t size, int flags) 2137{ |
2138 struct shmem_inode_info *info = SHMEM_I(dentry->d_inode); |
|
2249 int err; 2250 2251 /* 2252 * If this is a request for a synthetic attribute in the system.* 2253 * namespace use the generic infrastructure to resolve a handler 2254 * for it via sb->s_xattr. 2255 */ 2256 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 2257 return generic_setxattr(dentry, name, value, size, flags); 2258 2259 err = shmem_xattr_validate(name); 2260 if (err) 2261 return err; 2262 | 2139 int err; 2140 2141 /* 2142 * If this is a request for a synthetic attribute in the system.* 2143 * namespace use the generic infrastructure to resolve a handler 2144 * for it via sb->s_xattr. 2145 */ 2146 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 2147 return generic_setxattr(dentry, name, value, size, flags); 2148 2149 err = shmem_xattr_validate(name); 2150 if (err) 2151 return err; 2152 |
2263 if (size == 0) 2264 value = ""; /* empty EA, do not remove */ 2265 2266 return shmem_xattr_set(dentry->d_inode, name, value, size, flags); 2267 | 2153 return simple_xattr_set(&info->xattrs, name, value, size, flags); |
2268} 2269 2270static int shmem_removexattr(struct dentry *dentry, const char *name) 2271{ | 2154} 2155 2156static int shmem_removexattr(struct dentry *dentry, const char *name) 2157{ |
2158 struct shmem_inode_info *info = SHMEM_I(dentry->d_inode); |
|
2272 int err; 2273 2274 /* 2275 * If this is a request for a synthetic attribute in the system.* 2276 * namespace use the generic infrastructure to resolve a handler 2277 * for it via sb->s_xattr. 2278 */ 2279 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 2280 return generic_removexattr(dentry, name); 2281 2282 err = shmem_xattr_validate(name); 2283 if (err) 2284 return err; 2285 | 2159 int err; 2160 2161 /* 2162 * If this is a request for a synthetic attribute in the system.* 2163 * namespace use the generic infrastructure to resolve a handler 2164 * for it via sb->s_xattr. 2165 */ 2166 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 2167 return generic_removexattr(dentry, name); 2168 2169 err = shmem_xattr_validate(name); 2170 if (err) 2171 return err; 2172 |
2286 return shmem_xattr_set(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); | 2173 return simple_xattr_remove(&info->xattrs, name); |
2287} 2288 | 2174} 2175 |
2289static bool xattr_is_trusted(const char *name) 2290{ 2291 return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); 2292} 2293 | |
2294static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size) 2295{ | 2176static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size) 2177{ |
2296 bool trusted = capable(CAP_SYS_ADMIN); 2297 struct shmem_xattr *xattr; 2298 struct shmem_inode_info *info; 2299 size_t used = 0; 2300 2301 info = SHMEM_I(dentry->d_inode); 2302 2303 spin_lock(&info->lock); 2304 list_for_each_entry(xattr, &info->xattr_list, list) { 2305 size_t len; 2306 2307 /* skip "trusted." attributes for unprivileged callers */ 2308 if (!trusted && xattr_is_trusted(xattr->name)) 2309 continue; 2310 2311 len = strlen(xattr->name) + 1; 2312 used += len; 2313 if (buffer) { 2314 if (size < used) { 2315 used = -ERANGE; 2316 break; 2317 } 2318 memcpy(buffer, xattr->name, len); 2319 buffer += len; 2320 } 2321 } 2322 spin_unlock(&info->lock); 2323 2324 return used; | 2178 struct shmem_inode_info *info = SHMEM_I(dentry->d_inode); 2179 return simple_xattr_list(&info->xattrs, buffer, size); |
2325} 2326#endif /* CONFIG_TMPFS_XATTR */ 2327 2328static const struct inode_operations shmem_short_symlink_operations = { 2329 .readlink = generic_readlink, 2330 .follow_link = shmem_follow_short_symlink, 2331#ifdef CONFIG_TMPFS_XATTR 2332 .setxattr = shmem_setxattr, --- 693 unchanged lines hidden --- | 2180} 2181#endif /* CONFIG_TMPFS_XATTR */ 2182 2183static const struct inode_operations shmem_short_symlink_operations = { 2184 .readlink = generic_readlink, 2185 .follow_link = shmem_follow_short_symlink, 2186#ifdef CONFIG_TMPFS_XATTR 2187 .setxattr = shmem_setxattr, --- 693 unchanged lines hidden --- |