Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszer...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 16 Dec 2016 18:58:12 +0000 (10:58 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 16 Dec 2016 18:58:12 +0000 (10:58 -0800)
Pull overlayfs updates from Miklos Szeredi:
 "This update contains:

   - try to clone on copy-up

   - allow renaming a directory

   - split source into managable chunks

   - misc cleanups and fixes

  It does not contain the read-only fd data inconsistency fix, which Al
  didn't like. I'll leave that to the next year..."

* 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: (36 commits)
  ovl: fix reStructuredText syntax errors in documentation
  ovl: fix return value of ovl_fill_super
  ovl: clean up kstat usage
  ovl: fold ovl_copy_up_truncate() into ovl_copy_up()
  ovl: create directories inside merged parent opaque
  ovl: opaque cleanup
  ovl: show redirect_dir mount option
  ovl: allow setting max size of redirect
  ovl: allow redirect_dir to default to "on"
  ovl: check for emptiness of redirect dir
  ovl: redirect on rename-dir
  ovl: lookup redirects
  ovl: consolidate lookup for underlying layers
  ovl: fix nested overlayfs mount
  ovl: check namelen
  ovl: split super.c
  ovl: use d_is_dir()
  ovl: simplify lookup
  ovl: check lower existence of rename target
  ovl: rename: simplify handling of lower/merged directory
  ...

1  2 
fs/namei.c
fs/overlayfs/copy_up.c
include/linux/fs.h
net/unix/af_unix.c

diff --combined fs/namei.c
index 092ac5667ec72663f039b27d5bc2ed7a6fa536b0,31d04d993a2d7432c3b078f75f936a10d763a497..2b55ea142273e98e5cfc809950295f3cc772e362
@@@ -1725,35 -1725,30 +1725,35 @@@ static int pick_link(struct nameidata *
        return 1;
  }
  
 +enum {WALK_FOLLOW = 1, WALK_MORE = 2};
 +
  /*
   * Do we need to follow links? We _really_ want to be able
   * to do this check without having to look at inode->i_op,
   * so we keep a cache of "no, this doesn't need follow_link"
   * for the common case.
   */
 -static inline int should_follow_link(struct nameidata *nd, struct path *link,
 -                                   int follow,
 -                                   struct inode *inode, unsigned seq)
 +static inline int step_into(struct nameidata *nd, struct path *path,
 +                          int flags, struct inode *inode, unsigned seq)
  {
 -      if (likely(!d_is_symlink(link->dentry)))
 -              return 0;
 -      if (!follow)
 +      if (!(flags & WALK_MORE) && nd->depth)
 +              put_link(nd);
 +      if (likely(!d_is_symlink(path->dentry)) ||
 +         !(flags & WALK_FOLLOW || nd->flags & LOOKUP_FOLLOW)) {
 +              /* not a symlink or should not follow */
 +              path_to_nameidata(path, nd);
 +              nd->inode = inode;
 +              nd->seq = seq;
                return 0;
 +      }
        /* make sure that d_is_symlink above matches inode */
        if (nd->flags & LOOKUP_RCU) {
 -              if (read_seqcount_retry(&link->dentry->d_seq, seq))
 +              if (read_seqcount_retry(&path->dentry->d_seq, seq))
                        return -ECHILD;
        }
 -      return pick_link(nd, link, inode, seq);
 +      return pick_link(nd, path, inode, seq);
  }
  
 -enum {WALK_GET = 1, WALK_PUT = 2};
 -
  static int walk_component(struct nameidata *nd, int flags)
  {
        struct path path;
         */
        if (unlikely(nd->last_type != LAST_NORM)) {
                err = handle_dots(nd, nd->last_type);
 -              if (flags & WALK_PUT)
 +              if (!(flags & WALK_MORE) && nd->depth)
                        put_link(nd);
                return err;
        }
                inode = d_backing_inode(path.dentry);
        }
  
 -      if (flags & WALK_PUT)
 -              put_link(nd);
 -      err = should_follow_link(nd, &path, flags & WALK_GET, inode, seq);
 -      if (unlikely(err))
 -              return err;
 -      path_to_nameidata(&path, nd);
 -      nd->inode = inode;
 -      nd->seq = seq;
 -      return 0;
 +      return step_into(nd, &path, flags, inode, seq);
  }
  
  /*
                        if (!name)
                                return 0;
                        /* last component of nested symlink */
 -                      err = walk_component(nd, WALK_GET | WALK_PUT);
 +                      err = walk_component(nd, WALK_FOLLOW);
                } else {
 -                      err = walk_component(nd, WALK_GET);
 +                      /* not the last component */
 +                      err = walk_component(nd, WALK_FOLLOW | WALK_MORE);
                }
                if (err < 0)
                        return err;
