pre-2.3.4..
[davej-history.git] / fs / nfs / symlink.c
blob9194c801f8c23b9b1e827fede38b3963ac13a54a
1 /*
2 * linux/fs/nfs/symlink.c
4 * Copyright (C) 1992 Rick Sladkey
6 * Optimization changes Copyright (C) 1994 Florian La Roche
8 * nfs symlink handling code
9 */
11 #include <linux/sched.h>
12 #include <linux/errno.h>
13 #include <linux/nfs_fs.h>
14 #include <linux/stat.h>
15 #include <linux/mm.h>
16 #include <linux/malloc.h>
17 #include <linux/string.h>
19 #include <asm/uaccess.h>
21 static int nfs_readlink(struct dentry *, char *, int);
22 static struct dentry *nfs_follow_link(struct dentry *, struct dentry *, unsigned int);
25 * symlinks can't do much...
27 struct inode_operations nfs_symlink_inode_operations = {
28 NULL, /* no file-operations */
29 NULL, /* create */
30 NULL, /* lookup */
31 NULL, /* link */
32 NULL, /* unlink */
33 NULL, /* symlink */
34 NULL, /* mkdir */
35 NULL, /* rmdir */
36 NULL, /* mknod */
37 NULL, /* rename */
38 nfs_readlink, /* readlink */
39 nfs_follow_link, /* follow_link */
40 NULL, /* readpage */
41 NULL, /* writepage */
42 NULL, /* bmap */
43 NULL, /* truncate */
44 NULL /* permission */
47 static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen)
49 int error;
50 unsigned int len;
51 char *res;
52 void *mem;
54 dfprintk(VFS, "nfs: readlink(%s/%s)\n",
55 dentry->d_parent->d_name.name, dentry->d_name.name);
57 error = nfs_proc_readlink(NFS_DSERVER(dentry), NFS_FH(dentry),
58 &mem, &res, &len, NFS_MAXPATHLEN);
59 if (! error) {
60 if (len > buflen)
61 len = buflen;
62 copy_to_user(buffer, res, len);
63 error = len;
64 kfree(mem);
66 return error;
69 static struct dentry *
70 nfs_follow_link(struct dentry * dentry, struct dentry *base, unsigned int follow)
72 int error;
73 unsigned int len;
74 char *res;
75 void *mem;
76 char *path;
77 struct dentry *result;
79 dfprintk(VFS, "nfs: follow_link(%s/%s)\n",
80 dentry->d_parent->d_name.name, dentry->d_name.name);
82 error = nfs_proc_readlink(NFS_DSERVER(dentry), NFS_FH(dentry),
83 &mem, &res, &len, NFS_MAXPATHLEN);
84 result = ERR_PTR(error);
85 if (error)
86 goto out_dput;
88 result = ERR_PTR(-ENOMEM);
89 path = kmalloc(len + 1, GFP_KERNEL);
90 if (!path)
91 goto out_mem;
92 memcpy(path, res, len);
93 path[len] = 0;
94 kfree(mem);
96 result = lookup_dentry(path, base, follow);
97 kfree(path);
98 out:
99 return result;
101 out_mem:
102 kfree(mem);
103 out_dput:
104 dput(base);
105 goto out;