This source file includes following definitions.
- affs_follow_link
- affs_readlink
1
2
3
4
5
6
7
8
9
10
11 #include <linux/errno.h>
12 #include <linux/sched.h>
13 #include <linux/malloc.h>
14 #include <linux/fs.h>
15 #include <linux/stat.h>
16 #include <linux/affs_fs.h>
17 #include <linux/amigaffs.h>
18
19 #include <asm/segment.h>
20
21 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
22
23 static int affs_readlink(struct inode *, char *, int);
24 static int affs_follow_link(struct inode *, struct inode *, int, int, struct inode **);
25
26 struct inode_operations affs_symlink_inode_operations = {
27 NULL,
28 NULL,
29 NULL,
30 NULL,
31 NULL,
32 NULL,
33 NULL,
34 NULL,
35 NULL,
36 NULL,
37 affs_readlink,
38 affs_follow_link,
39 NULL,
40 NULL,
41 NULL
42 };
43
44 static int
45 affs_follow_link(struct inode *dir, struct inode *inode, int flag, int mode,
46 struct inode **res_inode)
47 {
48 struct buffer_head *bh;
49 struct slink_front *lf;
50 char *buffer;
51 int error;
52 int i, j;
53 char c;
54 char lc;
55
56 pr_debug("AFFS: follow_link(ino=%lu)\n",inode->i_ino);
57
58 *res_inode = NULL;
59 if (!dir) {
60 dir = current->fs->root;
61 dir->i_count++;
62 }
63 if (!inode) {
64 iput(dir);
65 return -ENOENT;
66 }
67 if (!S_ISLNK(inode->i_mode)) {
68 iput(dir);
69 *res_inode = inode;
70 return 0;
71 }
72 if (current->link_count > 5) {
73 iput(inode);
74 iput(dir);
75 return -ELOOP;
76 }
77 if (!(buffer = kmalloc(1024,GFP_KERNEL))) {
78 iput(inode);
79 iput(dir);
80 return -ENOSPC;
81 }
82 bh = affs_bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode));
83 i = 0;
84 j = 0;
85 if (!bh) {
86 printk("AFFS: unable to read i-node block %lu\n",inode->i_ino);
87 kfree(buffer);
88 iput(inode);
89 iput(dir);
90 return -EIO;
91 }
92 lf = (struct slink_front *)bh->b_data;
93 lc = 0;
94 if (strchr(lf->symname,':')) {
95 while (i < 1023 && (c = inode->i_sb->u.affs_sb.s_prefix[i]))
96 buffer[i++] = c;
97 while (i < 1023 && lf->symname[j] != ':')
98 buffer[i++] = lf->symname[j++];
99 if (i < 1023)
100 buffer[i++] = '/';
101 j++;
102 lc = '/';
103 }
104 while (i < 1023 && (c = lf->symname[j])) {
105 if (c == '/' && lc == '/' && i < 1020) {
106 buffer[i++] = '.';
107 buffer[i++] = '.';
108 }
109 buffer[i++] = c;
110 lc = c;
111 j++;
112 }
113 buffer[i] = '\0';
114 affs_brelse(bh);
115 iput(inode);
116 current->link_count++;
117 error = open_namei(buffer,flag,mode,res_inode,dir);
118 current->link_count--;
119 kfree(buffer);
120 return error;
121 }
122
123 static int
124 affs_readlink(struct inode *inode, char *buffer, int buflen)
125 {
126 struct buffer_head *bh;
127 struct slink_front *lf;
128 int i, j;
129 char c;
130 char lc;
131
132 pr_debug("AFFS: readlink(ino=%lu,buflen=%d)\n",inode->i_ino,buflen);
133
134 if (!S_ISLNK(inode->i_mode)) {
135 iput(inode);
136 return -EINVAL;
137 }
138 bh = affs_bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode));
139 i = 0;
140 j = 0;
141 if (!bh) {
142 printk("AFFS: unable to read i-node block %lu\n",inode->i_ino);
143 goto symlink_end;
144 }
145 lf = (struct slink_front *)bh->b_data;
146 lc = 0;
147
148 if (strchr(lf->symname,':')) {
149 while (i < buflen && (c = inode->i_sb->u.affs_sb.s_prefix[i])) {
150 put_user(c,buffer++);
151 i++;
152 }
153 while (i < buflen && (c = lf->symname[j]) != ':') {
154 put_user(c,buffer++);
155 i++, j++;
156 }
157 if (i < buflen) {
158 put_user('/',buffer++);
159 i++, j++;
160 }
161 lc = '/';
162 }
163 while (i < buflen && (c = lf->symname[j])) {
164 if (c == '/' && lc == '/' && (i + 3 < buflen)) {
165 put_user('.',buffer++);
166 put_user('.',buffer++);
167 i += 2;
168 }
169 put_user(c,buffer++);
170 lc = c;
171 i++, j++;
172 }
173 symlink_end:
174 iput(inode);
175 affs_brelse(bh);
176 return i;
177 }