diff options
author | Alexander Viro <viro@www.linux.org.uk> | 2004-06-23 20:19:06 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-06-23 20:19:06 -0700 |
commit | 0f41086e919525cbe268af5f470c30808f7e9762 (patch) | |
tree | 7b2c8b1e9412d11e13adb7f0fb6a98e2439e55d5 /mm | |
parent | 077688a9f0c7077c960aaf51718dfa3f8bb47bd0 (diff) | |
download | history-0f41086e919525cbe268af5f470c30808f7e9762.tar.gz |
[PATCH] symlink 7/9: shmfs
shm switched (it almost belongs to SL3, but it does some extra stuff
after the link traversal).
Diffstat (limited to 'mm')
-rw-r--r-- | mm/shmem.c | 47 |
1 files changed, 21 insertions, 26 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index 5a6d56a450d8e1..e59de1a98bdaa2 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -40,6 +40,7 @@ #include <linux/security.h> #include <linux/swapops.h> #include <linux/mempolicy.h> +#include <linux/namei.h> #include <asm/uaccess.h> #include <asm/div64.h> #include <asm/pgtable.h> @@ -1676,51 +1677,45 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s return 0; } -static int shmem_readlink_inline(struct dentry *dentry, char __user *buffer, int buflen) -{ - return vfs_readlink(dentry, buffer, buflen, (const char *)SHMEM_I(dentry->d_inode)); -} - static int shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd) { - return vfs_follow_link(nd, (const char *)SHMEM_I(dentry->d_inode)); + nd_set_link(nd, (char *)SHMEM_I(dentry->d_inode)); + return 0; } -static int shmem_readlink(struct dentry *dentry, char __user *buffer, int buflen) +static int shmem_follow_link(struct dentry *dentry, struct nameidata *nd) { struct page *page = NULL; int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL); - if (res) - return res; - res = vfs_readlink(dentry, buffer, buflen, kmap(page)); - kunmap(page); - mark_page_accessed(page); - page_cache_release(page); - return res; + nd_set_link(nd, res ? ERR_PTR(res) : kmap(page)); + return 0; } -static int shmem_follow_link(struct dentry *dentry, struct nameidata *nd) +static void shmem_put_link(struct dentry *dentry, struct nameidata *nd) { - struct page *page = NULL; - int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL); - if (res) - return res; - res = vfs_follow_link(nd, kmap(page)); - kunmap(page); - mark_page_accessed(page); - page_cache_release(page); - return res; + if (!IS_ERR(nd_get_link(nd))) { + struct page *page; + + page = find_get_page(dentry->d_inode->i_mapping, 0); + if (!page) + BUG(); + kunmap(page); + mark_page_accessed(page); + page_cache_release(page); + page_cache_release(page); + } } static struct inode_operations shmem_symlink_inline_operations = { - .readlink = shmem_readlink_inline, + .readlink = generic_readlink, .follow_link = shmem_follow_link_inline, }; static struct inode_operations shmem_symlink_inode_operations = { .truncate = shmem_truncate, - .readlink = shmem_readlink, + .readlink = generic_readlink, .follow_link = shmem_follow_link, + .put_link = shmem_put_link, }; static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long *blocks, unsigned long *inodes) |