]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 14 Jul 2013 18:42:26 +0000 (11:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 14 Jul 2013 18:42:26 +0000 (11:42 -0700)
Pull more vfs stuff from Al Viro:
 "O_TMPFILE ABI changes, Oleg's fput() series, misc cleanups, including
  making simple_lookup() usable for filesystems with non-NULL s_d_op,
  which allows us to get rid of quite a bit of ugliness"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  sunrpc: now we can just set ->s_d_op
  cgroup: we can use simple_lookup() now
  efivarfs: we can use simple_lookup() now
  make simple_lookup() usable for filesystems that set ->s_d_op
  configfs: don't open-code d_alloc_name()
  __rpc_lookup_create_exclusive: pass string instead of qstr
  rpc_create_*_dir: don't bother with qstr
  llist: llist_add() can use llist_add_batch()
  llist: fix/simplify llist_add() and llist_add_batch()
  fput: turn "list_head delayed_fput_list" into llist_head
  fs/file_table.c:fput(): add comment
  Safer ABI for O_TMPFILE

1  2 
fs/configfs/dir.c
include/linux/fs.h
net/sunrpc/cache.c
net/sunrpc/clnt.c
net/sunrpc/rpc_pipe.c

diff --combined fs/configfs/dir.c
index 5e7c60c1cb63ff541b855bfe227dbf9fde5b1708,437b0d535b33e1d2a7e49c91456df82da6d3687b..277bd1be21fd70061fcd8d6694ed65ab4a34abd3
@@@ -387,7 -387,7 +387,7 @@@ static void remove_dir(struct dentry * 
        if (d->d_inode)
                simple_rmdir(parent->d_inode,d);
  
 -      pr_debug(" o %s removing done (%d)\n",d->d_name.name, d->d_count);
 +      pr_debug(" o %s removing done (%d)\n",d->d_name.name, d_count(d));
  
        dput(parent);
  }
@@@ -660,19 -660,15 +660,15 @@@ static int create_default_group(struct 
                                struct config_group *group)
  {
        int ret;
-       struct qstr name;
        struct configfs_dirent *sd;
        /* We trust the caller holds a reference to parent */
        struct dentry *child, *parent = parent_group->cg_item.ci_dentry;
  
        if (!group->cg_item.ci_name)
                group->cg_item.ci_name = group->cg_item.ci_namebuf;
-       name.name = group->cg_item.ci_name;
-       name.len = strlen(name.name);
-       name.hash = full_name_hash(name.name, name.len);
  
        ret = -ENOMEM;
-       child = d_alloc(parent, &name);
+       child = d_alloc_name(parent, group->cg_item.ci_name);
        if (child) {
                d_add(child, NULL);
  
@@@ -1650,7 -1646,6 +1646,6 @@@ int configfs_register_subsystem(struct 
  {
        int err;
        struct config_group *group = &subsys->su_group;
-       struct qstr name;
        struct dentry *dentry;
        struct dentry *root;
        struct configfs_dirent *sd;
  
        mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT);
  
-       name.name = group->cg_item.ci_name;
-       name.len = strlen(name.name);
-       name.hash = full_name_hash(name.name, name.len);
        err = -ENOMEM;
-       dentry = d_alloc(root, &name);
+       dentry = d_alloc_name(root, group->cg_item.ci_name);
        if (dentry) {
                d_add(dentry, NULL);
  
diff --combined include/linux/fs.h
index a35b10e9a68071e553098899a589cd2bdf58a710,d40e8e78bbd12dea1a159daadb536a602c90d7cc..981874773e85adfe81c2d24d59daa79aea157114
@@@ -10,6 -10,7 +10,7 @@@
  #include <linux/stat.h>
  #include <linux/cache.h>
  #include <linux/list.h>
+ #include <linux/llist.h>
  #include <linux/radix-tree.h>
  #include <linux/rbtree.h>
  #include <linux/init.h>
@@@ -372,8 -373,8 +373,8 @@@ struct address_space_operations 
        int (*get_xip_mem)(struct address_space *, pgoff_t, int,
                                                void **, unsigned long *);
        /*
 -       * migrate the contents of a page to the specified target. If sync
 -       * is false, it must not block.
 +       * migrate the contents of a page to the specified target. If
 +       * migrate_mode is MIGRATE_ASYNC, it must not block.
         */
        int (*migratepage) (struct address_space *,
                        struct page *, struct page *, enum migrate_mode);
@@@ -768,6 -769,7 +769,7 @@@ struct file 
         */
        union {
                struct list_head        fu_list;
+               struct llist_node       fu_llist;
                struct rcu_head         fu_rcuhead;
        } f_u;
        struct path             f_path;
diff --combined net/sunrpc/cache.c
index 49eb37010aa35da3bba5e237a7cff107075114e0,b40f9567e628cf1844f0c7300c5ebe108a58a2cb..a72de074172d81a031305dae2f1551b22d9ced36
@@@ -50,6 -50,12 +50,6 @@@ static void cache_init(struct cache_hea
        h->last_refresh = now;
  }
  
 -static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h)
 -{
 -      return  (h->expiry_time < seconds_since_boot()) ||
 -              (detail->flush_time > h->last_refresh);
 -}
 -
  struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
                                       struct cache_head *key, int hash)
  {
@@@ -195,7 -201,7 +195,7 @@@ static int cache_make_upcall(struct cac
        return sunrpc_cache_pipe_upcall(cd, h);
  }
  
 -static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h)
 +static inline int cache_is_valid(struct cache_head *h)
  {
        if (!test_bit(CACHE_VALID, &h->flags))
                return -EAGAIN;
@@@ -221,15 -227,16 +221,15 @@@ static int try_to_negate_entry(struct c
        int rv;
  
        write_lock(&detail->hash_lock);
 -      rv = cache_is_valid(detail, h);
 -      if (rv != -EAGAIN) {
 -              write_unlock(&detail->hash_lock);
 -              return rv;
 +      rv = cache_is_valid(h);
 +      if (rv == -EAGAIN) {
 +              set_bit(CACHE_NEGATIVE, &h->flags);
 +              cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
 +              rv = -ENOENT;
        }
 -      set_bit(CACHE_NEGATIVE, &h->flags);
 -      cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
        write_unlock(&detail->hash_lock);
        cache_fresh_unlocked(h, detail);
 -      return -ENOENT;
 +      return rv;
  }
  
  /*
@@@ -253,7 -260,7 +253,7 @@@ int cache_check(struct cache_detail *de
        long refresh_age, age;
  
        /* First decide return status as best we can */
 -      rv = cache_is_valid(detail, h);
 +      rv = cache_is_valid(h);
  
        /* now see if we want to start an upcall */
        refresh_age = (h->expiry_time - h->last_refresh);
        if (rqstp == NULL) {
                if (rv == -EAGAIN)
                        rv = -ENOENT;
 -      } else if (rv == -EAGAIN || age > refresh_age/2) {
 +      } else if (rv == -EAGAIN ||
 +                 (h->expiry_time != 0 && age > refresh_age/2)) {
                dprintk("RPC:       Want update, refage=%ld, age=%ld\n",
                                refresh_age, age);
                if (!test_and_set_bit(CACHE_PENDING, &h->flags)) {
                        switch (cache_make_upcall(detail, h)) {
                        case -EINVAL:
 -                              clear_bit(CACHE_PENDING, &h->flags);
 -                              cache_revisit_request(h);
                                rv = try_to_negate_entry(detail, h);
                                break;
                        case -EAGAIN:
 -                              clear_bit(CACHE_PENDING, &h->flags);
 -                              cache_revisit_request(h);
 +                              cache_fresh_unlocked(h, detail);
                                break;
                        }
                }
                         * Request was not deferred; handle it as best
                         * we can ourselves:
                         */
 -                      rv = cache_is_valid(detail, h);
 +                      rv = cache_is_valid(h);
                        if (rv == -EAGAIN)
                                rv = -ETIMEDOUT;
                }
@@@ -301,7 -310,7 +301,7 @@@ EXPORT_SYMBOL_GPL(cache_check)
   * a current pointer into that list and into the table
   * for that entry.
   *
 - * Each time clean_cache is called it finds the next non-empty entry
 + * Each time cache_clean is called it finds the next non-empty entry
   * in the current table and walks the list in that entry
   * looking for entries that can be removed.
   *
@@@ -448,8 -457,9 +448,8 @@@ static int cache_clean(void
                        current_index ++;
                spin_unlock(&cache_list_lock);
                if (ch) {
 -                      if (test_and_clear_bit(CACHE_PENDING, &ch->flags))
 -                              cache_dequeue(current_detail, ch);
 -                      cache_revisit_request(ch);
 +                      set_bit(CACHE_CLEANED, &ch->flags);
 +                      cache_fresh_unlocked(ch, d);
                        cache_put(ch, d);
                }
        } else
@@@ -1026,32 -1036,23 +1026,32 @@@ static int cache_release(struct inode *
  
  static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch)
  {
 -      struct cache_queue *cq;
 +      struct cache_queue *cq, *tmp;
 +      struct cache_request *cr;
 +      struct list_head dequeued;
 +
 +      INIT_LIST_HEAD(&dequeued);
        spin_lock(&queue_lock);
 -      list_for_each_entry(cq, &detail->queue, list)
 +      list_for_each_entry_safe(cq, tmp, &detail->queue, list)
                if (!cq->reader) {
 -                      struct cache_request *cr = container_of(cq, struct cache_request, q);
 +                      cr = container_of(cq, struct cache_request, q);
                        if (cr->item != ch)
                                continue;
 +                      if (test_bit(CACHE_PENDING, &ch->flags))
 +                              /* Lost a race and it is pending again */
 +                              break;
                        if (cr->readers != 0)
                                continue;
 -                      list_del(&cr->q.list);
 -                      spin_unlock(&queue_lock);
 -                      cache_put(cr->item, detail);
 -                      kfree(cr->buf);
 -                      kfree(cr);
 -                      return;
 +                      list_move(&cr->q.list, &dequeued);
                }
        spin_unlock(&queue_lock);
 +      while (!list_empty(&dequeued)) {
 +              cr = list_entry(dequeued.next, struct cache_request, q.list);
 +              list_del(&cr->q.list);
 +              cache_put(cr->item, detail);
 +              kfree(cr->buf);
 +              kfree(cr);
 +      }
  }
  
  /*
@@@ -1165,7 -1166,6 +1165,7 @@@ int sunrpc_cache_pipe_upcall(struct cac
  
        char *buf;
        struct cache_request *crq;
 +      int ret = 0;
  
        if (!detail->cache_request)
                return -EINVAL;
                warn_no_listener(detail);
                return -EINVAL;
        }
 +      if (test_bit(CACHE_CLEANED, &h->flags))
 +              /* Too late to make an upcall */
 +              return -EAGAIN;
  
        buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
        if (!buf)
        crq->len = 0;
        crq->readers = 0;
        spin_lock(&queue_lock);
 -      list_add_tail(&crq->q.list, &detail->queue);
 +      if (test_bit(CACHE_PENDING, &h->flags))
 +              list_add_tail(&crq->q.list, &detail->queue);
 +      else
 +              /* Lost a race, no longer PENDING, so don't enqueue */
 +              ret = -EAGAIN;
        spin_unlock(&queue_lock);
        wake_up(&queue_wait);
 -      return 0;
 +      if (ret == -EAGAIN) {
 +              kfree(buf);
 +              kfree(crq);
 +      }
 +      return ret;
  }
  EXPORT_SYMBOL_GPL(sunrpc_cache_pipe_upcall);
  
@@@ -1823,19 -1812,11 +1823,11 @@@ int sunrpc_cache_register_pipefs(struc
                                 const char *name, umode_t umode,
                                 struct cache_detail *cd)
  {
-       struct qstr q;
-       struct dentry *dir;
-       int ret = 0;
-       q.name = name;
-       q.len = strlen(name);
-       q.hash = full_name_hash(q.name, q.len);
-       dir = rpc_create_cache_dir(parent, &q, umode, cd);
-       if (!IS_ERR(dir))
-               cd->u.pipefs.dir = dir;
-       else
-               ret = PTR_ERR(dir);
-       return ret;
+       struct dentry *dir = rpc_create_cache_dir(parent, name, umode, cd);
+       if (IS_ERR(dir))
+               return PTR_ERR(dir);
+       cd->u.pipefs.dir = dir;
+       return 0;
  }
  EXPORT_SYMBOL_GPL(sunrpc_cache_register_pipefs);
  
diff --combined net/sunrpc/clnt.c
index aa401560777b22ea0ec54abba730007f3347ea57,26456274b24e013e27b17ed15882e3a60fe8ea90..9963584605c06e06992fc1d4d1c0a608b360a74b
@@@ -128,9 -128,7 +128,7 @@@ static struct dentry *rpc_setup_pipedir
  {
        static uint32_t clntid;
        char name[15];
-       struct qstr q = { .name = name };
        struct dentry *dir, *dentry;
-       int error;
  
        dir = rpc_d_lookup_sb(sb, dir_name);
        if (dir == NULL) {
                return dir;
        }
        for (;;) {
-               q.len = snprintf(name, sizeof(name), "clnt%x", (unsigned int)clntid++);
+               snprintf(name, sizeof(name), "clnt%x", (unsigned int)clntid++);
                name[sizeof(name) - 1] = '\0';
-               q.hash = full_name_hash(q.name, q.len);
-               dentry = rpc_create_client_dir(dir, &q, clnt);
+               dentry = rpc_create_client_dir(dir, name, clnt);
                if (!IS_ERR(dentry))
                        break;
-               error = PTR_ERR(dentry);
-               if (error != -EEXIST) {
-                       printk(KERN_INFO "RPC: Couldn't create pipefs entry"
-                                       " %s/%s, error %d\n",
-                                       dir_name, name, error);
-                       break;
-               }
+               if (dentry == ERR_PTR(-EEXIST))
+                       continue;
+               printk(KERN_INFO "RPC: Couldn't create pipefs entry"
+                               " %s/%s, error %ld\n",
+                               dir_name, name, PTR_ERR(dentry));
+               break;
        }
        dput(dir);
        return dentry;
  }
  
  static int
 -rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name)
 +rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name,
 +                struct super_block *pipefs_sb)
  {
 -      struct net *net = rpc_net_ns(clnt);
 -      struct super_block *pipefs_sb;
        struct dentry *dentry;
  
        clnt->cl_dentry = NULL;
        if (dir_name == NULL)
                return 0;
 -      pipefs_sb = rpc_get_sb_net(net);
 -      if (!pipefs_sb)
 -              return 0;
        dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name);
 -      rpc_put_sb_net(net);
        if (IS_ERR(dentry))
                return PTR_ERR(dentry);
        clnt->cl_dentry = dentry;
@@@ -177,8 -178,6 +173,8 @@@ static inline int rpc_clnt_skip_event(s
        if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
            ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
                return 1;
 +      if ((event == RPC_PIPEFS_MOUNT) && atomic_read(&clnt->cl_count) == 0)
 +              return 1;
        return 0;
  }
  
@@@ -238,6 -237,8 +234,6 @@@ static struct rpc_clnt *rpc_get_client_
                        continue;
                if (rpc_clnt_skip_event(clnt, event))
                        continue;
 -              if (atomic_inc_not_zero(&clnt->cl_count) == 0)
 -                      continue;
                spin_unlock(&sn->rpc_client_lock);
                return clnt;
        }
@@@ -254,6 -255,7 +250,6 @@@ static int rpc_pipefs_event(struct noti
  
        while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) {
                error = __rpc_pipefs_event(clnt, event, sb);
 -              rpc_release_client(clnt);
                if (error)
                        break;
        }
@@@ -283,48 -285,12 +279,48 @@@ static void rpc_clnt_set_nodename(struc
        memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen);
  }
  
 +static int rpc_client_register(const struct rpc_create_args *args,
 +                             struct rpc_clnt *clnt)
 +{
 +      const struct rpc_program *program = args->program;
 +      struct rpc_auth *auth;
 +      struct net *net = rpc_net_ns(clnt);
 +      struct super_block *pipefs_sb;
 +      int err;
 +
 +      pipefs_sb = rpc_get_sb_net(net);
 +      if (pipefs_sb) {
 +              err = rpc_setup_pipedir(clnt, program->pipe_dir_name, pipefs_sb);
 +              if (err)
 +                      goto out;
 +      }
 +
 +      rpc_register_client(clnt);
 +      if (pipefs_sb)
 +              rpc_put_sb_net(net);
 +
 +      auth = rpcauth_create(args->authflavor, clnt);
 +      if (IS_ERR(auth)) {
 +              dprintk("RPC:       Couldn't create auth handle (flavor %u)\n",
 +                              args->authflavor);
 +              err = PTR_ERR(auth);
 +              goto err_auth;
 +      }
 +      return 0;
 +err_auth:
 +      pipefs_sb = rpc_get_sb_net(net);
 +      __rpc_clnt_remove_pipedir(clnt);
 +out:
 +      if (pipefs_sb)
 +              rpc_put_sb_net(net);
 +      return err;
 +}
 +
  static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
  {
        const struct rpc_program *program = args->program;
        const struct rpc_version *version;
        struct rpc_clnt         *clnt = NULL;
 -      struct rpc_auth         *auth;
        int err;
  
        /* sanity check the name before trying to print it */
  
        atomic_set(&clnt->cl_count, 1);
  
 -      err = rpc_setup_pipedir(clnt, program->pipe_dir_name);
 -      if (err < 0)
 -              goto out_no_path;
 -
 -      auth = rpcauth_create(args->authflavor, clnt);
 -      if (IS_ERR(auth)) {
 -              dprintk("RPC:       Couldn't create auth handle (flavor %u)\n",
 -                              args->authflavor);
 -              err = PTR_ERR(auth);
 -              goto out_no_auth;
 -      }
 -
        /* save the nodename */
        rpc_clnt_set_nodename(clnt, utsname()->nodename);
 -      rpc_register_client(clnt);
 +
 +      err = rpc_client_register(args, clnt);
 +      if (err)
 +              goto out_no_path;
        return clnt;
  
 -out_no_auth:
 -      rpc_clnt_remove_pipedir(clnt);
  out_no_path:
        kfree(clnt->cl_principal);
  out_no_principal:
@@@ -656,8 -633,8 +652,8 @@@ rpc_free_client(struct rpc_clnt *clnt
                        rcu_dereference(clnt->cl_xprt)->servername);
        if (clnt->cl_parent != clnt)
                rpc_release_client(clnt->cl_parent);
 -      rpc_unregister_client(clnt);
        rpc_clnt_remove_pipedir(clnt);
 +      rpc_unregister_client(clnt);
        rpc_free_iostats(clnt->cl_metrics);
        kfree(clnt->cl_principal);
        clnt->cl_metrics = NULL;
diff --combined net/sunrpc/rpc_pipe.c
index 61239a2cb7861ada7771855aee937a01433441af,260fe72656a10ea2741c53344d7ae429d6692de2..406859cc68aa90073ef237e91e0aa67116adcf33
@@@ -480,23 -480,6 +480,23 @@@ static const struct dentry_operations r
        .d_delete = rpc_delete_dentry,
  };
  
 +/*
 + * Lookup the data. This is trivial - if the dentry didn't already
 + * exist, we know it is negative.
 + */
 +static struct dentry *
 +rpc_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
 +{
 +      if (dentry->d_name.len > NAME_MAX)
 +              return ERR_PTR(-ENAMETOOLONG);
 +      d_add(dentry, NULL);
 +      return NULL;
 +}
 +
 +static const struct inode_operations rpc_dir_inode_operations = {
 +      .lookup         = rpc_lookup,
 +};
 +
  static struct inode *
  rpc_get_inode(struct super_block *sb, umode_t mode)
  {
        switch (mode & S_IFMT) {
        case S_IFDIR:
                inode->i_fop = &simple_dir_operations;
 -              inode->i_op = &simple_dir_inode_operations;
 +              inode->i_op = &rpc_dir_inode_operations;
                inc_nlink(inode);
        default:
                break;
@@@ -673,13 -656,12 +673,12 @@@ static int __rpc_rmpipe(struct inode *d
  }
  
  static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
-                                         struct qstr *name)
+                                         const char *name)
  {
-       struct dentry *dentry;
-       dentry = d_lookup(parent, name);
+       struct qstr q = QSTR_INIT(name, strlen(name));
+       struct dentry *dentry = d_hash_and_lookup(parent, &q);
        if (!dentry) {
-               dentry = d_alloc(parent, name);
+               dentry = d_alloc(parent, &q);
                if (!dentry)
                        return ERR_PTR(-ENOMEM);
        }
@@@ -704,8 -686,7 +703,7 @@@ static void __rpc_depopulate(struct den
        for (i = start; i < eof; i++) {
                name.name = files[i].name;
                name.len = strlen(files[i].name);
-               name.hash = full_name_hash(name.name, name.len);
-               dentry = d_lookup(parent, &name);
+               dentry = d_hash_and_lookup(parent, &name);
  
                if (dentry == NULL)
                        continue;
@@@ -747,12 -728,7 +745,7 @@@ static int rpc_populate(struct dentry *
  
        mutex_lock(&dir->i_mutex);
        for (i = start; i < eof; i++) {
-               struct qstr q;
-               q.name = files[i].name;
-               q.len = strlen(files[i].name);
-               q.hash = full_name_hash(q.name, q.len);
-               dentry = __rpc_lookup_create_exclusive(parent, &q);
+               dentry = __rpc_lookup_create_exclusive(parent, files[i].name);
                err = PTR_ERR(dentry);
                if (IS_ERR(dentry))
                        goto out_bad;
@@@ -785,7 -761,7 +778,7 @@@ out_bad
  }
  
  static struct dentry *rpc_mkdir_populate(struct dentry *parent,
-               struct qstr *name, umode_t mode, void *private,
+               const char *name, umode_t mode, void *private,
                int (*populate)(struct dentry *, void *), void *args_populate)
  {
        struct dentry *dentry;
@@@ -856,7 -832,6 +849,6 @@@ struct dentry *rpc_mkpipe_dentry(struc
        struct dentry *dentry;
        struct inode *dir = parent->d_inode;
        umode_t umode = S_IFIFO | S_IRUSR | S_IWUSR;
-       struct qstr q;
        int err;
  
        if (pipe->ops->upcall == NULL)
        if (pipe->ops->downcall == NULL)
                umode &= ~S_IWUGO;
  
-       q.name = name;
-       q.len = strlen(name);
-       q.hash = full_name_hash(q.name, q.len),
        mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
-       dentry = __rpc_lookup_create_exclusive(parent, &q);
+       dentry = __rpc_lookup_create_exclusive(parent, name);
        if (IS_ERR(dentry))
                goto out;
        err = __rpc_mkpipe_dentry(dir, dentry, umode, &rpc_pipe_fops,
@@@ -940,8 -911,8 +928,8 @@@ static void rpc_clntdir_depopulate(stru
  
  /**
   * rpc_create_client_dir - Create a new rpc_client directory in rpc_pipefs
-  * @dentry: dentry from the rpc_pipefs root to the new directory
-  * @name: &struct qstr for the name
+  * @dentry: the parent of new directory
+  * @name: the name of new directory
   * @rpc_client: rpc client to associate with this directory
   *
   * This creates a directory at the given @path associated with
   * later be created using rpc_mkpipe().
   */
  struct dentry *rpc_create_client_dir(struct dentry *dentry,
-                                  struct qstr *name,
+                                  const char *name,
                                   struct rpc_clnt *rpc_client)
  {
        return rpc_mkdir_populate(dentry, name, S_IRUGO | S_IXUGO, NULL,
@@@ -996,7 -967,7 +984,7 @@@ static void rpc_cachedir_depopulate(str
        rpc_depopulate(dentry, cache_pipefs_files, 0, 3);
  }
  
- struct dentry *rpc_create_cache_dir(struct dentry *parent, struct qstr *name,
+ struct dentry *rpc_create_cache_dir(struct dentry *parent, const char *name,
                                    umode_t umode, struct cache_detail *cd)
  {
        return rpc_mkdir_populate(parent, name, umode, NULL,
@@@ -1076,9 -1047,7 +1064,7 @@@ struct dentry *rpc_d_lookup_sb(const st
                               const unsigned char *dir_name)
  {
        struct qstr dir = QSTR_INIT(dir_name, strlen(dir_name));
-       dir.hash = full_name_hash(dir.name, dir.len);
-       return d_lookup(sb->s_root, &dir);
+       return d_hash_and_lookup(sb->s_root, &dir);
  }
  EXPORT_SYMBOL_GPL(rpc_d_lookup_sb);
  
@@@ -1142,7 -1111,6 +1128,7 @@@ rpc_fill_super(struct super_block *sb, 
                return -ENOMEM;
        dprintk("RPC:       sending pipefs MOUNT notification for net %p%s\n",
                net, NET_NAME(net));
 +      mutex_lock(&sn->pipefs_sb_lock);
        sn->pipefs_sb = sb;
        err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
                                           RPC_PIPEFS_MOUNT,
        if (err)
                goto err_depopulate;
        sb->s_fs_info = get_net(net);
 +      mutex_unlock(&sn->pipefs_sb_lock);
        return 0;
  
  err_depopulate:
                                           sb);
        sn->pipefs_sb = NULL;
        __rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF);
 +      mutex_unlock(&sn->pipefs_sb_lock);
        return err;
  }
  
@@@ -1181,12 -1147,12 +1167,12 @@@ static void rpc_kill_sb(struct super_bl
                goto out;
        }
        sn->pipefs_sb = NULL;
 -      mutex_unlock(&sn->pipefs_sb_lock);
        dprintk("RPC:       sending pipefs UMOUNT notification for net %p%s\n",
                net, NET_NAME(net));
        blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
                                           RPC_PIPEFS_UMOUNT,
                                           sb);
 +      mutex_unlock(&sn->pipefs_sb_lock);
        put_net(net);
  out:
        kill_litter_super(sb);