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

18 files changed:
arch/alpha/include/uapi/asm/fcntl.h
arch/parisc/include/uapi/asm/fcntl.h
arch/sparc/include/uapi/asm/fcntl.h
fs/configfs/dir.c
fs/efivarfs/inode.c
fs/file_table.c
fs/libfs.c
fs/namei.c
fs/open.c
include/linux/fs.h
include/linux/llist.h
include/linux/sunrpc/rpc_pipe_fs.h
include/uapi/asm-generic/fcntl.h
kernel/cgroup.c
lib/llist.c
net/sunrpc/cache.c
net/sunrpc/clnt.c
net/sunrpc/rpc_pipe.c

index dfdadb0..09f49a6 100644 (file)
@@ -32,7 +32,7 @@
 #define O_SYNC         (__O_SYNC|O_DSYNC)
 
 #define O_PATH         040000000
-#define O_TMPFILE      0100000000
+#define __O_TMPFILE    0100000000
 
 #define F_GETLK                7
 #define F_SETLK                8
index cc61c47..34a46cb 100644 (file)
@@ -20,7 +20,7 @@
 #define O_INVISIBLE    004000000 /* invisible I/O, for DMAPI/XDSM */
 
 #define O_PATH         020000000
-#define O_TMPFILE      040000000
+#define __O_TMPFILE    040000000
 
 #define F_GETLK64      8
 #define F_SETLK64      9
index d73e5e0..7e8ace5 100644 (file)
@@ -35,7 +35,7 @@
 #define O_SYNC         (__O_SYNC|O_DSYNC)
 
 #define O_PATH         0x1000000
-#define O_TMPFILE      0x2000000
+#define __O_TMPFILE    0x2000000
 
 #define F_GETOWN       5       /*  for sockets. */
 #define F_SETOWN       6       /*  for sockets. */
index 5e7c60c..277bd1b 100644 (file)
@@ -660,19 +660,15 @@ static int create_default_group(struct config_group *parent_group,
                                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 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
 {
        int err;
        struct config_group *group = &subsys->su_group;
-       struct qstr name;
        struct dentry *dentry;
        struct dentry *root;
        struct configfs_dirent *sd;
@@ -1667,12 +1662,8 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
 
        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);
 
index 7e787fb..07ab497 100644 (file)
@@ -155,20 +155,8 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
        return 0;
 };
 
-/*
- * Handle negative dentry.
- */
-static struct dentry *efivarfs_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;
-}
-
 const struct inode_operations efivarfs_dir_inode_operations = {
-       .lookup = efivarfs_lookup,
+       .lookup = simple_lookup,
        .unlink = efivarfs_unlink,
        .create = efivarfs_create,
 };
index 08e719b..b44e4c5 100644 (file)
@@ -265,18 +265,15 @@ static void __fput(struct file *file)
        mntput(mnt);
 }
 
-static DEFINE_SPINLOCK(delayed_fput_lock);
-static LIST_HEAD(delayed_fput_list);
+static LLIST_HEAD(delayed_fput_list);
 static void delayed_fput(struct work_struct *unused)
 {
-       LIST_HEAD(head);
-       spin_lock_irq(&delayed_fput_lock);
-       list_splice_init(&delayed_fput_list, &head);
-       spin_unlock_irq(&delayed_fput_lock);
-       while (!list_empty(&head)) {
-               struct file *f = list_first_entry(&head, struct file, f_u.fu_list);
-               list_del_init(&f->f_u.fu_list);
-               __fput(f);
+       struct llist_node *node = llist_del_all(&delayed_fput_list);
+       struct llist_node *next;
+
+       for (; node; node = next) {
+               next = llist_next(node);
+               __fput(llist_entry(node, struct file, f_u.fu_llist));
        }
 }
 
@@ -306,18 +303,22 @@ void fput(struct file *file)
 {
        if (atomic_long_dec_and_test(&file->f_count)) {
                struct task_struct *task = current;
-               unsigned long flags;
 
                file_sb_list_del(file);
                if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) {
                        init_task_work(&file->f_u.fu_rcuhead, ____fput);
                        if (!task_work_add(task, &file->f_u.fu_rcuhead, true))
                                return;
+                       /*
+                        * After this task has run exit_task_work(),
+                        * task_work_add() will fail.  free_ipc_ns()->
+                        * shm_destroy() can do this.  Fall through to delayed
+                        * fput to avoid leaking *file.
+                        */
                }
-               spin_lock_irqsave(&delayed_fput_lock, flags);
-               list_add(&file->f_u.fu_list, &delayed_fput_list);
-               schedule_work(&delayed_fput_work);
-               spin_unlock_irqrestore(&delayed_fput_lock, flags);
+
+               if (llist_add(&file->f_u.fu_llist, &delayed_fput_list))
+                       schedule_work(&delayed_fput_work);
        }
 }
 
