Merge with master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
This commit is contained in:
40
fs/namei.c
40
fs/namei.c
@@ -501,6 +501,7 @@ struct path {
|
||||
static inline int __do_follow_link(struct path *path, struct nameidata *nd)
|
||||
{
|
||||
int error;
|
||||
void *cookie;
|
||||
struct dentry *dentry = path->dentry;
|
||||
|
||||
touch_atime(path->mnt, dentry);
|
||||
@@ -508,13 +509,15 @@ static inline int __do_follow_link(struct path *path, struct nameidata *nd)
|
||||
|
||||
if (path->mnt == nd->mnt)
|
||||
mntget(path->mnt);
|
||||
error = dentry->d_inode->i_op->follow_link(dentry, nd);
|
||||
if (!error) {
|
||||
cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
|
||||
error = PTR_ERR(cookie);
|
||||
if (!IS_ERR(cookie)) {
|
||||
char *s = nd_get_link(nd);
|
||||
error = 0;
|
||||
if (s)
|
||||
error = __vfs_follow_link(nd, s);
|
||||
if (dentry->d_inode->i_op->put_link)
|
||||
dentry->d_inode->i_op->put_link(dentry, nd);
|
||||
dentry->d_inode->i_op->put_link(dentry, nd, cookie);
|
||||
}
|
||||
dput(dentry);
|
||||
mntput(path->mnt);
|
||||
@@ -2344,15 +2347,17 @@ out:
|
||||
int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
|
||||
{
|
||||
struct nameidata nd;
|
||||
int res;
|
||||
void *cookie;
|
||||
|
||||
nd.depth = 0;
|
||||
res = dentry->d_inode->i_op->follow_link(dentry, &nd);
|
||||
if (!res) {
|
||||
res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
|
||||
cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
|
||||
if (!IS_ERR(cookie)) {
|
||||
int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
|
||||
if (dentry->d_inode->i_op->put_link)
|
||||
dentry->d_inode->i_op->put_link(dentry, &nd);
|
||||
dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
|
||||
cookie = ERR_PTR(res);
|
||||
}
|
||||
return res;
|
||||
return PTR_ERR(cookie);
|
||||
}
|
||||
|
||||
int vfs_follow_link(struct nameidata *nd, const char *link)
|
||||
@@ -2395,23 +2400,20 @@ int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
|
||||
return res;
|
||||
}
|
||||
|
||||
int page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
|
||||
void *page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
|
||||
{
|
||||
struct page *page;
|
||||
struct page *page = NULL;
|
||||
nd_set_link(nd, page_getlink(dentry, &page));
|
||||
return 0;
|
||||
return page;
|
||||
}
|
||||
|
||||
void page_put_link(struct dentry *dentry, struct nameidata *nd)
|
||||
void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
|
||||
{
|
||||
if (!IS_ERR(nd_get_link(nd))) {
|
||||
struct page *page;
|
||||
page = find_get_page(dentry->d_inode->i_mapping, 0);
|
||||
if (!page)
|
||||
BUG();
|
||||
struct page *page = cookie;
|
||||
|
||||
if (page) {
|
||||
kunmap(page);
|
||||
page_cache_release(page);
|
||||
page_cache_release(page);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user