]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branch 'd_real' into overlayfs-next
authorMiklos Szeredi <mszeredi@redhat.com>
Wed, 27 Jul 2016 09:36:03 +0000 (11:36 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Wed, 27 Jul 2016 09:36:03 +0000 (11:36 +0200)
1  2 
fs/overlayfs/inode.c
fs/overlayfs/overlayfs.h
fs/overlayfs/super.c

diff --combined fs/overlayfs/inode.c
index d1cdc60dd68fa25aa74e2474a09e07aab08b7e26,e08cd94d7b26421e45372188410633b22850fb98..d554e86abbe365c82ca3413e3295715295fe7ad5
@@@ -59,40 -59,16 +59,40 @@@ int ovl_setattr(struct dentry *dentry, 
        if (err)
                goto out;
  
 +      if (attr->ia_valid & ATTR_SIZE) {
 +              struct inode *realinode = d_inode(ovl_dentry_real(dentry));
 +
 +              err = -ETXTBSY;
 +              if (atomic_read(&realinode->i_writecount) < 0)
 +                      goto out_drop_write;
 +      }
 +
        err = ovl_copy_up(dentry);
        if (!err) {
 +              struct inode *winode = NULL;
 +
                upperdentry = ovl_dentry_upper(dentry);
  
 +              if (attr->ia_valid & ATTR_SIZE) {
 +                      winode = d_inode(upperdentry);
 +                      err = get_write_access(winode);
 +                      if (err)
 +                              goto out_drop_write;
 +              }
 +
 +              if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
 +                      attr->ia_valid &= ~ATTR_MODE;
 +
                inode_lock(upperdentry->d_inode);
                err = notify_change(upperdentry, attr, NULL);
                if (!err)
                        ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
                inode_unlock(upperdentry->d_inode);
 +
 +              if (winode)
 +                      put_write_access(winode);
        }
 +out_drop_write:
        ovl_drop_write(dentry);
  out:
        return err;
@@@ -145,18 -121,16 +145,18 @@@ int ovl_permission(struct inode *inode
  
                err = vfs_getattr(&realpath, &stat);
                if (err)
 -                      return err;
 +                      goto out_dput;
  
 +              err = -ESTALE;
                if ((stat.mode ^ inode->i_mode) & S_IFMT)
 -                      return -ESTALE;
 +                      goto out_dput;
  
                inode->i_mode = stat.mode;
                inode->i_uid = stat.uid;
                inode->i_gid = stat.gid;
  
 -              return generic_permission(inode, mask);
 +              err = generic_permission(inode, mask);
 +              goto out_dput;
        }
  
        /* Careful in RCU walk mode */
@@@ -351,36 -325,25 +351,25 @@@ static bool ovl_open_need_copy_up(int f
        return true;
  }
  
struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags)
  {
-       int err;
+       int err = 0;
        struct path realpath;
        enum ovl_path_type type;
  
-       if (d_is_dir(dentry))
-               return d_backing_inode(dentry);
        type = ovl_path_real(dentry, &realpath);
        if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
                err = ovl_want_write(dentry);
-               if (err)
-                       return ERR_PTR(err);
-               if (file_flags & O_TRUNC)
-                       err = ovl_copy_up_truncate(dentry);
-               else
-                       err = ovl_copy_up(dentry);
-               ovl_drop_write(dentry);
-               if (err)
-                       return ERR_PTR(err);
-               ovl_path_upper(dentry, &realpath);
+               if (!err) {
+                       if (file_flags & O_TRUNC)
+                               err = ovl_copy_up_truncate(dentry);
+                       else
+                               err = ovl_copy_up(dentry);
+                       ovl_drop_write(dentry);
+               }
        }
  
-       if (realpath.dentry->d_flags & DCACHE_OP_SELECT_INODE)
-               return realpath.dentry->d_op->d_select_inode(realpath.dentry, file_flags);
-       return d_backing_inode(realpath.dentry);
+       return err;
  }
  
  static const struct inode_operations ovl_file_inode_operations = {
@@@ -413,11 -376,12 +402,11 @@@ struct inode *ovl_new_inode(struct supe
        if (!inode)
                return NULL;
  
 -      mode &= S_IFMT;
 -
        inode->i_ino = get_next_ino();
        inode->i_mode = mode;
        inode->i_flags |= S_NOATIME | S_NOCMTIME;
  
 +      mode &= S_IFMT;
        switch (mode) {
        case S_IFDIR:
                inode->i_private = oe;
diff --combined fs/overlayfs/overlayfs.h
index cfbca53590d078b89ca613e65c3b10486763f656,6b9fd25c5ad4d25507989198a42ad61c2731555e..0d3f2ad45708ee712ab6896b65d6aeb303855edc
@@@ -179,7 -179,7 +179,7 @@@ ssize_t ovl_getxattr(struct dentry *den
                     const char *name, void *value, size_t size);
  ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
  int ovl_removexattr(struct dentry *dentry, const char *name);
struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags);
int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags);
  
  struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
                            struct ovl_entry *oe);
