This source file includes following definitions.
- ufs_readlink
- ufs_follow_link
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/fs.h>
14 #include <linux/sched.h>
15
16 #include <asm/segment.h>
17
18 static int
19 ufs_readlink(struct inode * inode, char * buffer, int buflen)
20 {
21 unsigned long int block;
22 struct buffer_head * bh = NULL;
23 char * link;
24 int i, err;
25 char c;
26
27 if (inode->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_LINKS)) {
28 printk("ufs_readlink: called on ino %lu dev %u/%u\n",
29 inode->i_ino, MAJOR(inode->i_dev), MINOR(inode->i_dev));
30 }
31
32 if (!S_ISLNK(inode->i_mode)) {
33 iput (inode);
34 return -EINVAL;
35 }
36 if (buflen > inode->i_sb->s_blocksize - 1)
37 buflen = inode->i_sb->s_blocksize - 1;
38 if (inode->i_blocks) {
39
40 block = ufs_bmap(inode, 0);
41 if (inode->i_sb->u.ufs_sb.s_flags &(UFS_DEBUG|UFS_DEBUG_LINKS)) {
42 printk("ufs_readlink: bmap got %lu for ino %lu\n",
43 block, inode->i_ino);
44 }
45 bh = bread(inode->i_dev, block, BLOCK_SIZE);
46 if (!bh) {
47 iput (inode);
48 printk("ufs_readlink: can't read block 0 for ino %lu on dev %u/%u\n",
49 inode->i_ino, MAJOR(inode->i_dev),
50 MINOR(inode->i_dev));
51 return 0;
52 }
53 link = bh->b_data;
54 }
55 else {
56 link = (char *)&(inode->u.ufs_i.ui_db[0]);
57 }
58 i = 0;
59 while (i < buflen && (c = link[i])) {
60 i++;
61 put_user (c, buffer++);
62 }
63 iput (inode);
64 if (bh)
65 brelse (bh);
66 return i;
67
68 return(0);
69 }
70
71
72
73
74 static int
75 ufs_follow_link(struct inode * dir, struct inode * inode,
76 int flag, int mode, struct inode ** res_inode)
77 {
78 unsigned long int block;
79 int error;
80 struct buffer_head * bh;
81 char * link;
82
83 bh = NULL;
84
85 if (inode->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_LINKS)) {
86 printk("ufs_follow_link: called on ino %lu dev %u/%u\n",
87 dir->i_ino, MAJOR(dir->i_dev), MINOR(dir->i_dev));
88 }
89
90 *res_inode = NULL;
91 if (!dir) {
92 dir = current->fs->root;
93 dir->i_count++;
94 }
95 if (!inode) {
96 iput (dir);
97 return -ENOENT;
98 }
99 if (!S_ISLNK(inode->i_mode)) {
100 iput (dir);
101 *res_inode = inode;
102 return 0;
103 }
104 if (current->link_count > 5) {
105 iput (dir);
106 iput (inode);
107 return -ELOOP;
108 }
109 if (inode->i_blocks) {
110
111
112 block = ufs_bmap(inode, 0);
113 bh = bread(inode->i_dev, block, BLOCK_SIZE);
114 if (bh == NULL) {
115 printk("ufs_follow_link: can't read block 0 for ino %lu on dev %u/%u\n",
116 inode->i_ino, MAJOR(inode->i_dev),
117 MINOR(inode->i_dev));
118 iput(dir);
119 iput(inode);
120 return(-EIO);
121 }
122 link = bh->b_data;
123 } else {
124
125 link = (char *)&(inode->u.ufs_i.ui_db[0]);
126 }
127 current->link_count++;
128 error = open_namei (link, flag, mode, res_inode, dir);
129 current->link_count--;
130 iput (inode);
131 if (bh) {
132 brelse (bh);
133 }
134 return(error);
135 }
136
137
138 static struct file_operations ufs_symlink_operations = {
139 NULL,
140 NULL,
141 NULL,
142 NULL,
143 NULL,
144 NULL,
145 NULL,
146 NULL,
147 NULL,
148 NULL,
149 NULL,
150 NULL,
151 NULL,
152 };
153
154 struct inode_operations ufs_symlink_inode_operations = {
155 &ufs_symlink_operations,
156 NULL,
157 NULL,
158 NULL,
159 NULL,
160 NULL,
161 NULL,
162 NULL,
163 NULL,
164 NULL,
165 &ufs_readlink,
166 &ufs_follow_link,
167 NULL,
168 NULL,
169 NULL,
170 NULL,
171 NULL,
172 NULL,
173 };
174
175
176
177
178
179
180
181
182
183