diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-14 14:42:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-14 14:42:26 -0400 |
commit | 41d9884c44237cd66e2bdbc412028b29196b344c (patch) | |
tree | 7a386f6de2f07c01f87f3a16965c9bb8b40f63c1 /fs | |
parent | 63345b4794aef4ebe16502cfe35b02bc9822d763 (diff) | |
parent | dae3794fd603b92dcbac2859fe0bc7fe129a5188 (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.c | 13 | ||||
-rw-r--r-- | fs/efivarfs/inode.c | 14 | ||||
-rw-r--r-- | fs/file_table.c | 31 | ||||
-rw-r--r-- | fs/libfs.c | 3 | ||||
-rw-r--r-- | fs/namei.c | 2 | ||||
-rw-r--r-- | fs/open.c | 4 |
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 | */ | ||
161 | static 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 | |||
170 | const struct inode_operations efivarfs_dir_inode_operations = { | 158 | const 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 | ||
268 | static DEFINE_SPINLOCK(delayed_fput_lock); | 268 | static LLIST_HEAD(delayed_fput_list); |
269 | static LIST_HEAD(delayed_fput_list); | ||
270 | static void delayed_fput(struct work_struct *unused) | 269 | static 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 | } |
@@ -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) { |