fs/fscache/stats.c: fix memory leak
[linux-2.6.git] / fs / stat.c
index d5c61cf..dc6d0be 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -4,7 +4,7 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/file.h>
@@ -27,12 +27,12 @@ void generic_fillattr(struct inode *inode, struct kstat *stat)
        stat->uid = inode->i_uid;
        stat->gid = inode->i_gid;
        stat->rdev = inode->i_rdev;
+       stat->size = i_size_read(inode);
        stat->atime = inode->i_atime;
        stat->mtime = inode->i_mtime;
        stat->ctime = inode->i_ctime;
-       stat->size = i_size_read(inode);
-       stat->blocks = inode->i_blocks;
        stat->blksize = (1 << inode->i_blkbits);
+       stat->blocks = inode->i_blocks;
 }
 
 EXPORT_SYMBOL(generic_fillattr);
@@ -57,7 +57,7 @@ EXPORT_SYMBOL(vfs_getattr);
 
 int vfs_fstat(unsigned int fd, struct kstat *stat)
 {
-       struct file *f = fget(fd);
+       struct file *f = fget_raw(fd);
        int error = -EBADF;
 
        if (f) {
@@ -75,13 +75,14 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
        int error = -EINVAL;
        int lookup_flags = 0;
 
-       if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT)) != 0)
+       if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
+                     AT_EMPTY_PATH)) != 0)
                goto out;
 
        if (!(flag & AT_SYMLINK_NOFOLLOW))
                lookup_flags |= LOOKUP_FOLLOW;
-       if (flag & AT_NO_AUTOMOUNT)
-               lookup_flags |= LOOKUP_NO_AUTOMOUNT;
+       if (flag & AT_EMPTY_PATH)
+               lookup_flags |= LOOKUP_EMPTY;
 
        error = user_path_at(dfd, filename, lookup_flags, &path);
        if (error)
@@ -293,19 +294,20 @@ SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname,
 {
        struct path path;
        int error;
+       int empty = 0;
 
        if (bufsiz <= 0)
                return -EINVAL;
 
-       error = user_path_at(dfd, pathname, 0, &path);
+       error = user_path_at_empty(dfd, pathname, LOOKUP_EMPTY, &path, &empty);
        if (!error) {
                struct inode *inode = path.dentry->d_inode;
 
-               error = -EINVAL;
+               error = empty ? -ENOENT : -EINVAL;
                if (inode->i_op->readlink) {
                        error = security_inode_readlink(path.dentry);
                        if (!error) {
-                               touch_atime(path.mnt, path.dentry);
+                               touch_atime(&path);
                                error = inode->i_op->readlink(path.dentry,
                                                              buf, bufsiz);
                        }