Root/fs/stat.c

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

Archive Download this file



interactive