summaryrefslogtreecommitdiffstats
path: root/fs/coda/symlink.c
blob: 432b806f80b8d9966730a2368edcbd84dfdfe27e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
 * Symlink inode operations for Coda filesystem
 * Original version: (C) 1996 P. Braam and M. Callahan
 * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University
 * 
 * Carnegie Mellon encourages users to contribute improvements to
 * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/locks.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/string.h>

#include <linux/coda.h>
#include <linux/coda_linux.h>
#include <linux/coda_psdev.h>
#include <linux/coda_cnode.h>
#include <linux/coda_namecache.h>

static int coda_readlink(struct inode *inode, char *buffer, int length);

struct inode_operations coda_symlink_inode_operations = {
	NULL,			/* no file-operations */
	NULL,			/* create */
	NULL,			/* lookup */
	NULL,			/* link */
	NULL,			/* unlink */
	NULL,			/* symlink */
	NULL,			/* mkdir */
	NULL,			/* rmdir */
	NULL,			/* mknod */
	NULL,			/* rename */
	coda_readlink,		/* readlink */
	NULL,           	/* follow_link */
	NULL,			/* readpage */
	NULL,			/* writepage */
	NULL,			/* bmap */
	NULL,			/* truncate */
	NULL,            	/* permission */
	NULL,                   /* smap */
	NULL,                   /* update page */
        NULL                    /* revalidate */
};

static int coda_readlink(struct inode *inode, char *buffer, int length)
{
        int len;
	int error;
        char *buf;
	struct cnode *cp;
        ENTRY;

        cp = ITOC(inode);
        CHECK_CNODE(cp);

        /* the maximum length we receive is len */
        if ( length > CFS_MAXPATHLEN ) 
	        len = CFS_MAXPATHLEN;
	else
	        len = length;
	CODA_ALLOC(buf, char *, len);
	if ( !buf ) 
	        return -ENOMEM;
	
	error = venus_readlink(inode->i_sb, &(cp->c_fid), buf, &len);

        CDEBUG(D_INODE, "result %s\n", buf);
	if (! error) {
		copy_to_user(buffer, buf, len);
		put_user('\0', buffer + len);
		error = len;
		CODA_FREE(buf, len);
	}
	return error;
}