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
6 * Carnegie Mellon encourages users to contribute improvements to
7 * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.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
*,
32 struct inode_operations coda_symlink_inode_operations
= {
33 NULL
, /* no file-operations */
43 coda_readlink
, /* readlink */
44 coda_follow_link
, /* follow_link */
49 NULL
, /* permission */
51 NULL
, /* update page */
55 static int coda_readlink(struct dentry
*de
, char *buffer
, int length
)
57 struct inode
*inode
= de
->d_inode
;
61 struct coda_inode_info
*cp
;
65 coda_vfs_stat
.readlink
++;
67 /* the maximum length we receive is len */
68 if ( length
> CODA_MAXPATHLEN
)
69 len
= CODA_MAXPATHLEN
;
72 CODA_ALLOC(buf
, char *, len
);
76 error
= venus_readlink(inode
->i_sb
, &(cp
->c_fid
), buf
, &len
);
78 CDEBUG(D_INODE
, "result %s\n", buf
);
80 copy_to_user(buffer
, buf
, len
);
81 put_user('\0', buffer
+ len
);
89 static struct dentry
*coda_follow_link(struct dentry
*de
, struct dentry
*base
,
92 struct inode
*inode
= de
->d_inode
;
94 struct coda_inode_info
*cnp
;
96 char mem
[CODA_MAXPATHLEN
];
99 CDEBUG(D_INODE
, "(%x/%ld)\n", inode
->i_dev
, inode
->i_ino
);
102 coda_vfs_stat
.follow_link
++;
104 len
= CODA_MAXPATHLEN
;
105 error
= venus_readlink(inode
->i_sb
, &(cnp
->c_fid
), mem
, &len
);
109 return ERR_PTR(error
);
112 path
= kmalloc(len
+ 1, GFP_KERNEL
);
115 return ERR_PTR(-ENOMEM
);
117 memcpy(path
, mem
, len
);
120 base
= lookup_dentry(path
, base
, follow
);