shmem.c (6922c0c7abd387374255801f7739624867e8acad) | shmem.c (69f07ec938712b58755add82dd3d0b35f01317cc) |
---|---|
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. --- 59 unchanged lines hidden (view full) --- 68#include <asm/pgtable.h> 69 70#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512) 71#define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT) 72 73/* Pretend that each entry is of this size in directory's i_size */ 74#define BOGO_DIRENT_SIZE 20 75 | 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. --- 59 unchanged lines hidden (view full) --- 68#include <asm/pgtable.h> 69 70#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512) 71#define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT) 72 73/* Pretend that each entry is of this size in directory's i_size */ 74#define BOGO_DIRENT_SIZE 20 75 |
76/* Symlink up to this size is kmalloc'ed instead of using a swappable page */ 77#define SHORT_SYMLINK_LEN 128 78 |
|
76struct shmem_xattr { 77 struct list_head list; /* anchored by shmem_inode_info->xattr_list */ 78 char *name; /* xattr name */ 79 size_t size; 80 char value[0]; 81}; 82 83/* Flag allocation requirements to shmem_getpage */ --- 496 unchanged lines hidden (view full) --- 580 shmem_unacct_size(info->flags, inode->i_size); 581 inode->i_size = 0; 582 shmem_truncate_range(inode, 0, (loff_t)-1); 583 if (!list_empty(&info->swaplist)) { 584 mutex_lock(&shmem_swaplist_mutex); 585 list_del_init(&info->swaplist); 586 mutex_unlock(&shmem_swaplist_mutex); 587 } | 79struct shmem_xattr { 80 struct list_head list; /* anchored by shmem_inode_info->xattr_list */ 81 char *name; /* xattr name */ 82 size_t size; 83 char value[0]; 84}; 85 86/* Flag allocation requirements to shmem_getpage */ --- 496 unchanged lines hidden (view full) --- 583 shmem_unacct_size(info->flags, inode->i_size); 584 inode->i_size = 0; 585 shmem_truncate_range(inode, 0, (loff_t)-1); 586 if (!list_empty(&info->swaplist)) { 587 mutex_lock(&shmem_swaplist_mutex); 588 list_del_init(&info->swaplist); 589 mutex_unlock(&shmem_swaplist_mutex); 590 } |
588 } | 591 } else 592 kfree(info->symlink); |
589 590 list_for_each_entry_safe(xattr, nxattr, &info->xattr_list, list) { 591 kfree(xattr->name); 592 kfree(xattr); 593 } 594 BUG_ON(inode->i_blocks); 595 shmem_free_inode(inode->i_sb); 596 end_writeback(inode); --- 571 unchanged lines hidden (view full) --- 1168 } 1169 } else 1170 shmem_free_inode(sb); 1171 return inode; 1172} 1173 1174#ifdef CONFIG_TMPFS 1175static const struct inode_operations shmem_symlink_inode_operations; | 593 594 list_for_each_entry_safe(xattr, nxattr, &info->xattr_list, list) { 595 kfree(xattr->name); 596 kfree(xattr); 597 } 598 BUG_ON(inode->i_blocks); 599 shmem_free_inode(inode->i_sb); 600 end_writeback(inode); --- 571 unchanged lines hidden (view full) --- 1172 } 1173 } else 1174 shmem_free_inode(sb); 1175 return inode; 1176} 1177 1178#ifdef CONFIG_TMPFS 1179static const struct inode_operations shmem_symlink_inode_operations; |
1176static const struct inode_operations shmem_symlink_inline_operations; | 1180static const struct inode_operations shmem_short_symlink_operations; |
1177 1178static int 1179shmem_write_begin(struct file *file, struct address_space *mapping, 1180 loff_t pos, unsigned len, unsigned flags, 1181 struct page **pagep, void **fsdata) 1182{ 1183 struct inode *inode = mapping->host; 1184 pgoff_t index = pos >> PAGE_CACHE_SHIFT; --- 448 unchanged lines hidden (view full) --- 1633 iput(inode); 1634 return error; 1635 } 1636 error = 0; 1637 } 1638 1639 info = SHMEM_I(inode); 1640 inode->i_size = len-1; | 1181 1182static int 1183shmem_write_begin(struct file *file, struct address_space *mapping, 1184 loff_t pos, unsigned len, unsigned flags, 1185 struct page **pagep, void **fsdata) 1186{ 1187 struct inode *inode = mapping->host; 1188 pgoff_t index = pos >> PAGE_CACHE_SHIFT; --- 448 unchanged lines hidden (view full) --- 1637 iput(inode); 1638 return error; 1639 } 1640 error = 0; 1641 } 1642 1643 info = SHMEM_I(inode); 1644 inode->i_size = len-1; |
1641 if (len <= SHMEM_SYMLINK_INLINE_LEN) { 1642 /* do it inline */ 1643 memcpy(info->inline_symlink, symname, len); 1644 inode->i_op = &shmem_symlink_inline_operations; | 1645 if (len <= SHORT_SYMLINK_LEN) { 1646 info->symlink = kmemdup(symname, len, GFP_KERNEL); 1647 if (!info->symlink) { 1648 iput(inode); 1649 return -ENOMEM; 1650 } 1651 inode->i_op = &shmem_short_symlink_operations; |
1645 } else { 1646 error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL); 1647 if (error) { 1648 iput(inode); 1649 return error; 1650 } 1651 inode->i_mapping->a_ops = &shmem_aops; 1652 inode->i_op = &shmem_symlink_inode_operations; --- 6 unchanged lines hidden (view full) --- 1659 } 1660 dir->i_size += BOGO_DIRENT_SIZE; 1661 dir->i_ctime = dir->i_mtime = CURRENT_TIME; 1662 d_instantiate(dentry, inode); 1663 dget(dentry); 1664 return 0; 1665} 1666 | 1652 } else { 1653 error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL); 1654 if (error) { 1655 iput(inode); 1656 return error; 1657 } 1658 inode->i_mapping->a_ops = &shmem_aops; 1659 inode->i_op = &shmem_symlink_inode_operations; --- 6 unchanged lines hidden (view full) --- 1666 } 1667 dir->i_size += BOGO_DIRENT_SIZE; 1668 dir->i_ctime = dir->i_mtime = CURRENT_TIME; 1669 d_instantiate(dentry, inode); 1670 dget(dentry); 1671 return 0; 1672} 1673 |
1667static void *shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd) | 1674static void *shmem_follow_short_symlink(struct dentry *dentry, struct nameidata *nd) |
1668{ | 1675{ |
1669 nd_set_link(nd, SHMEM_I(dentry->d_inode)->inline_symlink); | 1676 nd_set_link(nd, SHMEM_I(dentry->d_inode)->symlink); |
1670 return NULL; 1671} 1672 1673static void *shmem_follow_link(struct dentry *dentry, struct nameidata *nd) 1674{ 1675 struct page *page = NULL; 1676 int error = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL); 1677 nd_set_link(nd, error ? ERR_PTR(error) : kmap(page)); --- 231 unchanged lines hidden (view full) --- 1909 } 1910 } 1911 spin_unlock(&info->lock); 1912 1913 return used; 1914} 1915#endif /* CONFIG_TMPFS_XATTR */ 1916 | 1677 return NULL; 1678} 1679 1680static void *shmem_follow_link(struct dentry *dentry, struct nameidata *nd) 1681{ 1682 struct page *page = NULL; 1683 int error = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL); 1684 nd_set_link(nd, error ? ERR_PTR(error) : kmap(page)); --- 231 unchanged lines hidden (view full) --- 1916 } 1917 } 1918 spin_unlock(&info->lock); 1919 1920 return used; 1921} 1922#endif /* CONFIG_TMPFS_XATTR */ 1923 |
1917static const struct inode_operations shmem_symlink_inline_operations = { | 1924static const struct inode_operations shmem_short_symlink_operations = { |
1918 .readlink = generic_readlink, | 1925 .readlink = generic_readlink, |
1919 .follow_link = shmem_follow_link_inline, | 1926 .follow_link = shmem_follow_short_symlink, |
1920#ifdef CONFIG_TMPFS_XATTR 1921 .setxattr = shmem_setxattr, 1922 .getxattr = shmem_getxattr, 1923 .listxattr = shmem_listxattr, 1924 .removexattr = shmem_removexattr, 1925#endif 1926}; 1927 --- 326 unchanged lines hidden (view full) --- 2254{ 2255 struct inode *inode = container_of(head, struct inode, i_rcu); 2256 INIT_LIST_HEAD(&inode->i_dentry); 2257 kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode)); 2258} 2259 2260static void shmem_destroy_inode(struct inode *inode) 2261{ | 1927#ifdef CONFIG_TMPFS_XATTR 1928 .setxattr = shmem_setxattr, 1929 .getxattr = shmem_getxattr, 1930 .listxattr = shmem_listxattr, 1931 .removexattr = shmem_removexattr, 1932#endif 1933}; 1934 --- 326 unchanged lines hidden (view full) --- 2261{ 2262 struct inode *inode = container_of(head, struct inode, i_rcu); 2263 INIT_LIST_HEAD(&inode->i_dentry); 2264 kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode)); 2265} 2266 2267static void shmem_destroy_inode(struct inode *inode) 2268{ |
2262 if ((inode->i_mode & S_IFMT) == S_IFREG) { 2263 /* only struct inode is valid if it's an inline symlink */ | 2269 if ((inode->i_mode & S_IFMT) == S_IFREG) |
2264 mpol_free_shared_policy(&SHMEM_I(inode)->policy); | 2270 mpol_free_shared_policy(&SHMEM_I(inode)->policy); |
2265 } | |
2266 call_rcu(&inode->i_rcu, shmem_destroy_callback); 2267} 2268 2269static void shmem_init_inode(void *foo) 2270{ 2271 struct shmem_inode_info *info = foo; 2272 inode_init_once(&info->vfs_inode); 2273} --- 335 unchanged lines hidden --- | 2271 call_rcu(&inode->i_rcu, shmem_destroy_callback); 2272} 2273 2274static void shmem_init_inode(void *foo) 2275{ 2276 struct shmem_inode_info *info = foo; 2277 inode_init_once(&info->vfs_inode); 2278} --- 335 unchanged lines hidden --- |