Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / fs / stat.c
1 /*
2  *  linux/fs/stat.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  */
6
7 #include <linux/config.h>
8 #include <linux/module.h>
9 #include <linux/mm.h>
10 #include <linux/errno.h>
11 #include <linux/file.h>
12 #include <linux/smp_lock.h>
13 #include <linux/highuid.h>
14 #include <linux/fs.h>
15 #include <linux/namei.h>
16 #include <linux/security.h>
17 #include <linux/syscalls.h>
18
19 #include <asm/uaccess.h>
20 #include <asm/unistd.h>
21
22 void generic_fillattr(struct inode *inode, struct kstat *stat)
23 {
24         stat->dev = inode->i_sb->s_dev;
25         stat->ino = inode->i_ino;
26         stat->mode = inode->i_mode;
27         stat->nlink = inode->i_nlink;
28         stat->uid = inode->i_uid;
29         stat->gid = inode->i_gid;
30         stat->xid = inode->i_xid;
31         stat->rdev = inode->i_rdev;
32         stat->atime = inode->i_atime;
33         stat->mtime = inode->i_mtime;
34         stat->ctime = inode->i_ctime;
35         stat->size = i_size_read(inode);
36         stat->blocks = inode->i_blocks;
37         stat->blksize = inode->i_blksize;
38 }
39
40 EXPORT_SYMBOL(generic_fillattr);
41
42 int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
43 {
44         struct inode *inode = dentry->d_inode;
45         int retval;
46
47         retval = security_inode_getattr(mnt, dentry);
48         if (retval)
49                 return retval;
50
51         if (inode->i_op->getattr)
52                 return inode->i_op->getattr(mnt, dentry, stat);
53
54         generic_fillattr(inode, stat);
55         if (!stat->blksize) {
56                 struct super_block *s = inode->i_sb;
57                 unsigned blocks;
58                 blocks = (stat->size+s->s_blocksize-1) >> s->s_blocksize_bits;
59                 stat->blocks = (s->s_blocksize / 512) * blocks;
60                 stat->blksize = s->s_blocksize;
61         }
62         return 0;
63 }
64
65 EXPORT_SYMBOL(vfs_getattr);
66
67 int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
68 {
69         struct nameidata nd;
70         int error;
71
72         error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd);
73         if (!error) {
74                 error = vfs_getattr(nd.mnt, nd.dentry, stat);
75                 path_release(&nd);
76         }
77         return error;
78 }
79
80 int vfs_stat(char __user *name, struct kstat *stat)
81 {
82         return vfs_stat_fd(AT_FDCWD, name, stat);
83 }
84
85 EXPORT_SYMBOL(vfs_stat);
86
87 int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat)
88 {
89         struct nameidata nd;
90         int error;
91
92         error = __user_walk_fd(dfd, name, 0, &nd);
93         if (!error) {
94                 error = vfs_getattr(nd.mnt, nd.dentry, stat);
95                 path_release(&nd);
96         }
97         return error;
98 }
99
100 int vfs_lstat(char __user *name, struct kstat *stat)
101 {
102         return vfs_lstat_fd(AT_FDCWD, name, stat);
103 }
104
105 EXPORT_SYMBOL(vfs_lstat);
106
107 int vfs_fstat(unsigned int fd, struct kstat *stat)
108 {
109         struct file *f = fget(fd);
110         int error = -EBADF;
111
112         if (f) {
113                 error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
114                 fput(f);
115         }
116         return error;
117 }
118
119 EXPORT_SYMBOL(vfs_fstat);
120
121 #ifdef __ARCH_WANT_OLD_STAT
122
123 /*
124  * For backward compatibility?  Maybe this should be moved
125  * into arch/i386 instead?
126  */
127 static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * statbuf)
128 {
129         static int warncount = 5;
130         struct __old_kernel_stat tmp;
131         
132         if (warncount > 0) {
133                 warncount--;
134                 printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
135                         current->comm);
136         } else if (warncount < 0) {
137                 /* it's laughable, but... */
138                 warncount = 0;
139         }
140
141         memset(&tmp, 0, sizeof(struct __old_kernel_stat));
142         tmp.st_dev = old_encode_dev(stat->dev);
143         tmp.st_ino = stat->ino;
144         tmp.st_mode = stat->mode;
145         tmp.st_nlink = stat->nlink;
146         if (tmp.st_nlink != stat->nlink)
147                 return -EOVERFLOW;
148         SET_UID(tmp.st_uid, stat->uid);
149         SET_GID(tmp.st_gid, stat->gid);
150         tmp.st_rdev = old_encode_dev(stat->rdev);
151 #if BITS_PER_LONG == 32
152         if (stat->size > MAX_NON_LFS)
153                 return -EOVERFLOW;
154 #endif  
155         tmp.st_size = stat->size;
156         tmp.st_atime = stat->atime.tv_sec;
157         tmp.st_mtime = stat->mtime.tv_sec;
158         tmp.st_ctime = stat->ctime.tv_sec;
159         return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
160 }
161
162 asmlinkage long sys_stat(char __user * filename, struct __old_kernel_stat __user * statbuf)
163 {
164         struct kstat stat;
165         int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
166
167         if (!error)
168                 error = cp_old_stat(&stat, statbuf);
169
170         return error;
171 }
172 asmlinkage long sys_lstat(char __user * filename, struct __old_kernel_stat __user * statbuf)
173 {
174         struct kstat stat;
175         int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
176
177         if (!error)
178                 error = cp_old_stat(&stat, statbuf);
179
180         return error;
181 }
182 asmlinkage long sys_fstat(unsigned int fd, struct __old_kernel_stat __user * statbuf)
183 {
184         struct kstat stat;
185         int error = vfs_fstat(fd, &stat);
186
187         if (!error)
188                 error = cp_old_stat(&stat, statbuf);
189
190         return error;
191 }
192
193 #endif /* __ARCH_WANT_OLD_STAT */
194
195 static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
196 {
197         struct stat tmp;
198
199 #if BITS_PER_LONG == 32
200         if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
201                 return -EOVERFLOW;
202 #else
203         if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
204                 return -EOVERFLOW;
205 #endif
206
207         memset(&tmp, 0, sizeof(tmp));
208 #if BITS_PER_LONG == 32
209         tmp.st_dev = old_encode_dev(stat->dev);
210 #else
211         tmp.st_dev = new_encode_dev(stat->dev);
212 #endif
213         tmp.st_ino = stat->ino;
214         tmp.st_mode = stat->mode;
215         tmp.st_nlink = stat->nlink;
216         if (tmp.st_nlink != stat->nlink)
217                 return -EOVERFLOW;
218         SET_UID(tmp.st_uid, stat->uid);
219         SET_GID(tmp.st_gid, stat->gid);
220 #if BITS_PER_LONG == 32
221         tmp.st_rdev = old_encode_dev(stat->rdev);
222 #else
223         tmp.st_rdev = new_encode_dev(stat->rdev);
224 #endif
225 #if BITS_PER_LONG == 32
226         if (stat->size > MAX_NON_LFS)
227                 return -EOVERFLOW;
228 #endif  
229         tmp.st_size = stat->size;
230         tmp.st_atime = stat->atime.tv_sec;
231         tmp.st_mtime = stat->mtime.tv_sec;
232         tmp.st_ctime = stat->ctime.tv_sec;
233 #ifdef STAT_HAVE_NSEC
234         tmp.st_atime_nsec = stat->atime.tv_nsec;
235         tmp.st_mtime_nsec = stat->mtime.tv_nsec;
236         tmp.st_ctime_nsec = stat->ctime.tv_nsec;
237 #endif
238         tmp.st_blocks = stat->blocks;
239         tmp.st_blksize = stat->blksize;
240         return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
241 }
242
243 asmlinkage long sys_newstat(char __user *filename, struct stat __user *statbuf)
244 {
245         struct kstat stat;
246         int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
247
248         if (!error)
249                 error = cp_new_stat(&stat, statbuf);
250
251         return error;
252 }
253
254 asmlinkage long sys_newlstat(char __user *filename, struct stat __user *statbuf)
255 {
256         struct kstat stat;
257         int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
258
259         if (!error)
260                 error = cp_new_stat(&stat, statbuf);
261
262         return error;
263 }
264
265 #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
266 asmlinkage long sys_newfstatat(int dfd, char __user *filename,
267                                 struct stat __user *statbuf, int flag)
268 {
269         struct kstat stat;
270         int error = -EINVAL;
271
272         if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
273                 goto out;
274
275         if (flag & AT_SYMLINK_NOFOLLOW)
276                 error = vfs_lstat_fd(dfd, filename, &stat);
277         else
278                 error = vfs_stat_fd(dfd, filename, &stat);
279
280         if (!error)
281                 error = cp_new_stat(&stat, statbuf);
282
283 out:
284         return error;
285 }
286 #endif
287
288 asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf)
289 {
290         struct kstat stat;
291         int error = vfs_fstat(fd, &stat);
292
293         if (!error)
294                 error = cp_new_stat(&stat, statbuf);
295
296         return error;
297 }
298
299 asmlinkage long sys_readlinkat(int dfd, const char __user *path,
300                                 char __user *buf, int bufsiz)
301 {
302         struct nameidata nd;
303         int error;
304
305         if (bufsiz <= 0)
306                 return -EINVAL;
307
308         error = __user_walk_fd(dfd, path, 0, &nd);
309         if (!error) {
310                 struct inode * inode = nd.dentry->d_inode;
311
312                 error = -EINVAL;
313                 if (inode->i_op && inode->i_op->readlink) {
314                         error = security_inode_readlink(nd.dentry);
315                         if (!error) {
316                                 touch_atime(nd.mnt, nd.dentry);
317                                 error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
318                         }
319                 }
320                 path_release(&nd);
321         }
322         return error;
323 }
324
325 asmlinkage long sys_readlink(const char __user *path, char __user *buf,
326                                 int bufsiz)
327 {
328         return sys_readlinkat(AT_FDCWD, path, buf, bufsiz);
329 }
330
331
332 /* ---------- LFS-64 ----------- */
333 #ifdef __ARCH_WANT_STAT64
334
335 static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf)
336 {
337         struct stat64 tmp;
338
339         memset(&tmp, 0, sizeof(struct stat64));
340 #ifdef CONFIG_MIPS
341         /* mips has weird padding, so we don't get 64 bits there */
342         if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
343                 return -EOVERFLOW;
344         tmp.st_dev = new_encode_dev(stat->dev);
345         tmp.st_rdev = new_encode_dev(stat->rdev);
346 #else
347         tmp.st_dev = huge_encode_dev(stat->dev);
348         tmp.st_rdev = huge_encode_dev(stat->rdev);
349 #endif
350         tmp.st_ino = stat->ino;
351 #ifdef STAT64_HAS_BROKEN_ST_INO
352         tmp.__st_ino = stat->ino;
353 #endif
354         tmp.st_mode = stat->mode;
355         tmp.st_nlink = stat->nlink;
356         tmp.st_uid = stat->uid;
357         tmp.st_gid = stat->gid;
358         tmp.st_atime = stat->atime.tv_sec;
359         tmp.st_atime_nsec = stat->atime.tv_nsec;
360         tmp.st_mtime = stat->mtime.tv_sec;
361         tmp.st_mtime_nsec = stat->mtime.tv_nsec;
362         tmp.st_ctime = stat->ctime.tv_sec;
363         tmp.st_ctime_nsec = stat->ctime.tv_nsec;
364         tmp.st_size = stat->size;
365         tmp.st_blocks = stat->blocks;
366         tmp.st_blksize = stat->blksize;
367         return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
368 }
369
370 asmlinkage long sys_stat64(char __user * filename, struct stat64 __user * statbuf)
371 {
372         struct kstat stat;
373         int error = vfs_stat(filename, &stat);
374
375         if (!error)
376                 error = cp_new_stat64(&stat, statbuf);
377
378         return error;
379 }
380 asmlinkage long sys_lstat64(char __user * filename, struct stat64 __user * statbuf)
381 {
382         struct kstat stat;
383         int error = vfs_lstat(filename, &stat);
384
385         if (!error)
386                 error = cp_new_stat64(&stat, statbuf);
387
388         return error;
389 }
390 asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user * statbuf)
391 {
392         struct kstat stat;
393         int error = vfs_fstat(fd, &stat);
394
395         if (!error)
396                 error = cp_new_stat64(&stat, statbuf);
397
398         return error;
399 }
400
401 asmlinkage long sys_fstatat64(int dfd, char __user *filename,
402                                struct stat64 __user *statbuf, int flag)
403 {
404         struct kstat stat;
405         int error = -EINVAL;
406
407         if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
408                 goto out;
409
410         if (flag & AT_SYMLINK_NOFOLLOW)
411                 error = vfs_lstat_fd(dfd, filename, &stat);
412         else
413                 error = vfs_stat_fd(dfd, filename, &stat);
414
415         if (!error)
416                 error = cp_new_stat64(&stat, statbuf);
417
418 out:
419         return error;
420 }
421 #endif /* __ARCH_WANT_STAT64 */
422
423 void inode_add_bytes(struct inode *inode, loff_t bytes)
424 {
425         spin_lock(&inode->i_lock);
426         inode->i_blocks += bytes >> 9;
427         bytes &= 511;
428         inode->i_bytes += bytes;
429         if (inode->i_bytes >= 512) {
430                 inode->i_blocks++;
431                 inode->i_bytes -= 512;
432         }
433         spin_unlock(&inode->i_lock);
434 }
435
436 EXPORT_SYMBOL(inode_add_bytes);
437
438 void inode_sub_bytes(struct inode *inode, loff_t bytes)
439 {
440         spin_lock(&inode->i_lock);
441         inode->i_blocks -= bytes >> 9;
442         bytes &= 511;
443         if (inode->i_bytes < bytes) {
444                 inode->i_blocks--;
445                 inode->i_bytes += 512;
446         }
447         inode->i_bytes -= bytes;
448         spin_unlock(&inode->i_lock);
449 }
450
451 EXPORT_SYMBOL(inode_sub_bytes);
452
453 loff_t inode_get_bytes(struct inode *inode)
454 {
455         loff_t ret;
456
457         spin_lock(&inode->i_lock);
458         ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;
459         spin_unlock(&inode->i_lock);
460         return ret;
461 }
462
463 EXPORT_SYMBOL(inode_get_bytes);
464
465 void inode_set_bytes(struct inode *inode, loff_t bytes)
466 {
467         /* Caller is here responsible for sufficient locking
468          * (ie. inode->i_lock) */
469         inode->i_blocks = bytes >> 9;
470         inode->i_bytes = bytes & 511;
471 }
472
473 EXPORT_SYMBOL(inode_set_bytes);