This source file includes following definitions.
- cp_old_stat
- cp_new_stat
- sys_stat
- sys_newstat
- sys_lstat
- sys_newlstat
- sys_fstat
- sys_newfstat
- sys_readlink
1
2
3
4
5
6
7 #include <linux/errno.h>
8 #include <linux/string.h>
9 #include <linux/stat.h>
10 #include <linux/fs.h>
11 #include <linux/sched.h>
12 #include <linux/kernel.h>
13 #include <linux/mm.h>
14
15 #include <asm/segment.h>
16
17 static void cp_old_stat(struct inode * inode, struct old_stat * statbuf)
18 {
19 struct old_stat tmp;
20
21 printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n",
22 current->comm);
23 tmp.st_dev = kdev_t_to_nr(inode->i_dev);
24 tmp.st_ino = inode->i_ino;
25 tmp.st_mode = inode->i_mode;
26 tmp.st_nlink = inode->i_nlink;
27 tmp.st_uid = inode->i_uid;
28 tmp.st_gid = inode->i_gid;
29 tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
30 tmp.st_size = inode->i_size;
31 if (inode->i_pipe)
32 tmp.st_size = PIPE_SIZE(*inode);
33 tmp.st_atime = inode->i_atime;
34 tmp.st_mtime = inode->i_mtime;
35 tmp.st_ctime = inode->i_ctime;
36 memcpy_tofs(statbuf,&tmp,sizeof(tmp));
37 }
38
39 static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
40 {
41 struct new_stat tmp;
42 unsigned int blocks, indirect;
43
44 memset(&tmp, 0, sizeof(tmp));
45 tmp.st_dev = kdev_t_to_nr(inode->i_dev);
46 tmp.st_ino = inode->i_ino;
47 tmp.st_mode = inode->i_mode;
48 tmp.st_nlink = inode->i_nlink;
49 tmp.st_uid = inode->i_uid;
50 tmp.st_gid = inode->i_gid;
51 tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
52 tmp.st_size = inode->i_size;
53 if (inode->i_pipe)
54 tmp.st_size = PIPE_SIZE(*inode);
55 tmp.st_atime = inode->i_atime;
56 tmp.st_mtime = inode->i_mtime;
57 tmp.st_ctime = inode->i_ctime;
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 #define D_B 7
74 #define I_B (BLOCK_SIZE / sizeof(unsigned short))
75
76 if (!inode->i_blksize) {
77 blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
78 if (blocks > D_B) {
79 indirect = (blocks - D_B + I_B - 1) / I_B;
80 blocks += indirect;
81 if (indirect > 1) {
82 indirect = (indirect - 1 + I_B - 1) / I_B;
83 blocks += indirect;
84 if (indirect > 1)
85 blocks++;
86 }
87 }
88 tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
89 tmp.st_blksize = BLOCK_SIZE;
90 } else {
91 tmp.st_blocks = inode->i_blocks;
92 tmp.st_blksize = inode->i_blksize;
93 }
94 memcpy_tofs(statbuf,&tmp,sizeof(tmp));
95 }
96
97 asmlinkage int sys_stat(char * filename, struct old_stat * statbuf)
98 {
99 struct inode * inode;
100 int error;
101
102 error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
103 if (error)
104 return error;
105 error = namei(filename,&inode);
106 if (error)
107 return error;
108 cp_old_stat(inode,statbuf);
109 iput(inode);
110 return 0;
111 }
112
113 asmlinkage int sys_newstat(char * filename, struct new_stat * statbuf)
114 {
115 struct inode * inode;
116 int error;
117
118 error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
119 if (error)
120 return error;
121 error = namei(filename,&inode);
122 if (error)
123 return error;
124 cp_new_stat(inode,statbuf);
125 iput(inode);
126 return 0;
127 }
128
129 asmlinkage int sys_lstat(char * filename, struct old_stat * statbuf)
130 {
131 struct inode * inode;
132 int error;
133
134 error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
135 if (error)
136 return error;
137 error = lnamei(filename,&inode);
138 if (error)
139 return error;
140 cp_old_stat(inode,statbuf);
141 iput(inode);
142 return 0;
143 }
144
145 asmlinkage int sys_newlstat(char * filename, struct new_stat * statbuf)
146 {
147 struct inode * inode;
148 int error;
149
150 error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
151 if (error)
152 return error;
153 error = lnamei(filename,&inode);
154 if (error)
155 return error;
156 cp_new_stat(inode,statbuf);
157 iput(inode);
158 return 0;
159 }
160
161 asmlinkage int sys_fstat(unsigned int fd, struct old_stat * statbuf)
162 {
163 struct file * f;
164 struct inode * inode;
165 int error;
166
167 error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
168 if (error)
169 return error;
170 if (fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))
171 return -EBADF;
172 cp_old_stat(inode,statbuf);
173 return 0;
174 }
175
176 asmlinkage int sys_newfstat(unsigned int fd, struct new_stat * statbuf)
177 {
178 struct file * f;
179 struct inode * inode;
180 int error;
181
182 error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
183 if (error)
184 return error;
185 if (fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))
186 return -EBADF;
187 cp_new_stat(inode,statbuf);
188 return 0;
189 }
190
191 asmlinkage int sys_readlink(const char * path, char * buf, int bufsiz)
192 {
193 struct inode * inode;
194 int error;
195
196 if (bufsiz <= 0)
197 return -EINVAL;
198 error = verify_area(VERIFY_WRITE,buf,bufsiz);
199 if (error)
200 return error;
201 error = lnamei(path,&inode);
202 if (error)
203 return error;
204 if (!inode->i_op || !inode->i_op->readlink) {
205 iput(inode);
206 return -EINVAL;
207 }
208 return inode->i_op->readlink(inode,buf,bufsiz);
209 }