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
17 static int nfs_readlink(struct inode *, char *, int);
18 static int nfs_follow_link(struct inode *, struct inode *, int, int,
19 struct inode **);
20
21
22
23
24 struct inode_operations nfs_symlink_inode_operations = {
25 NULL,
26 NULL,
27 NULL,
28 NULL,
29 NULL,
30 NULL,
31 NULL,
32 NULL,
33 NULL,
34 NULL,
35 nfs_readlink,
36 nfs_follow_link,
37 NULL,
38 NULL,
39 NULL
40 };
41
42 static int nfs_follow_link(struct inode *dir, struct inode *inode,
43 int flag, int mode, struct inode **res_inode)
44 {
45 int error;
46 unsigned short fs;
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 __asm__("mov %%fs,%0":"=r" (fs));
78 __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
79 current->link_count++;
80 error = open_namei(res, flag, mode, res_inode, dir);
81 current->link_count--;
82 kfree_s(res, NFS_MAXPATHLEN + 1);
83 __asm__("mov %0,%%fs"::"r" (fs));
84 return error;
85 }
86
87 static int nfs_readlink(struct inode *inode, char *buffer, int buflen)
88 {
89 int i;
90 char c;
91 int error;
92 char *res;
93
94 if (!S_ISLNK(inode->i_mode)) {
95 iput(inode);
96 return -EINVAL;
97 }
98 if (buflen > NFS_MAXPATHLEN)
99 buflen = NFS_MAXPATHLEN;
100 res = (char *) kmalloc(buflen + 1, GFP_KERNEL);
101 error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), res);
102 iput(inode);
103 if (error) {
104 kfree_s(res, buflen + 1);
105 return error;
106 }
107 for (i = 0; i < buflen && (c = res[i]); i++)
108 put_fs_byte(c,buffer++);
109 kfree_s(res, buflen + 1);
110 return i;
111 }