This source file includes following definitions.
- nfs_follow_link
- nfs_readlink
1
2
3
4
5
6
7
8
9 #include <asm/segment.h>
10
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
18 static int nfs_readlink(struct inode *, char *, int);
19 static int nfs_follow_link(struct inode *, struct inode *, int, int,
20 struct inode **);
21
22
23
24
25 struct inode_operations nfs_symlink_inode_operations = {
26 NULL,
27 NULL,
28 NULL,
29 NULL,
30 NULL,
31 NULL,
32 NULL,
33 NULL,
34 NULL,
35 NULL,
36 nfs_readlink,
37 nfs_follow_link,
38 NULL,
39 NULL,
40 NULL
41 };
42
43 static int nfs_follow_link(struct inode *dir, struct inode *inode,
44 int flag, int mode, struct inode **res_inode)
45 {
46 int error;
47 char *res;
48
49 *res_inode = NULL;
50 if (!dir) {
51 dir = current->root;
52 dir->i_count++;
53 }
54 if (!inode) {
55 iput(dir);
56 return -ENOENT;
57 }
58 if (!S_ISLNK(inode->i_mode)) {
59 iput(dir);
60 *res_inode = inode;
61 return 0;
62 }
63 if (current->link_count > 5) {
64 iput(inode);
65 iput(dir);
66 return -ELOOP;
67 }
68 res = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_KERNEL);
69 error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), res);
70 if (error) {
71 iput(inode);
72 iput(dir);
73 kfree_s(res, NFS_MAXPATHLEN + 1);
74 return error;
75 }
76 iput(inode);
77 current->link_count++;
78 error = open_namei(res, flag, mode, res_inode, dir);
79 current->link_count--;
80 kfree_s(res, NFS_MAXPATHLEN + 1);
81 return error;
82 }
83
84 static int nfs_readlink(struct inode *inode, char *buffer, int buflen)
85 {
86 int i;
87 char c;
88 int error;
89 char *res;
90
91 if (!S_ISLNK(inode->i_mode)) {
92 iput(inode);
93 return -EINVAL;
94 }
95 if (buflen > NFS_MAXPATHLEN)
96 buflen = NFS_MAXPATHLEN;
97 res = (char *) kmalloc(buflen + 1, GFP_KERNEL);
98 error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), res);
99 iput(inode);
100 if (error) {
101 kfree_s(res, buflen + 1);
102 return error;
103 }
104 for (i = 0; i < buflen && (c = res[i]); i++)
105 put_fs_byte(c,buffer++);
106 kfree_s(res, buflen + 1);
107 return i;
108 }