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 ---