From a4d2a82954d000ede9065b38c98ce07b636c1894 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Tue, 31 Aug 2004 07:46:13 -0700 Subject: [PATCH] [PATCH] cifs ->follow_link() switched to new scheme, cleaned up Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- fs/cifs/cifsfs.c | 1 + fs/cifs/cifsfs.h | 1 + fs/cifs/link.c | 41 ++++++++++++++++++++++------------------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index ec1ef2a61b1d6..01c6d3448369d 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -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, diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 866b68c8beeb3..b1cbc68d09add 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -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); diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 957936d585e65..398c2b7359125 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -20,6 +20,7 @@ */ #include #include +#include #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); +} -- 2.53.0