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