aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-14 14:42:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-14 14:42:26 -0400
commit41d9884c44237cd66e2bdbc412028b29196b344c (patch)
tree7a386f6de2f07c01f87f3a16965c9bb8b40f63c1 /fs
parent63345b4794aef4ebe16502cfe35b02bc9822d763 (diff)
parentdae3794fd603b92dcbac2859fe0bc7fe129a5188 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
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
Diffstat (limited to 'fs')
-rw-r--r--fs/configfs/dir.c13
-rw-r--r--fs/efivarfs/inode.c14
-rw-r--r--fs/file_table.c31
-rw-r--r--fs/libfs.c3
-rw-r--r--fs/namei.c2
-rw-r--r--fs/open.c4
6 files changed, 24 insertions, 43 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 5e7c60c1cb63..277bd1be21fd 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -660,19 +660,15 @@ static int create_default_group(struct config_group *parent_group,
660 struct config_group *group) 660 struct config_group *group)
661{ 661{
662 int ret; 662 int ret;
663 struct qstr name;
664 struct configfs_dirent *sd; 663 struct configfs_dirent *sd;
665 /* We trust the caller holds a reference to parent */ 664 /* We trust the caller holds a reference to parent */
666 struct dentry *child, *parent = parent_group->cg_item.ci_dentry; 665 struct dentry *child, *parent = parent_group->cg_item.ci_dentry;
667 666
668 if (!group->cg_item.ci_name) 667 if (!group->cg_item.ci_name)
669 group->cg_item.ci_name = group->cg_item.ci_namebuf; 668 group->cg_item.ci_name = group->cg_item.ci_namebuf;
670 name.name = group->cg_item.ci_name;
671 name.len = strlen(name.name);
672 name.hash = full_name_hash(name.name, name.len);
673 669
674 ret = -ENOMEM; 670 ret = -ENOMEM;
675 child = d_alloc(parent, &name); 671 child = d_alloc_name(parent, group->cg_item.ci_name);
676 if (child) { 672 if (child) {
677 d_add(child, NULL); 673 d_add(child, NULL);
678 674
@@ -1650,7 +1646,6 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
1650{ 1646{
1651 int err; 1647 int err;
1652 struct config_group *group = &subsys->su_group; 1648 struct config_group *group = &subsys->su_group;
1653 struct qstr name;
1654 struct dentry *dentry; 1649 struct dentry *dentry;
1655 struct dentry *root; 1650 struct dentry *root;
1656 struct configfs_dirent *sd; 1651 struct configfs_dirent *sd;
@@ -1667,12 +1662,8 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
1667 1662
1668 mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT); 1663 mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT);
1669 1664
1670 name.name = group->cg_item.ci_name;
1671 name.len = strlen(name.name);
1672 name.hash = full_name_hash(name.name, name.len);
1673
1674 err = -ENOMEM; 1665 err = -ENOMEM;
1675 dentry = d_alloc(root, &name); 1666 dentry = d_alloc_name(root, group->cg_item.ci_name);
1676 if (dentry) { 1667 if (dentry) {
1677 d_add(dentry, NULL); 1668 d_add(dentry, NULL);
1678 1669
diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c
index 7e787fb90293..07ab49745e31 100644
--- a/fs/efivarfs/inode.c
+++ b/fs/efivarfs/inode.c
@@ -155,20 +155,8 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
155 return 0; 155 return 0;
156}; 156};
157 157
158/*
159 * Handle negative dentry.
160 */
161static struct dentry *efivarfs_lookup(struct inode *dir, struct dentry *dentry,
162 unsigned int flags)
163{
164 if (dentry->d_name.len > NAME_MAX)
165 return ERR_PTR(-ENAMETOOLONG);
166 d_add(dentry, NULL);
167 return NULL;
168}
169
170const struct inode_operations efivarfs_dir_inode_operations = { 158const struct inode_operations efivarfs_dir_inode_operations = {
171 .lookup = efivarfs_lookup, 159 .lookup = simple_lookup,
172 .unlink = efivarfs_unlink, 160 .unlink = efivarfs_unlink,
173 .create = efivarfs_create, 161 .create = efivarfs_create,
174}; 162};
diff --git a/fs/file_table.c b/fs/file_table.c
index 08e719b884ca..b44e4c559786 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -265,18 +265,15 @@ static void __fput(struct file *file)
265 mntput(mnt); 265 mntput(mnt);
266} 266}
267 267
268static DEFINE_SPINLOCK(delayed_fput_lock); 268static LLIST_HEAD(delayed_fput_list);
269static LIST_HEAD(delayed_fput_list);
270static void delayed_fput(struct work_struct *unused) 269static void delayed_fput(struct work_struct *unused)
271{ 270{
272 LIST_HEAD(head); 271 struct llist_node *node = llist_del_all(&delayed_fput_list);
273 spin_lock_irq(&delayed_fput_lock); 272 struct llist_node *next;
274 list_splice_init(&delayed_fput_list, &head); 273
275 spin_unlock_irq(&delayed_fput_lock); 274 for (; node; node = next) {
276 while (!list_empty(&head)) { 275 next = llist_next(node);
277 struct file *f = list_first_entry(&head, struct file, f_u.fu_list); 276 __fput(llist_entry(node, struct file, f_u.fu_llist));
278 list_del_init(&f->f_u.fu_list);
279 __fput(f);
280 } 277 }
281} 278}
282 279
@@ -306,18 +303,22 @@ void fput(struct file *file)
306{ 303{
307 if (atomic_long_dec_and_test(&file->f_count)) { 304 if (atomic_long_dec_and_test(&file->f_count)) {
308 struct task_struct *task = current; 305 struct task_struct *task = current;
309 unsigned long flags;
310 306
311 file_sb_list_del(file); 307 file_sb_list_del(file);
312 if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) { 308 if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) {
313 init_task_work(&file->f_u.fu_rcuhead, ____fput); 309 init_task_work(&file->f_u.fu_rcuhead, ____fput);
314 if (!task_work_add(task, &file->f_u.fu_rcuhead, true)) 310 if (!task_work_add(task, &file->f_u.fu_rcuhead, true))
315 return; 311 return;
312 /*
313 * After this task has run exit_task_work(),
314 * task_work_add() will fail. free_ipc_ns()->
315 * shm_destroy() can do this. Fall through to delayed
316 * fput to avoid leaking *file.
317 */
316 } 318 }
317 spin_lock_irqsave(&delayed_fput_lock, flags); 319
318 list_add(&file->f_u.fu_list, &delayed_fput_list); 320 if (llist_add(&file->f_u.fu_llist, &delayed_fput_list))
319 schedule_work(&delayed_fput_work); 321 schedule_work(&delayed_fput_work);
320 spin_unlock_irqrestore(&delayed_fput_lock, flags);
321 } 322 }
322} 323}
323 324
diff --git a/fs/libfs.c b/fs/libfs.c
index c3a0837fb861..3a3a9b53bf5a 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -61,7 +61,8 @@ struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, unsigned
61 61
62 if (dentry->d_name.len > NAME_MAX) 62 if (dentry->d_name.len > NAME_MAX)
63 return ERR_PTR(-ENAMETOOLONG); 63 return ERR_PTR(-ENAMETOOLONG);
64 d_set_d_op(dentry, &simple_dentry_operations); 64 if (!dentry->d_sb->s_d_op)
65 d_set_d_op(dentry, &simple_dentry_operations);
65 d_add(dentry, NULL); 66 d_add(dentry, NULL);
66 return NULL; 67 return NULL;
67} 68}
diff --git a/fs/namei.c b/fs/namei.c
index b2beee7a733f..8b61d103a8a7 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2977,7 +2977,7 @@ static struct file *path_openat(int dfd, struct filename *pathname,
2977 2977
2978 file->f_flags = op->open_flag; 2978 file->f_flags = op->open_flag;
2979 2979
2980 if (unlikely(file->f_flags & O_TMPFILE)) { 2980 if (unlikely(file->f_flags & __O_TMPFILE)) {
2981 error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened); 2981 error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened);
2982 goto out; 2982 goto out;
2983 } 2983 }
diff --git a/fs/open.c b/fs/open.c
index fca72c4d3f17..9156cb050d08 100644
--- 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
840 if (flags & __O_SYNC) 840 if (flags & __O_SYNC)
841 flags |= O_DSYNC; 841 flags |= O_DSYNC;
842 842
843 if (flags & O_TMPFILE) { 843 if (flags & __O_TMPFILE) {
844 if (!(flags & O_CREAT)) 844 if ((flags & O_TMPFILE_MASK) != O_TMPFILE)
845 return -EINVAL; 845 return -EINVAL;
846 acc_mode = MAY_OPEN | ACC_MODE(flags); 846 acc_mode = MAY_OPEN | ACC_MODE(flags);
847 } else if (flags & O_PATH) { 847 } else if (flags & O_PATH) {