/* * symlink.c * * Copyright (C) 2002 by John Newbigin * * Please add a note about your changes to smbfs in the ChangeLog file. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "smb_debug.h" #include "proto.h" int smb_read_link(struct dentry *dentry, char *buffer, int len) { char *link; int result; DEBUG1("read link buffer len = %d\n", len); result = -ENOMEM; link = kmalloc(SMB_MAXNAMELEN + 1, GFP_KERNEL); if (!link) goto out; result = smb_proc_read_link(server_from_dentry(dentry), dentry, link, SMB_MAXNAMELEN); if (result < 0) goto out_free; result = vfs_readlink(dentry, buffer, len, link); out_free: kfree(link); out: return result; } int smb_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) { DEBUG1("create symlink %s -> %s/%s\n", oldname, DENTRY_PATH(dentry)); smb_invalid_dir_cache(dir); return smb_proc_symlink(server_from_dentry(dentry), dentry, oldname); } int smb_follow_link(struct dentry *dentry, struct nameidata *nd) { char *link; int result; DEBUG1("followlink of %s/%s\n", DENTRY_PATH(dentry)); result = -ENOMEM; link = kmalloc(SMB_MAXNAMELEN + 1, GFP_KERNEL); if (!link) goto out; result = smb_proc_read_link(server_from_dentry(dentry), dentry, link, SMB_MAXNAMELEN); if (result < 0 || result >= SMB_MAXNAMELEN) goto out_free; link[result] = 0; result = vfs_follow_link(nd, link); out_free: kfree(link); out: return result; } struct inode_operations smb_link_inode_operations = { .readlink = smb_read_link, .follow_link = smb_follow_link, };