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; }
static int smb_follow_link(struct dentry *dentry, struct nameidata *nd) { char *link = __getname(); DEBUG1("followlink of %s/%s\n", DENTRY_PATH(dentry)); if (!link) { link = ERR_PTR(-ENOMEM); } else { int len = smb_proc_read_link(server_from_dentry(dentry), dentry, link, PATH_MAX - 1); if (len < 0) { __putname(link); link = ERR_PTR(len); } else { link[len] = 0; } } nd_set_link(nd, link); return 0; }
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; }