Commit a4d2a829 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] cifs ->follow_link() switched to new scheme, cleaned up

Signed-off-by: default avatarAl Viro <viro@parcelfarce.linux.org.uk>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 2b3fcc10
......@@ -514,6 +514,7 @@ struct inode_operations cifs_file_inode_ops = {
struct inode_operations cifs_symlink_inode_ops = {
.readlink = cifs_readlink,
.follow_link = cifs_follow_link,
.put_link = cifs_put_link,
.permission = cifs_permission,
/* BB add the following two eventually */
/* revalidate: cifs_revalidate,
......
......@@ -81,6 +81,7 @@ extern struct dentry_operations cifs_dentry_ops;
/* Functions related to symlinks */
extern int cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
extern void cifs_put_link(struct dentry *direntry, struct nameidata *nd);
extern int cifs_readlink(struct dentry *direntry, char __user *buffer, int buflen);
extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
const char *symname);
......
......@@ -20,6 +20,7 @@
*/
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/namei.h>
#include "cifsfs.h"
#include "cifspdu.h"
#include "cifsglob.h"
......@@ -94,7 +95,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
int rc = -EACCES;
int xid;
char *full_path = NULL;
char * target_path;
char * target_path = ERR_PTR(-ENOMEM);
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
......@@ -104,22 +105,17 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
full_path = build_path_from_dentry(direntry);
up(&direntry->d_sb->s_vfs_rename_sem);
if(full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
}
if (!full_path)
goto out;
cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode));
cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
target_path = kmalloc(PATH_MAX, GFP_KERNEL);
if(target_path == NULL) {
if (full_path)
kfree(full_path);
FreeXid(xid);
return -ENOMEM;
if (!target_path) {
target_path = ERR_PTR(-ENOMEM);
goto out;
}
/* can not call the following line due to EFAULT in vfs_readlink which is presumably expecting a user space buffer */
/* length = cifs_readlink(direntry,target_path, sizeof(target_path) - 1); */
/* BB add read reparse point symlink code and Unix extensions symlink code here BB */
if (pTcon->ses->capabilities & CAP_UNIX)
......@@ -139,16 +135,16 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
/* BB Add special case check for Samba DFS symlinks */
target_path[PATH_MAX-1] = 0;
rc = vfs_follow_link(nd, target_path);
} else {
kfree(target_path);
target_path = ERR_PTR(rc);
}
/* else EACCESS */
if (target_path)
kfree(target_path);
if (full_path)
kfree(full_path);
out:
kfree(full_path);
FreeXid(xid);
return rc;
nd_set_link(nd, target_path);
return 0;
}
int
......@@ -323,3 +319,10 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
FreeXid(xid);
return rc;
}
void cifs_put_link(struct dentry *direntry, struct nameidata *nd)
{
char *p = nd_get_link(nd);
if (!IS_ERR(p))
kfree(p);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment