]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/open.c
[PATCH] ftruncate does not always update m/ctime
[net-next-2.6.git] / fs / open.c
index 7d02d19bd0a28281a108353883902fae745e1f10..303f06d2a7b92e8e001489cf2b1db17bdae6bd0c 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
 #include <linux/pagemap.h>
 #include <linux/syscalls.h>
 #include <linux/rcupdate.h>
+#include <linux/audit.h>
 
 #include <asm/unistd.h>
 
-int vfs_statfs(struct super_block *sb, struct kstatfs *buf)
+int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        int retval = -ENODEV;
 
-       if (sb) {
+       if (dentry) {
                retval = -ENOSYS;
-               if (sb->s_op->statfs) {
+               if (dentry->d_sb->s_op->statfs) {
                        memset(buf, 0, sizeof(*buf));
-                       retval = security_sb_statfs(sb);
+                       retval = security_sb_statfs(dentry);
                        if (retval)
                                return retval;
-                       retval = sb->s_op->statfs(sb, buf);
+                       retval = dentry->d_sb->s_op->statfs(dentry, buf);
                        if (retval == 0 && buf->f_frsize == 0)
                                buf->f_frsize = buf->f_bsize;
                }
@@ -51,12 +52,12 @@ int vfs_statfs(struct super_block *sb, struct kstatfs *buf)
 
 EXPORT_SYMBOL(vfs_statfs);
 
-static int vfs_statfs_native(struct super_block *sb, struct statfs *buf)
+static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf)
 {
        struct kstatfs st;
        int retval;
 
-       retval = vfs_statfs(sb, &st);
+       retval = vfs_statfs(dentry, &st);
        if (retval)
                return retval;
 
@@ -94,12 +95,12 @@ static int vfs_statfs_native(struct super_block *sb, struct statfs *buf)
        return 0;
 }
 
-static int vfs_statfs64(struct super_block *sb, struct statfs64 *buf)
+static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf)
 {
        struct kstatfs st;
        int retval;
 
-       retval = vfs_statfs(sb, &st);
+       retval = vfs_statfs(dentry, &st);
        if (retval)
                return retval;
 
@@ -129,7 +130,7 @@ asmlinkage long sys_statfs(const char __user * path, struct statfs __user * buf)
        error = user_path_walk(path, &nd);
        if (!error) {
                struct statfs tmp;
-               error = vfs_statfs_native(nd.dentry->d_inode->i_sb, &tmp);
+               error = vfs_statfs_native(nd.dentry, &tmp);
                if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
                        error = -EFAULT;
                path_release(&nd);
@@ -148,7 +149,7 @@ asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64
        error = user_path_walk(path, &nd);
        if (!error) {
                struct statfs64 tmp;
-               error = vfs_statfs64(nd.dentry->d_inode->i_sb, &tmp);
+               error = vfs_statfs64(nd.dentry, &tmp);
                if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
                        error = -EFAULT;
                path_release(&nd);
@@ -167,7 +168,7 @@ asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user * buf)
        file = fget(fd);
        if (!file)
                goto out;
-       error = vfs_statfs_native(file->f_dentry->d_inode->i_sb, &tmp);
+       error = vfs_statfs_native(file->f_dentry, &tmp);
        if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
                error = -EFAULT;
        fput(file);
@@ -188,7 +189,7 @@ asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, struct statfs64 __user
        file = fget(fd);
        if (!file)
                goto out;
-       error = vfs_statfs64(file->f_dentry->d_inode->i_sb, &tmp);
+       error = vfs_statfs64(file->f_dentry, &tmp);
        if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
                error = -EFAULT;
        fput(file);
@@ -321,7 +322,7 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
 
        error = locks_verify_truncate(inode, file, length);
        if (!error)
-               error = do_truncate(dentry, length, 0, file);
+               error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
 out_putf:
        fput(file);
 out:
@@ -330,7 +331,10 @@ out:
 
 asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
 {
-       return do_sys_ftruncate(fd, length, 1);
+       long ret = do_sys_ftruncate(fd, length, 1);
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 /* LFS versions of truncate are only needed on 32 bit machines */
@@ -342,7 +346,10 @@ asmlinkage long sys_truncate64(const char __user * path, loff_t length)
 
 asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
 {
-       return do_sys_ftruncate(fd, length, 0);
+       long ret = do_sys_ftruncate(fd, length, 0);
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 #endif
 
@@ -626,6 +633,8 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
        dentry = file->f_dentry;
        inode = dentry->d_inode;
 
+       audit_inode(NULL, inode);
+
        err = -EROFS;
        if (IS_RDONLY(inode))
                goto out_putf;
@@ -775,7 +784,10 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
 
        file = fget(fd);
        if (file) {
-               error = chown_common(file->f_dentry, user, group);
+               struct dentry * dentry;
+               dentry = file->f_dentry;
+               audit_inode(NULL, dentry->d_inode);
+               error = chown_common(dentry, user, group);
                fput(file);
        }
        return error;
@@ -1087,22 +1099,31 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
 
 asmlinkage long sys_open(const char __user *filename, int flags, int mode)
 {
+       long ret;
+
        if (force_o_largefile())
                flags |= O_LARGEFILE;
 
-       return do_sys_open(AT_FDCWD, filename, flags, mode);
+       ret = do_sys_open(AT_FDCWD, filename, flags, mode);
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(sys_open);
 
 asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
                           int mode)
 {
+       long ret;
+
        if (force_o_largefile())
                flags |= O_LARGEFILE;
 
-       return do_sys_open(dfd, filename, flags, mode);
+       ret = do_sys_open(dfd, filename, flags, mode);
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
-EXPORT_SYMBOL_GPL(sys_openat);
 
 #ifndef __alpha__
 
@@ -1131,7 +1152,7 @@ int filp_close(struct file *filp, fl_owner_t id)
        }
 
        if (filp->f_op && filp->f_op->flush)
-               retval = filp->f_op->flush(filp);
+               retval = filp->f_op->flush(filp, id);
 
        dnotify_flush(filp, id);
        locks_remove_posix(filp, id);