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 extern int ufs_bmap (struct inode *, int);
19
20 static int
21 ufs_readlink(struct inode * inode, char * buffer, int buflen)
22 {
23 unsigned long int block;
24 struct buffer_head * bh = NULL;
25 char * link;
26 int i;
27 char c;
28
29 if (inode->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_LINKS)) {
30 printk("ufs_readlink: called on ino %lu dev %u/%u\n",
31 inode->i_ino, MAJOR(inode->i_dev), MINOR(inode->i_dev));
32 }
33
34 if (!S_ISLNK(inode->i_mode)) {
35 iput (inode);
36 return -EINVAL;
37 }
38 if (buflen > inode->i_sb->s_blocksize - 1)
39 buflen = inode->i_sb->s_blocksize - 1;
40 if (inode->i_blocks) {
41
42 block = ufs_bmap(inode, 0);
43 if (inode->i_sb->u.ufs_sb.s_flags &(UFS_DEBUG|UFS_DEBUG_LINKS)) {
44 printk("ufs_readlink: bmap got %lu for ino %lu\n",
45 block, inode->i_ino);
46 }
47 bh = bread(inode->i_dev, block, BLOCK_SIZE);
48 if (!bh) {
49 iput (inode);
50 printk("ufs_readlink: can't read block 0 for ino %lu on dev %u/%u\n",
51 inode->i_ino, MAJOR(inode->i_dev),
52 MINOR(inode->i_dev));
53 return 0;
54 }
55 link = bh->b_data;
56 }
57 else {
58 link = (char *)&(inode->u.ufs_i.ui_db[0]);
59 }
60 i = 0;
61 while (i < buflen && (c = link[i])) {
62 i++;
63 put_user (c, buffer++);
64 }
65 iput (inode);
66 if (bh)
67 brelse (bh);
68 return i;
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