Import 2.2.7
[davej-history.git] / fs / coda / symlink.c
blobb42555811e4951a39726a9c3a8e9d969b2ecc32c
1 /*
2 * Symlink inode operations for Coda filesystem
3 * Original version: (C) 1996 P. Braam and M. Callahan
4 * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University
5 *
6 * Carnegie Mellon encourages users to contribute improvements to
7 * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
8 */
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
13 #include <linux/fs.h>
14 #include <linux/stat.h>
15 #include <linux/errno.h>
16 #include <linux/locks.h>
17 #include <asm/segment.h>
18 #include <asm/uaccess.h>
19 #include <linux/string.h>
21 #include <linux/coda.h>
22 #include <linux/coda_linux.h>
23 #include <linux/coda_psdev.h>
24 #include <linux/coda_fs_i.h>
25 #include <linux/coda_cache.h>
26 #include <linux/coda_proc.h>
28 static int coda_readlink(struct dentry *de, char *buffer, int length);
29 static struct dentry *coda_follow_link(struct dentry *, struct dentry *,
30 unsigned int);
32 struct inode_operations coda_symlink_inode_operations = {
33 NULL, /* no file-operations */
34 NULL, /* create */
35 NULL, /* lookup */
36 NULL, /* link */
37 NULL, /* unlink */
38 NULL, /* symlink */
39 NULL, /* mkdir */
40 NULL, /* rmdir */
41 NULL, /* mknod */
42 NULL, /* rename */
43 coda_readlink, /* readlink */
44 coda_follow_link, /* follow_link */
45 NULL, /* readpage */
46 NULL, /* writepage */
47 NULL, /* bmap */
48 NULL, /* truncate */
49 NULL, /* permission */
50 NULL, /* smap */
51 NULL, /* update page */
52 NULL /* revalidate */
55 static int coda_readlink(struct dentry *de, char *buffer, int length)
57 struct inode *inode = de->d_inode;
58 int len;
59 int error;
60 char *buf;
61 struct coda_inode_info *cp;
62 ENTRY;
64 cp = ITOC(inode);
65 coda_vfs_stat.readlink++;
67 /* the maximum length we receive is len */
68 if ( length > CODA_MAXPATHLEN )
69 len = CODA_MAXPATHLEN;
70 else
71 len = length;
72 CODA_ALLOC(buf, char *, len);
73 if ( !buf )
74 return -ENOMEM;
76 error = venus_readlink(inode->i_sb, &(cp->c_fid), buf, &len);
78 CDEBUG(D_INODE, "result %s\n", buf);
79 if (! error) {
80 copy_to_user(buffer, buf, len);
81 put_user('\0', buffer + len);
82 error = len;
84 if ( buf )
85 CODA_FREE(buf, len);
86 return error;
89 static struct dentry *coda_follow_link(struct dentry *de, struct dentry *base,
90 unsigned int follow)
92 struct inode *inode = de->d_inode;
93 int error;
94 struct coda_inode_info *cnp;
95 unsigned int len;
96 char mem[CODA_MAXPATHLEN];
97 char *path;
98 ENTRY;
99 CDEBUG(D_INODE, "(%x/%ld)\n", inode->i_dev, inode->i_ino);
101 cnp = ITOC(inode);
102 coda_vfs_stat.follow_link++;
104 len = CODA_MAXPATHLEN;
105 error = venus_readlink(inode->i_sb, &(cnp->c_fid), mem, &len);
107 if (error) {
108 dput(base);
109 return ERR_PTR(error);
111 len = strlen(mem);
112 path = kmalloc(len + 1, GFP_KERNEL);
113 if (!path) {
114 dput(base);
115 return ERR_PTR(-ENOMEM);
117 memcpy(path, mem, len);
118 path[len] = 0;
120 base = lookup_dentry(path, base, follow);
121 kfree(path);
122 return base;