@@@ -2246,7 -2248,12 +2246,7 @@@ static inline int lookup_last(struct na
                nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
  
        nd->flags &= ~LOOKUP_PARENT;
 -      return walk_component(nd,
 -                      nd->flags & LOOKUP_FOLLOW
 -                              ? nd->depth
 -                                      ? WALK_PUT | WALK_GET
 -                                      : WALK_GET
 -                              : 0);
 +      return walk_component(nd, 0);
  }
  
  /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
@@@ -2551,9 -2558,28 +2551,9 @@@ int user_path_at_empty(int dfd, const c
  }
  EXPORT_SYMBOL(user_path_at_empty);
  
 -/*
 - * NB: most callers don't do anything directly with the reference to the
 - *     to struct filename, but the nd->last pointer points into the name string
 - *     allocated by getname. So we must hold the reference to it until all
 - *     path-walking is complete.
 - */
 -static inline struct filename *
 -user_path_parent(int dfd, const char __user *path,
 -               struct path *parent,
 -               struct qstr *last,
 -               int *type,
 -               unsigned int flags)
 -{
 -      /* only LOOKUP_REVAL is allowed in extra flags */
 -      return filename_parentat(dfd, getname(path), flags & LOOKUP_REVAL,
 -                               parent, last, type);
 -}
 -
  /**
   * mountpoint_last - look up last component for umount
   * @nd:   pathwalk nameidata - currently pointing at parent directory of "last"
 - * @path: pointer to container for result
   *
   * This is a special lookup_last function just for umount. In this case, we
   * need to resolve the path without doing any revalidation.
   *
   * Returns:
   * -error: if there was an error during lookup. This includes -ENOENT if the
 - *         lookup found a negative dentry. The nd->path reference will also be
 - *         put in this case.
 + *         lookup found a negative dentry.
   *
 - * 0:      if we successfully resolved nd->path and found it to not to be a
 - *         symlink that needs to be followed. "path" will also be populated.
 - *         The nd->path reference will also be put.
 + * 0:      if we successfully resolved nd->last and found it to not to be a
 + *         symlink that needs to be followed.
   *
   * 1:      if we successfully resolved nd->last and found it to be a symlink
 - *         that needs to be followed. "path" will be populated with the path
 - *         to the link, and nd->path will *not* be put.
 + *         that needs to be followed.
   */
  static int
 -mountpoint_last(struct nameidata *nd, struct path *path)
 +mountpoint_last(struct nameidata *nd)
  {
        int error = 0;
 -      struct dentry *dentry;
        struct dentry *dir = nd->path.dentry;
 +      struct path path;
  
        /* If we're in rcuwalk, drop out of it to handle last component */
        if (nd->flags & LOOKUP_RCU) {
                error = handle_dots(nd, nd->last_type);
                if (error)
                        return error;
 -              dentry = dget(nd->path.dentry);
 +              path.dentry = dget(nd->path.dentry);
        } else {
 -              dentry = d_lookup(dir, &nd->last);
 -              if (!dentry) {
 +              path.dentry = d_lookup(dir, &nd->last);
 +              if (!path.dentry) {
                        /*
                         * No cached dentry. Mounted dentries are pinned in the
                         * cache, so that means that this dentry is probably
                         * a symlink or the path doesn't actually point
                         * to a mounted dentry.
                         */
 -                      dentry = lookup_slow(&nd->last, dir,
 +                      path.dentry = lookup_slow(&nd->last, dir,
                                             nd->flags | LOOKUP_NO_REVAL);
 -                      if (IS_ERR(dentry))
 -                              return PTR_ERR(dentry);
 +                      if (IS_ERR(path.dentry))
 +                              return PTR_ERR(path.dentry);
                }
        }
 -      if (d_is_negative(dentry)) {
 -              dput(dentry);
 +      if (d_is_negative(path.dentry)) {
 +              dput(path.dentry);
                return -ENOENT;
        }
 -      if (nd->depth)
 -              put_link(nd);
 -      path->dentry = dentry;
 -      path->mnt = nd->path.mnt;
 -      error = should_follow_link(nd, path, nd->flags & LOOKUP_FOLLOW,
 -                                 d_backing_inode(dentry), 0);
 -      if (unlikely(error))
 -              return error;
 -      mntget(path->mnt);
 -      follow_mount(path);
 -      return 0;
 +      path.mnt = nd->path.mnt;
 +      return step_into(nd, &path, 0, d_backing_inode(path.dentry), 0);
  }
  
  /**
@@@ -2634,19 -2672,13 +2634,19 @@@ path_mountpoint(struct nameidata *nd, u
        if (IS_ERR(s))
                return PTR_ERR(s);
        while (!(err = link_path_walk(s, nd)) &&
 -              (err = mountpoint_last(nd, path)) > 0) {
 +              (err = mountpoint_last(nd)) > 0) {
                s = trailing_symlink(nd);
                if (IS_ERR(s)) {
                        err = PTR_ERR(s);
                        break;
                }
        }
 +      if (!err) {
 +              *path = nd->path;
 +              nd->path.mnt = NULL;
 +              nd->path.dentry = NULL;
 +              follow_mount(path);
 +      }
        terminate_walk(nd);
        return err;
  }
@@@ -3303,11 -3335,18 +3303,11 @@@ static int do_last(struct nameidata *nd
        seq = 0;        /* out of RCU mode, so the value doesn't matter */
        inode = d_backing_inode(path.dentry);
  finish_lookup:
 -      if (nd->depth)
 -              put_link(nd);
 -      error = should_follow_link(nd, &path, nd->flags & LOOKUP_FOLLOW,
 -                                 inode, seq);
 +      error = step_into(nd, &path, 0, inode, seq);
        if (unlikely(error))
                return error;
 -
 -      path_to_nameidata(&path, nd);
 -      nd->inode = inode;
 -      nd->seq = seq;
 -      /* Why this, you ask?  _Now_ we might have grown LOOKUP_JUMPED... */
  finish_open:
 +      /* Why this, you ask?  _Now_ we might have grown LOOKUP_JUMPED... */
        error = complete_walk(nd);
        if (error)
                return error;
@@@ -3822,8 -3861,8 +3822,8 @@@ static long do_rmdir(int dfd, const cha
        int type;
        unsigned int lookup_flags = 0;
  retry:
 -      name = user_path_parent(dfd, pathname,
 -                              &path, &last, &type, lookup_flags);
 +      name = filename_parentat(dfd, getname(pathname), lookup_flags,
 +                              &path, &last, &type);
        if (IS_ERR(name))
                return PTR_ERR(name);
  
@@@ -3952,8 -3991,8 +3952,8 @@@ static long do_unlinkat(int dfd, const 
        struct inode *delegated_inode = NULL;
        unsigned int lookup_flags = 0;
  retry:
 -      name = user_path_parent(dfd, pathname,
 -                              &path, &last, &type, lookup_flags);
 +      name = filename_parentat(dfd, getname(pathname), lookup_flags,
 +                              &path, &last, &type);
        if (IS_ERR(name))
                return PTR_ERR(name);
  
@@@ -4306,11 -4345,7 +4306,7 @@@ int vfs_rename(struct inode *old_dir, s
        bool new_is_dir = false;
        unsigned max_links = new_dir->i_sb->s_max_links;
  
-       /*
-        * Check source == target.
-        * On overlayfs need to look at underlying inodes.
-        */
-       if (d_real_inode(old_dentry) == d_real_inode(new_dentry))
+       if (source == target)
                return 0;
  
        error = may_delete(old_dir, old_dentry, is_dir);
@@@ -4452,15 -4487,15 +4448,15 @@@ SYSCALL_DEFINE5(renameat2, int, olddfd
                target_flags = 0;
  
  retry:
 -      from = user_path_parent(olddfd, oldname,
 -                              &old_path, &old_last, &old_type, lookup_flags);
 +      from = filename_parentat(olddfd, getname(oldname), lookup_flags,
 +                              &old_path, &old_last, &old_type);
        if (IS_ERR(from)) {
                error = PTR_ERR(from);
                goto exit;
        }
  
 -      to = user_path_parent(newdfd, newname,
 -                              &new_path, &new_last, &new_type, lookup_flags);
 +      to = filename_parentat(newdfd, getname(newname), lookup_flags,
 +                              &new_path, &new_last, &new_type);
        if (IS_ERR(to)) {
                error = PTR_ERR(to);
                goto exit1;
diff --combined fs/overlayfs/copy_up.c
index 2838bddb1f91324da782bff2915cce1b60a1ddc0,0e9940f9f34abcc3e6bbddc2e01d0471aa62232d..f57043dace628767fddc0cb4b9f27692a6b672c3
@@@ -33,7 -33,7 +33,7 @@@ static int ovl_check_fd(const void *dat
  {
        const struct dentry *dentry = data;
  
 -      if (f->f_inode == d_inode(dentry))
 +      if (file_inode(f) == d_inode(dentry))
                pr_warn_ratelimited("overlayfs: Warning: Copying up %pD, but open R/O on fd %u which will cease to be coherent [pid=%d %s]\n",
                                    f, fd, current->pid, current->comm);
        return 0;
@@@ -153,6 -153,13 +153,13 @@@ static int ovl_copy_up_data(struct pat
                goto out_fput;
        }
  
+       /* Try to use clone_file_range to clone up within the same fs */
+       error = vfs_clone_file_range(old_file, 0, new_file, 0, len);
+       if (!error)
+               goto out;
+       /* Couldn't clone, so now we try to copy the data */
+       error = 0;
        /* FIXME: copy up sparse files efficiently */
        while (len) {
                size_t this_len = OVL_COPY_UP_CHUNK_SIZE;
  
                len -= bytes;
        }
+ out:
        if (!error)
                error = vfs_fsync(new_file, 0);
        fput(new_file);
@@@ -231,10 -238,15 +238,15 @@@ static int ovl_copy_up_locked(struct de
        struct inode *udir = upperdir->d_inode;
        struct dentry *newdentry = NULL;
        struct dentry *upper = NULL;
-       umode_t mode = stat->mode;
        int err;
        const struct cred *old_creds = NULL;
        struct cred *new_creds = NULL;
+       struct cattr cattr = {
+               /* Can't properly set mode on creation because of the umask */
+               .mode = stat->mode & S_IFMT,
+               .rdev = stat->rdev,
+               .link = link
+       };
  
        newdentry = ovl_lookup_temp(workdir, dentry);
        err = PTR_ERR(newdentry);
        if (new_creds)
                old_creds = override_creds(new_creds);
  
-       /* Can't properly set mode on creation because of the umask */
-       stat->mode &= S_IFMT;
-       err = ovl_create_real(wdir, newdentry, stat, link, NULL, true);
-       stat->mode = mode;
+       err = ovl_create_real(wdir, newdentry, &cattr, NULL, true);
  
        if (new_creds) {
                revert_creds(old_creds);
        ovl_dentry_update(dentry, newdentry);
        ovl_inode_update(d_inode(dentry), d_inode(newdentry));
        newdentry = NULL;
-       /*
-        * Non-directores become opaque when copied up.
-        */
-       if (!S_ISDIR(stat->mode))
-               ovl_dentry_set_opaque(dentry, true);
  out2:
        dput(upper);
  out1:
@@@ -317,20 -320,14 +320,14 @@@ out_cleanup
  /*
   * Copy up a single dentry
   *
-  * Directory renames only allowed on "pure upper" (already created on
-  * upper filesystem, never copied up).  Directories which are on lower or
-  * are merged may not be renamed.  For these -EXDEV is returned and
-  * userspace has to deal with it.  This means, when copying up a
-  * directory we can rely on it and ancestors being stable.
-  *
-  * Non-directory renames start with copy up of source if necessary.  The
-  * actual rename will only proceed once the copy up was successful.  Copy
-  * up uses upper parent i_mutex for exclusion.  Since rename can change
-  * d_parent it is possible that the copy up will lock the old parent.  At
-  * that point the file will have already been copied up anyway.
+  * All renames start with copy up of source if necessary.  The actual
+  * rename will only proceed once the copy up was successful.  Copy up uses
+  * upper parent i_mutex for exclusion.  Since rename can change d_parent it
+  * is possible that the copy up will lock the old parent.  At that point
+  * the file will have already been copied up anyway.
   */
- int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
-                   struct path *lowerpath, struct kstat *stat)
static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
+                          struct path *lowerpath, struct kstat *stat)
  {
        DEFINE_DELAYED_CALL(done);
        struct dentry *workdir = ovl_workdir(dentry);
        struct path parentpath;
        struct dentry *lowerdentry = lowerpath->dentry;
        struct dentry *upperdir;
-       struct dentry *upperdentry;
        const char *link = NULL;
  
        if (WARN_ON(!workdir))
                pr_err("overlayfs: failed to lock workdir+upperdir\n");
                goto out_unlock;
        }
-       upperdentry = ovl_dentry_upper(dentry);
-       if (upperdentry) {
+       if (ovl_dentry_upper(dentry)) {
                /* Raced with another copy-up?  Nothing to do, then... */
                err = 0;
                goto out_unlock;
@@@ -385,7 -380,7 +380,7 @@@ out_unlock
        return err;
  }
  
- int ovl_copy_up(struct dentry *dentry)
+ int ovl_copy_up_flags(struct dentry *dentry, int flags)
  {
        int err = 0;
        const struct cred *old_cred = ovl_override_creds(dentry->d_sb);
  
                ovl_path_lower(next, &lowerpath);
                err = vfs_getattr(&lowerpath, &stat);
+               /* maybe truncate regular file. this has no effect on dirs */
+               if (flags & O_TRUNC)
+                       stat.size = 0;
                if (!err)
                        err = ovl_copy_up_one(parent, next, &lowerpath, &stat);
  
  
        return err;
  }
+ int ovl_copy_up(struct dentry *dentry)
+ {
+       return ovl_copy_up_flags(dentry, 0);
+ }
diff --combined include/linux/fs.h
index b84230e070be27a74788b7f00d826f541f27b7cb,52663f1f308454091bcb27216f44a17e26cde135..83de8b6601baf5da358e2acb87f1b90bf41e95e0
@@@ -28,6 -28,7 +28,6 @@@
  #include <linux/uidgid.h>
  #include <linux/lockdep.h>
  #include <linux/percpu-rwsem.h>
 -#include <linux/blk_types.h>
  #include <linux/workqueue.h>
  #include <linux/percpu-rwsem.h>
  #include <linux/delayed_call.h>
@@@ -37,7 -38,6 +37,7 @@@
  
  struct backing_dev_info;
  struct bdi_writeback;
 +struct bio;
  struct export_operations;
  struct hd_geometry;
  struct iovec;
@@@ -151,6 -151,58 +151,6 @@@ typedef int (dio_iodone_t)(struct kioc
   */
  #define CHECK_IOVEC_ONLY -1
  
 -/*
 - * The below are the various read and write flags that we support. Some of
 - * them include behavioral modifiers that send information down to the
 - * block layer and IO scheduler. They should be used along with a req_op.
 - * Terminology:
 - *
 - *    The block layer uses device plugging to defer IO a little bit, in
 - *    the hope that we will see more IO very shortly. This increases
 - *    coalescing of adjacent IO and thus reduces the number of IOs we
 - *    have to send to the device. It also allows for better queuing,
 - *    if the IO isn't mergeable. If the caller is going to be waiting
 - *    for the IO, then he must ensure that the device is unplugged so
 - *    that the IO is dispatched to the driver.
 - *
 - *    All IO is handled async in Linux. This is fine for background
 - *    writes, but for reads or writes that someone waits for completion
 - *    on, we want to notify the block layer and IO scheduler so that they
 - *    know about it. That allows them to make better scheduling
 - *    decisions. So when the below references 'sync' and 'async', it
 - *    is referencing this priority hint.
 - *
 - * With that in mind, the available types are:
 - *
 - * READ                       A normal read operation. Device will be plugged.
 - * READ_SYNC          A synchronous read. Device is not plugged, caller can
 - *                    immediately wait on this read without caring about
 - *                    unplugging.
 - * WRITE              A normal async write. Device will be plugged.
 - * WRITE_SYNC         Synchronous write. Identical to WRITE, but passes down
 - *                    the hint that someone will be waiting on this IO
 - *                    shortly. The write equivalent of READ_SYNC.
 - * WRITE_ODIRECT      Special case write for O_DIRECT only.
 - * WRITE_FLUSH                Like WRITE_SYNC but with preceding cache flush.
 - * WRITE_FUA          Like WRITE_SYNC but data is guaranteed to be on
 - *                    non-volatile media on completion.
 - * WRITE_FLUSH_FUA    Combination of WRITE_FLUSH and FUA. The IO is preceded
 - *                    by a cache flush and data is guaranteed to be on
 - *                    non-volatile media on completion.
 - *
 - */
 -#define RW_MASK                       REQ_OP_WRITE
 -
 -#define READ                  REQ_OP_READ
 -#define WRITE                 REQ_OP_WRITE
 -
 -#define READ_SYNC             REQ_SYNC
 -#define WRITE_SYNC            (REQ_SYNC | REQ_NOIDLE)
 -#define WRITE_ODIRECT         REQ_SYNC
 -#define WRITE_FLUSH           (REQ_SYNC | REQ_NOIDLE | REQ_PREFLUSH)
 -#define WRITE_FUA             (REQ_SYNC | REQ_NOIDLE | REQ_FUA)
 -#define WRITE_FLUSH_FUA               (REQ_SYNC | REQ_NOIDLE | REQ_PREFLUSH | REQ_FUA)
 -
  /*
   * Attribute flags.  These should be or-ed together to figure out what
   * has been changed!
@@@ -1730,6 -1782,19 +1730,19 @@@ extern int vfs_clone_file_range(struct 
                struct file *file_out, loff_t pos_out, u64 len);
  extern int vfs_dedupe_file_range(struct file *file,
                                 struct file_dedupe_range *same);
+ static inline int do_clone_file_range(struct file *file_in, loff_t pos_in,
+                                     struct file *file_out, loff_t pos_out,
+                                     u64 len)
+ {
+       int ret;
+       sb_start_write(file_inode(file_out)->i_sb);
+       ret = vfs_clone_file_range(file_in, pos_in, file_out, pos_out, len);
+       sb_end_write(file_inode(file_out)->i_sb);
+       return ret;
+ }
  
  struct super_operations {
        struct inode *(*alloc_inode)(struct super_block *sb);
@@@ -2447,6 -2512,19 +2460,6 @@@ extern void make_bad_inode(struct inod
  extern bool is_bad_inode(struct inode *);
  
  #ifdef CONFIG_BLOCK
 -static inline bool op_is_write(unsigned int op)
 -{
 -      return op == REQ_OP_READ ? false : true;
 -}
 -
 -/*
 - * return data direction, READ or WRITE
 - */
 -static inline int bio_data_dir(struct bio *bio)
 -{
 -      return op_is_write(bio_op(bio)) ? WRITE : READ;
 -}
 -
  extern void check_disk_size_change(struct gendisk *disk,
                                   struct block_device *bdev);
  extern int revalidate_disk(struct gendisk *);
@@@ -2717,6 -2795,7 +2730,6 @@@ static inline void remove_inode_hash(st
  extern void inode_sb_list_add(struct inode *inode);
  
  #ifdef CONFIG_BLOCK
 -extern blk_qc_t submit_bio(struct bio *);
  extern int bdev_read_only(struct block_device *);
  #endif
  extern int set_blocksize(struct block_device *, int);
diff --combined net/unix/af_unix.c
index 1752d6b10ac4e5821172a3c06d4332b59c0c0084,6f72508cccb7523bb154d92c3e1dcdf480a15497..310882fb698e83c854ebe0b93795399fd262245c
@@@ -315,7 -315,7 +315,7 @@@ static struct sock *unix_find_socket_by
                    &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
                struct dentry *dentry = unix_sk(s)->path.dentry;
  
-               if (dentry && d_real_inode(dentry) == i) {
+               if (dentry && d_backing_inode(dentry) == i) {
                        sock_hold(s);
                        goto found;
                }
@@@ -913,7 -913,7 +913,7 @@@ static struct sock *unix_find_other(str
                err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
                if (err)
                        goto fail;
-               inode = d_real_inode(path.dentry);
+               inode = d_backing_inode(path.dentry);
                err = inode_permission(inode, MAY_WRITE);
                if (err)
                        goto put_fail;
@@@ -1040,7 -1040,7 +1040,7 @@@ static int unix_bind(struct socket *soc
                        goto out_up;
                }
                addr->hash = UNIX_HASH_SIZE;
-               hash = d_real_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1);
+               hash = d_backing_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1);
                spin_lock(&unix_table_lock);
                u->path = path;
                list = &unix_socket_table[hash];
@@@ -2113,8 -2113,8 +2113,8 @@@ static int unix_dgram_recvmsg(struct so
                mutex_lock(&u->iolock);
  
                skip = sk_peek_offset(sk, flags);
 -              skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err,
 -                                            &last);
 +              skb = __skb_try_recv_datagram(sk, flags, NULL, &peeked, &skip,
 +                                            &err, &last);
                if (skb)
                        break;