@@@ -187,7 -187,6 +187,7 @@@ static inline void ovl_copyattr(struct 
  {
        to->i_uid = from->i_uid;
        to->i_gid = from->i_gid;
 +      to->i_mode = from->i_mode;
  }
  
  /* dir.c */
diff --combined fs/overlayfs/super.c
index 9a7693d5f8fffb38bd4a07804e4627ed7f50361a,035c176edf0013f6839ac7033a9b3be891f9e563..5e254b3a8c5601256d8960ed66a304081210cce1
@@@ -304,7 -304,9 +304,9 @@@ static void ovl_dentry_release(struct d
        }
  }
  
- static struct dentry *ovl_d_real(struct dentry *dentry, struct inode *inode)
+ static struct dentry *ovl_d_real(struct dentry *dentry,
+                                const struct inode *inode,
+                                unsigned int open_flags)
  {
        struct dentry *real;
  
                goto bug;
        }
  
+       if (d_is_negative(dentry))
+               return dentry;
+       if (open_flags) {
+               int err = ovl_open_maybe_copy_up(dentry, open_flags);
+               if (err)
+                       return ERR_PTR(err);
+       }
        real = ovl_dentry_upper(dentry);
        if (real && (!inode || inode == d_inode(real)))
                return real;
                return real;
  
        /* Handle recursion */
-       if (real->d_flags & DCACHE_OP_REAL)
-               return real->d_op->d_real(real, inode);
+       return d_real(real, inode, open_flags);
  bug:
        WARN(1, "ovl_d_real(%pd4, %s:%lu\n): real dentry not found\n", dentry,
             inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0);
@@@ -378,13 -388,11 +388,11 @@@ static int ovl_dentry_weak_revalidate(s
  
  static const struct dentry_operations ovl_dentry_operations = {
        .d_release = ovl_dentry_release,
-       .d_select_inode = ovl_d_select_inode,
        .d_real = ovl_d_real,
  };
  
  static const struct dentry_operations ovl_reval_dentry_operations = {
        .d_release = ovl_dentry_release,
-       .d_select_inode = ovl_d_select_inode,
        .d_real = ovl_d_real,
        .d_revalidate = ovl_dentry_revalidate,
        .d_weak_revalidate = ovl_dentry_weak_revalidate,
@@@ -1082,13 -1090,11 +1090,13 @@@ static int ovl_fill_super(struct super_
                        if (err < 0)
                                goto out_put_workdir;
  
 -                      if (!err) {
 -                              pr_err("overlayfs: upper fs needs to support d_type.\n");
 -                              err = -EINVAL;
 -                              goto out_put_workdir;
 -                      }
 +                      /*
 +                       * We allowed this configuration and don't want to
 +                       * break users over kernel upgrade. So warn instead
 +                       * of erroring out.
 +                       */
 +                      if (!err)
 +                              pr_warn("overlayfs: upper fs needs to support d_type.\n");
                }
        }