Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[sfrench/cifs-2.6.git] / fs / open.c
index a6b054edacba7c4cffa127ceb413120ddd5fe101..3b69c53e18379801e9bad4111e689be2cdaf1952 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -256,24 +256,26 @@ static long do_sys_truncate(const char __user * path, loff_t length)
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                goto dput_and_out;
 
-       /*
-        * Make sure that there are no leases.
-        */
-       error = break_lease(inode, FMODE_WRITE);
+       error = get_write_access(inode);
        if (error)
                goto dput_and_out;
 
-       error = get_write_access(inode);
+       /*
+        * Make sure that there are no leases.  get_write_access() protects
+        * against the truncate racing with a lease-granting setlease().
+        */
+       error = break_lease(inode, FMODE_WRITE);
        if (error)
-               goto dput_and_out;
+               goto put_write_and_out;
 
        error = locks_verify_truncate(inode, NULL, length);
        if (!error) {
                DQUOT_INIT(inode);
                error = do_truncate(nd.dentry, length, 0, NULL);
        }
-       put_write_access(inode);
 
+put_write_and_out:
+       put_write_access(inode);
 dput_and_out:
        path_release(&nd);
 out:
@@ -403,7 +405,7 @@ asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len)
        if (inode->i_op && inode->i_op->fallocate)
                ret = inode->i_op->fallocate(inode, mode, offset, len);
        else
-               ret = -ENOSYS;
+               ret = -EOPNOTSUPP;
 
 out_fput:
        fput(file);
@@ -567,7 +569,7 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
        dentry = file->f_path.dentry;
        inode = dentry->d_inode;
 
-       audit_inode(NULL, inode);
+       audit_inode(NULL, dentry);
 
        err = -EROFS;
        if (IS_RDONLY(inode))
@@ -656,7 +658,8 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
                newattrs.ia_gid = group;
        }
        if (!S_ISDIR(inode->i_mode))
-               newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
+               newattrs.ia_valid |=
+                       ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
        mutex_lock(&inode->i_mutex);
        error = notify_change(dentry, &newattrs);
        mutex_unlock(&inode->i_mutex);
@@ -724,7 +727,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
                goto out;
 
        dentry = file->f_path.dentry;
-       audit_inode(NULL, dentry->d_inode);
+       audit_inode(NULL, dentry);
        error = chown_common(dentry, user, group);
        fput(file);
 out:
@@ -755,6 +758,10 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
        f->f_op = fops_get(inode->i_fop);
        file_move(f, &inode->i_sb->s_files);
 
+       error = security_dentry_open(f);
+       if (error)
+               goto cleanup_all;
+
        if (!open && f->f_op)
                open = f->f_op->open;
        if (open) {
@@ -1171,7 +1178,7 @@ asmlinkage long sys_vhangup(void)
 int generic_file_open(struct inode * inode, struct file * filp)
 {
        if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
-               return -EFBIG;
+               return -EOVERFLOW;
        return 0;
 }