These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / fs / open.c
index 98e5a52..b6f1e96 100644 (file)
@@ -51,8 +51,10 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
                newattrs.ia_valid |= ATTR_FILE;
        }
 
-       /* Remove suid/sgid on truncate too */
-       ret = should_remove_suid(dentry);
+       /* Remove suid, sgid, and file capabilities on truncate too */
+       ret = dentry_needs_remove_privs(dentry);
+       if (ret < 0)
+               return ret;
        if (ret)
                newattrs.ia_valid |= ret | ATTR_FORCE;
 
@@ -367,7 +369,7 @@ retry:
        if (res)
                goto out;
 
-       inode = path.dentry->d_inode;
+       inode = d_backing_inode(path.dentry);
 
        if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) {
                /*
@@ -375,7 +377,7 @@ retry:
                 * with the "noexec" flag.
                 */
                res = -EACCES;
-               if (path.mnt->mnt_flags & MNT_NOEXEC)
+               if (path_noexec(&path))
                        goto out_path_release;
        }
 
@@ -678,18 +680,18 @@ int open_check_o_direct(struct file *f)
 }
 
 static int do_dentry_open(struct file *f,
+                         struct inode *inode,
                          int (*open)(struct inode *, struct file *),
                          const struct cred *cred)
 {
        static const struct file_operations empty_fops = {};
-       struct inode *inode;
        int error;
 
        f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK |
                                FMODE_PREAD | FMODE_PWRITE;
 
        path_get(&f->f_path);
-       inode = f->f_inode = f->f_path.dentry->d_inode;
+       f->f_inode = inode;
        f->f_mapping = inode->i_mapping;
 
        if (unlikely(f->f_flags & O_PATH)) {
@@ -793,7 +795,8 @@ int finish_open(struct file *file, struct dentry *dentry,
        BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
 
        file->f_path.dentry = dentry;
-       error = do_dentry_open(file, open, current_cred());
+       error = do_dentry_open(file, d_backing_inode(dentry), open,
+                              current_cred());
        if (!error)
                *opened |= FILE_OPENED;
 
@@ -822,6 +825,34 @@ int finish_no_open(struct file *file, struct dentry *dentry)
 }
 EXPORT_SYMBOL(finish_no_open);
 
+char *file_path(struct file *filp, char *buf, int buflen)
+{
+       return d_path(&filp->f_path, buf, buflen);
+}
+EXPORT_SYMBOL(file_path);
+
+/**
+ * vfs_open - open the file at the given path
+ * @path: path to open
+ * @file: newly allocated file with f_flag initialized
+ * @cred: credentials to use
+ */
+int vfs_open(const struct path *path, struct file *file,
+            const struct cred *cred)
+{
+       struct dentry *dentry = path->dentry;
+       struct inode *inode = dentry->d_inode;
+
+       file->f_path = *path;
+       if (dentry->d_flags & DCACHE_OP_SELECT_INODE) {
+               inode = dentry->d_op->d_select_inode(dentry, file->f_flags);
+               if (IS_ERR(inode))
+                       return PTR_ERR(inode);
+       }
+
+       return do_dentry_open(file, inode, NULL, cred);
+}
+
 struct file *dentry_open(const struct path *path, int flags,
                         const struct cred *cred)
 {
@@ -853,26 +884,6 @@ struct file *dentry_open(const struct path *path, int flags,
 }
 EXPORT_SYMBOL(dentry_open);
 
-/**
- * vfs_open - open the file at the given path
- * @path: path to open
- * @filp: newly allocated file with f_flag initialized
- * @cred: credentials to use
- */
-int vfs_open(const struct path *path, struct file *filp,
-            const struct cred *cred)
-{
-       struct inode *inode = path->dentry->d_inode;
-
-       if (inode->i_op->dentry_open)
-               return inode->i_op->dentry_open(path->dentry, filp, cred);
-       else {
-               filp->f_path = *path;
-               return do_dentry_open(filp, NULL, cred);
-       }
-}
-EXPORT_SYMBOL(vfs_open);
-
 static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op)
 {
        int lookup_flags = 0;