index c3a0837..3a3a9b5 100644 (file)
@@ -61,7 +61,8 @@ struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, unsigned
 
        if (dentry->d_name.len > NAME_MAX)
                return ERR_PTR(-ENAMETOOLONG);
-       d_set_d_op(dentry, &simple_dentry_operations);
+       if (!dentry->d_sb->s_d_op)
+               d_set_d_op(dentry, &simple_dentry_operations);
        d_add(dentry, NULL);
        return NULL;
 }
index b2beee7..8b61d10 100644 (file)
@@ -2977,7 +2977,7 @@ static struct file *path_openat(int dfd, struct filename *pathname,
 
        file->f_flags = op->open_flag;
 
-       if (unlikely(file->f_flags & O_TMPFILE)) {
+       if (unlikely(file->f_flags & __O_TMPFILE)) {
                error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened);
                goto out;
        }
index fca72c4..9156cb0 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -840,8 +840,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
        if (flags & __O_SYNC)
                flags |= O_DSYNC;
 
-       if (flags & O_TMPFILE) {
-               if (!(flags & O_CREAT))
+       if (flags & __O_TMPFILE) {
+               if ((flags & O_TMPFILE_MASK) != O_TMPFILE)
                        return -EINVAL;
                acc_mode = MAY_OPEN | ACC_MODE(flags);
        } else if (flags & O_PATH) {
index a35b10e..9818747 100644 (file)
@@ -10,6 +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>
@@ -768,6 +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;
index a5199f6..cdaa7f0 100644 (file)
@@ -142,6 +142,9 @@ static inline struct llist_node *llist_next(struct llist_node *node)
        return node->next;
 }
 
+extern bool llist_add_batch(struct llist_node *new_first,
+                           struct llist_node *new_last,
+                           struct llist_head *head);
 /**
  * llist_add - add a new entry
  * @new:       new entry to be added
@@ -151,18 +154,7 @@ static inline struct llist_node *llist_next(struct llist_node *node)
  */
 static inline bool llist_add(struct llist_node *new, struct llist_head *head)
 {
-       struct llist_node *entry, *old_entry;
-
-       entry = head->first;
-       for (;;) {
-               old_entry = entry;
-               new->next = entry;
-               entry = cmpxchg(&head->first, old_entry, new);
-               if (entry == old_entry)
-                       break;
-       }
-
-       return old_entry == NULL;
+       return llist_add_batch(new, new, head);
 }
 
 /**
@@ -178,9 +170,6 @@ static inline struct llist_node *llist_del_all(struct llist_head *head)
        return xchg(&head->first, NULL);
 }
 
-extern bool llist_add_batch(struct llist_node *new_first,
-                           struct llist_node *new_last,
-                           struct llist_head *head);
 extern struct llist_node *llist_del_first(struct llist_head *head);
 
 #endif /* LLIST_H */
index a7b422b..aa5b582 100644 (file)
@@ -73,12 +73,12 @@ extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *,
 extern int rpc_queue_upcall(struct rpc_pipe *, struct rpc_pipe_msg *);
 
 struct rpc_clnt;
-extern struct dentry *rpc_create_client_dir(struct dentry *, struct qstr *, struct rpc_clnt *);
+extern struct dentry *rpc_create_client_dir(struct dentry *, const char *, struct rpc_clnt *);
 extern int rpc_remove_client_dir(struct dentry *);
 
 struct cache_detail;
 extern struct dentry *rpc_create_cache_dir(struct dentry *,
-                                          struct qstr *,
+                                          const char *,
                                           umode_t umode,
                                           struct cache_detail *);
 extern void rpc_remove_cache_dir(struct dentry *);
index 06632be..05ac354 100644 (file)
 #define O_PATH         010000000
 #endif
 
-#ifndef O_TMPFILE
-#define O_TMPFILE      020000000
+#ifndef __O_TMPFILE
+#define __O_TMPFILE    020000000
 #endif
 
+/* a horrid kludge trying to make sure that this will fail on old kernels */
+#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY | O_RDWR)
+#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT | O_ACCMODE)      
+
 #ifndef O_NDELAY
 #define O_NDELAY       O_NONBLOCK
 #endif
index e5583d1..0e0b20b 100644 (file)
@@ -802,7 +802,6 @@ static struct cgroup *task_cgroup_from_root(struct task_struct *task,
  */
 
 static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
-static struct dentry *cgroup_lookup(struct inode *, struct dentry *, unsigned int);
 static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
 static int cgroup_populate_dir(struct cgroup *cgrp, bool base_files,
                               unsigned long subsys_mask);
@@ -2642,7 +2641,7 @@ static const struct inode_operations cgroup_file_inode_operations = {
 };
 
 static const struct inode_operations cgroup_dir_inode_operations = {
-       .lookup = cgroup_lookup,
+       .lookup = simple_lookup,
        .mkdir = cgroup_mkdir,
        .rmdir = cgroup_rmdir,
        .rename = cgroup_rename,
@@ -2652,14 +2651,6 @@ static const struct inode_operations cgroup_dir_inode_operations = {
        .removexattr = cgroup_removexattr,
 };
 
-static struct dentry *cgroup_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;
-}
-
 /*
  * Check if a file is a control file
  */
index 4a15115..4a70d12 100644 (file)
 bool llist_add_batch(struct llist_node *new_first, struct llist_node *new_last,
                     struct llist_head *head)
 {
-       struct llist_node *entry, *old_entry;
+       struct llist_node *first;
 
-       entry = head->first;
-       for (;;) {
-               old_entry = entry;
-               new_last->next = entry;
-               entry = cmpxchg(&head->first, old_entry, new_first);
-               if (entry == old_entry)
-                       break;
-       }
+       do {
+               new_last->next = first = ACCESS_ONCE(head->first);
+       } while (cmpxchg(&head->first, first, new_first) != first);
 
-       return old_entry == NULL;
+       return !first;
 }
 EXPORT_SYMBOL_GPL(llist_add_batch);
 
index 49eb370..a72de07 100644 (file)
@@ -1823,19 +1823,11 @@ int sunrpc_cache_register_pipefs(struct dentry *parent,
                                 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);
 
index aa40156..9963584 100644 (file)
@@ -128,9 +128,7 @@ static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb,
 {
        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) {
@@ -138,19 +136,17 @@ static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb,
                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;
index 61239a2..406859c 100644 (file)
@@ -673,13 +673,12 @@ static int __rpc_rmpipe(struct inode *dir, struct dentry *dentry)
 }
 
 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 +703,7 @@ static void __rpc_depopulate(struct dentry *parent,
        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 +745,7 @@ static int rpc_populate(struct dentry *parent,
 
        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 +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 +849,6 @@ struct dentry *rpc_mkpipe_dentry(struct dentry *parent, const char *name,
        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)
@@ -864,12 +856,8 @@ struct dentry *rpc_mkpipe_dentry(struct dentry *parent, const char *name,
        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 +928,8 @@ static void rpc_clntdir_depopulate(struct dentry *dentry)
 
 /**
  * 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
@@ -950,7 +938,7 @@ static void rpc_clntdir_depopulate(struct dentry *dentry)
  * 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 +984,7 @@ static void rpc_cachedir_depopulate(struct dentry *dentry)
        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 +1064,7 @@ struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
                               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);