diff options
Diffstat (limited to 'fs/kernfs/file.c')
| -rw-r--r-- | fs/kernfs/file.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index dbf397bfdff2..8034706a7af8 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c | |||
| @@ -252,10 +252,18 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, | |||
| 252 | size_t count, loff_t *ppos) | 252 | size_t count, loff_t *ppos) |
| 253 | { | 253 | { |
| 254 | struct kernfs_open_file *of = kernfs_of(file); | 254 | struct kernfs_open_file *of = kernfs_of(file); |
| 255 | ssize_t len = min_t(size_t, count, PAGE_SIZE); | ||
| 256 | const struct kernfs_ops *ops; | 255 | const struct kernfs_ops *ops; |
| 256 | size_t len; | ||
| 257 | char *buf; | 257 | char *buf; |
| 258 | 258 | ||
| 259 | if (of->atomic_write_len) { | ||
| 260 | len = count; | ||
| 261 | if (len > of->atomic_write_len) | ||
| 262 | return -E2BIG; | ||
| 263 | } else { | ||
| 264 | len = min_t(size_t, count, PAGE_SIZE); | ||
| 265 | } | ||
| 266 | |||
| 259 | buf = kmalloc(len + 1, GFP_KERNEL); | 267 | buf = kmalloc(len + 1, GFP_KERNEL); |
| 260 | if (!buf) | 268 | if (!buf) |
| 261 | return -ENOMEM; | 269 | return -ENOMEM; |
| @@ -653,6 +661,12 @@ static int kernfs_fop_open(struct inode *inode, struct file *file) | |||
| 653 | of->file = file; | 661 | of->file = file; |
| 654 | 662 | ||
| 655 | /* | 663 | /* |
| 664 | * Write path needs to atomic_write_len outside active reference. | ||
| 665 | * Cache it in open_file. See kernfs_fop_write() for details. | ||
| 666 | */ | ||
| 667 | of->atomic_write_len = ops->atomic_write_len; | ||
| 668 | |||
| 669 | /* | ||
| 656 | * Always instantiate seq_file even if read access doesn't use | 670 | * Always instantiate seq_file even if read access doesn't use |
| 657 | * seq_file or is not requested. This unifies private data access | 671 | * seq_file or is not requested. This unifies private data access |
| 658 | * and readable regular files are the vast majority anyway. | 672 | * and readable regular files are the vast majority anyway. |
| @@ -820,7 +834,6 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, | |||
| 820 | bool name_is_static, | 834 | bool name_is_static, |
| 821 | struct lock_class_key *key) | 835 | struct lock_class_key *key) |
| 822 | { | 836 | { |
| 823 | struct kernfs_addrm_cxt acxt; | ||
| 824 | struct kernfs_node *kn; | 837 | struct kernfs_node *kn; |
| 825 | unsigned flags; | 838 | unsigned flags; |
| 826 | int rc; | 839 | int rc; |
| @@ -855,10 +868,7 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, | |||
| 855 | if (ops->mmap) | 868 | if (ops->mmap) |
| 856 | kn->flags |= KERNFS_HAS_MMAP; | 869 | kn->flags |= KERNFS_HAS_MMAP; |
| 857 | 870 | ||
| 858 | kernfs_addrm_start(&acxt); | 871 | rc = kernfs_add_one(kn); |
| 859 | rc = kernfs_add_one(&acxt, kn); | ||
| 860 | kernfs_addrm_finish(&acxt); | ||
| 861 | |||
| 862 | if (rc) { | 872 | if (rc) { |
| 863 | kernfs_put(kn); | 873 | kernfs_put(kn); |
| 864 | return ERR_PTR(rc); | 874 | return ERR_PTR(rc); |
