diff options
Diffstat (limited to 'fs')
41 files changed, 2395 insertions, 673 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index f9b6e2979aaa..32883589ee54 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -721,7 +721,20 @@ config CONFIGFS_FS | |||
721 | 721 | ||
722 | endmenu | 722 | endmenu |
723 | 723 | ||
724 | menu "Miscellaneous filesystems" | 724 | menuconfig MISC_FILESYSTEMS |
725 | bool "Miscellaneous filesystems" | ||
726 | default y | ||
727 | ---help--- | ||
728 | Say Y here to get to see options for various miscellaneous | ||
729 | filesystems, such as filesystems that came from other | ||
730 | operating systems. | ||
731 | |||
732 | This option alone does not add any kernel code. | ||
733 | |||
734 | If you say N, all options in this submenu will be skipped and | ||
735 | disabled; if unsure, say Y here. | ||
736 | |||
737 | if MISC_FILESYSTEMS | ||
725 | 738 | ||
726 | config ADFS_FS | 739 | config ADFS_FS |
727 | tristate "ADFS file system support (EXPERIMENTAL)" | 740 | tristate "ADFS file system support (EXPERIMENTAL)" |
@@ -1091,7 +1104,7 @@ config UFS_DEBUG | |||
1091 | Y here. This will result in _many_ additional debugging messages to be | 1104 | Y here. This will result in _many_ additional debugging messages to be |
1092 | written to the system log. | 1105 | written to the system log. |
1093 | 1106 | ||
1094 | endmenu | 1107 | endif # MISC_FILESYSTEMS |
1095 | 1108 | ||
1096 | menuconfig NETWORK_FILESYSTEMS | 1109 | menuconfig NETWORK_FILESYSTEMS |
1097 | bool "Network File Systems" | 1110 | bool "Network File Systems" |
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index e0f16da00e54..a76803108d06 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -25,8 +25,6 @@ | |||
25 | #define AUTOFS_DEV_IOCTL_IOC_FIRST (AUTOFS_DEV_IOCTL_VERSION) | 25 | #define AUTOFS_DEV_IOCTL_IOC_FIRST (AUTOFS_DEV_IOCTL_VERSION) |
26 | #define AUTOFS_DEV_IOCTL_IOC_COUNT (AUTOFS_IOC_COUNT - 11) | 26 | #define AUTOFS_DEV_IOCTL_IOC_COUNT (AUTOFS_IOC_COUNT - 11) |
27 | 27 | ||
28 | #define AUTOFS_TYPE_TRIGGER (AUTOFS_TYPE_DIRECT|AUTOFS_TYPE_OFFSET) | ||
29 | |||
30 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
31 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
32 | #include <linux/time.h> | 30 | #include <linux/time.h> |
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index 63b7c7afe8df..025e105bffea 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c | |||
@@ -124,7 +124,7 @@ static inline void free_dev_ioctl(struct autofs_dev_ioctl *param) | |||
124 | 124 | ||
125 | /* | 125 | /* |
126 | * Check sanity of parameter control fields and if a path is present | 126 | * Check sanity of parameter control fields and if a path is present |
127 | * check that it has a "/" and is terminated. | 127 | * check that it is terminated and contains at least one "/". |
128 | */ | 128 | */ |
129 | static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param) | 129 | static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param) |
130 | { | 130 | { |
@@ -138,15 +138,16 @@ static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param) | |||
138 | } | 138 | } |
139 | 139 | ||
140 | if (param->size > sizeof(*param)) { | 140 | if (param->size > sizeof(*param)) { |
141 | err = check_name(param->path); | 141 | err = invalid_str(param->path, |
142 | (void *) ((size_t) param + param->size)); | ||
142 | if (err) { | 143 | if (err) { |
143 | AUTOFS_WARN("invalid path supplied for cmd(0x%08x)", | 144 | AUTOFS_WARN( |
144 | cmd); | 145 | "path string terminator missing for cmd(0x%08x)", |
146 | cmd); | ||
145 | goto out; | 147 | goto out; |
146 | } | 148 | } |
147 | 149 | ||
148 | err = invalid_str(param->path, | 150 | err = check_name(param->path); |
149 | (void *) ((size_t) param + param->size)); | ||
150 | if (err) { | 151 | if (err) { |
151 | AUTOFS_WARN("invalid path supplied for cmd(0x%08x)", | 152 | AUTOFS_WARN("invalid path supplied for cmd(0x%08x)", |
152 | cmd); | 153 | cmd); |
@@ -180,7 +181,7 @@ static int autofs_dev_ioctl_protover(struct file *fp, | |||
180 | struct autofs_sb_info *sbi, | 181 | struct autofs_sb_info *sbi, |
181 | struct autofs_dev_ioctl *param) | 182 | struct autofs_dev_ioctl *param) |
182 | { | 183 | { |
183 | param->arg1 = sbi->version; | 184 | param->protover.version = sbi->version; |
184 | return 0; | 185 | return 0; |
185 | } | 186 | } |
186 | 187 | ||
@@ -189,7 +190,7 @@ static int autofs_dev_ioctl_protosubver(struct file *fp, | |||
189 | struct autofs_sb_info *sbi, | 190 | struct autofs_sb_info *sbi, |
190 | struct autofs_dev_ioctl *param) | 191 | struct autofs_dev_ioctl *param) |
191 | { | 192 | { |
192 | param->arg1 = sbi->sub_version; | 193 | param->protosubver.sub_version = sbi->sub_version; |
193 | return 0; | 194 | return 0; |
194 | } | 195 | } |
195 | 196 | ||
@@ -335,13 +336,13 @@ static int autofs_dev_ioctl_openmount(struct file *fp, | |||
335 | int err, fd; | 336 | int err, fd; |
336 | 337 | ||
337 | /* param->path has already been checked */ | 338 | /* param->path has already been checked */ |
338 | if (!param->arg1) | 339 | if (!param->openmount.devid) |
339 | return -EINVAL; | 340 | return -EINVAL; |
340 | 341 | ||
341 | param->ioctlfd = -1; | 342 | param->ioctlfd = -1; |
342 | 343 | ||
343 | path = param->path; | 344 | path = param->path; |
344 | devid = param->arg1; | 345 | devid = param->openmount.devid; |
345 | 346 | ||
346 | err = 0; | 347 | err = 0; |
347 | fd = autofs_dev_ioctl_open_mountpoint(path, devid); | 348 | fd = autofs_dev_ioctl_open_mountpoint(path, devid); |
@@ -373,7 +374,7 @@ static int autofs_dev_ioctl_ready(struct file *fp, | |||
373 | { | 374 | { |
374 | autofs_wqt_t token; | 375 | autofs_wqt_t token; |
375 | 376 | ||
376 | token = (autofs_wqt_t) param->arg1; | 377 | token = (autofs_wqt_t) param->ready.token; |
377 | return autofs4_wait_release(sbi, token, 0); | 378 | return autofs4_wait_release(sbi, token, 0); |
378 | } | 379 | } |
379 | 380 | ||
@@ -388,8 +389,8 @@ static int autofs_dev_ioctl_fail(struct file *fp, | |||
388 | autofs_wqt_t token; | 389 | autofs_wqt_t token; |
389 | int status; | 390 | int status; |
390 | 391 | ||
391 | token = (autofs_wqt_t) param->arg1; | 392 | token = (autofs_wqt_t) param->fail.token; |
392 | status = param->arg2 ? param->arg2 : -ENOENT; | 393 | status = param->fail.status ? param->fail.status : -ENOENT; |
393 | return autofs4_wait_release(sbi, token, status); | 394 | return autofs4_wait_release(sbi, token, status); |
394 | } | 395 | } |
395 | 396 | ||
@@ -412,10 +413,10 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp, | |||
412 | int pipefd; | 413 | int pipefd; |
413 | int err = 0; | 414 | int err = 0; |
414 | 415 | ||
415 | if (param->arg1 == -1) | 416 | if (param->setpipefd.pipefd == -1) |
416 | return -EINVAL; | 417 | return -EINVAL; |
417 | 418 | ||
418 | pipefd = param->arg1; | 419 | pipefd = param->setpipefd.pipefd; |
419 | 420 | ||
420 | mutex_lock(&sbi->wq_mutex); | 421 | mutex_lock(&sbi->wq_mutex); |
421 | if (!sbi->catatonic) { | 422 | if (!sbi->catatonic) { |
@@ -457,8 +458,8 @@ static int autofs_dev_ioctl_timeout(struct file *fp, | |||
457 | { | 458 | { |
458 | unsigned long timeout; | 459 | unsigned long timeout; |
459 | 460 | ||
460 | timeout = param->arg1; | 461 | timeout = param->timeout.timeout; |
461 | param->arg1 = sbi->exp_timeout / HZ; | 462 | param->timeout.timeout = sbi->exp_timeout / HZ; |
462 | sbi->exp_timeout = timeout * HZ; | 463 | sbi->exp_timeout = timeout * HZ; |
463 | return 0; | 464 | return 0; |
464 | } | 465 | } |
@@ -489,7 +490,7 @@ static int autofs_dev_ioctl_requester(struct file *fp, | |||
489 | path = param->path; | 490 | path = param->path; |
490 | devid = sbi->sb->s_dev; | 491 | devid = sbi->sb->s_dev; |
491 | 492 | ||
492 | param->arg1 = param->arg2 = -1; | 493 | param->requester.uid = param->requester.gid = -1; |
493 | 494 | ||
494 | /* Get nameidata of the parent directory */ | 495 | /* Get nameidata of the parent directory */ |
495 | err = path_lookup(path, LOOKUP_PARENT, &nd); | 496 | err = path_lookup(path, LOOKUP_PARENT, &nd); |
@@ -505,8 +506,8 @@ static int autofs_dev_ioctl_requester(struct file *fp, | |||
505 | err = 0; | 506 | err = 0; |
506 | autofs4_expire_wait(nd.path.dentry); | 507 | autofs4_expire_wait(nd.path.dentry); |
507 | spin_lock(&sbi->fs_lock); | 508 | spin_lock(&sbi->fs_lock); |
508 | param->arg1 = ino->uid; | 509 | param->requester.uid = ino->uid; |
509 | param->arg2 = ino->gid; | 510 | param->requester.gid = ino->gid; |
510 | spin_unlock(&sbi->fs_lock); | 511 | spin_unlock(&sbi->fs_lock); |
511 | } | 512 | } |
512 | 513 | ||
@@ -529,10 +530,10 @@ static int autofs_dev_ioctl_expire(struct file *fp, | |||
529 | int err = -EAGAIN; | 530 | int err = -EAGAIN; |
530 | int how; | 531 | int how; |
531 | 532 | ||
532 | how = param->arg1; | 533 | how = param->expire.how; |
533 | mnt = fp->f_path.mnt; | 534 | mnt = fp->f_path.mnt; |
534 | 535 | ||
535 | if (sbi->type & AUTOFS_TYPE_TRIGGER) | 536 | if (autofs_type_trigger(sbi->type)) |
536 | dentry = autofs4_expire_direct(sbi->sb, mnt, sbi, how); | 537 | dentry = autofs4_expire_direct(sbi->sb, mnt, sbi, how); |
537 | else | 538 | else |
538 | dentry = autofs4_expire_indirect(sbi->sb, mnt, sbi, how); | 539 | dentry = autofs4_expire_indirect(sbi->sb, mnt, sbi, how); |
@@ -565,9 +566,9 @@ static int autofs_dev_ioctl_askumount(struct file *fp, | |||
565 | struct autofs_sb_info *sbi, | 566 | struct autofs_sb_info *sbi, |
566 | struct autofs_dev_ioctl *param) | 567 | struct autofs_dev_ioctl *param) |
567 | { | 568 | { |
568 | param->arg1 = 0; | 569 | param->askumount.may_umount = 0; |
569 | if (may_umount(fp->f_path.mnt)) | 570 | if (may_umount(fp->f_path.mnt)) |
570 | param->arg1 = 1; | 571 | param->askumount.may_umount = 1; |
571 | return 0; | 572 | return 0; |
572 | } | 573 | } |
573 | 574 | ||
@@ -600,6 +601,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
600 | struct nameidata nd; | 601 | struct nameidata nd; |
601 | const char *path; | 602 | const char *path; |
602 | unsigned int type; | 603 | unsigned int type; |
604 | unsigned int devid, magic; | ||
603 | int err = -ENOENT; | 605 | int err = -ENOENT; |
604 | 606 | ||
605 | if (param->size <= sizeof(*param)) { | 607 | if (param->size <= sizeof(*param)) { |
@@ -608,13 +610,13 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
608 | } | 610 | } |
609 | 611 | ||
610 | path = param->path; | 612 | path = param->path; |
611 | type = param->arg1; | 613 | type = param->ismountpoint.in.type; |
612 | 614 | ||
613 | param->arg1 = 0; | 615 | param->ismountpoint.out.devid = devid = 0; |
614 | param->arg2 = 0; | 616 | param->ismountpoint.out.magic = magic = 0; |
615 | 617 | ||
616 | if (!fp || param->ioctlfd == -1) { | 618 | if (!fp || param->ioctlfd == -1) { |
617 | if (type == AUTOFS_TYPE_ANY) { | 619 | if (autofs_type_any(type)) { |
618 | struct super_block *sb; | 620 | struct super_block *sb; |
619 | 621 | ||
620 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); | 622 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); |
@@ -622,7 +624,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
622 | goto out; | 624 | goto out; |
623 | 625 | ||
624 | sb = nd.path.dentry->d_sb; | 626 | sb = nd.path.dentry->d_sb; |
625 | param->arg1 = new_encode_dev(sb->s_dev); | 627 | devid = new_encode_dev(sb->s_dev); |
626 | } else { | 628 | } else { |
627 | struct autofs_info *ino; | 629 | struct autofs_info *ino; |
628 | 630 | ||
@@ -635,38 +637,41 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
635 | goto out_release; | 637 | goto out_release; |
636 | 638 | ||
637 | ino = autofs4_dentry_ino(nd.path.dentry); | 639 | ino = autofs4_dentry_ino(nd.path.dentry); |
638 | param->arg1 = autofs4_get_dev(ino->sbi); | 640 | devid = autofs4_get_dev(ino->sbi); |
639 | } | 641 | } |
640 | 642 | ||
641 | err = 0; | 643 | err = 0; |
642 | if (nd.path.dentry->d_inode && | 644 | if (nd.path.dentry->d_inode && |
643 | nd.path.mnt->mnt_root == nd.path.dentry) { | 645 | nd.path.mnt->mnt_root == nd.path.dentry) { |
644 | err = 1; | 646 | err = 1; |
645 | param->arg2 = nd.path.dentry->d_inode->i_sb->s_magic; | 647 | magic = nd.path.dentry->d_inode->i_sb->s_magic; |
646 | } | 648 | } |
647 | } else { | 649 | } else { |
648 | dev_t devid = new_encode_dev(sbi->sb->s_dev); | 650 | dev_t dev = autofs4_get_dev(sbi); |
649 | 651 | ||
650 | err = path_lookup(path, LOOKUP_PARENT, &nd); | 652 | err = path_lookup(path, LOOKUP_PARENT, &nd); |
651 | if (err) | 653 | if (err) |
652 | goto out; | 654 | goto out; |
653 | 655 | ||
654 | err = autofs_dev_ioctl_find_super(&nd, devid); | 656 | err = autofs_dev_ioctl_find_super(&nd, dev); |
655 | if (err) | 657 | if (err) |
656 | goto out_release; | 658 | goto out_release; |
657 | 659 | ||
658 | param->arg1 = autofs4_get_dev(sbi); | 660 | devid = dev; |
659 | 661 | ||
660 | err = have_submounts(nd.path.dentry); | 662 | err = have_submounts(nd.path.dentry); |
661 | 663 | ||
662 | if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) { | 664 | if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) { |
663 | if (follow_down(&nd.path.mnt, &nd.path.dentry)) { | 665 | if (follow_down(&nd.path.mnt, &nd.path.dentry)) { |
664 | struct inode *inode = nd.path.dentry->d_inode; | 666 | struct inode *inode = nd.path.dentry->d_inode; |
665 | param->arg2 = inode->i_sb->s_magic; | 667 | magic = inode->i_sb->s_magic; |
666 | } | 668 | } |
667 | } | 669 | } |
668 | } | 670 | } |
669 | 671 | ||
672 | param->ismountpoint.out.devid = devid; | ||
673 | param->ismountpoint.out.magic = magic; | ||
674 | |||
670 | out_release: | 675 | out_release: |
671 | path_put(&nd.path); | 676 | path_put(&nd.path); |
672 | out: | 677 | out: |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 4b6fb3f628c0..e3bd50776f9e 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -63,7 +63,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry) | |||
63 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 63 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
64 | 64 | ||
65 | /* This is an autofs submount, we can't expire it */ | 65 | /* This is an autofs submount, we can't expire it */ |
66 | if (sbi->type == AUTOFS_TYPE_INDIRECT) | 66 | if (autofs_type_indirect(sbi->type)) |
67 | goto done; | 67 | goto done; |
68 | 68 | ||
69 | /* | 69 | /* |
@@ -490,7 +490,7 @@ int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt, | |||
490 | if (arg && get_user(do_now, arg)) | 490 | if (arg && get_user(do_now, arg)) |
491 | return -EFAULT; | 491 | return -EFAULT; |
492 | 492 | ||
493 | if (sbi->type & AUTOFS_TYPE_TRIGGER) | 493 | if (autofs_type_trigger(sbi->type)) |
494 | dentry = autofs4_expire_direct(sb, mnt, sbi, do_now); | 494 | dentry = autofs4_expire_direct(sb, mnt, sbi, do_now); |
495 | else | 495 | else |
496 | dentry = autofs4_expire_indirect(sb, mnt, sbi, do_now); | 496 | dentry = autofs4_expire_indirect(sb, mnt, sbi, do_now); |
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index cfc23e53b6f4..716e12b627b2 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -197,9 +197,9 @@ static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
197 | seq_printf(m, ",minproto=%d", sbi->min_proto); | 197 | seq_printf(m, ",minproto=%d", sbi->min_proto); |
198 | seq_printf(m, ",maxproto=%d", sbi->max_proto); | 198 | seq_printf(m, ",maxproto=%d", sbi->max_proto); |
199 | 199 | ||
200 | if (sbi->type & AUTOFS_TYPE_OFFSET) | 200 | if (autofs_type_offset(sbi->type)) |
201 | seq_printf(m, ",offset"); | 201 | seq_printf(m, ",offset"); |
202 | else if (sbi->type & AUTOFS_TYPE_DIRECT) | 202 | else if (autofs_type_direct(sbi->type)) |
203 | seq_printf(m, ",direct"); | 203 | seq_printf(m, ",direct"); |
204 | else | 204 | else |
205 | seq_printf(m, ",indirect"); | 205 | seq_printf(m, ",indirect"); |
@@ -284,13 +284,13 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, | |||
284 | *maxproto = option; | 284 | *maxproto = option; |
285 | break; | 285 | break; |
286 | case Opt_indirect: | 286 | case Opt_indirect: |
287 | *type = AUTOFS_TYPE_INDIRECT; | 287 | set_autofs_type_indirect(type); |
288 | break; | 288 | break; |
289 | case Opt_direct: | 289 | case Opt_direct: |
290 | *type = AUTOFS_TYPE_DIRECT; | 290 | set_autofs_type_direct(type); |
291 | break; | 291 | break; |
292 | case Opt_offset: | 292 | case Opt_offset: |
293 | *type = AUTOFS_TYPE_OFFSET; | 293 | set_autofs_type_offset(type); |
294 | break; | 294 | break; |
295 | default: | 295 | default: |
296 | return 1; | 296 | return 1; |
@@ -338,7 +338,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
338 | sbi->sb = s; | 338 | sbi->sb = s; |
339 | sbi->version = 0; | 339 | sbi->version = 0; |
340 | sbi->sub_version = 0; | 340 | sbi->sub_version = 0; |
341 | sbi->type = AUTOFS_TYPE_INDIRECT; | 341 | set_autofs_type_indirect(&sbi->type); |
342 | sbi->min_proto = 0; | 342 | sbi->min_proto = 0; |
343 | sbi->max_proto = 0; | 343 | sbi->max_proto = 0; |
344 | mutex_init(&sbi->wq_mutex); | 344 | mutex_init(&sbi->wq_mutex); |
@@ -380,7 +380,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
380 | } | 380 | } |
381 | 381 | ||
382 | root_inode->i_fop = &autofs4_root_operations; | 382 | root_inode->i_fop = &autofs4_root_operations; |
383 | root_inode->i_op = sbi->type & AUTOFS_TYPE_TRIGGER ? | 383 | root_inode->i_op = autofs_type_trigger(sbi->type) ? |
384 | &autofs4_direct_root_inode_operations : | 384 | &autofs4_direct_root_inode_operations : |
385 | &autofs4_indirect_root_inode_operations; | 385 | &autofs4_indirect_root_inode_operations; |
386 | 386 | ||
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index e02cc8ae5eb3..eeb246845909 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
@@ -337,7 +337,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, | |||
337 | * is very similar for indirect mounts except only dentrys | 337 | * is very similar for indirect mounts except only dentrys |
338 | * in the root of the autofs file system may be negative. | 338 | * in the root of the autofs file system may be negative. |
339 | */ | 339 | */ |
340 | if (sbi->type & AUTOFS_TYPE_TRIGGER) | 340 | if (autofs_type_trigger(sbi->type)) |
341 | return -ENOENT; | 341 | return -ENOENT; |
342 | else if (!IS_ROOT(dentry->d_parent)) | 342 | else if (!IS_ROOT(dentry->d_parent)) |
343 | return -ENOENT; | 343 | return -ENOENT; |
@@ -348,7 +348,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, | |||
348 | return -ENOMEM; | 348 | return -ENOMEM; |
349 | 349 | ||
350 | /* If this is a direct mount request create a dummy name */ | 350 | /* If this is a direct mount request create a dummy name */ |
351 | if (IS_ROOT(dentry) && sbi->type & AUTOFS_TYPE_TRIGGER) | 351 | if (IS_ROOT(dentry) && autofs_type_trigger(sbi->type)) |
352 | qstr.len = sprintf(name, "%p", dentry); | 352 | qstr.len = sprintf(name, "%p", dentry); |
353 | else { | 353 | else { |
354 | qstr.len = autofs4_getpath(sbi, dentry, &name); | 354 | qstr.len = autofs4_getpath(sbi, dentry, &name); |
@@ -406,11 +406,11 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, | |||
406 | type = autofs_ptype_expire_multi; | 406 | type = autofs_ptype_expire_multi; |
407 | } else { | 407 | } else { |
408 | if (notify == NFY_MOUNT) | 408 | if (notify == NFY_MOUNT) |
409 | type = (sbi->type & AUTOFS_TYPE_TRIGGER) ? | 409 | type = autofs_type_trigger(sbi->type) ? |
410 | autofs_ptype_missing_direct : | 410 | autofs_ptype_missing_direct : |
411 | autofs_ptype_missing_indirect; | 411 | autofs_ptype_missing_indirect; |
412 | else | 412 | else |
413 | type = (sbi->type & AUTOFS_TYPE_TRIGGER) ? | 413 | type = autofs_type_trigger(sbi->type) ? |
414 | autofs_ptype_expire_direct : | 414 | autofs_ptype_expire_direct : |
415 | autofs_ptype_expire_indirect; | 415 | autofs_ptype_expire_indirect; |
416 | } | 416 | } |
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 0ed57b5ee012..cc4062d12ca2 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c | |||
@@ -213,6 +213,9 @@ static void bfs_put_super(struct super_block *s) | |||
213 | { | 213 | { |
214 | struct bfs_sb_info *info = BFS_SB(s); | 214 | struct bfs_sb_info *info = BFS_SB(s); |
215 | 215 | ||
216 | if (!info) | ||
217 | return; | ||
218 | |||
216 | brelse(info->si_sbh); | 219 | brelse(info->si_sbh); |
217 | mutex_destroy(&info->bfs_lock); | 220 | mutex_destroy(&info->bfs_lock); |
218 | kfree(info->si_imap); | 221 | kfree(info->si_imap); |
@@ -327,6 +330,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) | |||
327 | unsigned i, imap_len; | 330 | unsigned i, imap_len; |
328 | struct bfs_sb_info *info; | 331 | struct bfs_sb_info *info; |
329 | long ret = -EINVAL; | 332 | long ret = -EINVAL; |
333 | unsigned long i_sblock, i_eblock, i_eoff, s_size; | ||
330 | 334 | ||
331 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 335 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
332 | if (!info) | 336 | if (!info) |
@@ -350,6 +354,12 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) | |||
350 | 354 | ||
351 | s->s_magic = BFS_MAGIC; | 355 | s->s_magic = BFS_MAGIC; |
352 | info->si_sbh = bh; | 356 | info->si_sbh = bh; |
357 | |||
358 | if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end)) { | ||
359 | printf("Superblock is corrupted\n"); | ||
360 | goto out; | ||
361 | } | ||
362 | |||
353 | info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / | 363 | info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / |
354 | sizeof(struct bfs_inode) | 364 | sizeof(struct bfs_inode) |
355 | + BFS_ROOT_INO - 1; | 365 | + BFS_ROOT_INO - 1; |
@@ -380,6 +390,18 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) | |||
380 | - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS; | 390 | - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS; |
381 | info->si_freei = 0; | 391 | info->si_freei = 0; |
382 | info->si_lf_eblk = 0; | 392 | info->si_lf_eblk = 0; |
393 | |||
394 | /* can we read the last block? */ | ||
395 | bh = sb_bread(s, info->si_blocks - 1); | ||
396 | if (!bh) { | ||
397 | printf("Last block not available: %lu\n", info->si_blocks - 1); | ||
398 | iput(inode); | ||
399 | ret = -EIO; | ||
400 | kfree(info->si_imap); | ||
401 | goto out; | ||
402 | } | ||
403 | brelse(bh); | ||
404 | |||
383 | bh = NULL; | 405 | bh = NULL; |
384 | for (i = BFS_ROOT_INO; i <= info->si_lasti; i++) { | 406 | for (i = BFS_ROOT_INO; i <= info->si_lasti; i++) { |
385 | struct bfs_inode *di; | 407 | struct bfs_inode *di; |
@@ -397,6 +419,29 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) | |||
397 | 419 | ||
398 | di = (struct bfs_inode *)bh->b_data + off; | 420 | di = (struct bfs_inode *)bh->b_data + off; |
399 | 421 | ||
422 | /* test if filesystem is not corrupted */ | ||
423 | |||
424 | i_eoff = le32_to_cpu(di->i_eoffset); | ||
425 | i_sblock = le32_to_cpu(di->i_sblock); | ||
426 | i_eblock = le32_to_cpu(di->i_eblock); | ||
427 | s_size = le32_to_cpu(bfs_sb->s_end); | ||
428 | |||
429 | if (i_sblock > info->si_blocks || | ||
430 | i_eblock > info->si_blocks || | ||
431 | i_sblock > i_eblock || | ||
432 | i_eoff > s_size || | ||
433 | i_sblock * BFS_BSIZE > i_eoff) { | ||
434 | |||
435 | printf("Inode 0x%08x corrupted\n", i); | ||
436 | |||
437 | brelse(bh); | ||
438 | s->s_root = NULL; | ||
439 | kfree(info->si_imap); | ||
440 | kfree(info); | ||
441 | s->s_fs_info = NULL; | ||
442 | return -EIO; | ||
443 | } | ||
444 | |||
400 | if (!di->i_ino) { | 445 | if (!di->i_ino) { |
401 | info->si_freei++; | 446 | info->si_freei++; |
402 | continue; | 447 | continue; |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index e1158cb4fbd6..c4e83537ead7 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -649,7 +649,7 @@ static const struct file_operations bm_register_operations = { | |||
649 | static ssize_t | 649 | static ssize_t |
650 | bm_status_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | 650 | bm_status_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
651 | { | 651 | { |
652 | char *s = enabled ? "enabled" : "disabled"; | 652 | char *s = enabled ? "enabled\n" : "disabled\n"; |
653 | 653 | ||
654 | return simple_read_from_buffer(buf, nbytes, ppos, s, strlen(s)); | 654 | return simple_read_from_buffer(buf, nbytes, ppos, s, strlen(s)); |
655 | } | 655 | } |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 349a26c10001..b957717e25ab 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -1262,7 +1262,7 @@ EXPORT_SYMBOL(ioctl_by_bdev); | |||
1262 | 1262 | ||
1263 | /** | 1263 | /** |
1264 | * lookup_bdev - lookup a struct block_device by name | 1264 | * lookup_bdev - lookup a struct block_device by name |
1265 | * @path: special file representing the block device | 1265 | * @pathname: special file representing the block device |
1266 | * | 1266 | * |
1267 | * Get a reference to the blockdevice at @pathname in the current | 1267 | * Get a reference to the blockdevice at @pathname in the current |
1268 | * namespace if possible and return it. Return ERR_PTR(error) | 1268 | * namespace if possible and return it. Return ERR_PTR(error) |
diff --git a/fs/buffer.c b/fs/buffer.c index a13f09b696f7..c26da785938a 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2022,7 +2022,6 @@ int block_write_begin(struct file *file, struct address_space *mapping, | |||
2022 | if (pos + len > inode->i_size) | 2022 | if (pos + len > inode->i_size) |
2023 | vmtruncate(inode, inode->i_size); | 2023 | vmtruncate(inode, inode->i_size); |
2024 | } | 2024 | } |
2025 | goto out; | ||
2026 | } | 2025 | } |
2027 | 2026 | ||
2028 | out: | 2027 | out: |
diff --git a/fs/char_dev.c b/fs/char_dev.c index 700697a72618..38f71222a552 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -120,7 +120,7 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, | |||
120 | cd->major = major; | 120 | cd->major = major; |
121 | cd->baseminor = baseminor; | 121 | cd->baseminor = baseminor; |
122 | cd->minorct = minorct; | 122 | cd->minorct = minorct; |
123 | strncpy(cd->name,name, 64); | 123 | strlcpy(cd->name, name, sizeof(cd->name)); |
124 | 124 | ||
125 | i = major_to_index(major); | 125 | i = major_to_index(major); |
126 | 126 | ||
diff --git a/fs/compat.c b/fs/compat.c index d1ece79b6411..30f2faa22f5c 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1187,6 +1187,9 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsign | |||
1187 | ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos); | 1187 | ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos); |
1188 | 1188 | ||
1189 | out: | 1189 | out: |
1190 | if (ret > 0) | ||
1191 | add_rchar(current, ret); | ||
1192 | inc_syscr(current); | ||
1190 | fput(file); | 1193 | fput(file); |
1191 | return ret; | 1194 | return ret; |
1192 | } | 1195 | } |
@@ -1210,6 +1213,9 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, unsig | |||
1210 | ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos); | 1213 | ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos); |
1211 | 1214 | ||
1212 | out: | 1215 | out: |
1216 | if (ret > 0) | ||
1217 | add_wchar(current, ret); | ||
1218 | inc_syscw(current); | ||
1213 | fput(file); | 1219 | fput(file); |
1214 | return ret; | 1220 | return ret; |
1215 | } | 1221 | } |
diff --git a/fs/direct-io.c b/fs/direct-io.c index af0558dbe8b7..b6d43908ff7a 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -1209,6 +1209,19 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1209 | retval = direct_io_worker(rw, iocb, inode, iov, offset, | 1209 | retval = direct_io_worker(rw, iocb, inode, iov, offset, |
1210 | nr_segs, blkbits, get_block, end_io, dio); | 1210 | nr_segs, blkbits, get_block, end_io, dio); |
1211 | 1211 | ||
1212 | /* | ||
1213 | * In case of error extending write may have instantiated a few | ||
1214 | * blocks outside i_size. Trim these off again for DIO_LOCKING. | ||
1215 | * NOTE: DIO_NO_LOCK/DIO_OWN_LOCK callers have to handle this by | ||
1216 | * it's own meaner. | ||
1217 | */ | ||
1218 | if (unlikely(retval < 0 && (rw & WRITE))) { | ||
1219 | loff_t isize = i_size_read(inode); | ||
1220 | |||
1221 | if (end > isize && dio_lock_type == DIO_LOCKING) | ||
1222 | vmtruncate(inode, isize); | ||
1223 | } | ||
1224 | |||
1212 | if (rw == READ && dio_lock_type == DIO_LOCKING) | 1225 | if (rw == READ && dio_lock_type == DIO_LOCKING) |
1213 | release_i_mutex = 0; | 1226 | release_i_mutex = 0; |
1214 | 1227 | ||
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 6046239465a1..c01e043670e2 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -175,8 +175,8 @@ out: | |||
175 | * | 175 | * |
176 | * Returns zero on success; non-zero on error. | 176 | * Returns zero on success; non-zero on error. |
177 | */ | 177 | */ |
178 | static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, | 178 | int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, |
179 | loff_t offset) | 179 | loff_t offset) |
180 | { | 180 | { |
181 | int rc = 0; | 181 | int rc = 0; |
182 | char dst[MD5_DIGEST_SIZE]; | 182 | char dst[MD5_DIGEST_SIZE]; |
@@ -924,6 +924,15 @@ static void ecryptfs_copy_mount_wide_flags_to_inode_flags( | |||
924 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | 924 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; |
925 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) | 925 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) |
926 | crypt_stat->flags |= ECRYPTFS_VIEW_AS_ENCRYPTED; | 926 | crypt_stat->flags |= ECRYPTFS_VIEW_AS_ENCRYPTED; |
927 | if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) { | ||
928 | crypt_stat->flags |= ECRYPTFS_ENCRYPT_FILENAMES; | ||
929 | if (mount_crypt_stat->flags | ||
930 | & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK) | ||
931 | crypt_stat->flags |= ECRYPTFS_ENCFN_USE_MOUNT_FNEK; | ||
932 | else if (mount_crypt_stat->flags | ||
933 | & ECRYPTFS_GLOBAL_ENCFN_USE_FEK) | ||
934 | crypt_stat->flags |= ECRYPTFS_ENCFN_USE_FEK; | ||
935 | } | ||
927 | } | 936 | } |
928 | 937 | ||
929 | static int ecryptfs_copy_mount_wide_sigs_to_inode_sigs( | 938 | static int ecryptfs_copy_mount_wide_sigs_to_inode_sigs( |
@@ -1060,7 +1069,8 @@ struct ecryptfs_flag_map_elem { | |||
1060 | static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = { | 1069 | static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = { |
1061 | {0x00000001, ECRYPTFS_ENABLE_HMAC}, | 1070 | {0x00000001, ECRYPTFS_ENABLE_HMAC}, |
1062 | {0x00000002, ECRYPTFS_ENCRYPTED}, | 1071 | {0x00000002, ECRYPTFS_ENCRYPTED}, |
1063 | {0x00000004, ECRYPTFS_METADATA_IN_XATTR} | 1072 | {0x00000004, ECRYPTFS_METADATA_IN_XATTR}, |
1073 | {0x00000008, ECRYPTFS_ENCRYPT_FILENAMES} | ||
1064 | }; | 1074 | }; |
1065 | 1075 | ||
1066 | /** | 1076 | /** |
@@ -1149,19 +1159,20 @@ ecryptfs_cipher_code_str_map[] = { | |||
1149 | 1159 | ||
1150 | /** | 1160 | /** |
1151 | * ecryptfs_code_for_cipher_string | 1161 | * ecryptfs_code_for_cipher_string |
1152 | * @crypt_stat: The cryptographic context | 1162 | * @cipher_name: The string alias for the cipher |
1163 | * @key_bytes: Length of key in bytes; used for AES code selection | ||
1153 | * | 1164 | * |
1154 | * Returns zero on no match, or the cipher code on match | 1165 | * Returns zero on no match, or the cipher code on match |
1155 | */ | 1166 | */ |
1156 | u8 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat) | 1167 | u8 ecryptfs_code_for_cipher_string(char *cipher_name, size_t key_bytes) |
1157 | { | 1168 | { |
1158 | int i; | 1169 | int i; |
1159 | u8 code = 0; | 1170 | u8 code = 0; |
1160 | struct ecryptfs_cipher_code_str_map_elem *map = | 1171 | struct ecryptfs_cipher_code_str_map_elem *map = |
1161 | ecryptfs_cipher_code_str_map; | 1172 | ecryptfs_cipher_code_str_map; |
1162 | 1173 | ||
1163 | if (strcmp(crypt_stat->cipher, "aes") == 0) { | 1174 | if (strcmp(cipher_name, "aes") == 0) { |
1164 | switch (crypt_stat->key_size) { | 1175 | switch (key_bytes) { |
1165 | case 16: | 1176 | case 16: |
1166 | code = RFC2440_CIPHER_AES_128; | 1177 | code = RFC2440_CIPHER_AES_128; |
1167 | break; | 1178 | break; |
@@ -1173,7 +1184,7 @@ u8 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat) | |||
1173 | } | 1184 | } |
1174 | } else { | 1185 | } else { |
1175 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++) | 1186 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++) |
1176 | if (strcmp(crypt_stat->cipher, map[i].cipher_str) == 0){ | 1187 | if (strcmp(cipher_name, map[i].cipher_str) == 0) { |
1177 | code = map[i].cipher_code; | 1188 | code = map[i].cipher_code; |
1178 | break; | 1189 | break; |
1179 | } | 1190 | } |
@@ -1212,6 +1223,8 @@ int ecryptfs_read_and_validate_header_region(char *data, | |||
1212 | &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat); | 1223 | &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat); |
1213 | int rc; | 1224 | int rc; |
1214 | 1225 | ||
1226 | if (crypt_stat->extent_size == 0) | ||
1227 | crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE; | ||
1215 | rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size, | 1228 | rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size, |
1216 | ecryptfs_inode); | 1229 | ecryptfs_inode); |
1217 | if (rc) { | 1230 | if (rc) { |
@@ -1221,7 +1234,6 @@ int ecryptfs_read_and_validate_header_region(char *data, | |||
1221 | } | 1234 | } |
1222 | if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) { | 1235 | if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) { |
1223 | rc = -EINVAL; | 1236 | rc = -EINVAL; |
1224 | ecryptfs_printk(KERN_DEBUG, "Valid marker not found\n"); | ||
1225 | } | 1237 | } |
1226 | out: | 1238 | out: |
1227 | return rc; | 1239 | return rc; |
@@ -1628,95 +1640,95 @@ out: | |||
1628 | } | 1640 | } |
1629 | 1641 | ||
1630 | /** | 1642 | /** |
1631 | * ecryptfs_encode_filename - converts a plaintext file name to cipher text | 1643 | * ecryptfs_encrypt_filename - encrypt filename |
1632 | * @crypt_stat: The crypt_stat struct associated with the file anem to encode | ||
1633 | * @name: The plaintext name | ||
1634 | * @length: The length of the plaintext | ||
1635 | * @encoded_name: The encypted name | ||
1636 | * | 1644 | * |
1637 | * Encrypts and encodes a filename into something that constitutes a | 1645 | * CBC-encrypts the filename. We do not want to encrypt the same |
1638 | * valid filename for a filesystem, with printable characters. | 1646 | * filename with the same key and IV, which may happen with hard |
1647 | * links, so we prepend random bits to each filename. | ||
1639 | * | 1648 | * |
1640 | * We assume that we have a properly initialized crypto context, | 1649 | * Returns zero on success; non-zero otherwise |
1641 | * pointed to by crypt_stat->tfm. | ||
1642 | * | ||
1643 | * TODO: Implement filename decoding and decryption here, in place of | ||
1644 | * memcpy. We are keeping the framework around for now to (1) | ||
1645 | * facilitate testing of the components needed to implement filename | ||
1646 | * encryption and (2) to provide a code base from which other | ||
1647 | * developers in the community can easily implement this feature. | ||
1648 | * | ||
1649 | * Returns the length of encoded filename; negative if error | ||
1650 | */ | 1650 | */ |
1651 | int | 1651 | static int |
1652 | ecryptfs_encode_filename(struct ecryptfs_crypt_stat *crypt_stat, | 1652 | ecryptfs_encrypt_filename(struct ecryptfs_filename *filename, |
1653 | const char *name, int length, char **encoded_name) | 1653 | struct ecryptfs_crypt_stat *crypt_stat, |
1654 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | ||
1654 | { | 1655 | { |
1655 | int error = 0; | 1656 | int rc = 0; |
1656 | 1657 | ||
1657 | (*encoded_name) = kmalloc(length + 2, GFP_KERNEL); | 1658 | filename->encrypted_filename = NULL; |
1658 | if (!(*encoded_name)) { | 1659 | filename->encrypted_filename_size = 0; |
1659 | error = -ENOMEM; | 1660 | if ((crypt_stat && (crypt_stat->flags & ECRYPTFS_ENCFN_USE_MOUNT_FNEK)) |
1661 | || (mount_crypt_stat && (mount_crypt_stat->flags | ||
1662 | & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK))) { | ||
1663 | size_t packet_size; | ||
1664 | size_t remaining_bytes; | ||
1665 | |||
1666 | rc = ecryptfs_write_tag_70_packet( | ||
1667 | NULL, NULL, | ||
1668 | &filename->encrypted_filename_size, | ||
1669 | mount_crypt_stat, NULL, | ||
1670 | filename->filename_size); | ||
1671 | if (rc) { | ||
1672 | printk(KERN_ERR "%s: Error attempting to get packet " | ||
1673 | "size for tag 72; rc = [%d]\n", __func__, | ||
1674 | rc); | ||
1675 | filename->encrypted_filename_size = 0; | ||
1676 | goto out; | ||
1677 | } | ||
1678 | filename->encrypted_filename = | ||
1679 | kmalloc(filename->encrypted_filename_size, GFP_KERNEL); | ||
1680 | if (!filename->encrypted_filename) { | ||
1681 | printk(KERN_ERR "%s: Out of memory whilst attempting " | ||
1682 | "to kmalloc [%zd] bytes\n", __func__, | ||
1683 | filename->encrypted_filename_size); | ||
1684 | rc = -ENOMEM; | ||
1685 | goto out; | ||
1686 | } | ||
1687 | remaining_bytes = filename->encrypted_filename_size; | ||
1688 | rc = ecryptfs_write_tag_70_packet(filename->encrypted_filename, | ||
1689 | &remaining_bytes, | ||
1690 | &packet_size, | ||
1691 | mount_crypt_stat, | ||
1692 | filename->filename, | ||
1693 | filename->filename_size); | ||
1694 | if (rc) { | ||
1695 | printk(KERN_ERR "%s: Error attempting to generate " | ||
1696 | "tag 70 packet; rc = [%d]\n", __func__, | ||
1697 | rc); | ||
1698 | kfree(filename->encrypted_filename); | ||
1699 | filename->encrypted_filename = NULL; | ||
1700 | filename->encrypted_filename_size = 0; | ||
1701 | goto out; | ||
1702 | } | ||
1703 | filename->encrypted_filename_size = packet_size; | ||
1704 | } else { | ||
1705 | printk(KERN_ERR "%s: No support for requested filename " | ||
1706 | "encryption method in this release\n", __func__); | ||
1707 | rc = -ENOTSUPP; | ||
1660 | goto out; | 1708 | goto out; |
1661 | } | 1709 | } |
1662 | /* TODO: Filename encryption is a scheduled feature for a | ||
1663 | * future version of eCryptfs. This function is here only for | ||
1664 | * the purpose of providing a framework for other developers | ||
1665 | * to easily implement filename encryption. Hint: Replace this | ||
1666 | * memcpy() with a call to encrypt and encode the | ||
1667 | * filename, the set the length accordingly. */ | ||
1668 | memcpy((void *)(*encoded_name), (void *)name, length); | ||
1669 | (*encoded_name)[length] = '\0'; | ||
1670 | error = length + 1; | ||
1671 | out: | 1710 | out: |
1672 | return error; | 1711 | return rc; |
1673 | } | 1712 | } |
1674 | 1713 | ||
1675 | /** | 1714 | static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size, |
1676 | * ecryptfs_decode_filename - converts the cipher text name to plaintext | 1715 | const char *name, size_t name_size) |
1677 | * @crypt_stat: The crypt_stat struct associated with the file | ||
1678 | * @name: The filename in cipher text | ||
1679 | * @length: The length of the cipher text name | ||
1680 | * @decrypted_name: The plaintext name | ||
1681 | * | ||
1682 | * Decodes and decrypts the filename. | ||
1683 | * | ||
1684 | * We assume that we have a properly initialized crypto context, | ||
1685 | * pointed to by crypt_stat->tfm. | ||
1686 | * | ||
1687 | * TODO: Implement filename decoding and decryption here, in place of | ||
1688 | * memcpy. We are keeping the framework around for now to (1) | ||
1689 | * facilitate testing of the components needed to implement filename | ||
1690 | * encryption and (2) to provide a code base from which other | ||
1691 | * developers in the community can easily implement this feature. | ||
1692 | * | ||
1693 | * Returns the length of decoded filename; negative if error | ||
1694 | */ | ||
1695 | int | ||
1696 | ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, | ||
1697 | const char *name, int length, char **decrypted_name) | ||
1698 | { | 1716 | { |
1699 | int error = 0; | 1717 | int rc = 0; |
1700 | 1718 | ||
1701 | (*decrypted_name) = kmalloc(length + 2, GFP_KERNEL); | 1719 | (*copied_name) = kmalloc((name_size + 2), GFP_KERNEL); |
1702 | if (!(*decrypted_name)) { | 1720 | if (!(*copied_name)) { |
1703 | error = -ENOMEM; | 1721 | rc = -ENOMEM; |
1704 | goto out; | 1722 | goto out; |
1705 | } | 1723 | } |
1706 | /* TODO: Filename encryption is a scheduled feature for a | 1724 | memcpy((void *)(*copied_name), (void *)name, name_size); |
1707 | * future version of eCryptfs. This function is here only for | 1725 | (*copied_name)[(name_size)] = '\0'; /* Only for convenience |
1708 | * the purpose of providing a framework for other developers | ||
1709 | * to easily implement filename encryption. Hint: Replace this | ||
1710 | * memcpy() with a call to decode and decrypt the | ||
1711 | * filename, the set the length accordingly. */ | ||
1712 | memcpy((void *)(*decrypted_name), (void *)name, length); | ||
1713 | (*decrypted_name)[length + 1] = '\0'; /* Only for convenience | ||
1714 | * in printing out the | 1726 | * in printing out the |
1715 | * string in debug | 1727 | * string in debug |
1716 | * messages */ | 1728 | * messages */ |
1717 | error = length; | 1729 | (*copied_name_size) = (name_size + 1); |
1718 | out: | 1730 | out: |
1719 | return error; | 1731 | return rc; |
1720 | } | 1732 | } |
1721 | 1733 | ||
1722 | /** | 1734 | /** |
@@ -1740,7 +1752,7 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm, | |||
1740 | *key_tfm = NULL; | 1752 | *key_tfm = NULL; |
1741 | if (*key_size > ECRYPTFS_MAX_KEY_BYTES) { | 1753 | if (*key_size > ECRYPTFS_MAX_KEY_BYTES) { |
1742 | rc = -EINVAL; | 1754 | rc = -EINVAL; |
1743 | printk(KERN_ERR "Requested key size is [%Zd] bytes; maximum " | 1755 | printk(KERN_ERR "Requested key size is [%zd] bytes; maximum " |
1744 | "allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES); | 1756 | "allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES); |
1745 | goto out; | 1757 | goto out; |
1746 | } | 1758 | } |
@@ -1765,7 +1777,7 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm, | |||
1765 | get_random_bytes(dummy_key, *key_size); | 1777 | get_random_bytes(dummy_key, *key_size); |
1766 | rc = crypto_blkcipher_setkey(*key_tfm, dummy_key, *key_size); | 1778 | rc = crypto_blkcipher_setkey(*key_tfm, dummy_key, *key_size); |
1767 | if (rc) { | 1779 | if (rc) { |
1768 | printk(KERN_ERR "Error attempting to set key of size [%Zd] for " | 1780 | printk(KERN_ERR "Error attempting to set key of size [%zd] for " |
1769 | "cipher [%s]; rc = [%d]\n", *key_size, cipher_name, rc); | 1781 | "cipher [%s]; rc = [%d]\n", *key_size, cipher_name, rc); |
1770 | rc = -EINVAL; | 1782 | rc = -EINVAL; |
1771 | goto out; | 1783 | goto out; |
@@ -1910,3 +1922,341 @@ out: | |||
1910 | mutex_unlock(&key_tfm_list_mutex); | 1922 | mutex_unlock(&key_tfm_list_mutex); |
1911 | return rc; | 1923 | return rc; |
1912 | } | 1924 | } |
1925 | |||
1926 | /* 64 characters forming a 6-bit target field */ | ||
1927 | static unsigned char *portable_filename_chars = ("-.0123456789ABCD" | ||
1928 | "EFGHIJKLMNOPQRST" | ||
1929 | "UVWXYZabcdefghij" | ||
1930 | "klmnopqrstuvwxyz"); | ||
1931 | |||
1932 | /* We could either offset on every reverse map or just pad some 0x00's | ||
1933 | * at the front here */ | ||
1934 | static const unsigned char filename_rev_map[] = { | ||
1935 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */ | ||
1936 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 15 */ | ||
1937 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 23 */ | ||
1938 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 31 */ | ||
1939 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 39 */ | ||
1940 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* 47 */ | ||
1941 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* 55 */ | ||
1942 | 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 63 */ | ||
1943 | 0x00, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, /* 71 */ | ||
1944 | 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, /* 79 */ | ||
1945 | 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, /* 87 */ | ||
1946 | 0x23, 0x24, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, /* 95 */ | ||
1947 | 0x00, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, /* 103 */ | ||
1948 | 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, /* 111 */ | ||
1949 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, /* 119 */ | ||
1950 | 0x3D, 0x3E, 0x3F | ||
1951 | }; | ||
1952 | |||
1953 | /** | ||
1954 | * ecryptfs_encode_for_filename | ||
1955 | * @dst: Destination location for encoded filename | ||
1956 | * @dst_size: Size of the encoded filename in bytes | ||
1957 | * @src: Source location for the filename to encode | ||
1958 | * @src_size: Size of the source in bytes | ||
1959 | */ | ||
1960 | void ecryptfs_encode_for_filename(unsigned char *dst, size_t *dst_size, | ||
1961 | unsigned char *src, size_t src_size) | ||
1962 | { | ||
1963 | size_t num_blocks; | ||
1964 | size_t block_num = 0; | ||
1965 | size_t dst_offset = 0; | ||
1966 | unsigned char last_block[3]; | ||
1967 | |||
1968 | if (src_size == 0) { | ||
1969 | (*dst_size) = 0; | ||
1970 | goto out; | ||
1971 | } | ||
1972 | num_blocks = (src_size / 3); | ||
1973 | if ((src_size % 3) == 0) { | ||
1974 | memcpy(last_block, (&src[src_size - 3]), 3); | ||
1975 | } else { | ||
1976 | num_blocks++; | ||
1977 | last_block[2] = 0x00; | ||
1978 | switch (src_size % 3) { | ||
1979 | case 1: | ||
1980 | last_block[0] = src[src_size - 1]; | ||
1981 | last_block[1] = 0x00; | ||
1982 | break; | ||
1983 | case 2: | ||
1984 | last_block[0] = src[src_size - 2]; | ||
1985 | last_block[1] = src[src_size - 1]; | ||
1986 | } | ||
1987 | } | ||
1988 | (*dst_size) = (num_blocks * 4); | ||
1989 | if (!dst) | ||
1990 | goto out; | ||
1991 | while (block_num < num_blocks) { | ||
1992 | unsigned char *src_block; | ||
1993 | unsigned char dst_block[4]; | ||
1994 | |||
1995 | if (block_num == (num_blocks - 1)) | ||
1996 | src_block = last_block; | ||
1997 | else | ||
1998 | src_block = &src[block_num * 3]; | ||
1999 | dst_block[0] = ((src_block[0] >> 2) & 0x3F); | ||
2000 | dst_block[1] = (((src_block[0] << 4) & 0x30) | ||
2001 | | ((src_block[1] >> 4) & 0x0F)); | ||
2002 | dst_block[2] = (((src_block[1] << 2) & 0x3C) | ||
2003 | | ((src_block[2] >> 6) & 0x03)); | ||
2004 | dst_block[3] = (src_block[2] & 0x3F); | ||
2005 | dst[dst_offset++] = portable_filename_chars[dst_block[0]]; | ||
2006 | dst[dst_offset++] = portable_filename_chars[dst_block[1]]; | ||
2007 | dst[dst_offset++] = portable_filename_chars[dst_block[2]]; | ||
2008 | dst[dst_offset++] = portable_filename_chars[dst_block[3]]; | ||
2009 | block_num++; | ||
2010 | } | ||
2011 | out: | ||
2012 | return; | ||
2013 | } | ||
2014 | |||
2015 | /** | ||
2016 | * ecryptfs_decode_from_filename | ||
2017 | * @dst: If NULL, this function only sets @dst_size and returns. If | ||
2018 | * non-NULL, this function decodes the encoded octets in @src | ||
2019 | * into the memory that @dst points to. | ||
2020 | * @dst_size: Set to the size of the decoded string. | ||
2021 | * @src: The encoded set of octets to decode. | ||
2022 | * @src_size: The size of the encoded set of octets to decode. | ||
2023 | */ | ||
2024 | static void | ||
2025 | ecryptfs_decode_from_filename(unsigned char *dst, size_t *dst_size, | ||
2026 | const unsigned char *src, size_t src_size) | ||
2027 | { | ||
2028 | u8 current_bit_offset = 0; | ||
2029 | size_t src_byte_offset = 0; | ||
2030 | size_t dst_byte_offset = 0; | ||
2031 | |||
2032 | if (dst == NULL) { | ||
2033 | /* Not exact; conservatively long. Every block of 4 | ||
2034 | * encoded characters decodes into a block of 3 | ||
2035 | * decoded characters. This segment of code provides | ||
2036 | * the caller with the maximum amount of allocated | ||
2037 | * space that @dst will need to point to in a | ||
2038 | * subsequent call. */ | ||
2039 | (*dst_size) = (((src_size + 1) * 3) / 4); | ||
2040 | goto out; | ||
2041 | } | ||
2042 | while (src_byte_offset < src_size) { | ||
2043 | unsigned char src_byte = | ||
2044 | filename_rev_map[(int)src[src_byte_offset]]; | ||
2045 | |||
2046 | switch (current_bit_offset) { | ||
2047 | case 0: | ||
2048 | dst[dst_byte_offset] = (src_byte << 2); | ||
2049 | current_bit_offset = 6; | ||
2050 | break; | ||
2051 | case 6: | ||
2052 | dst[dst_byte_offset++] |= (src_byte >> 4); | ||
2053 | dst[dst_byte_offset] = ((src_byte & 0xF) | ||
2054 | << 4); | ||
2055 | current_bit_offset = 4; | ||
2056 | break; | ||
2057 | case 4: | ||
2058 | dst[dst_byte_offset++] |= (src_byte >> 2); | ||
2059 | dst[dst_byte_offset] = (src_byte << 6); | ||
2060 | current_bit_offset = 2; | ||
2061 | break; | ||
2062 | case 2: | ||
2063 | dst[dst_byte_offset++] |= (src_byte); | ||
2064 | dst[dst_byte_offset] = 0; | ||
2065 | current_bit_offset = 0; | ||
2066 | break; | ||
2067 | } | ||
2068 | src_byte_offset++; | ||
2069 | } | ||
2070 | (*dst_size) = dst_byte_offset; | ||
2071 | out: | ||
2072 | return; | ||
2073 | } | ||
2074 | |||
2075 | /** | ||
2076 | * ecryptfs_encrypt_and_encode_filename - converts a plaintext file name to cipher text | ||
2077 | * @crypt_stat: The crypt_stat struct associated with the file anem to encode | ||
2078 | * @name: The plaintext name | ||
2079 | * @length: The length of the plaintext | ||
2080 | * @encoded_name: The encypted name | ||
2081 | * | ||
2082 | * Encrypts and encodes a filename into something that constitutes a | ||
2083 | * valid filename for a filesystem, with printable characters. | ||
2084 | * | ||
2085 | * We assume that we have a properly initialized crypto context, | ||
2086 | * pointed to by crypt_stat->tfm. | ||
2087 | * | ||
2088 | * Returns zero on success; non-zero on otherwise | ||
2089 | */ | ||
2090 | int ecryptfs_encrypt_and_encode_filename( | ||
2091 | char **encoded_name, | ||
2092 | size_t *encoded_name_size, | ||
2093 | struct ecryptfs_crypt_stat *crypt_stat, | ||
2094 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
2095 | const char *name, size_t name_size) | ||
2096 | { | ||
2097 | size_t encoded_name_no_prefix_size; | ||
2098 | int rc = 0; | ||
2099 | |||
2100 | (*encoded_name) = NULL; | ||
2101 | (*encoded_name_size) = 0; | ||
2102 | if ((crypt_stat && (crypt_stat->flags & ECRYPTFS_ENCRYPT_FILENAMES)) | ||
2103 | || (mount_crypt_stat && (mount_crypt_stat->flags | ||
2104 | & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) { | ||
2105 | struct ecryptfs_filename *filename; | ||
2106 | |||
2107 | filename = kzalloc(sizeof(*filename), GFP_KERNEL); | ||
2108 | if (!filename) { | ||
2109 | printk(KERN_ERR "%s: Out of memory whilst attempting " | ||
2110 | "to kzalloc [%zd] bytes\n", __func__, | ||
2111 | sizeof(*filename)); | ||
2112 | rc = -ENOMEM; | ||
2113 | goto out; | ||
2114 | } | ||
2115 | filename->filename = (char *)name; | ||
2116 | filename->filename_size = name_size; | ||
2117 | rc = ecryptfs_encrypt_filename(filename, crypt_stat, | ||
2118 | mount_crypt_stat); | ||
2119 | if (rc) { | ||
2120 | printk(KERN_ERR "%s: Error attempting to encrypt " | ||
2121 | "filename; rc = [%d]\n", __func__, rc); | ||
2122 | kfree(filename); | ||
2123 | goto out; | ||
2124 | } | ||
2125 | ecryptfs_encode_for_filename( | ||
2126 | NULL, &encoded_name_no_prefix_size, | ||
2127 | filename->encrypted_filename, | ||
2128 | filename->encrypted_filename_size); | ||
2129 | if ((crypt_stat && (crypt_stat->flags | ||
2130 | & ECRYPTFS_ENCFN_USE_MOUNT_FNEK)) | ||
2131 | || (mount_crypt_stat | ||
2132 | && (mount_crypt_stat->flags | ||
2133 | & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK))) | ||
2134 | (*encoded_name_size) = | ||
2135 | (ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE | ||
2136 | + encoded_name_no_prefix_size); | ||
2137 | else | ||
2138 | (*encoded_name_size) = | ||
2139 | (ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX_SIZE | ||
2140 | + encoded_name_no_prefix_size); | ||
2141 | (*encoded_name) = kmalloc((*encoded_name_size) + 1, GFP_KERNEL); | ||
2142 | if (!(*encoded_name)) { | ||
2143 | printk(KERN_ERR "%s: Out of memory whilst attempting " | ||
2144 | "to kzalloc [%zd] bytes\n", __func__, | ||
2145 | (*encoded_name_size)); | ||
2146 | rc = -ENOMEM; | ||
2147 | kfree(filename->encrypted_filename); | ||
2148 | kfree(filename); | ||
2149 | goto out; | ||
2150 | } | ||
2151 | if ((crypt_stat && (crypt_stat->flags | ||
2152 | & ECRYPTFS_ENCFN_USE_MOUNT_FNEK)) | ||
2153 | || (mount_crypt_stat | ||
2154 | && (mount_crypt_stat->flags | ||
2155 | & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK))) { | ||
2156 | memcpy((*encoded_name), | ||
2157 | ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, | ||
2158 | ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE); | ||
2159 | ecryptfs_encode_for_filename( | ||
2160 | ((*encoded_name) | ||
2161 | + ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE), | ||
2162 | &encoded_name_no_prefix_size, | ||
2163 | filename->encrypted_filename, | ||
2164 | filename->encrypted_filename_size); | ||
2165 | (*encoded_name_size) = | ||
2166 | (ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE | ||
2167 | + encoded_name_no_prefix_size); | ||
2168 | (*encoded_name)[(*encoded_name_size)] = '\0'; | ||
2169 | (*encoded_name_size)++; | ||
2170 | } else { | ||
2171 | rc = -ENOTSUPP; | ||
2172 | } | ||
2173 | if (rc) { | ||
2174 | printk(KERN_ERR "%s: Error attempting to encode " | ||
2175 | "encrypted filename; rc = [%d]\n", __func__, | ||
2176 | rc); | ||
2177 | kfree((*encoded_name)); | ||
2178 | (*encoded_name) = NULL; | ||
2179 | (*encoded_name_size) = 0; | ||
2180 | } | ||
2181 | kfree(filename->encrypted_filename); | ||
2182 | kfree(filename); | ||
2183 | } else { | ||
2184 | rc = ecryptfs_copy_filename(encoded_name, | ||
2185 | encoded_name_size, | ||
2186 | name, name_size); | ||
2187 | } | ||
2188 | out: | ||
2189 | return rc; | ||
2190 | } | ||
2191 | |||
2192 | /** | ||
2193 | * ecryptfs_decode_and_decrypt_filename - converts the encoded cipher text name to decoded plaintext | ||
2194 | * @plaintext_name: The plaintext name | ||
2195 | * @plaintext_name_size: The plaintext name size | ||
2196 | * @ecryptfs_dir_dentry: eCryptfs directory dentry | ||
2197 | * @name: The filename in cipher text | ||
2198 | * @name_size: The cipher text name size | ||
2199 | * | ||
2200 | * Decrypts and decodes the filename. | ||
2201 | * | ||
2202 | * Returns zero on error; non-zero otherwise | ||
2203 | */ | ||
2204 | int ecryptfs_decode_and_decrypt_filename(char **plaintext_name, | ||
2205 | size_t *plaintext_name_size, | ||
2206 | struct dentry *ecryptfs_dir_dentry, | ||
2207 | const char *name, size_t name_size) | ||
2208 | { | ||
2209 | char *decoded_name; | ||
2210 | size_t decoded_name_size; | ||
2211 | size_t packet_size; | ||
2212 | int rc = 0; | ||
2213 | |||
2214 | if ((name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) | ||
2215 | && (strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, | ||
2216 | ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) == 0)) { | ||
2217 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
2218 | &ecryptfs_superblock_to_private( | ||
2219 | ecryptfs_dir_dentry->d_sb)->mount_crypt_stat; | ||
2220 | const char *orig_name = name; | ||
2221 | size_t orig_name_size = name_size; | ||
2222 | |||
2223 | name += ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE; | ||
2224 | name_size -= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE; | ||
2225 | ecryptfs_decode_from_filename(NULL, &decoded_name_size, | ||
2226 | name, name_size); | ||
2227 | decoded_name = kmalloc(decoded_name_size, GFP_KERNEL); | ||
2228 | if (!decoded_name) { | ||
2229 | printk(KERN_ERR "%s: Out of memory whilst attempting " | ||
2230 | "to kmalloc [%zd] bytes\n", __func__, | ||
2231 | decoded_name_size); | ||
2232 | rc = -ENOMEM; | ||
2233 | goto out; | ||
2234 | } | ||
2235 | ecryptfs_decode_from_filename(decoded_name, &decoded_name_size, | ||
2236 | name, name_size); | ||
2237 | rc = ecryptfs_parse_tag_70_packet(plaintext_name, | ||
2238 | plaintext_name_size, | ||
2239 | &packet_size, | ||
2240 | mount_crypt_stat, | ||
2241 | decoded_name, | ||
2242 | decoded_name_size); | ||
2243 | if (rc) { | ||
2244 | printk(KERN_INFO "%s: Could not parse tag 70 packet " | ||
2245 | "from filename; copying through filename " | ||
2246 | "as-is\n", __func__); | ||
2247 | rc = ecryptfs_copy_filename(plaintext_name, | ||
2248 | plaintext_name_size, | ||
2249 | orig_name, orig_name_size); | ||
2250 | goto out_free; | ||
2251 | } | ||
2252 | } else { | ||
2253 | rc = ecryptfs_copy_filename(plaintext_name, | ||
2254 | plaintext_name_size, | ||
2255 | name, name_size); | ||
2256 | goto out; | ||
2257 | } | ||
2258 | out_free: | ||
2259 | kfree(decoded_name); | ||
2260 | out: | ||
2261 | return rc; | ||
2262 | } | ||
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index a75026d35d16..c11fc95714ab 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -51,12 +51,16 @@ | |||
51 | #define ECRYPTFS_VERSIONING_XATTR 0x00000010 | 51 | #define ECRYPTFS_VERSIONING_XATTR 0x00000010 |
52 | #define ECRYPTFS_VERSIONING_MULTKEY 0x00000020 | 52 | #define ECRYPTFS_VERSIONING_MULTKEY 0x00000020 |
53 | #define ECRYPTFS_VERSIONING_DEVMISC 0x00000040 | 53 | #define ECRYPTFS_VERSIONING_DEVMISC 0x00000040 |
54 | #define ECRYPTFS_VERSIONING_HMAC 0x00000080 | ||
55 | #define ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION 0x00000100 | ||
56 | #define ECRYPTFS_VERSIONING_GCM 0x00000200 | ||
54 | #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ | 57 | #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ |
55 | | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ | 58 | | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ |
56 | | ECRYPTFS_VERSIONING_PUBKEY \ | 59 | | ECRYPTFS_VERSIONING_PUBKEY \ |
57 | | ECRYPTFS_VERSIONING_XATTR \ | 60 | | ECRYPTFS_VERSIONING_XATTR \ |
58 | | ECRYPTFS_VERSIONING_MULTKEY \ | 61 | | ECRYPTFS_VERSIONING_MULTKEY \ |
59 | | ECRYPTFS_VERSIONING_DEVMISC) | 62 | | ECRYPTFS_VERSIONING_DEVMISC \ |
63 | | ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION) | ||
60 | #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 | 64 | #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 |
61 | #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH | 65 | #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH |
62 | #define ECRYPTFS_SALT_SIZE 8 | 66 | #define ECRYPTFS_SALT_SIZE 8 |
@@ -199,6 +203,7 @@ ecryptfs_get_key_payload_data(struct key *key) | |||
199 | #define ECRYPTFS_DEFAULT_CIPHER "aes" | 203 | #define ECRYPTFS_DEFAULT_CIPHER "aes" |
200 | #define ECRYPTFS_DEFAULT_KEY_BYTES 16 | 204 | #define ECRYPTFS_DEFAULT_KEY_BYTES 16 |
201 | #define ECRYPTFS_DEFAULT_HASH "md5" | 205 | #define ECRYPTFS_DEFAULT_HASH "md5" |
206 | #define ECRYPTFS_TAG_70_DIGEST ECRYPTFS_DEFAULT_HASH | ||
202 | #define ECRYPTFS_TAG_1_PACKET_TYPE 0x01 | 207 | #define ECRYPTFS_TAG_1_PACKET_TYPE 0x01 |
203 | #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C | 208 | #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C |
204 | #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED | 209 | #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED |
@@ -206,30 +211,64 @@ ecryptfs_get_key_payload_data(struct key *key) | |||
206 | #define ECRYPTFS_TAG_65_PACKET_TYPE 0x41 | 211 | #define ECRYPTFS_TAG_65_PACKET_TYPE 0x41 |
207 | #define ECRYPTFS_TAG_66_PACKET_TYPE 0x42 | 212 | #define ECRYPTFS_TAG_66_PACKET_TYPE 0x42 |
208 | #define ECRYPTFS_TAG_67_PACKET_TYPE 0x43 | 213 | #define ECRYPTFS_TAG_67_PACKET_TYPE 0x43 |
214 | #define ECRYPTFS_TAG_70_PACKET_TYPE 0x46 /* FNEK-encrypted filename | ||
215 | * as dentry name */ | ||
216 | #define ECRYPTFS_TAG_71_PACKET_TYPE 0x47 /* FNEK-encrypted filename in | ||
217 | * metadata */ | ||
218 | #define ECRYPTFS_TAG_72_PACKET_TYPE 0x48 /* FEK-encrypted filename as | ||
219 | * dentry name */ | ||
220 | #define ECRYPTFS_TAG_73_PACKET_TYPE 0x49 /* FEK-encrypted filename as | ||
221 | * metadata */ | ||
222 | /* Constraint: ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES >= | ||
223 | * ECRYPTFS_MAX_IV_BYTES */ | ||
224 | #define ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES 16 | ||
225 | #define ECRYPTFS_NON_NULL 0x42 /* A reasonable substitute for NULL */ | ||
209 | #define MD5_DIGEST_SIZE 16 | 226 | #define MD5_DIGEST_SIZE 16 |
227 | #define ECRYPTFS_TAG_70_DIGEST_SIZE MD5_DIGEST_SIZE | ||
228 | #define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FEK_ENCRYPTED." | ||
229 | #define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX_SIZE 23 | ||
230 | #define ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FNEK_ENCRYPTED." | ||
231 | #define ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE 24 | ||
232 | #define ECRYPTFS_ENCRYPTED_DENTRY_NAME_LEN (18 + 1 + 4 + 1 + 32) | ||
210 | 233 | ||
211 | struct ecryptfs_key_sig { | 234 | struct ecryptfs_key_sig { |
212 | struct list_head crypt_stat_list; | 235 | struct list_head crypt_stat_list; |
213 | char keysig[ECRYPTFS_SIG_SIZE_HEX]; | 236 | char keysig[ECRYPTFS_SIG_SIZE_HEX]; |
214 | }; | 237 | }; |
215 | 238 | ||
239 | struct ecryptfs_filename { | ||
240 | struct list_head crypt_stat_list; | ||
241 | #define ECRYPTFS_FILENAME_CONTAINS_DECRYPTED 0x00000001 | ||
242 | u32 flags; | ||
243 | u32 seq_no; | ||
244 | char *filename; | ||
245 | char *encrypted_filename; | ||
246 | size_t filename_size; | ||
247 | size_t encrypted_filename_size; | ||
248 | char fnek_sig[ECRYPTFS_SIG_SIZE_HEX]; | ||
249 | char dentry_name[ECRYPTFS_ENCRYPTED_DENTRY_NAME_LEN + 1]; | ||
250 | }; | ||
251 | |||
216 | /** | 252 | /** |
217 | * This is the primary struct associated with each encrypted file. | 253 | * This is the primary struct associated with each encrypted file. |
218 | * | 254 | * |
219 | * TODO: cache align/pack? | 255 | * TODO: cache align/pack? |
220 | */ | 256 | */ |
221 | struct ecryptfs_crypt_stat { | 257 | struct ecryptfs_crypt_stat { |
222 | #define ECRYPTFS_STRUCT_INITIALIZED 0x00000001 | 258 | #define ECRYPTFS_STRUCT_INITIALIZED 0x00000001 |
223 | #define ECRYPTFS_POLICY_APPLIED 0x00000002 | 259 | #define ECRYPTFS_POLICY_APPLIED 0x00000002 |
224 | #define ECRYPTFS_NEW_FILE 0x00000004 | 260 | #define ECRYPTFS_NEW_FILE 0x00000004 |
225 | #define ECRYPTFS_ENCRYPTED 0x00000008 | 261 | #define ECRYPTFS_ENCRYPTED 0x00000008 |
226 | #define ECRYPTFS_SECURITY_WARNING 0x00000010 | 262 | #define ECRYPTFS_SECURITY_WARNING 0x00000010 |
227 | #define ECRYPTFS_ENABLE_HMAC 0x00000020 | 263 | #define ECRYPTFS_ENABLE_HMAC 0x00000020 |
228 | #define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040 | 264 | #define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040 |
229 | #define ECRYPTFS_KEY_VALID 0x00000080 | 265 | #define ECRYPTFS_KEY_VALID 0x00000080 |
230 | #define ECRYPTFS_METADATA_IN_XATTR 0x00000100 | 266 | #define ECRYPTFS_METADATA_IN_XATTR 0x00000100 |
231 | #define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200 | 267 | #define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200 |
232 | #define ECRYPTFS_KEY_SET 0x00000400 | 268 | #define ECRYPTFS_KEY_SET 0x00000400 |
269 | #define ECRYPTFS_ENCRYPT_FILENAMES 0x00000800 | ||
270 | #define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00001000 | ||
271 | #define ECRYPTFS_ENCFN_USE_FEK 0x00002000 | ||
233 | u32 flags; | 272 | u32 flags; |
234 | unsigned int file_version; | 273 | unsigned int file_version; |
235 | size_t iv_bytes; | 274 | size_t iv_bytes; |
@@ -332,13 +371,20 @@ struct ecryptfs_mount_crypt_stat { | |||
332 | #define ECRYPTFS_XATTR_METADATA_ENABLED 0x00000002 | 371 | #define ECRYPTFS_XATTR_METADATA_ENABLED 0x00000002 |
333 | #define ECRYPTFS_ENCRYPTED_VIEW_ENABLED 0x00000004 | 372 | #define ECRYPTFS_ENCRYPTED_VIEW_ENABLED 0x00000004 |
334 | #define ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED 0x00000008 | 373 | #define ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED 0x00000008 |
374 | #define ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES 0x00000010 | ||
375 | #define ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK 0x00000020 | ||
376 | #define ECRYPTFS_GLOBAL_ENCFN_USE_FEK 0x00000040 | ||
335 | u32 flags; | 377 | u32 flags; |
336 | struct list_head global_auth_tok_list; | 378 | struct list_head global_auth_tok_list; |
337 | struct mutex global_auth_tok_list_mutex; | 379 | struct mutex global_auth_tok_list_mutex; |
338 | size_t num_global_auth_toks; | 380 | size_t num_global_auth_toks; |
339 | size_t global_default_cipher_key_size; | 381 | size_t global_default_cipher_key_size; |
382 | size_t global_default_fn_cipher_key_bytes; | ||
340 | unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE | 383 | unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE |
341 | + 1]; | 384 | + 1]; |
385 | unsigned char global_default_fn_cipher_name[ | ||
386 | ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; | ||
387 | char global_default_fnek_sig[ECRYPTFS_SIG_SIZE_HEX + 1]; | ||
342 | }; | 388 | }; |
343 | 389 | ||
344 | /* superblock private data. */ | 390 | /* superblock private data. */ |
@@ -571,13 +617,22 @@ struct ecryptfs_open_req { | |||
571 | int ecryptfs_interpose(struct dentry *hidden_dentry, | 617 | int ecryptfs_interpose(struct dentry *hidden_dentry, |
572 | struct dentry *this_dentry, struct super_block *sb, | 618 | struct dentry *this_dentry, struct super_block *sb, |
573 | u32 flags); | 619 | u32 flags); |
620 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | ||
621 | struct dentry *lower_dentry, | ||
622 | struct ecryptfs_crypt_stat *crypt_stat, | ||
623 | struct inode *ecryptfs_dir_inode, | ||
624 | struct nameidata *ecryptfs_nd); | ||
625 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, | ||
626 | size_t *decrypted_name_size, | ||
627 | struct dentry *ecryptfs_dentry, | ||
628 | const char *name, size_t name_size); | ||
574 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length); | 629 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length); |
575 | int ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, | 630 | int ecryptfs_encrypt_and_encode_filename( |
576 | const char *name, int length, | 631 | char **encoded_name, |
577 | char **decrypted_name); | 632 | size_t *encoded_name_size, |
578 | int ecryptfs_encode_filename(struct ecryptfs_crypt_stat *crypt_stat, | 633 | struct ecryptfs_crypt_stat *crypt_stat, |
579 | const char *name, int length, | 634 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
580 | char **encoded_name); | 635 | const char *name, size_t name_size); |
581 | struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry); | 636 | struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry); |
582 | void ecryptfs_dump_hex(char *data, int bytes); | 637 | void ecryptfs_dump_hex(char *data, int bytes); |
583 | int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg, | 638 | int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg, |
@@ -599,7 +654,7 @@ int ecryptfs_read_and_validate_header_region(char *data, | |||
599 | struct inode *ecryptfs_inode); | 654 | struct inode *ecryptfs_inode); |
600 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, | 655 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, |
601 | struct dentry *ecryptfs_dentry); | 656 | struct dentry *ecryptfs_dentry); |
602 | u8 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat); | 657 | u8 ecryptfs_code_for_cipher_string(char *cipher_name, size_t key_bytes); |
603 | int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code); | 658 | int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code); |
604 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); | 659 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); |
605 | int ecryptfs_generate_key_packet_set(char *dest_base, | 660 | int ecryptfs_generate_key_packet_set(char *dest_base, |
@@ -694,5 +749,17 @@ int ecryptfs_privileged_open(struct file **lower_file, | |||
694 | struct vfsmount *lower_mnt, | 749 | struct vfsmount *lower_mnt, |
695 | const struct cred *cred); | 750 | const struct cred *cred); |
696 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); | 751 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); |
752 | int | ||
753 | ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, | ||
754 | size_t *packet_size, | ||
755 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
756 | char *filename, size_t filename_size); | ||
757 | int | ||
758 | ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, | ||
759 | size_t *packet_size, | ||
760 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
761 | char *data, size_t max_packet_size); | ||
762 | int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, | ||
763 | loff_t offset); | ||
697 | 764 | ||
698 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 765 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 713834371229..9e944057001b 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -77,27 +77,27 @@ struct ecryptfs_getdents_callback { | |||
77 | 77 | ||
78 | /* Inspired by generic filldir in fs/readdir.c */ | 78 | /* Inspired by generic filldir in fs/readdir.c */ |
79 | static int | 79 | static int |
80 | ecryptfs_filldir(void *dirent, const char *name, int namelen, loff_t offset, | 80 | ecryptfs_filldir(void *dirent, const char *lower_name, int lower_namelen, |
81 | u64 ino, unsigned int d_type) | 81 | loff_t offset, u64 ino, unsigned int d_type) |
82 | { | 82 | { |
83 | struct ecryptfs_crypt_stat *crypt_stat; | ||
84 | struct ecryptfs_getdents_callback *buf = | 83 | struct ecryptfs_getdents_callback *buf = |
85 | (struct ecryptfs_getdents_callback *)dirent; | 84 | (struct ecryptfs_getdents_callback *)dirent; |
85 | size_t name_size; | ||
86 | char *name; | ||
86 | int rc; | 87 | int rc; |
87 | int decoded_length; | ||
88 | char *decoded_name; | ||
89 | 88 | ||
90 | crypt_stat = ecryptfs_dentry_to_private(buf->dentry)->crypt_stat; | ||
91 | buf->filldir_called++; | 89 | buf->filldir_called++; |
92 | decoded_length = ecryptfs_decode_filename(crypt_stat, name, namelen, | 90 | rc = ecryptfs_decode_and_decrypt_filename(&name, &name_size, |
93 | &decoded_name); | 91 | buf->dentry, lower_name, |
94 | if (decoded_length < 0) { | 92 | lower_namelen); |
95 | rc = decoded_length; | 93 | if (rc) { |
94 | printk(KERN_ERR "%s: Error attempting to decode and decrypt " | ||
95 | "filename [%s]; rc = [%d]\n", __func__, lower_name, | ||
96 | rc); | ||
96 | goto out; | 97 | goto out; |
97 | } | 98 | } |
98 | rc = buf->filldir(buf->dirent, decoded_name, decoded_length, offset, | 99 | rc = buf->filldir(buf->dirent, name, name_size, offset, ino, d_type); |
99 | ino, d_type); | 100 | kfree(name); |
100 | kfree(decoded_name); | ||
101 | if (rc >= 0) | 101 | if (rc >= 0) |
102 | buf->entries_written++; | 102 | buf->entries_written++; |
103 | out: | 103 | out: |
@@ -106,8 +106,8 @@ out: | |||
106 | 106 | ||
107 | /** | 107 | /** |
108 | * ecryptfs_readdir | 108 | * ecryptfs_readdir |
109 | * @file: The ecryptfs file struct | 109 | * @file: The eCryptfs directory file |
110 | * @dirent: Directory entry | 110 | * @dirent: Directory entry handle |
111 | * @filldir: The filldir callback function | 111 | * @filldir: The filldir callback function |
112 | */ | 112 | */ |
113 | static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir) | 113 | static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir) |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 0111906a8877..5697899a168d 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -52,8 +52,7 @@ static void unlock_dir(struct dentry *dir) | |||
52 | /** | 52 | /** |
53 | * ecryptfs_create_underlying_file | 53 | * ecryptfs_create_underlying_file |
54 | * @lower_dir_inode: inode of the parent in the lower fs of the new file | 54 | * @lower_dir_inode: inode of the parent in the lower fs of the new file |
55 | * @lower_dentry: New file's dentry in the lower fs | 55 | * @dentry: New file's dentry |
56 | * @ecryptfs_dentry: New file's dentry in ecryptfs | ||
57 | * @mode: The mode of the new file | 56 | * @mode: The mode of the new file |
58 | * @nd: nameidata of ecryptfs' parent's dentry & vfsmount | 57 | * @nd: nameidata of ecryptfs' parent's dentry & vfsmount |
59 | * | 58 | * |
@@ -228,8 +227,7 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, | |||
228 | { | 227 | { |
229 | int rc; | 228 | int rc; |
230 | 229 | ||
231 | /* ecryptfs_do_create() calls ecryptfs_interpose(), which opens | 230 | /* ecryptfs_do_create() calls ecryptfs_interpose() */ |
232 | * the crypt_stat->lower_file (persistent file) */ | ||
233 | rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, nd); | 231 | rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, nd); |
234 | if (unlikely(rc)) { | 232 | if (unlikely(rc)) { |
235 | ecryptfs_printk(KERN_WARNING, "Failed to create file in" | 233 | ecryptfs_printk(KERN_WARNING, "Failed to create file in" |
@@ -244,141 +242,91 @@ out: | |||
244 | } | 242 | } |
245 | 243 | ||
246 | /** | 244 | /** |
247 | * ecryptfs_lookup | 245 | * ecryptfs_lookup_and_interpose_lower - Perform a lookup |
248 | * @dir: inode | ||
249 | * @dentry: The dentry | ||
250 | * @nd: nameidata, may be NULL | ||
251 | * | ||
252 | * Find a file on disk. If the file does not exist, then we'll add it to the | ||
253 | * dentry cache and continue on to read it from the disk. | ||
254 | */ | 246 | */ |
255 | static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | 247 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, |
256 | struct nameidata *nd) | 248 | struct dentry *lower_dentry, |
249 | struct ecryptfs_crypt_stat *crypt_stat, | ||
250 | struct inode *ecryptfs_dir_inode, | ||
251 | struct nameidata *ecryptfs_nd) | ||
257 | { | 252 | { |
258 | int rc = 0; | ||
259 | struct dentry *lower_dir_dentry; | 253 | struct dentry *lower_dir_dentry; |
260 | struct dentry *lower_dentry; | ||
261 | struct vfsmount *lower_mnt; | 254 | struct vfsmount *lower_mnt; |
262 | char *encoded_name; | 255 | struct inode *lower_inode; |
263 | int encoded_namelen; | ||
264 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | ||
265 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | 256 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; |
266 | char *page_virt = NULL; | 257 | char *page_virt = NULL; |
267 | struct inode *lower_inode; | ||
268 | u64 file_size; | 258 | u64 file_size; |
259 | int rc = 0; | ||
269 | 260 | ||
270 | lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); | 261 | lower_dir_dentry = lower_dentry->d_parent; |
271 | dentry->d_op = &ecryptfs_dops; | 262 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( |
272 | if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, ".")) | 263 | ecryptfs_dentry->d_parent)); |
273 | || (dentry->d_name.len == 2 | ||
274 | && !strcmp(dentry->d_name.name, ".."))) { | ||
275 | d_drop(dentry); | ||
276 | goto out; | ||
277 | } | ||
278 | encoded_namelen = ecryptfs_encode_filename(crypt_stat, | ||
279 | dentry->d_name.name, | ||
280 | dentry->d_name.len, | ||
281 | &encoded_name); | ||
282 | if (encoded_namelen < 0) { | ||
283 | rc = encoded_namelen; | ||
284 | d_drop(dentry); | ||
285 | goto out; | ||
286 | } | ||
287 | ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen " | ||
288 | "= [%d]\n", encoded_name, encoded_namelen); | ||
289 | lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry, | ||
290 | encoded_namelen - 1); | ||
291 | kfree(encoded_name); | ||
292 | if (IS_ERR(lower_dentry)) { | ||
293 | ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n"); | ||
294 | rc = PTR_ERR(lower_dentry); | ||
295 | d_drop(dentry); | ||
296 | goto out; | ||
297 | } | ||
298 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); | ||
299 | ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->" | ||
300 | "d_name.name = [%s]\n", lower_dentry, | ||
301 | lower_dentry->d_name.name); | ||
302 | lower_inode = lower_dentry->d_inode; | 264 | lower_inode = lower_dentry->d_inode; |
303 | fsstack_copy_attr_atime(dir, lower_dir_dentry->d_inode); | 265 | fsstack_copy_attr_atime(ecryptfs_dir_inode, lower_dir_dentry->d_inode); |
304 | BUG_ON(!atomic_read(&lower_dentry->d_count)); | 266 | BUG_ON(!atomic_read(&lower_dentry->d_count)); |
305 | ecryptfs_set_dentry_private(dentry, | 267 | ecryptfs_set_dentry_private(ecryptfs_dentry, |
306 | kmem_cache_alloc(ecryptfs_dentry_info_cache, | 268 | kmem_cache_alloc(ecryptfs_dentry_info_cache, |
307 | GFP_KERNEL)); | 269 | GFP_KERNEL)); |
308 | if (!ecryptfs_dentry_to_private(dentry)) { | 270 | if (!ecryptfs_dentry_to_private(ecryptfs_dentry)) { |
309 | rc = -ENOMEM; | 271 | rc = -ENOMEM; |
310 | ecryptfs_printk(KERN_ERR, "Out of memory whilst attempting " | 272 | printk(KERN_ERR "%s: Out of memory whilst attempting " |
311 | "to allocate ecryptfs_dentry_info struct\n"); | 273 | "to allocate ecryptfs_dentry_info struct\n", |
274 | __func__); | ||
312 | goto out_dput; | 275 | goto out_dput; |
313 | } | 276 | } |
314 | ecryptfs_set_dentry_lower(dentry, lower_dentry); | 277 | ecryptfs_set_dentry_lower(ecryptfs_dentry, lower_dentry); |
315 | ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt); | 278 | ecryptfs_set_dentry_lower_mnt(ecryptfs_dentry, lower_mnt); |
316 | if (!lower_dentry->d_inode) { | 279 | if (!lower_dentry->d_inode) { |
317 | /* We want to add because we couldn't find in lower */ | 280 | /* We want to add because we couldn't find in lower */ |
318 | d_add(dentry, NULL); | 281 | d_add(ecryptfs_dentry, NULL); |
319 | goto out; | 282 | goto out; |
320 | } | 283 | } |
321 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, | 284 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, |
322 | ECRYPTFS_INTERPOSE_FLAG_D_ADD); | 285 | ecryptfs_dir_inode->i_sb, 1); |
323 | if (rc) { | 286 | if (rc) { |
324 | ecryptfs_printk(KERN_ERR, "Error interposing\n"); | 287 | printk(KERN_ERR "%s: Error interposing; rc = [%d]\n", |
288 | __func__, rc); | ||
325 | goto out; | 289 | goto out; |
326 | } | 290 | } |
327 | if (S_ISDIR(lower_inode->i_mode)) { | 291 | if (S_ISDIR(lower_inode->i_mode)) |
328 | ecryptfs_printk(KERN_DEBUG, "Is a directory; returning\n"); | ||
329 | goto out; | 292 | goto out; |
330 | } | 293 | if (S_ISLNK(lower_inode->i_mode)) |
331 | if (S_ISLNK(lower_inode->i_mode)) { | ||
332 | ecryptfs_printk(KERN_DEBUG, "Is a symlink; returning\n"); | ||
333 | goto out; | 294 | goto out; |
334 | } | 295 | if (special_file(lower_inode->i_mode)) |
335 | if (special_file(lower_inode->i_mode)) { | ||
336 | ecryptfs_printk(KERN_DEBUG, "Is a special file; returning\n"); | ||
337 | goto out; | 296 | goto out; |
338 | } | 297 | if (!ecryptfs_nd) |
339 | if (!nd) { | ||
340 | ecryptfs_printk(KERN_DEBUG, "We have a NULL nd, just leave" | ||
341 | "as we *think* we are about to unlink\n"); | ||
342 | goto out; | 298 | goto out; |
343 | } | ||
344 | /* Released in this function */ | 299 | /* Released in this function */ |
345 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, | 300 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, GFP_USER); |
346 | GFP_USER); | ||
347 | if (!page_virt) { | 301 | if (!page_virt) { |
302 | printk(KERN_ERR "%s: Cannot kmem_cache_zalloc() a page\n", | ||
303 | __func__); | ||
348 | rc = -ENOMEM; | 304 | rc = -ENOMEM; |
349 | ecryptfs_printk(KERN_ERR, | ||
350 | "Cannot ecryptfs_kmalloc a page\n"); | ||
351 | goto out; | 305 | goto out; |
352 | } | 306 | } |
353 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 307 | if (!ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->lower_file) { |
354 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) | 308 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); |
355 | ecryptfs_set_default_sizes(crypt_stat); | ||
356 | if (!ecryptfs_inode_to_private(dentry->d_inode)->lower_file) { | ||
357 | rc = ecryptfs_init_persistent_file(dentry); | ||
358 | if (rc) { | 309 | if (rc) { |
359 | printk(KERN_ERR "%s: Error attempting to initialize " | 310 | printk(KERN_ERR "%s: Error attempting to initialize " |
360 | "the persistent file for the dentry with name " | 311 | "the persistent file for the dentry with name " |
361 | "[%s]; rc = [%d]\n", __func__, | 312 | "[%s]; rc = [%d]\n", __func__, |
362 | dentry->d_name.name, rc); | 313 | ecryptfs_dentry->d_name.name, rc); |
363 | goto out; | 314 | goto out_free_kmem; |
364 | } | 315 | } |
365 | } | 316 | } |
366 | rc = ecryptfs_read_and_validate_header_region(page_virt, | 317 | rc = ecryptfs_read_and_validate_header_region(page_virt, |
367 | dentry->d_inode); | 318 | ecryptfs_dentry->d_inode); |
368 | if (rc) { | 319 | if (rc) { |
369 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry); | 320 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, |
321 | ecryptfs_dentry); | ||
370 | if (rc) { | 322 | if (rc) { |
371 | printk(KERN_DEBUG "Valid metadata not found in header " | ||
372 | "region or xattr region; treating file as " | ||
373 | "unencrypted\n"); | ||
374 | rc = 0; | 323 | rc = 0; |
375 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 324 | goto out_free_kmem; |
376 | goto out; | ||
377 | } | 325 | } |
378 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | 326 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; |
379 | } | 327 | } |
380 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 328 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
381 | dentry->d_sb)->mount_crypt_stat; | 329 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
382 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | 330 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { |
383 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 331 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
384 | file_size = (crypt_stat->num_header_bytes_at_front | 332 | file_size = (crypt_stat->num_header_bytes_at_front |
@@ -388,14 +336,103 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
388 | } else { | 336 | } else { |
389 | file_size = get_unaligned_be64(page_virt); | 337 | file_size = get_unaligned_be64(page_virt); |
390 | } | 338 | } |
391 | i_size_write(dentry->d_inode, (loff_t)file_size); | 339 | i_size_write(ecryptfs_dentry->d_inode, (loff_t)file_size); |
340 | out_free_kmem: | ||
392 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 341 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
393 | goto out; | 342 | goto out; |
394 | |||
395 | out_dput: | 343 | out_dput: |
396 | dput(lower_dentry); | 344 | dput(lower_dentry); |
397 | d_drop(dentry); | 345 | d_drop(ecryptfs_dentry); |
346 | out: | ||
347 | return rc; | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * ecryptfs_lookup | ||
352 | * @ecryptfs_dir_inode: The eCryptfs directory inode | ||
353 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up | ||
354 | * @ecryptfs_nd: nameidata; may be NULL | ||
355 | * | ||
356 | * Find a file on disk. If the file does not exist, then we'll add it to the | ||
357 | * dentry cache and continue on to read it from the disk. | ||
358 | */ | ||
359 | static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | ||
360 | struct dentry *ecryptfs_dentry, | ||
361 | struct nameidata *ecryptfs_nd) | ||
362 | { | ||
363 | char *encrypted_and_encoded_name = NULL; | ||
364 | size_t encrypted_and_encoded_name_size; | ||
365 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | ||
366 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; | ||
367 | struct ecryptfs_inode_info *inode_info; | ||
368 | struct dentry *lower_dir_dentry, *lower_dentry; | ||
369 | int rc = 0; | ||
370 | |||
371 | ecryptfs_dentry->d_op = &ecryptfs_dops; | ||
372 | if ((ecryptfs_dentry->d_name.len == 1 | ||
373 | && !strcmp(ecryptfs_dentry->d_name.name, ".")) | ||
374 | || (ecryptfs_dentry->d_name.len == 2 | ||
375 | && !strcmp(ecryptfs_dentry->d_name.name, ".."))) { | ||
376 | goto out_d_drop; | ||
377 | } | ||
378 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); | ||
379 | lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name, | ||
380 | lower_dir_dentry, | ||
381 | ecryptfs_dentry->d_name.len); | ||
382 | if (IS_ERR(lower_dentry)) { | ||
383 | rc = PTR_ERR(lower_dentry); | ||
384 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " | ||
385 | "lower_dentry = [%s]\n", __func__, rc, | ||
386 | ecryptfs_dentry->d_name.name); | ||
387 | goto out_d_drop; | ||
388 | } | ||
389 | if (lower_dentry->d_inode) | ||
390 | goto lookup_and_interpose; | ||
391 | inode_info = ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | ||
392 | if (inode_info) { | ||
393 | crypt_stat = &inode_info->crypt_stat; | ||
394 | /* TODO: lock for crypt_stat comparison */ | ||
395 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) | ||
396 | ecryptfs_set_default_sizes(crypt_stat); | ||
397 | } | ||
398 | if (crypt_stat) | ||
399 | mount_crypt_stat = crypt_stat->mount_crypt_stat; | ||
400 | else | ||
401 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
402 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
403 | if (!(crypt_stat && (crypt_stat->flags & ECRYPTFS_ENCRYPT_FILENAMES)) | ||
404 | && !(mount_crypt_stat && (mount_crypt_stat->flags | ||
405 | & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) | ||
406 | goto lookup_and_interpose; | ||
407 | dput(lower_dentry); | ||
408 | rc = ecryptfs_encrypt_and_encode_filename( | ||
409 | &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, | ||
410 | crypt_stat, mount_crypt_stat, ecryptfs_dentry->d_name.name, | ||
411 | ecryptfs_dentry->d_name.len); | ||
412 | if (rc) { | ||
413 | printk(KERN_ERR "%s: Error attempting to encrypt and encode " | ||
414 | "filename; rc = [%d]\n", __func__, rc); | ||
415 | goto out_d_drop; | ||
416 | } | ||
417 | lower_dentry = lookup_one_len(encrypted_and_encoded_name, | ||
418 | lower_dir_dentry, | ||
419 | encrypted_and_encoded_name_size - 1); | ||
420 | if (IS_ERR(lower_dentry)) { | ||
421 | rc = PTR_ERR(lower_dentry); | ||
422 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " | ||
423 | "lower_dentry = [%s]\n", __func__, rc, | ||
424 | encrypted_and_encoded_name); | ||
425 | goto out_d_drop; | ||
426 | } | ||
427 | lookup_and_interpose: | ||
428 | rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry, | ||
429 | crypt_stat, ecryptfs_dir_inode, | ||
430 | ecryptfs_nd); | ||
431 | goto out; | ||
432 | out_d_drop: | ||
433 | d_drop(ecryptfs_dentry); | ||
398 | out: | 434 | out: |
435 | kfree(encrypted_and_encoded_name); | ||
399 | return ERR_PTR(rc); | 436 | return ERR_PTR(rc); |
400 | } | 437 | } |
401 | 438 | ||
@@ -466,19 +503,21 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | |||
466 | struct dentry *lower_dentry; | 503 | struct dentry *lower_dentry; |
467 | struct dentry *lower_dir_dentry; | 504 | struct dentry *lower_dir_dentry; |
468 | char *encoded_symname; | 505 | char *encoded_symname; |
469 | int encoded_symlen; | 506 | size_t encoded_symlen; |
470 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | 507 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; |
471 | 508 | ||
472 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 509 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
473 | dget(lower_dentry); | 510 | dget(lower_dentry); |
474 | lower_dir_dentry = lock_parent(lower_dentry); | 511 | lower_dir_dentry = lock_parent(lower_dentry); |
475 | encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, | 512 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
476 | strlen(symname), | 513 | dir->i_sb)->mount_crypt_stat; |
477 | &encoded_symname); | 514 | rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname, |
478 | if (encoded_symlen < 0) { | 515 | &encoded_symlen, |
479 | rc = encoded_symlen; | 516 | NULL, |
517 | mount_crypt_stat, symname, | ||
518 | strlen(symname)); | ||
519 | if (rc) | ||
480 | goto out_lock; | 520 | goto out_lock; |
481 | } | ||
482 | rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, | 521 | rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, |
483 | encoded_symname); | 522 | encoded_symname); |
484 | kfree(encoded_symname); | 523 | kfree(encoded_symname); |
@@ -602,52 +641,54 @@ out_lock: | |||
602 | } | 641 | } |
603 | 642 | ||
604 | static int | 643 | static int |
605 | ecryptfs_readlink(struct dentry *dentry, char __user * buf, int bufsiz) | 644 | ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) |
606 | { | 645 | { |
607 | int rc; | ||
608 | struct dentry *lower_dentry; | ||
609 | char *decoded_name; | ||
610 | char *lower_buf; | 646 | char *lower_buf; |
611 | mm_segment_t old_fs; | 647 | struct dentry *lower_dentry; |
612 | struct ecryptfs_crypt_stat *crypt_stat; | 648 | struct ecryptfs_crypt_stat *crypt_stat; |
649 | char *plaintext_name; | ||
650 | size_t plaintext_name_size; | ||
651 | mm_segment_t old_fs; | ||
652 | int rc; | ||
613 | 653 | ||
614 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 654 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
615 | if (!lower_dentry->d_inode->i_op->readlink) { | 655 | if (!lower_dentry->d_inode->i_op->readlink) { |
616 | rc = -EINVAL; | 656 | rc = -EINVAL; |
617 | goto out; | 657 | goto out; |
618 | } | 658 | } |
659 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | ||
619 | /* Released in this function */ | 660 | /* Released in this function */ |
620 | lower_buf = kmalloc(bufsiz, GFP_KERNEL); | 661 | lower_buf = kmalloc(bufsiz, GFP_KERNEL); |
621 | if (lower_buf == NULL) { | 662 | if (lower_buf == NULL) { |
622 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | 663 | printk(KERN_ERR "%s: Out of memory whilst attempting to " |
664 | "kmalloc [%d] bytes\n", __func__, bufsiz); | ||
623 | rc = -ENOMEM; | 665 | rc = -ENOMEM; |
624 | goto out; | 666 | goto out; |
625 | } | 667 | } |
626 | old_fs = get_fs(); | 668 | old_fs = get_fs(); |
627 | set_fs(get_ds()); | 669 | set_fs(get_ds()); |
628 | ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ " | ||
629 | "lower_dentry->d_name.name = [%s]\n", | ||
630 | lower_dentry->d_name.name); | ||
631 | rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, | 670 | rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, |
632 | (char __user *)lower_buf, | 671 | (char __user *)lower_buf, |
633 | bufsiz); | 672 | bufsiz); |
634 | set_fs(old_fs); | 673 | set_fs(old_fs); |
635 | if (rc >= 0) { | 674 | if (rc >= 0) { |
636 | crypt_stat = NULL; | 675 | rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name, |
637 | rc = ecryptfs_decode_filename(crypt_stat, lower_buf, rc, | 676 | &plaintext_name_size, |
638 | &decoded_name); | 677 | dentry, lower_buf, |
639 | if (rc == -ENOMEM) | 678 | rc); |
679 | if (rc) { | ||
680 | printk(KERN_ERR "%s: Error attempting to decode and " | ||
681 | "decrypt filename; rc = [%d]\n", __func__, | ||
682 | rc); | ||
640 | goto out_free_lower_buf; | 683 | goto out_free_lower_buf; |
641 | if (rc > 0) { | ||
642 | ecryptfs_printk(KERN_DEBUG, "Copying [%d] bytes " | ||
643 | "to userspace: [%*s]\n", rc, | ||
644 | decoded_name); | ||
645 | if (copy_to_user(buf, decoded_name, rc)) | ||
646 | rc = -EFAULT; | ||
647 | } | 684 | } |
648 | kfree(decoded_name); | 685 | rc = copy_to_user(buf, plaintext_name, plaintext_name_size); |
649 | fsstack_copy_attr_atime(dentry->d_inode, | 686 | if (rc) |
650 | lower_dentry->d_inode); | 687 | rc = -EFAULT; |
688 | else | ||
689 | rc = plaintext_name_size; | ||
690 | kfree(plaintext_name); | ||
691 | fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode); | ||
651 | } | 692 | } |
652 | out_free_lower_buf: | 693 | out_free_lower_buf: |
653 | kfree(lower_buf); | 694 | kfree(lower_buf); |
@@ -669,8 +710,6 @@ static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
669 | } | 710 | } |
670 | old_fs = get_fs(); | 711 | old_fs = get_fs(); |
671 | set_fs(get_ds()); | 712 | set_fs(get_ds()); |
672 | ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ " | ||
673 | "dentry->d_name.name = [%s]\n", dentry->d_name.name); | ||
674 | rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len); | 713 | rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len); |
675 | set_fs(old_fs); | 714 | set_fs(old_fs); |
676 | if (rc < 0) | 715 | if (rc < 0) |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 0d713b691941..ff539420cc6f 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -358,7 +358,7 @@ parse_tag_67_packet(struct ecryptfs_key_record *key_rec, | |||
358 | /* verify that everything through the encrypted FEK size is present */ | 358 | /* verify that everything through the encrypted FEK size is present */ |
359 | if (message_len < 4) { | 359 | if (message_len < 4) { |
360 | rc = -EIO; | 360 | rc = -EIO; |
361 | printk(KERN_ERR "%s: message_len is [%Zd]; minimum acceptable " | 361 | printk(KERN_ERR "%s: message_len is [%zd]; minimum acceptable " |
362 | "message length is [%d]\n", __func__, message_len, 4); | 362 | "message length is [%d]\n", __func__, message_len, 4); |
363 | goto out; | 363 | goto out; |
364 | } | 364 | } |
@@ -385,13 +385,13 @@ parse_tag_67_packet(struct ecryptfs_key_record *key_rec, | |||
385 | i += data_len; | 385 | i += data_len; |
386 | if (message_len < (i + key_rec->enc_key_size)) { | 386 | if (message_len < (i + key_rec->enc_key_size)) { |
387 | rc = -EIO; | 387 | rc = -EIO; |
388 | printk(KERN_ERR "%s: message_len [%Zd]; max len is [%Zd]\n", | 388 | printk(KERN_ERR "%s: message_len [%zd]; max len is [%zd]\n", |
389 | __func__, message_len, (i + key_rec->enc_key_size)); | 389 | __func__, message_len, (i + key_rec->enc_key_size)); |
390 | goto out; | 390 | goto out; |
391 | } | 391 | } |
392 | if (key_rec->enc_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | 392 | if (key_rec->enc_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { |
393 | rc = -EIO; | 393 | rc = -EIO; |
394 | printk(KERN_ERR "%s: Encrypted key_size [%Zd] larger than " | 394 | printk(KERN_ERR "%s: Encrypted key_size [%zd] larger than " |
395 | "the maximum key size [%d]\n", __func__, | 395 | "the maximum key size [%d]\n", __func__, |
396 | key_rec->enc_key_size, | 396 | key_rec->enc_key_size, |
397 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); | 397 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); |
@@ -403,6 +403,580 @@ out: | |||
403 | } | 403 | } |
404 | 404 | ||
405 | static int | 405 | static int |
406 | ecryptfs_find_global_auth_tok_for_sig( | ||
407 | struct ecryptfs_global_auth_tok **global_auth_tok, | ||
408 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) | ||
409 | { | ||
410 | struct ecryptfs_global_auth_tok *walker; | ||
411 | int rc = 0; | ||
412 | |||
413 | (*global_auth_tok) = NULL; | ||
414 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
415 | list_for_each_entry(walker, | ||
416 | &mount_crypt_stat->global_auth_tok_list, | ||
417 | mount_crypt_stat_list) { | ||
418 | if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) { | ||
419 | (*global_auth_tok) = walker; | ||
420 | goto out; | ||
421 | } | ||
422 | } | ||
423 | rc = -EINVAL; | ||
424 | out: | ||
425 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
426 | return rc; | ||
427 | } | ||
428 | |||
429 | /** | ||
430 | * ecryptfs_find_auth_tok_for_sig | ||
431 | * @auth_tok: Set to the matching auth_tok; NULL if not found | ||
432 | * @crypt_stat: inode crypt_stat crypto context | ||
433 | * @sig: Sig of auth_tok to find | ||
434 | * | ||
435 | * For now, this function simply looks at the registered auth_tok's | ||
436 | * linked off the mount_crypt_stat, so all the auth_toks that can be | ||
437 | * used must be registered at mount time. This function could | ||
438 | * potentially try a lot harder to find auth_tok's (e.g., by calling | ||
439 | * out to ecryptfsd to dynamically retrieve an auth_tok object) so | ||
440 | * that static registration of auth_tok's will no longer be necessary. | ||
441 | * | ||
442 | * Returns zero on no error; non-zero on error | ||
443 | */ | ||
444 | static int | ||
445 | ecryptfs_find_auth_tok_for_sig( | ||
446 | struct ecryptfs_auth_tok **auth_tok, | ||
447 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
448 | char *sig) | ||
449 | { | ||
450 | struct ecryptfs_global_auth_tok *global_auth_tok; | ||
451 | int rc = 0; | ||
452 | |||
453 | (*auth_tok) = NULL; | ||
454 | if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, | ||
455 | mount_crypt_stat, sig)) { | ||
456 | struct key *auth_tok_key; | ||
457 | |||
458 | rc = ecryptfs_keyring_auth_tok_for_sig(&auth_tok_key, auth_tok, | ||
459 | sig); | ||
460 | } else | ||
461 | (*auth_tok) = global_auth_tok->global_auth_tok; | ||
462 | return rc; | ||
463 | } | ||
464 | |||
465 | /** | ||
466 | * write_tag_70_packet can gobble a lot of stack space. We stuff most | ||
467 | * of the function's parameters in a kmalloc'd struct to help reduce | ||
468 | * eCryptfs' overall stack usage. | ||
469 | */ | ||
470 | struct ecryptfs_write_tag_70_packet_silly_stack { | ||
471 | u8 cipher_code; | ||
472 | size_t max_packet_size; | ||
473 | size_t packet_size_len; | ||
474 | size_t block_aligned_filename_size; | ||
475 | size_t block_size; | ||
476 | size_t i; | ||
477 | size_t j; | ||
478 | size_t num_rand_bytes; | ||
479 | struct mutex *tfm_mutex; | ||
480 | char *block_aligned_filename; | ||
481 | struct ecryptfs_auth_tok *auth_tok; | ||
482 | struct scatterlist src_sg; | ||
483 | struct scatterlist dst_sg; | ||
484 | struct blkcipher_desc desc; | ||
485 | char iv[ECRYPTFS_MAX_IV_BYTES]; | ||
486 | char hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; | ||
487 | char tmp_hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; | ||
488 | struct hash_desc hash_desc; | ||
489 | struct scatterlist hash_sg; | ||
490 | }; | ||
491 | |||
492 | /** | ||
493 | * write_tag_70_packet - Write encrypted filename (EFN) packet against FNEK | ||
494 | * @filename: NULL-terminated filename string | ||
495 | * | ||
496 | * This is the simplest mechanism for achieving filename encryption in | ||
497 | * eCryptfs. It encrypts the given filename with the mount-wide | ||
498 | * filename encryption key (FNEK) and stores it in a packet to @dest, | ||
499 | * which the callee will encode and write directly into the dentry | ||
500 | * name. | ||
501 | */ | ||
502 | int | ||
503 | ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, | ||
504 | size_t *packet_size, | ||
505 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
506 | char *filename, size_t filename_size) | ||
507 | { | ||
508 | struct ecryptfs_write_tag_70_packet_silly_stack *s; | ||
509 | int rc = 0; | ||
510 | |||
511 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
512 | if (!s) { | ||
513 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " | ||
514 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); | ||
515 | goto out; | ||
516 | } | ||
517 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
518 | (*packet_size) = 0; | ||
519 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name( | ||
520 | &s->desc.tfm, | ||
521 | &s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name); | ||
522 | if (unlikely(rc)) { | ||
523 | printk(KERN_ERR "Internal error whilst attempting to get " | ||
524 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", | ||
525 | mount_crypt_stat->global_default_fn_cipher_name, rc); | ||
526 | goto out; | ||
527 | } | ||
528 | mutex_lock(s->tfm_mutex); | ||
529 | s->block_size = crypto_blkcipher_blocksize(s->desc.tfm); | ||
530 | /* Plus one for the \0 separator between the random prefix | ||
531 | * and the plaintext filename */ | ||
532 | s->num_rand_bytes = (ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES + 1); | ||
533 | s->block_aligned_filename_size = (s->num_rand_bytes + filename_size); | ||
534 | if ((s->block_aligned_filename_size % s->block_size) != 0) { | ||
535 | s->num_rand_bytes += (s->block_size | ||
536 | - (s->block_aligned_filename_size | ||
537 | % s->block_size)); | ||
538 | s->block_aligned_filename_size = (s->num_rand_bytes | ||
539 | + filename_size); | ||
540 | } | ||
541 | /* Octet 0: Tag 70 identifier | ||
542 | * Octets 1-N1: Tag 70 packet size (includes cipher identifier | ||
543 | * and block-aligned encrypted filename size) | ||
544 | * Octets N1-N2: FNEK sig (ECRYPTFS_SIG_SIZE) | ||
545 | * Octet N2-N3: Cipher identifier (1 octet) | ||
546 | * Octets N3-N4: Block-aligned encrypted filename | ||
547 | * - Consists of a minimum number of random characters, a \0 | ||
548 | * separator, and then the filename */ | ||
549 | s->max_packet_size = (1 /* Tag 70 identifier */ | ||
550 | + 3 /* Max Tag 70 packet size */ | ||
551 | + ECRYPTFS_SIG_SIZE /* FNEK sig */ | ||
552 | + 1 /* Cipher identifier */ | ||
553 | + s->block_aligned_filename_size); | ||
554 | if (dest == NULL) { | ||
555 | (*packet_size) = s->max_packet_size; | ||
556 | goto out_unlock; | ||
557 | } | ||
558 | if (s->max_packet_size > (*remaining_bytes)) { | ||
559 | printk(KERN_WARNING "%s: Require [%zd] bytes to write; only " | ||
560 | "[%zd] available\n", __func__, s->max_packet_size, | ||
561 | (*remaining_bytes)); | ||
562 | rc = -EINVAL; | ||
563 | goto out_unlock; | ||
564 | } | ||
565 | s->block_aligned_filename = kzalloc(s->block_aligned_filename_size, | ||
566 | GFP_KERNEL); | ||
567 | if (!s->block_aligned_filename) { | ||
568 | printk(KERN_ERR "%s: Out of kernel memory whilst attempting to " | ||
569 | "kzalloc [%zd] bytes\n", __func__, | ||
570 | s->block_aligned_filename_size); | ||
571 | rc = -ENOMEM; | ||
572 | goto out_unlock; | ||
573 | } | ||
574 | s->i = 0; | ||
575 | dest[s->i++] = ECRYPTFS_TAG_70_PACKET_TYPE; | ||
576 | rc = ecryptfs_write_packet_length(&dest[s->i], | ||
577 | (ECRYPTFS_SIG_SIZE | ||
578 | + 1 /* Cipher code */ | ||
579 | + s->block_aligned_filename_size), | ||
580 | &s->packet_size_len); | ||
581 | if (rc) { | ||
582 | printk(KERN_ERR "%s: Error generating tag 70 packet " | ||
583 | "header; cannot generate packet length; rc = [%d]\n", | ||
584 | __func__, rc); | ||
585 | goto out_free_unlock; | ||
586 | } | ||
587 | s->i += s->packet_size_len; | ||
588 | ecryptfs_from_hex(&dest[s->i], | ||
589 | mount_crypt_stat->global_default_fnek_sig, | ||
590 | ECRYPTFS_SIG_SIZE); | ||
591 | s->i += ECRYPTFS_SIG_SIZE; | ||
592 | s->cipher_code = ecryptfs_code_for_cipher_string( | ||
593 | mount_crypt_stat->global_default_fn_cipher_name, | ||
594 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | ||
595 | if (s->cipher_code == 0) { | ||
596 | printk(KERN_WARNING "%s: Unable to generate code for " | ||
597 | "cipher [%s] with key bytes [%zd]\n", __func__, | ||
598 | mount_crypt_stat->global_default_fn_cipher_name, | ||
599 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | ||
600 | rc = -EINVAL; | ||
601 | goto out_free_unlock; | ||
602 | } | ||
603 | dest[s->i++] = s->cipher_code; | ||
604 | rc = ecryptfs_find_auth_tok_for_sig( | ||
605 | &s->auth_tok, mount_crypt_stat, | ||
606 | mount_crypt_stat->global_default_fnek_sig); | ||
607 | if (rc) { | ||
608 | printk(KERN_ERR "%s: Error attempting to find auth tok for " | ||
609 | "fnek sig [%s]; rc = [%d]\n", __func__, | ||
610 | mount_crypt_stat->global_default_fnek_sig, rc); | ||
611 | goto out_free_unlock; | ||
612 | } | ||
613 | /* TODO: Support other key modules than passphrase for | ||
614 | * filename encryption */ | ||
615 | BUG_ON(s->auth_tok->token_type != ECRYPTFS_PASSWORD); | ||
616 | sg_init_one( | ||
617 | &s->hash_sg, | ||
618 | (u8 *)s->auth_tok->token.password.session_key_encryption_key, | ||
619 | s->auth_tok->token.password.session_key_encryption_key_bytes); | ||
620 | s->hash_desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
621 | s->hash_desc.tfm = crypto_alloc_hash(ECRYPTFS_TAG_70_DIGEST, 0, | ||
622 | CRYPTO_ALG_ASYNC); | ||
623 | if (IS_ERR(s->hash_desc.tfm)) { | ||
624 | rc = PTR_ERR(s->hash_desc.tfm); | ||
625 | printk(KERN_ERR "%s: Error attempting to " | ||
626 | "allocate hash crypto context; rc = [%d]\n", | ||
627 | __func__, rc); | ||
628 | goto out_free_unlock; | ||
629 | } | ||
630 | rc = crypto_hash_init(&s->hash_desc); | ||
631 | if (rc) { | ||
632 | printk(KERN_ERR | ||
633 | "%s: Error initializing crypto hash; rc = [%d]\n", | ||
634 | __func__, rc); | ||
635 | goto out_release_free_unlock; | ||
636 | } | ||
637 | rc = crypto_hash_update( | ||
638 | &s->hash_desc, &s->hash_sg, | ||
639 | s->auth_tok->token.password.session_key_encryption_key_bytes); | ||
640 | if (rc) { | ||
641 | printk(KERN_ERR | ||
642 | "%s: Error updating crypto hash; rc = [%d]\n", | ||
643 | __func__, rc); | ||
644 | goto out_release_free_unlock; | ||
645 | } | ||
646 | rc = crypto_hash_final(&s->hash_desc, s->hash); | ||
647 | if (rc) { | ||
648 | printk(KERN_ERR | ||
649 | "%s: Error finalizing crypto hash; rc = [%d]\n", | ||
650 | __func__, rc); | ||
651 | goto out_release_free_unlock; | ||
652 | } | ||
653 | for (s->j = 0; s->j < (s->num_rand_bytes - 1); s->j++) { | ||
654 | s->block_aligned_filename[s->j] = | ||
655 | s->hash[(s->j % ECRYPTFS_TAG_70_DIGEST_SIZE)]; | ||
656 | if ((s->j % ECRYPTFS_TAG_70_DIGEST_SIZE) | ||
657 | == (ECRYPTFS_TAG_70_DIGEST_SIZE - 1)) { | ||
658 | sg_init_one(&s->hash_sg, (u8 *)s->hash, | ||
659 | ECRYPTFS_TAG_70_DIGEST_SIZE); | ||
660 | rc = crypto_hash_init(&s->hash_desc); | ||
661 | if (rc) { | ||
662 | printk(KERN_ERR | ||
663 | "%s: Error initializing crypto hash; " | ||
664 | "rc = [%d]\n", __func__, rc); | ||
665 | goto out_release_free_unlock; | ||
666 | } | ||
667 | rc = crypto_hash_update(&s->hash_desc, &s->hash_sg, | ||
668 | ECRYPTFS_TAG_70_DIGEST_SIZE); | ||
669 | if (rc) { | ||
670 | printk(KERN_ERR | ||
671 | "%s: Error updating crypto hash; " | ||
672 | "rc = [%d]\n", __func__, rc); | ||
673 | goto out_release_free_unlock; | ||
674 | } | ||
675 | rc = crypto_hash_final(&s->hash_desc, s->tmp_hash); | ||
676 | if (rc) { | ||
677 | printk(KERN_ERR | ||
678 | "%s: Error finalizing crypto hash; " | ||
679 | "rc = [%d]\n", __func__, rc); | ||
680 | goto out_release_free_unlock; | ||
681 | } | ||
682 | memcpy(s->hash, s->tmp_hash, | ||
683 | ECRYPTFS_TAG_70_DIGEST_SIZE); | ||
684 | } | ||
685 | if (s->block_aligned_filename[s->j] == '\0') | ||
686 | s->block_aligned_filename[s->j] = ECRYPTFS_NON_NULL; | ||
687 | } | ||
688 | memcpy(&s->block_aligned_filename[s->num_rand_bytes], filename, | ||
689 | filename_size); | ||
690 | rc = virt_to_scatterlist(s->block_aligned_filename, | ||
691 | s->block_aligned_filename_size, &s->src_sg, 1); | ||
692 | if (rc != 1) { | ||
693 | printk(KERN_ERR "%s: Internal error whilst attempting to " | ||
694 | "convert filename memory to scatterlist; " | ||
695 | "expected rc = 1; got rc = [%d]. " | ||
696 | "block_aligned_filename_size = [%zd]\n", __func__, rc, | ||
697 | s->block_aligned_filename_size); | ||
698 | goto out_release_free_unlock; | ||
699 | } | ||
700 | rc = virt_to_scatterlist(&dest[s->i], s->block_aligned_filename_size, | ||
701 | &s->dst_sg, 1); | ||
702 | if (rc != 1) { | ||
703 | printk(KERN_ERR "%s: Internal error whilst attempting to " | ||
704 | "convert encrypted filename memory to scatterlist; " | ||
705 | "expected rc = 1; got rc = [%d]. " | ||
706 | "block_aligned_filename_size = [%zd]\n", __func__, rc, | ||
707 | s->block_aligned_filename_size); | ||
708 | goto out_release_free_unlock; | ||
709 | } | ||
710 | /* The characters in the first block effectively do the job | ||
711 | * of the IV here, so we just use 0's for the IV. Note the | ||
712 | * constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES | ||
713 | * >= ECRYPTFS_MAX_IV_BYTES. */ | ||
714 | memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); | ||
715 | s->desc.info = s->iv; | ||
716 | rc = crypto_blkcipher_setkey( | ||
717 | s->desc.tfm, | ||
718 | s->auth_tok->token.password.session_key_encryption_key, | ||
719 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | ||
720 | if (rc < 0) { | ||
721 | printk(KERN_ERR "%s: Error setting key for crypto context; " | ||
722 | "rc = [%d]. s->auth_tok->token.password.session_key_" | ||
723 | "encryption_key = [0x%p]; mount_crypt_stat->" | ||
724 | "global_default_fn_cipher_key_bytes = [%zd]\n", __func__, | ||
725 | rc, | ||
726 | s->auth_tok->token.password.session_key_encryption_key, | ||
727 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | ||
728 | goto out_release_free_unlock; | ||
729 | } | ||
730 | rc = crypto_blkcipher_encrypt_iv(&s->desc, &s->dst_sg, &s->src_sg, | ||
731 | s->block_aligned_filename_size); | ||
732 | if (rc) { | ||
733 | printk(KERN_ERR "%s: Error attempting to encrypt filename; " | ||
734 | "rc = [%d]\n", __func__, rc); | ||
735 | goto out_release_free_unlock; | ||
736 | } | ||
737 | s->i += s->block_aligned_filename_size; | ||
738 | (*packet_size) = s->i; | ||
739 | (*remaining_bytes) -= (*packet_size); | ||
740 | out_release_free_unlock: | ||
741 | crypto_free_hash(s->hash_desc.tfm); | ||
742 | out_free_unlock: | ||
743 | memset(s->block_aligned_filename, 0, s->block_aligned_filename_size); | ||
744 | kfree(s->block_aligned_filename); | ||
745 | out_unlock: | ||
746 | mutex_unlock(s->tfm_mutex); | ||
747 | out: | ||
748 | kfree(s); | ||
749 | return rc; | ||
750 | } | ||
751 | |||
752 | struct ecryptfs_parse_tag_70_packet_silly_stack { | ||
753 | u8 cipher_code; | ||
754 | size_t max_packet_size; | ||
755 | size_t packet_size_len; | ||
756 | size_t parsed_tag_70_packet_size; | ||
757 | size_t block_aligned_filename_size; | ||
758 | size_t block_size; | ||
759 | size_t i; | ||
760 | struct mutex *tfm_mutex; | ||
761 | char *decrypted_filename; | ||
762 | struct ecryptfs_auth_tok *auth_tok; | ||
763 | struct scatterlist src_sg; | ||
764 | struct scatterlist dst_sg; | ||
765 | struct blkcipher_desc desc; | ||
766 | char fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1]; | ||
767 | char iv[ECRYPTFS_MAX_IV_BYTES]; | ||
768 | char cipher_string[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; | ||
769 | }; | ||
770 | |||
771 | /** | ||
772 | * parse_tag_70_packet - Parse and process FNEK-encrypted passphrase packet | ||
773 | * @filename: This function kmalloc's the memory for the filename | ||
774 | * @filename_size: This function sets this to the amount of memory | ||
775 | * kmalloc'd for the filename | ||
776 | * @packet_size: This function sets this to the the number of octets | ||
777 | * in the packet parsed | ||
778 | * @mount_crypt_stat: The mount-wide cryptographic context | ||
779 | * @data: The memory location containing the start of the tag 70 | ||
780 | * packet | ||
781 | * @max_packet_size: The maximum legal size of the packet to be parsed | ||
782 | * from @data | ||
783 | * | ||
784 | * Returns zero on success; non-zero otherwise | ||
785 | */ | ||
786 | int | ||
787 | ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, | ||
788 | size_t *packet_size, | ||
789 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
790 | char *data, size_t max_packet_size) | ||
791 | { | ||
792 | struct ecryptfs_parse_tag_70_packet_silly_stack *s; | ||
793 | int rc = 0; | ||
794 | |||
795 | (*packet_size) = 0; | ||
796 | (*filename_size) = 0; | ||
797 | (*filename) = NULL; | ||
798 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
799 | if (!s) { | ||
800 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " | ||
801 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); | ||
802 | goto out; | ||
803 | } | ||
804 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
805 | if (max_packet_size < (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)) { | ||
806 | printk(KERN_WARNING "%s: max_packet_size is [%zd]; it must be " | ||
807 | "at least [%d]\n", __func__, max_packet_size, | ||
808 | (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)); | ||
809 | rc = -EINVAL; | ||
810 | goto out; | ||
811 | } | ||
812 | /* Octet 0: Tag 70 identifier | ||
813 | * Octets 1-N1: Tag 70 packet size (includes cipher identifier | ||
814 | * and block-aligned encrypted filename size) | ||
815 | * Octets N1-N2: FNEK sig (ECRYPTFS_SIG_SIZE) | ||
816 | * Octet N2-N3: Cipher identifier (1 octet) | ||
817 | * Octets N3-N4: Block-aligned encrypted filename | ||
818 | * - Consists of a minimum number of random numbers, a \0 | ||
819 | * separator, and then the filename */ | ||
820 | if (data[(*packet_size)++] != ECRYPTFS_TAG_70_PACKET_TYPE) { | ||
821 | printk(KERN_WARNING "%s: Invalid packet tag [0x%.2x]; must be " | ||
822 | "tag [0x%.2x]\n", __func__, | ||
823 | data[((*packet_size) - 1)], ECRYPTFS_TAG_70_PACKET_TYPE); | ||
824 | rc = -EINVAL; | ||
825 | goto out; | ||
826 | } | ||
827 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], | ||
828 | &s->parsed_tag_70_packet_size, | ||
829 | &s->packet_size_len); | ||
830 | if (rc) { | ||
831 | printk(KERN_WARNING "%s: Error parsing packet length; " | ||
832 | "rc = [%d]\n", __func__, rc); | ||
833 | goto out; | ||
834 | } | ||
835 | s->block_aligned_filename_size = (s->parsed_tag_70_packet_size | ||
836 | - ECRYPTFS_SIG_SIZE - 1); | ||
837 | if ((1 + s->packet_size_len + s->parsed_tag_70_packet_size) | ||
838 | > max_packet_size) { | ||
839 | printk(KERN_WARNING "%s: max_packet_size is [%zd]; real packet " | ||
840 | "size is [%zd]\n", __func__, max_packet_size, | ||
841 | (1 + s->packet_size_len + 1 | ||
842 | + s->block_aligned_filename_size)); | ||
843 | rc = -EINVAL; | ||
844 | goto out; | ||
845 | } | ||
846 | (*packet_size) += s->packet_size_len; | ||
847 | ecryptfs_to_hex(s->fnek_sig_hex, &data[(*packet_size)], | ||
848 | ECRYPTFS_SIG_SIZE); | ||
849 | s->fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | ||
850 | (*packet_size) += ECRYPTFS_SIG_SIZE; | ||
851 | s->cipher_code = data[(*packet_size)++]; | ||
852 | rc = ecryptfs_cipher_code_to_string(s->cipher_string, s->cipher_code); | ||
853 | if (rc) { | ||
854 | printk(KERN_WARNING "%s: Cipher code [%d] is invalid\n", | ||
855 | __func__, s->cipher_code); | ||
856 | goto out; | ||
857 | } | ||
858 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm, | ||
859 | &s->tfm_mutex, | ||
860 | s->cipher_string); | ||
861 | if (unlikely(rc)) { | ||
862 | printk(KERN_ERR "Internal error whilst attempting to get " | ||
863 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", | ||
864 | s->cipher_string, rc); | ||
865 | goto out; | ||
866 | } | ||
867 | mutex_lock(s->tfm_mutex); | ||
868 | rc = virt_to_scatterlist(&data[(*packet_size)], | ||
869 | s->block_aligned_filename_size, &s->src_sg, 1); | ||
870 | if (rc != 1) { | ||
871 | printk(KERN_ERR "%s: Internal error whilst attempting to " | ||
872 | "convert encrypted filename memory to scatterlist; " | ||
873 | "expected rc = 1; got rc = [%d]. " | ||
874 | "block_aligned_filename_size = [%zd]\n", __func__, rc, | ||
875 | s->block_aligned_filename_size); | ||
876 | goto out_unlock; | ||
877 | } | ||
878 | (*packet_size) += s->block_aligned_filename_size; | ||
879 | s->decrypted_filename = kmalloc(s->block_aligned_filename_size, | ||
880 | GFP_KERNEL); | ||
881 | if (!s->decrypted_filename) { | ||
882 | printk(KERN_ERR "%s: Out of memory whilst attempting to " | ||
883 | "kmalloc [%zd] bytes\n", __func__, | ||
884 | s->block_aligned_filename_size); | ||
885 | rc = -ENOMEM; | ||
886 | goto out_unlock; | ||
887 | } | ||
888 | rc = virt_to_scatterlist(s->decrypted_filename, | ||
889 | s->block_aligned_filename_size, &s->dst_sg, 1); | ||
890 | if (rc != 1) { | ||
891 | printk(KERN_ERR "%s: Internal error whilst attempting to " | ||
892 | "convert decrypted filename memory to scatterlist; " | ||
893 | "expected rc = 1; got rc = [%d]. " | ||
894 | "block_aligned_filename_size = [%zd]\n", __func__, rc, | ||
895 | s->block_aligned_filename_size); | ||
896 | goto out_free_unlock; | ||
897 | } | ||
898 | /* The characters in the first block effectively do the job of | ||
899 | * the IV here, so we just use 0's for the IV. Note the | ||
900 | * constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES | ||
901 | * >= ECRYPTFS_MAX_IV_BYTES. */ | ||
902 | memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); | ||
903 | s->desc.info = s->iv; | ||
904 | rc = ecryptfs_find_auth_tok_for_sig(&s->auth_tok, mount_crypt_stat, | ||
905 | s->fnek_sig_hex); | ||
906 | if (rc) { | ||
907 | printk(KERN_ERR "%s: Error attempting to find auth tok for " | ||
908 | "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex, | ||
909 | rc); | ||
910 | goto out_free_unlock; | ||
911 | } | ||
912 | /* TODO: Support other key modules than passphrase for | ||
913 | * filename encryption */ | ||
914 | BUG_ON(s->auth_tok->token_type != ECRYPTFS_PASSWORD); | ||
915 | rc = crypto_blkcipher_setkey( | ||
916 | s->desc.tfm, | ||
917 | s->auth_tok->token.password.session_key_encryption_key, | ||
918 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | ||
919 | if (rc < 0) { | ||
920 | printk(KERN_ERR "%s: Error setting key for crypto context; " | ||
921 | "rc = [%d]. s->auth_tok->token.password.session_key_" | ||
922 | "encryption_key = [0x%p]; mount_crypt_stat->" | ||
923 | "global_default_fn_cipher_key_bytes = [%zd]\n", __func__, | ||
924 | rc, | ||
925 | s->auth_tok->token.password.session_key_encryption_key, | ||
926 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | ||
927 | goto out_free_unlock; | ||
928 | } | ||
929 | rc = crypto_blkcipher_decrypt_iv(&s->desc, &s->dst_sg, &s->src_sg, | ||
930 | s->block_aligned_filename_size); | ||
931 | if (rc) { | ||
932 | printk(KERN_ERR "%s: Error attempting to decrypt filename; " | ||
933 | "rc = [%d]\n", __func__, rc); | ||
934 | goto out_free_unlock; | ||
935 | } | ||
936 | s->i = 0; | ||
937 | while (s->decrypted_filename[s->i] != '\0' | ||
938 | && s->i < s->block_aligned_filename_size) | ||
939 | s->i++; | ||
940 | if (s->i == s->block_aligned_filename_size) { | ||
941 | printk(KERN_WARNING "%s: Invalid tag 70 packet; could not " | ||
942 | "find valid separator between random characters and " | ||
943 | "the filename\n", __func__); | ||
944 | rc = -EINVAL; | ||
945 | goto out_free_unlock; | ||
946 | } | ||
947 | s->i++; | ||
948 | (*filename_size) = (s->block_aligned_filename_size - s->i); | ||
949 | if (!((*filename_size) > 0 && (*filename_size < PATH_MAX))) { | ||
950 | printk(KERN_WARNING "%s: Filename size is [%zd], which is " | ||
951 | "invalid\n", __func__, (*filename_size)); | ||
952 | rc = -EINVAL; | ||
953 | goto out_free_unlock; | ||
954 | } | ||
955 | (*filename) = kmalloc(((*filename_size) + 1), GFP_KERNEL); | ||
956 | if (!(*filename)) { | ||
957 | printk(KERN_ERR "%s: Out of memory whilst attempting to " | ||
958 | "kmalloc [%zd] bytes\n", __func__, | ||
959 | ((*filename_size) + 1)); | ||
960 | rc = -ENOMEM; | ||
961 | goto out_free_unlock; | ||
962 | } | ||
963 | memcpy((*filename), &s->decrypted_filename[s->i], (*filename_size)); | ||
964 | (*filename)[(*filename_size)] = '\0'; | ||
965 | out_free_unlock: | ||
966 | kfree(s->decrypted_filename); | ||
967 | out_unlock: | ||
968 | mutex_unlock(s->tfm_mutex); | ||
969 | out: | ||
970 | if (rc) { | ||
971 | (*packet_size) = 0; | ||
972 | (*filename_size) = 0; | ||
973 | (*filename) = NULL; | ||
974 | } | ||
975 | kfree(s); | ||
976 | return rc; | ||
977 | } | ||
978 | |||
979 | static int | ||
406 | ecryptfs_get_auth_tok_sig(char **sig, struct ecryptfs_auth_tok *auth_tok) | 980 | ecryptfs_get_auth_tok_sig(char **sig, struct ecryptfs_auth_tok *auth_tok) |
407 | { | 981 | { |
408 | int rc = 0; | 982 | int rc = 0; |
@@ -897,30 +1471,6 @@ out: | |||
897 | return rc; | 1471 | return rc; |
898 | } | 1472 | } |
899 | 1473 | ||
900 | static int | ||
901 | ecryptfs_find_global_auth_tok_for_sig( | ||
902 | struct ecryptfs_global_auth_tok **global_auth_tok, | ||
903 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) | ||
904 | { | ||
905 | struct ecryptfs_global_auth_tok *walker; | ||
906 | int rc = 0; | ||
907 | |||
908 | (*global_auth_tok) = NULL; | ||
909 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
910 | list_for_each_entry(walker, | ||
911 | &mount_crypt_stat->global_auth_tok_list, | ||
912 | mount_crypt_stat_list) { | ||
913 | if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) { | ||
914 | (*global_auth_tok) = walker; | ||
915 | goto out; | ||
916 | } | ||
917 | } | ||
918 | rc = -EINVAL; | ||
919 | out: | ||
920 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
921 | return rc; | ||
922 | } | ||
923 | |||
924 | /** | 1474 | /** |
925 | * ecryptfs_verify_version | 1475 | * ecryptfs_verify_version |
926 | * @version: The version number to confirm | 1476 | * @version: The version number to confirm |
@@ -990,43 +1540,6 @@ out: | |||
990 | } | 1540 | } |
991 | 1541 | ||
992 | /** | 1542 | /** |
993 | * ecryptfs_find_auth_tok_for_sig | ||
994 | * @auth_tok: Set to the matching auth_tok; NULL if not found | ||
995 | * @crypt_stat: inode crypt_stat crypto context | ||
996 | * @sig: Sig of auth_tok to find | ||
997 | * | ||
998 | * For now, this function simply looks at the registered auth_tok's | ||
999 | * linked off the mount_crypt_stat, so all the auth_toks that can be | ||
1000 | * used must be registered at mount time. This function could | ||
1001 | * potentially try a lot harder to find auth_tok's (e.g., by calling | ||
1002 | * out to ecryptfsd to dynamically retrieve an auth_tok object) so | ||
1003 | * that static registration of auth_tok's will no longer be necessary. | ||
1004 | * | ||
1005 | * Returns zero on no error; non-zero on error | ||
1006 | */ | ||
1007 | static int | ||
1008 | ecryptfs_find_auth_tok_for_sig( | ||
1009 | struct ecryptfs_auth_tok **auth_tok, | ||
1010 | struct ecryptfs_crypt_stat *crypt_stat, char *sig) | ||
1011 | { | ||
1012 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
1013 | crypt_stat->mount_crypt_stat; | ||
1014 | struct ecryptfs_global_auth_tok *global_auth_tok; | ||
1015 | int rc = 0; | ||
1016 | |||
1017 | (*auth_tok) = NULL; | ||
1018 | if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, | ||
1019 | mount_crypt_stat, sig)) { | ||
1020 | struct key *auth_tok_key; | ||
1021 | |||
1022 | rc = ecryptfs_keyring_auth_tok_for_sig(&auth_tok_key, auth_tok, | ||
1023 | sig); | ||
1024 | } else | ||
1025 | (*auth_tok) = global_auth_tok->global_auth_tok; | ||
1026 | return rc; | ||
1027 | } | ||
1028 | |||
1029 | /** | ||
1030 | * decrypt_passphrase_encrypted_session_key - Decrypt the session key with the given auth_tok. | 1543 | * decrypt_passphrase_encrypted_session_key - Decrypt the session key with the given auth_tok. |
1031 | * @auth_tok: The passphrase authentication token to use to encrypt the FEK | 1544 | * @auth_tok: The passphrase authentication token to use to encrypt the FEK |
1032 | * @crypt_stat: The cryptographic context | 1545 | * @crypt_stat: The cryptographic context |
@@ -1256,7 +1769,8 @@ find_next_matching_auth_tok: | |||
1256 | rc = -EINVAL; | 1769 | rc = -EINVAL; |
1257 | goto out_wipe_list; | 1770 | goto out_wipe_list; |
1258 | } | 1771 | } |
1259 | ecryptfs_find_auth_tok_for_sig(&matching_auth_tok, crypt_stat, | 1772 | ecryptfs_find_auth_tok_for_sig(&matching_auth_tok, |
1773 | crypt_stat->mount_crypt_stat, | ||
1260 | candidate_auth_tok_sig); | 1774 | candidate_auth_tok_sig); |
1261 | if (matching_auth_tok) { | 1775 | if (matching_auth_tok) { |
1262 | found_auth_tok = 1; | 1776 | found_auth_tok = 1; |
@@ -1336,7 +1850,9 @@ pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
1336 | int rc; | 1850 | int rc; |
1337 | 1851 | ||
1338 | rc = write_tag_66_packet(auth_tok->token.private_key.signature, | 1852 | rc = write_tag_66_packet(auth_tok->token.private_key.signature, |
1339 | ecryptfs_code_for_cipher_string(crypt_stat), | 1853 | ecryptfs_code_for_cipher_string( |
1854 | crypt_stat->cipher, | ||
1855 | crypt_stat->key_size), | ||
1340 | crypt_stat, &payload, &payload_len); | 1856 | crypt_stat, &payload, &payload_len); |
1341 | if (rc) { | 1857 | if (rc) { |
1342 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); | 1858 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); |
@@ -1696,7 +2212,8 @@ encrypted_session_key_set: | |||
1696 | dest[(*packet_size)++] = 0x04; /* version 4 */ | 2212 | dest[(*packet_size)++] = 0x04; /* version 4 */ |
1697 | /* TODO: Break from RFC2440 so that arbitrary ciphers can be | 2213 | /* TODO: Break from RFC2440 so that arbitrary ciphers can be |
1698 | * specified with strings */ | 2214 | * specified with strings */ |
1699 | cipher_code = ecryptfs_code_for_cipher_string(crypt_stat); | 2215 | cipher_code = ecryptfs_code_for_cipher_string(crypt_stat->cipher, |
2216 | crypt_stat->key_size); | ||
1700 | if (cipher_code == 0) { | 2217 | if (cipher_code == 0) { |
1701 | ecryptfs_printk(KERN_WARNING, "Unable to generate code for " | 2218 | ecryptfs_printk(KERN_WARNING, "Unable to generate code for " |
1702 | "cipher [%s]\n", crypt_stat->cipher); | 2219 | "cipher [%s]\n", crypt_stat->cipher); |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index fd630713c5c7..789cf2e1be1e 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -206,7 +206,9 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, | |||
206 | ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher, | 206 | ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher, |
207 | ecryptfs_opt_ecryptfs_key_bytes, | 207 | ecryptfs_opt_ecryptfs_key_bytes, |
208 | ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata, | 208 | ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata, |
209 | ecryptfs_opt_encrypted_view, ecryptfs_opt_err }; | 209 | ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, |
210 | ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, | ||
211 | ecryptfs_opt_err }; | ||
210 | 212 | ||
211 | static const match_table_t tokens = { | 213 | static const match_table_t tokens = { |
212 | {ecryptfs_opt_sig, "sig=%s"}, | 214 | {ecryptfs_opt_sig, "sig=%s"}, |
@@ -217,6 +219,9 @@ static const match_table_t tokens = { | |||
217 | {ecryptfs_opt_passthrough, "ecryptfs_passthrough"}, | 219 | {ecryptfs_opt_passthrough, "ecryptfs_passthrough"}, |
218 | {ecryptfs_opt_xattr_metadata, "ecryptfs_xattr_metadata"}, | 220 | {ecryptfs_opt_xattr_metadata, "ecryptfs_xattr_metadata"}, |
219 | {ecryptfs_opt_encrypted_view, "ecryptfs_encrypted_view"}, | 221 | {ecryptfs_opt_encrypted_view, "ecryptfs_encrypted_view"}, |
222 | {ecryptfs_opt_fnek_sig, "ecryptfs_fnek_sig=%s"}, | ||
223 | {ecryptfs_opt_fn_cipher, "ecryptfs_fn_cipher=%s"}, | ||
224 | {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, | ||
220 | {ecryptfs_opt_err, NULL} | 225 | {ecryptfs_opt_err, NULL} |
221 | }; | 226 | }; |
222 | 227 | ||
@@ -281,8 +286,11 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
281 | int rc = 0; | 286 | int rc = 0; |
282 | int sig_set = 0; | 287 | int sig_set = 0; |
283 | int cipher_name_set = 0; | 288 | int cipher_name_set = 0; |
289 | int fn_cipher_name_set = 0; | ||
284 | int cipher_key_bytes; | 290 | int cipher_key_bytes; |
285 | int cipher_key_bytes_set = 0; | 291 | int cipher_key_bytes_set = 0; |
292 | int fn_cipher_key_bytes; | ||
293 | int fn_cipher_key_bytes_set = 0; | ||
286 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 294 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
287 | &ecryptfs_superblock_to_private(sb)->mount_crypt_stat; | 295 | &ecryptfs_superblock_to_private(sb)->mount_crypt_stat; |
288 | substring_t args[MAX_OPT_ARGS]; | 296 | substring_t args[MAX_OPT_ARGS]; |
@@ -290,7 +298,12 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
290 | char *sig_src; | 298 | char *sig_src; |
291 | char *cipher_name_dst; | 299 | char *cipher_name_dst; |
292 | char *cipher_name_src; | 300 | char *cipher_name_src; |
301 | char *fn_cipher_name_dst; | ||
302 | char *fn_cipher_name_src; | ||
303 | char *fnek_dst; | ||
304 | char *fnek_src; | ||
293 | char *cipher_key_bytes_src; | 305 | char *cipher_key_bytes_src; |
306 | char *fn_cipher_key_bytes_src; | ||
294 | 307 | ||
295 | if (!options) { | 308 | if (!options) { |
296 | rc = -EINVAL; | 309 | rc = -EINVAL; |
@@ -322,10 +335,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
322 | global_default_cipher_name; | 335 | global_default_cipher_name; |
323 | strncpy(cipher_name_dst, cipher_name_src, | 336 | strncpy(cipher_name_dst, cipher_name_src, |
324 | ECRYPTFS_MAX_CIPHER_NAME_SIZE); | 337 | ECRYPTFS_MAX_CIPHER_NAME_SIZE); |
325 | ecryptfs_printk(KERN_DEBUG, | 338 | cipher_name_dst[ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; |
326 | "The mount_crypt_stat " | ||
327 | "global_default_cipher_name set to: " | ||
328 | "[%s]\n", cipher_name_dst); | ||
329 | cipher_name_set = 1; | 339 | cipher_name_set = 1; |
330 | break; | 340 | break; |
331 | case ecryptfs_opt_ecryptfs_key_bytes: | 341 | case ecryptfs_opt_ecryptfs_key_bytes: |
@@ -335,11 +345,6 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
335 | &cipher_key_bytes_src, 0); | 345 | &cipher_key_bytes_src, 0); |
336 | mount_crypt_stat->global_default_cipher_key_size = | 346 | mount_crypt_stat->global_default_cipher_key_size = |
337 | cipher_key_bytes; | 347 | cipher_key_bytes; |
338 | ecryptfs_printk(KERN_DEBUG, | ||
339 | "The mount_crypt_stat " | ||
340 | "global_default_cipher_key_size " | ||
341 | "set to: [%d]\n", mount_crypt_stat-> | ||
342 | global_default_cipher_key_size); | ||
343 | cipher_key_bytes_set = 1; | 348 | cipher_key_bytes_set = 1; |
344 | break; | 349 | break; |
345 | case ecryptfs_opt_passthrough: | 350 | case ecryptfs_opt_passthrough: |
@@ -356,11 +361,51 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
356 | mount_crypt_stat->flags |= | 361 | mount_crypt_stat->flags |= |
357 | ECRYPTFS_ENCRYPTED_VIEW_ENABLED; | 362 | ECRYPTFS_ENCRYPTED_VIEW_ENABLED; |
358 | break; | 363 | break; |
364 | case ecryptfs_opt_fnek_sig: | ||
365 | fnek_src = args[0].from; | ||
366 | fnek_dst = | ||
367 | mount_crypt_stat->global_default_fnek_sig; | ||
368 | strncpy(fnek_dst, fnek_src, ECRYPTFS_SIG_SIZE_HEX); | ||
369 | mount_crypt_stat->global_default_fnek_sig[ | ||
370 | ECRYPTFS_SIG_SIZE_HEX] = '\0'; | ||
371 | rc = ecryptfs_add_global_auth_tok( | ||
372 | mount_crypt_stat, | ||
373 | mount_crypt_stat->global_default_fnek_sig); | ||
374 | if (rc) { | ||
375 | printk(KERN_ERR "Error attempting to register " | ||
376 | "global fnek sig [%s]; rc = [%d]\n", | ||
377 | mount_crypt_stat->global_default_fnek_sig, | ||
378 | rc); | ||
379 | goto out; | ||
380 | } | ||
381 | mount_crypt_stat->flags |= | ||
382 | (ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES | ||
383 | | ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK); | ||
384 | break; | ||
385 | case ecryptfs_opt_fn_cipher: | ||
386 | fn_cipher_name_src = args[0].from; | ||
387 | fn_cipher_name_dst = | ||
388 | mount_crypt_stat->global_default_fn_cipher_name; | ||
389 | strncpy(fn_cipher_name_dst, fn_cipher_name_src, | ||
390 | ECRYPTFS_MAX_CIPHER_NAME_SIZE); | ||
391 | mount_crypt_stat->global_default_fn_cipher_name[ | ||
392 | ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; | ||
393 | fn_cipher_name_set = 1; | ||
394 | break; | ||
395 | case ecryptfs_opt_fn_cipher_key_bytes: | ||
396 | fn_cipher_key_bytes_src = args[0].from; | ||
397 | fn_cipher_key_bytes = | ||
398 | (int)simple_strtol(fn_cipher_key_bytes_src, | ||
399 | &fn_cipher_key_bytes_src, 0); | ||
400 | mount_crypt_stat->global_default_fn_cipher_key_bytes = | ||
401 | fn_cipher_key_bytes; | ||
402 | fn_cipher_key_bytes_set = 1; | ||
403 | break; | ||
359 | case ecryptfs_opt_err: | 404 | case ecryptfs_opt_err: |
360 | default: | 405 | default: |
361 | ecryptfs_printk(KERN_WARNING, | 406 | printk(KERN_WARNING |
362 | "eCryptfs: unrecognized option '%s'\n", | 407 | "%s: eCryptfs: unrecognized option [%s]\n", |
363 | p); | 408 | __func__, p); |
364 | } | 409 | } |
365 | } | 410 | } |
366 | if (!sig_set) { | 411 | if (!sig_set) { |
@@ -374,33 +419,60 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
374 | int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); | 419 | int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); |
375 | 420 | ||
376 | BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE); | 421 | BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE); |
377 | |||
378 | strcpy(mount_crypt_stat->global_default_cipher_name, | 422 | strcpy(mount_crypt_stat->global_default_cipher_name, |
379 | ECRYPTFS_DEFAULT_CIPHER); | 423 | ECRYPTFS_DEFAULT_CIPHER); |
380 | } | 424 | } |
381 | if (!cipher_key_bytes_set) { | 425 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) |
426 | && !fn_cipher_name_set) | ||
427 | strcpy(mount_crypt_stat->global_default_fn_cipher_name, | ||
428 | mount_crypt_stat->global_default_cipher_name); | ||
429 | if (!cipher_key_bytes_set) | ||
382 | mount_crypt_stat->global_default_cipher_key_size = 0; | 430 | mount_crypt_stat->global_default_cipher_key_size = 0; |
383 | } | 431 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) |
432 | && !fn_cipher_key_bytes_set) | ||
433 | mount_crypt_stat->global_default_fn_cipher_key_bytes = | ||
434 | mount_crypt_stat->global_default_cipher_key_size; | ||
384 | mutex_lock(&key_tfm_list_mutex); | 435 | mutex_lock(&key_tfm_list_mutex); |
385 | if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, | 436 | if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, |
386 | NULL)) | 437 | NULL)) { |
387 | rc = ecryptfs_add_new_key_tfm( | 438 | rc = ecryptfs_add_new_key_tfm( |
388 | NULL, mount_crypt_stat->global_default_cipher_name, | 439 | NULL, mount_crypt_stat->global_default_cipher_name, |
389 | mount_crypt_stat->global_default_cipher_key_size); | 440 | mount_crypt_stat->global_default_cipher_key_size); |
390 | mutex_unlock(&key_tfm_list_mutex); | 441 | if (rc) { |
391 | if (rc) { | 442 | printk(KERN_ERR "Error attempting to initialize " |
392 | printk(KERN_ERR "Error attempting to initialize cipher with " | 443 | "cipher with name = [%s] and key size = [%td]; " |
393 | "name = [%s] and key size = [%td]; rc = [%d]\n", | 444 | "rc = [%d]\n", |
394 | mount_crypt_stat->global_default_cipher_name, | 445 | mount_crypt_stat->global_default_cipher_name, |
395 | mount_crypt_stat->global_default_cipher_key_size, rc); | 446 | mount_crypt_stat->global_default_cipher_key_size, |
396 | rc = -EINVAL; | 447 | rc); |
397 | goto out; | 448 | rc = -EINVAL; |
449 | mutex_unlock(&key_tfm_list_mutex); | ||
450 | goto out; | ||
451 | } | ||
398 | } | 452 | } |
453 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) | ||
454 | && !ecryptfs_tfm_exists( | ||
455 | mount_crypt_stat->global_default_fn_cipher_name, NULL)) { | ||
456 | rc = ecryptfs_add_new_key_tfm( | ||
457 | NULL, mount_crypt_stat->global_default_fn_cipher_name, | ||
458 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | ||
459 | if (rc) { | ||
460 | printk(KERN_ERR "Error attempting to initialize " | ||
461 | "cipher with name = [%s] and key size = [%td]; " | ||
462 | "rc = [%d]\n", | ||
463 | mount_crypt_stat->global_default_fn_cipher_name, | ||
464 | mount_crypt_stat->global_default_fn_cipher_key_bytes, | ||
465 | rc); | ||
466 | rc = -EINVAL; | ||
467 | mutex_unlock(&key_tfm_list_mutex); | ||
468 | goto out; | ||
469 | } | ||
470 | } | ||
471 | mutex_unlock(&key_tfm_list_mutex); | ||
399 | rc = ecryptfs_init_global_auth_toks(mount_crypt_stat); | 472 | rc = ecryptfs_init_global_auth_toks(mount_crypt_stat); |
400 | if (rc) { | 473 | if (rc) |
401 | printk(KERN_WARNING "One or more global auth toks could not " | 474 | printk(KERN_WARNING "One or more global auth toks could not " |
402 | "properly register; rc = [%d]\n", rc); | 475 | "properly register; rc = [%d]\n", rc); |
403 | } | ||
404 | out: | 476 | out: |
405 | return rc; | 477 | return rc; |
406 | } | 478 | } |
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index 6913f727624d..96ef51489e01 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -193,7 +193,7 @@ ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | |||
193 | (*daemon) = kzalloc(sizeof(**daemon), GFP_KERNEL); | 193 | (*daemon) = kzalloc(sizeof(**daemon), GFP_KERNEL); |
194 | if (!(*daemon)) { | 194 | if (!(*daemon)) { |
195 | rc = -ENOMEM; | 195 | rc = -ENOMEM; |
196 | printk(KERN_ERR "%s: Failed to allocate [%Zd] bytes of " | 196 | printk(KERN_ERR "%s: Failed to allocate [%zd] bytes of " |
197 | "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); | 197 | "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); |
198 | goto out; | 198 | goto out; |
199 | } | 199 | } |
@@ -435,7 +435,7 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
435 | msg_ctx->msg = kmalloc(msg_size, GFP_KERNEL); | 435 | msg_ctx->msg = kmalloc(msg_size, GFP_KERNEL); |
436 | if (!msg_ctx->msg) { | 436 | if (!msg_ctx->msg) { |
437 | rc = -ENOMEM; | 437 | rc = -ENOMEM; |
438 | printk(KERN_ERR "%s: Failed to allocate [%Zd] bytes of " | 438 | printk(KERN_ERR "%s: Failed to allocate [%zd] bytes of " |
439 | "GFP_KERNEL memory\n", __func__, msg_size); | 439 | "GFP_KERNEL memory\n", __func__, msg_size); |
440 | goto unlock; | 440 | goto unlock; |
441 | } | 441 | } |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index efd95a0ed1ea..a67fea655f49 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -199,7 +199,7 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, | |||
199 | if (!msg_ctx->msg) { | 199 | if (!msg_ctx->msg) { |
200 | rc = -ENOMEM; | 200 | rc = -ENOMEM; |
201 | printk(KERN_ERR "%s: Out of memory whilst attempting " | 201 | printk(KERN_ERR "%s: Out of memory whilst attempting " |
202 | "to kmalloc(%Zd, GFP_KERNEL)\n", __func__, | 202 | "to kmalloc(%zd, GFP_KERNEL)\n", __func__, |
203 | (sizeof(*msg_ctx->msg) + data_size)); | 203 | (sizeof(*msg_ctx->msg) + data_size)); |
204 | goto out_unlock; | 204 | goto out_unlock; |
205 | } | 205 | } |
@@ -322,7 +322,7 @@ check_list: | |||
322 | if (count < total_length) { | 322 | if (count < total_length) { |
323 | rc = 0; | 323 | rc = 0; |
324 | printk(KERN_WARNING "%s: Only given user buffer of " | 324 | printk(KERN_WARNING "%s: Only given user buffer of " |
325 | "size [%Zd], but we need [%Zd] to read the " | 325 | "size [%zd], but we need [%zd] to read the " |
326 | "pending message\n", __func__, count, total_length); | 326 | "pending message\n", __func__, count, total_length); |
327 | goto out_unlock_msg_ctx; | 327 | goto out_unlock_msg_ctx; |
328 | } | 328 | } |
@@ -376,7 +376,7 @@ static int ecryptfs_miscdev_response(char *data, size_t data_size, | |||
376 | 376 | ||
377 | if ((sizeof(*msg) + msg->data_len) != data_size) { | 377 | if ((sizeof(*msg) + msg->data_len) != data_size) { |
378 | printk(KERN_WARNING "%s: (sizeof(*msg) + msg->data_len) = " | 378 | printk(KERN_WARNING "%s: (sizeof(*msg) + msg->data_len) = " |
379 | "[%Zd]; data_size = [%Zd]. Invalid packet.\n", __func__, | 379 | "[%zd]; data_size = [%zd]. Invalid packet.\n", __func__, |
380 | (sizeof(*msg) + msg->data_len), data_size); | 380 | (sizeof(*msg) + msg->data_len), data_size); |
381 | rc = -EINVAL; | 381 | rc = -EINVAL; |
382 | goto out; | 382 | goto out; |
@@ -421,7 +421,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
421 | data = kmalloc(count, GFP_KERNEL); | 421 | data = kmalloc(count, GFP_KERNEL); |
422 | if (!data) { | 422 | if (!data) { |
423 | printk(KERN_ERR "%s: Out of memory whilst attempting to " | 423 | printk(KERN_ERR "%s: Out of memory whilst attempting to " |
424 | "kmalloc([%Zd], GFP_KERNEL)\n", __func__, count); | 424 | "kmalloc([%zd], GFP_KERNEL)\n", __func__, count); |
425 | goto out; | 425 | goto out; |
426 | } | 426 | } |
427 | rc = copy_from_user(data, buf, count); | 427 | rc = copy_from_user(data, buf, count); |
@@ -436,8 +436,8 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
436 | case ECRYPTFS_MSG_RESPONSE: | 436 | case ECRYPTFS_MSG_RESPONSE: |
437 | if (count < (1 + 4 + 1 + sizeof(struct ecryptfs_message))) { | 437 | if (count < (1 + 4 + 1 + sizeof(struct ecryptfs_message))) { |
438 | printk(KERN_WARNING "%s: Minimum acceptable packet " | 438 | printk(KERN_WARNING "%s: Minimum acceptable packet " |
439 | "size is [%Zd], but amount of data written is " | 439 | "size is [%zd], but amount of data written is " |
440 | "only [%Zd]. Discarding response packet.\n", | 440 | "only [%zd]. Discarding response packet.\n", |
441 | __func__, | 441 | __func__, |
442 | (1 + 4 + 1 + sizeof(struct ecryptfs_message)), | 442 | (1 + 4 + 1 + sizeof(struct ecryptfs_message)), |
443 | count); | 443 | count); |
@@ -455,9 +455,9 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
455 | } | 455 | } |
456 | i += packet_size_length; | 456 | i += packet_size_length; |
457 | if ((1 + 4 + packet_size_length + packet_size) != count) { | 457 | if ((1 + 4 + packet_size_length + packet_size) != count) { |
458 | printk(KERN_WARNING "%s: (1 + packet_size_length([%Zd])" | 458 | printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])" |
459 | " + packet_size([%Zd]))([%Zd]) != " | 459 | " + packet_size([%zd]))([%zd]) != " |
460 | "count([%Zd]). Invalid packet format.\n", | 460 | "count([%zd]). Invalid packet format.\n", |
461 | __func__, packet_size_length, packet_size, | 461 | __func__, packet_size_length, packet_size, |
462 | (1 + packet_size_length + packet_size), count); | 462 | (1 + packet_size_length + packet_size), count); |
463 | goto out_free; | 463 | goto out_free; |
@@ -232,13 +232,13 @@ static void flush_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
232 | 232 | ||
233 | static int __bprm_mm_init(struct linux_binprm *bprm) | 233 | static int __bprm_mm_init(struct linux_binprm *bprm) |
234 | { | 234 | { |
235 | int err = -ENOMEM; | 235 | int err; |
236 | struct vm_area_struct *vma = NULL; | 236 | struct vm_area_struct *vma = NULL; |
237 | struct mm_struct *mm = bprm->mm; | 237 | struct mm_struct *mm = bprm->mm; |
238 | 238 | ||
239 | bprm->vma = vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); | 239 | bprm->vma = vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
240 | if (!vma) | 240 | if (!vma) |
241 | goto err; | 241 | return -ENOMEM; |
242 | 242 | ||
243 | down_write(&mm->mmap_sem); | 243 | down_write(&mm->mmap_sem); |
244 | vma->vm_mm = mm; | 244 | vma->vm_mm = mm; |
@@ -251,28 +251,20 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
251 | */ | 251 | */ |
252 | vma->vm_end = STACK_TOP_MAX; | 252 | vma->vm_end = STACK_TOP_MAX; |
253 | vma->vm_start = vma->vm_end - PAGE_SIZE; | 253 | vma->vm_start = vma->vm_end - PAGE_SIZE; |
254 | |||
255 | vma->vm_flags = VM_STACK_FLAGS; | 254 | vma->vm_flags = VM_STACK_FLAGS; |
256 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | 255 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
257 | err = insert_vm_struct(mm, vma); | 256 | err = insert_vm_struct(mm, vma); |
258 | if (err) { | 257 | if (err) |
259 | up_write(&mm->mmap_sem); | ||
260 | goto err; | 258 | goto err; |
261 | } | ||
262 | 259 | ||
263 | mm->stack_vm = mm->total_vm = 1; | 260 | mm->stack_vm = mm->total_vm = 1; |
264 | up_write(&mm->mmap_sem); | 261 | up_write(&mm->mmap_sem); |
265 | |||
266 | bprm->p = vma->vm_end - sizeof(void *); | 262 | bprm->p = vma->vm_end - sizeof(void *); |
267 | |||
268 | return 0; | 263 | return 0; |
269 | |||
270 | err: | 264 | err: |
271 | if (vma) { | 265 | up_write(&mm->mmap_sem); |
272 | bprm->vma = NULL; | 266 | bprm->vma = NULL; |
273 | kmem_cache_free(vm_area_cachep, vma); | 267 | kmem_cache_free(vm_area_cachep, vma); |
274 | } | ||
275 | |||
276 | return err; | 268 | return err; |
277 | } | 269 | } |
278 | 270 | ||
@@ -1694,7 +1686,7 @@ int get_dumpable(struct mm_struct *mm) | |||
1694 | return (ret >= 2) ? 2 : ret; | 1686 | return (ret >= 2) ? 2 : ret; |
1695 | } | 1687 | } |
1696 | 1688 | ||
1697 | int do_coredump(long signr, int exit_code, struct pt_regs * regs) | 1689 | void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
1698 | { | 1690 | { |
1699 | struct core_state core_state; | 1691 | struct core_state core_state; |
1700 | char corename[CORENAME_MAX_SIZE + 1]; | 1692 | char corename[CORENAME_MAX_SIZE + 1]; |
@@ -1778,6 +1770,11 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1778 | 1770 | ||
1779 | if (ispipe) { | 1771 | if (ispipe) { |
1780 | helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc); | 1772 | helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc); |
1773 | if (!helper_argv) { | ||
1774 | printk(KERN_WARNING "%s failed to allocate memory\n", | ||
1775 | __func__); | ||
1776 | goto fail_unlock; | ||
1777 | } | ||
1781 | /* Terminate the string before the first option */ | 1778 | /* Terminate the string before the first option */ |
1782 | delimit = strchr(corename, ' '); | 1779 | delimit = strchr(corename, ' '); |
1783 | if (delimit) | 1780 | if (delimit) |
@@ -1845,5 +1842,5 @@ fail_unlock: | |||
1845 | put_cred(cred); | 1842 | put_cred(cred); |
1846 | coredump_finish(mm); | 1843 | coredump_finish(mm); |
1847 | fail: | 1844 | fail: |
1848 | return retval; | 1845 | return; |
1849 | } | 1846 | } |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index b0537c827024..6c46c648430d 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1225,11 +1225,11 @@ do { \ | |||
1225 | } while (0) | 1225 | } while (0) |
1226 | 1226 | ||
1227 | #ifdef CONFIG_SMP | 1227 | #ifdef CONFIG_SMP |
1228 | /* Each CPU can accumulate FBC_BATCH blocks in their local | 1228 | /* Each CPU can accumulate percpu_counter_batch blocks in their local |
1229 | * counters. So we need to make sure we have free blocks more | 1229 | * counters. So we need to make sure we have free blocks more |
1230 | * than FBC_BATCH * nr_cpu_ids. Also add a window of 4 times. | 1230 | * than percpu_counter_batch * nr_cpu_ids. Also add a window of 4 times. |
1231 | */ | 1231 | */ |
1232 | #define EXT4_FREEBLOCKS_WATERMARK (4 * (FBC_BATCH * nr_cpu_ids)) | 1232 | #define EXT4_FREEBLOCKS_WATERMARK (4 * (percpu_counter_batch * nr_cpu_ids)) |
1233 | #else | 1233 | #else |
1234 | #define EXT4_FREEBLOCKS_WATERMARK 0 | 1234 | #define EXT4_FREEBLOCKS_WATERMARK 0 |
1235 | #endif | 1235 | #endif |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 6702a49992a6..98d3fe7057ef 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2498,7 +2498,7 @@ static int ext4_nonda_switch(struct super_block *sb) | |||
2498 | /* | 2498 | /* |
2499 | * switch to non delalloc mode if we are running low | 2499 | * switch to non delalloc mode if we are running low |
2500 | * on free block. The free block accounting via percpu | 2500 | * on free block. The free block accounting via percpu |
2501 | * counters can get slightly wrong with FBC_BATCH getting | 2501 | * counters can get slightly wrong with percpu_counter_batch getting |
2502 | * accumulated on each CPU without updating global counters | 2502 | * accumulated on each CPU without updating global counters |
2503 | * Delalloc need an accurate free block accounting. So switch | 2503 | * Delalloc need an accurate free block accounting. So switch |
2504 | * to non delalloc when we are near to error range. | 2504 | * to non delalloc when we are near to error range. |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index d0ff0b8cf309..e5eaa62fd17f 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -421,9 +421,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
421 | * If we're a pdlfush thread, then implement pdflush collision avoidance | 421 | * If we're a pdlfush thread, then implement pdflush collision avoidance |
422 | * against the entire list. | 422 | * against the entire list. |
423 | * | 423 | * |
424 | * WB_SYNC_HOLD is a hack for sys_sync(): reattach the inode to sb->s_dirty so | ||
425 | * that it can be located for waiting on in __writeback_single_inode(). | ||
426 | * | ||
427 | * If `bdi' is non-zero then we're being asked to writeback a specific queue. | 424 | * If `bdi' is non-zero then we're being asked to writeback a specific queue. |
428 | * This function assumes that the blockdev superblock's inodes are backed by | 425 | * This function assumes that the blockdev superblock's inodes are backed by |
429 | * a variety of queues, so all inodes are searched. For other superblocks, | 426 | * a variety of queues, so all inodes are searched. For other superblocks, |
@@ -443,6 +440,7 @@ void generic_sync_sb_inodes(struct super_block *sb, | |||
443 | struct writeback_control *wbc) | 440 | struct writeback_control *wbc) |
444 | { | 441 | { |
445 | const unsigned long start = jiffies; /* livelock avoidance */ | 442 | const unsigned long start = jiffies; /* livelock avoidance */ |
443 | int sync = wbc->sync_mode == WB_SYNC_ALL; | ||
446 | 444 | ||
447 | spin_lock(&inode_lock); | 445 | spin_lock(&inode_lock); |
448 | if (!wbc->for_kupdate || list_empty(&sb->s_io)) | 446 | if (!wbc->for_kupdate || list_empty(&sb->s_io)) |
@@ -499,10 +497,6 @@ void generic_sync_sb_inodes(struct super_block *sb, | |||
499 | __iget(inode); | 497 | __iget(inode); |
500 | pages_skipped = wbc->pages_skipped; | 498 | pages_skipped = wbc->pages_skipped; |
501 | __writeback_single_inode(inode, wbc); | 499 | __writeback_single_inode(inode, wbc); |
502 | if (wbc->sync_mode == WB_SYNC_HOLD) { | ||
503 | inode->dirtied_when = jiffies; | ||
504 | list_move(&inode->i_list, &sb->s_dirty); | ||
505 | } | ||
506 | if (current_is_pdflush()) | 500 | if (current_is_pdflush()) |
507 | writeback_release(bdi); | 501 | writeback_release(bdi); |
508 | if (wbc->pages_skipped != pages_skipped) { | 502 | if (wbc->pages_skipped != pages_skipped) { |
@@ -523,7 +517,49 @@ void generic_sync_sb_inodes(struct super_block *sb, | |||
523 | if (!list_empty(&sb->s_more_io)) | 517 | if (!list_empty(&sb->s_more_io)) |
524 | wbc->more_io = 1; | 518 | wbc->more_io = 1; |
525 | } | 519 | } |
526 | spin_unlock(&inode_lock); | 520 | |
521 | if (sync) { | ||
522 | struct inode *inode, *old_inode = NULL; | ||
523 | |||
524 | /* | ||
525 | * Data integrity sync. Must wait for all pages under writeback, | ||
526 | * because there may have been pages dirtied before our sync | ||
527 | * call, but which had writeout started before we write it out. | ||
528 | * In which case, the inode may not be on the dirty list, but | ||
529 | * we still have to wait for that writeout. | ||
530 | */ | ||
531 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { | ||
532 | struct address_space *mapping; | ||
533 | |||
534 | if (inode->i_state & (I_FREEING|I_WILL_FREE)) | ||
535 | continue; | ||
536 | mapping = inode->i_mapping; | ||
537 | if (mapping->nrpages == 0) | ||
538 | continue; | ||
539 | __iget(inode); | ||
540 | spin_unlock(&inode_lock); | ||
541 | /* | ||
542 | * We hold a reference to 'inode' so it couldn't have | ||
543 | * been removed from s_inodes list while we dropped the | ||
544 | * inode_lock. We cannot iput the inode now as we can | ||
545 | * be holding the last reference and we cannot iput it | ||
546 | * under inode_lock. So we keep the reference and iput | ||
547 | * it later. | ||
548 | */ | ||
549 | iput(old_inode); | ||
550 | old_inode = inode; | ||
551 | |||
552 | filemap_fdatawait(mapping); | ||
553 | |||
554 | cond_resched(); | ||
555 | |||
556 | spin_lock(&inode_lock); | ||
557 | } | ||
558 | spin_unlock(&inode_lock); | ||
559 | iput(old_inode); | ||
560 | } else | ||
561 | spin_unlock(&inode_lock); | ||
562 | |||
527 | return; /* Leave any unwritten inodes on s_io */ | 563 | return; /* Leave any unwritten inodes on s_io */ |
528 | } | 564 | } |
529 | EXPORT_SYMBOL_GPL(generic_sync_sb_inodes); | 565 | EXPORT_SYMBOL_GPL(generic_sync_sb_inodes); |
@@ -588,8 +624,7 @@ restart: | |||
588 | 624 | ||
589 | /* | 625 | /* |
590 | * writeback and wait upon the filesystem's dirty inodes. The caller will | 626 | * writeback and wait upon the filesystem's dirty inodes. The caller will |
591 | * do this in two passes - one to write, and one to wait. WB_SYNC_HOLD is | 627 | * do this in two passes - one to write, and one to wait. |
592 | * used to park the written inodes on sb->s_dirty for the wait pass. | ||
593 | * | 628 | * |
594 | * A finite limit is set on the number of pages which will be written. | 629 | * A finite limit is set on the number of pages which will be written. |
595 | * To prevent infinite livelock of sys_sync(). | 630 | * To prevent infinite livelock of sys_sync(). |
@@ -600,30 +635,21 @@ restart: | |||
600 | void sync_inodes_sb(struct super_block *sb, int wait) | 635 | void sync_inodes_sb(struct super_block *sb, int wait) |
601 | { | 636 | { |
602 | struct writeback_control wbc = { | 637 | struct writeback_control wbc = { |
603 | .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_HOLD, | 638 | .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_NONE, |
604 | .range_start = 0, | 639 | .range_start = 0, |
605 | .range_end = LLONG_MAX, | 640 | .range_end = LLONG_MAX, |
606 | }; | 641 | }; |
607 | unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); | ||
608 | unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); | ||
609 | 642 | ||
610 | wbc.nr_to_write = nr_dirty + nr_unstable + | 643 | if (!wait) { |
611 | (inodes_stat.nr_inodes - inodes_stat.nr_unused) + | 644 | unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); |
612 | nr_dirty + nr_unstable; | 645 | unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); |
613 | wbc.nr_to_write += wbc.nr_to_write / 2; /* Bit more for luck */ | ||
614 | sync_sb_inodes(sb, &wbc); | ||
615 | } | ||
616 | 646 | ||
617 | /* | 647 | wbc.nr_to_write = nr_dirty + nr_unstable + |
618 | * Rather lame livelock avoidance. | 648 | (inodes_stat.nr_inodes - inodes_stat.nr_unused); |
619 | */ | 649 | } else |
620 | static void set_sb_syncing(int val) | 650 | wbc.nr_to_write = LONG_MAX; /* doesn't actually matter */ |
621 | { | 651 | |
622 | struct super_block *sb; | 652 | sync_sb_inodes(sb, &wbc); |
623 | spin_lock(&sb_lock); | ||
624 | list_for_each_entry_reverse(sb, &super_blocks, s_list) | ||
625 | sb->s_syncing = val; | ||
626 | spin_unlock(&sb_lock); | ||
627 | } | 653 | } |
628 | 654 | ||
629 | /** | 655 | /** |
@@ -652,9 +678,6 @@ static void __sync_inodes(int wait) | |||
652 | spin_lock(&sb_lock); | 678 | spin_lock(&sb_lock); |
653 | restart: | 679 | restart: |
654 | list_for_each_entry(sb, &super_blocks, s_list) { | 680 | list_for_each_entry(sb, &super_blocks, s_list) { |
655 | if (sb->s_syncing) | ||
656 | continue; | ||
657 | sb->s_syncing = 1; | ||
658 | sb->s_count++; | 681 | sb->s_count++; |
659 | spin_unlock(&sb_lock); | 682 | spin_unlock(&sb_lock); |
660 | down_read(&sb->s_umount); | 683 | down_read(&sb->s_umount); |
@@ -672,13 +695,10 @@ restart: | |||
672 | 695 | ||
673 | void sync_inodes(int wait) | 696 | void sync_inodes(int wait) |
674 | { | 697 | { |
675 | set_sb_syncing(0); | ||
676 | __sync_inodes(0); | 698 | __sync_inodes(0); |
677 | 699 | ||
678 | if (wait) { | 700 | if (wait) |
679 | set_sb_syncing(0); | ||
680 | __sync_inodes(1); | 701 | __sync_inodes(1); |
681 | } | ||
682 | } | 702 | } |
683 | 703 | ||
684 | /** | 704 | /** |
diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 4f3cab321415..99c99dfb0373 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | FUSE: Filesystem in Userspace | 2 | FUSE: Filesystem in Userspace |
3 | Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> | 3 | Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> |
4 | 4 | ||
5 | This program can be distributed under the terms of the GNU GPL. | 5 | This program can be distributed under the terms of the GNU GPL. |
6 | See the file COPYING. | 6 | See the file COPYING. |
@@ -48,11 +48,13 @@ static ssize_t fuse_conn_waiting_read(struct file *file, char __user *buf, | |||
48 | size_t size; | 48 | size_t size; |
49 | 49 | ||
50 | if (!*ppos) { | 50 | if (!*ppos) { |
51 | long value; | ||
51 | struct fuse_conn *fc = fuse_ctl_file_conn_get(file); | 52 | struct fuse_conn *fc = fuse_ctl_file_conn_get(file); |
52 | if (!fc) | 53 | if (!fc) |
53 | return 0; | 54 | return 0; |
54 | 55 | ||
55 | file->private_data=(void *)(long)atomic_read(&fc->num_waiting); | 56 | value = atomic_read(&fc->num_waiting); |
57 | file->private_data = (void *)value; | ||
56 | fuse_conn_put(fc); | 58 | fuse_conn_put(fc); |
57 | } | 59 | } |
58 | size = sprintf(tmp, "%ld\n", (long)file->private_data); | 60 | size = sprintf(tmp, "%ld\n", (long)file->private_data); |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index fba571648a8e..e0c7ada08a1f 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | FUSE: Filesystem in Userspace | 2 | FUSE: Filesystem in Userspace |
3 | Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> | 3 | Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> |
4 | 4 | ||
5 | This program can be distributed under the terms of the GNU GPL. | 5 | This program can be distributed under the terms of the GNU GPL. |
6 | See the file COPYING. | 6 | See the file COPYING. |
@@ -269,7 +269,7 @@ static void flush_bg_queue(struct fuse_conn *fc) | |||
269 | * Called with fc->lock, unlocks it | 269 | * Called with fc->lock, unlocks it |
270 | */ | 270 | */ |
271 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) | 271 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) |
272 | __releases(fc->lock) | 272 | __releases(&fc->lock) |
273 | { | 273 | { |
274 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; | 274 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; |
275 | req->end = NULL; | 275 | req->end = NULL; |
@@ -293,13 +293,13 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) | |||
293 | wake_up(&req->waitq); | 293 | wake_up(&req->waitq); |
294 | if (end) | 294 | if (end) |
295 | end(fc, req); | 295 | end(fc, req); |
296 | else | 296 | fuse_put_request(fc, req); |
297 | fuse_put_request(fc, req); | ||
298 | } | 297 | } |
299 | 298 | ||
300 | static void wait_answer_interruptible(struct fuse_conn *fc, | 299 | static void wait_answer_interruptible(struct fuse_conn *fc, |
301 | struct fuse_req *req) | 300 | struct fuse_req *req) |
302 | __releases(fc->lock) __acquires(fc->lock) | 301 | __releases(&fc->lock) |
302 | __acquires(&fc->lock) | ||
303 | { | 303 | { |
304 | if (signal_pending(current)) | 304 | if (signal_pending(current)) |
305 | return; | 305 | return; |
@@ -317,7 +317,8 @@ static void queue_interrupt(struct fuse_conn *fc, struct fuse_req *req) | |||
317 | } | 317 | } |
318 | 318 | ||
319 | static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) | 319 | static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) |
320 | __releases(fc->lock) __acquires(fc->lock) | 320 | __releases(&fc->lock) |
321 | __acquires(&fc->lock) | ||
321 | { | 322 | { |
322 | if (!fc->no_interrupt) { | 323 | if (!fc->no_interrupt) { |
323 | /* Any signal may interrupt this */ | 324 | /* Any signal may interrupt this */ |
@@ -380,7 +381,7 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) | |||
380 | } | 381 | } |
381 | } | 382 | } |
382 | 383 | ||
383 | void request_send(struct fuse_conn *fc, struct fuse_req *req) | 384 | void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) |
384 | { | 385 | { |
385 | req->isreply = 1; | 386 | req->isreply = 1; |
386 | spin_lock(&fc->lock); | 387 | spin_lock(&fc->lock); |
@@ -399,8 +400,8 @@ void request_send(struct fuse_conn *fc, struct fuse_req *req) | |||
399 | spin_unlock(&fc->lock); | 400 | spin_unlock(&fc->lock); |
400 | } | 401 | } |
401 | 402 | ||
402 | static void request_send_nowait_locked(struct fuse_conn *fc, | 403 | static void fuse_request_send_nowait_locked(struct fuse_conn *fc, |
403 | struct fuse_req *req) | 404 | struct fuse_req *req) |
404 | { | 405 | { |
405 | req->background = 1; | 406 | req->background = 1; |
406 | fc->num_background++; | 407 | fc->num_background++; |
@@ -414,11 +415,11 @@ static void request_send_nowait_locked(struct fuse_conn *fc, | |||
414 | flush_bg_queue(fc); | 415 | flush_bg_queue(fc); |
415 | } | 416 | } |
416 | 417 | ||
417 | static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) | 418 | static void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) |
418 | { | 419 | { |
419 | spin_lock(&fc->lock); | 420 | spin_lock(&fc->lock); |
420 | if (fc->connected) { | 421 | if (fc->connected) { |
421 | request_send_nowait_locked(fc, req); | 422 | fuse_request_send_nowait_locked(fc, req); |
422 | spin_unlock(&fc->lock); | 423 | spin_unlock(&fc->lock); |
423 | } else { | 424 | } else { |
424 | req->out.h.error = -ENOTCONN; | 425 | req->out.h.error = -ENOTCONN; |
@@ -426,16 +427,16 @@ static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) | |||
426 | } | 427 | } |
427 | } | 428 | } |
428 | 429 | ||
429 | void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req) | 430 | void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req) |
430 | { | 431 | { |
431 | req->isreply = 0; | 432 | req->isreply = 0; |
432 | request_send_nowait(fc, req); | 433 | fuse_request_send_nowait(fc, req); |
433 | } | 434 | } |
434 | 435 | ||
435 | void request_send_background(struct fuse_conn *fc, struct fuse_req *req) | 436 | void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) |
436 | { | 437 | { |
437 | req->isreply = 1; | 438 | req->isreply = 1; |
438 | request_send_nowait(fc, req); | 439 | fuse_request_send_nowait(fc, req); |
439 | } | 440 | } |
440 | 441 | ||
441 | /* | 442 | /* |
@@ -443,10 +444,11 @@ void request_send_background(struct fuse_conn *fc, struct fuse_req *req) | |||
443 | * | 444 | * |
444 | * fc->connected must have been checked previously | 445 | * fc->connected must have been checked previously |
445 | */ | 446 | */ |
446 | void request_send_background_locked(struct fuse_conn *fc, struct fuse_req *req) | 447 | void fuse_request_send_background_locked(struct fuse_conn *fc, |
448 | struct fuse_req *req) | ||
447 | { | 449 | { |
448 | req->isreply = 1; | 450 | req->isreply = 1; |
449 | request_send_nowait_locked(fc, req); | 451 | fuse_request_send_nowait_locked(fc, req); |
450 | } | 452 | } |
451 | 453 | ||
452 | /* | 454 | /* |
@@ -539,8 +541,8 @@ static int fuse_copy_fill(struct fuse_copy_state *cs) | |||
539 | BUG_ON(!cs->nr_segs); | 541 | BUG_ON(!cs->nr_segs); |
540 | cs->seglen = cs->iov[0].iov_len; | 542 | cs->seglen = cs->iov[0].iov_len; |
541 | cs->addr = (unsigned long) cs->iov[0].iov_base; | 543 | cs->addr = (unsigned long) cs->iov[0].iov_base; |
542 | cs->iov ++; | 544 | cs->iov++; |
543 | cs->nr_segs --; | 545 | cs->nr_segs--; |
544 | } | 546 | } |
545 | down_read(¤t->mm->mmap_sem); | 547 | down_read(¤t->mm->mmap_sem); |
546 | err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0, | 548 | err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0, |
@@ -589,9 +591,11 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page *page, | |||
589 | kunmap_atomic(mapaddr, KM_USER1); | 591 | kunmap_atomic(mapaddr, KM_USER1); |
590 | } | 592 | } |
591 | while (count) { | 593 | while (count) { |
592 | int err; | 594 | if (!cs->len) { |
593 | if (!cs->len && (err = fuse_copy_fill(cs))) | 595 | int err = fuse_copy_fill(cs); |
594 | return err; | 596 | if (err) |
597 | return err; | ||
598 | } | ||
595 | if (page) { | 599 | if (page) { |
596 | void *mapaddr = kmap_atomic(page, KM_USER1); | 600 | void *mapaddr = kmap_atomic(page, KM_USER1); |
597 | void *buf = mapaddr + offset; | 601 | void *buf = mapaddr + offset; |
@@ -631,9 +635,11 @@ static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes, | |||
631 | static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size) | 635 | static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size) |
632 | { | 636 | { |
633 | while (size) { | 637 | while (size) { |
634 | int err; | 638 | if (!cs->len) { |
635 | if (!cs->len && (err = fuse_copy_fill(cs))) | 639 | int err = fuse_copy_fill(cs); |
636 | return err; | 640 | if (err) |
641 | return err; | ||
642 | } | ||
637 | fuse_copy_do(cs, &val, &size); | 643 | fuse_copy_do(cs, &val, &size); |
638 | } | 644 | } |
639 | return 0; | 645 | return 0; |
@@ -664,6 +670,8 @@ static int request_pending(struct fuse_conn *fc) | |||
664 | 670 | ||
665 | /* Wait until a request is available on the pending list */ | 671 | /* Wait until a request is available on the pending list */ |
666 | static void request_wait(struct fuse_conn *fc) | 672 | static void request_wait(struct fuse_conn *fc) |
673 | __releases(&fc->lock) | ||
674 | __acquires(&fc->lock) | ||
667 | { | 675 | { |
668 | DECLARE_WAITQUEUE(wait, current); | 676 | DECLARE_WAITQUEUE(wait, current); |
669 | 677 | ||
@@ -691,7 +699,7 @@ static void request_wait(struct fuse_conn *fc) | |||
691 | */ | 699 | */ |
692 | static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req, | 700 | static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req, |
693 | const struct iovec *iov, unsigned long nr_segs) | 701 | const struct iovec *iov, unsigned long nr_segs) |
694 | __releases(fc->lock) | 702 | __releases(&fc->lock) |
695 | { | 703 | { |
696 | struct fuse_copy_state cs; | 704 | struct fuse_copy_state cs; |
697 | struct fuse_in_header ih; | 705 | struct fuse_in_header ih; |
@@ -813,6 +821,34 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, | |||
813 | return err; | 821 | return err; |
814 | } | 822 | } |
815 | 823 | ||
824 | static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size, | ||
825 | struct fuse_copy_state *cs) | ||
826 | { | ||
827 | struct fuse_notify_poll_wakeup_out outarg; | ||
828 | int err; | ||
829 | |||
830 | if (size != sizeof(outarg)) | ||
831 | return -EINVAL; | ||
832 | |||
833 | err = fuse_copy_one(cs, &outarg, sizeof(outarg)); | ||
834 | if (err) | ||
835 | return err; | ||
836 | |||
837 | return fuse_notify_poll_wakeup(fc, &outarg); | ||
838 | } | ||
839 | |||
840 | static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, | ||
841 | unsigned int size, struct fuse_copy_state *cs) | ||
842 | { | ||
843 | switch (code) { | ||
844 | case FUSE_NOTIFY_POLL: | ||
845 | return fuse_notify_poll(fc, size, cs); | ||
846 | |||
847 | default: | ||
848 | return -EINVAL; | ||
849 | } | ||
850 | } | ||
851 | |||
816 | /* Look up request on processing list by unique ID */ | 852 | /* Look up request on processing list by unique ID */ |
817 | static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) | 853 | static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) |
818 | { | 854 | { |
@@ -876,9 +912,23 @@ static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, | |||
876 | err = fuse_copy_one(&cs, &oh, sizeof(oh)); | 912 | err = fuse_copy_one(&cs, &oh, sizeof(oh)); |
877 | if (err) | 913 | if (err) |
878 | goto err_finish; | 914 | goto err_finish; |
915 | |||
916 | err = -EINVAL; | ||
917 | if (oh.len != nbytes) | ||
918 | goto err_finish; | ||
919 | |||
920 | /* | ||
921 | * Zero oh.unique indicates unsolicited notification message | ||
922 | * and error contains notification code. | ||
923 | */ | ||
924 | if (!oh.unique) { | ||
925 | err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), &cs); | ||
926 | fuse_copy_finish(&cs); | ||
927 | return err ? err : nbytes; | ||
928 | } | ||
929 | |||
879 | err = -EINVAL; | 930 | err = -EINVAL; |
880 | if (!oh.unique || oh.error <= -1000 || oh.error > 0 || | 931 | if (oh.error <= -1000 || oh.error > 0) |
881 | oh.len != nbytes) | ||
882 | goto err_finish; | 932 | goto err_finish; |
883 | 933 | ||
884 | spin_lock(&fc->lock); | 934 | spin_lock(&fc->lock); |
@@ -966,6 +1016,8 @@ static unsigned fuse_dev_poll(struct file *file, poll_table *wait) | |||
966 | * This function releases and reacquires fc->lock | 1016 | * This function releases and reacquires fc->lock |
967 | */ | 1017 | */ |
968 | static void end_requests(struct fuse_conn *fc, struct list_head *head) | 1018 | static void end_requests(struct fuse_conn *fc, struct list_head *head) |
1019 | __releases(&fc->lock) | ||
1020 | __acquires(&fc->lock) | ||
969 | { | 1021 | { |
970 | while (!list_empty(head)) { | 1022 | while (!list_empty(head)) { |
971 | struct fuse_req *req; | 1023 | struct fuse_req *req; |
@@ -988,7 +1040,8 @@ static void end_requests(struct fuse_conn *fc, struct list_head *head) | |||
988 | * locked). | 1040 | * locked). |
989 | */ | 1041 | */ |
990 | static void end_io_requests(struct fuse_conn *fc) | 1042 | static void end_io_requests(struct fuse_conn *fc) |
991 | __releases(fc->lock) __acquires(fc->lock) | 1043 | __releases(&fc->lock) |
1044 | __acquires(&fc->lock) | ||
992 | { | 1045 | { |
993 | while (!list_empty(&fc->io)) { | 1046 | while (!list_empty(&fc->io)) { |
994 | struct fuse_req *req = | 1047 | struct fuse_req *req = |
@@ -1002,11 +1055,11 @@ static void end_io_requests(struct fuse_conn *fc) | |||
1002 | wake_up(&req->waitq); | 1055 | wake_up(&req->waitq); |
1003 | if (end) { | 1056 | if (end) { |
1004 | req->end = NULL; | 1057 | req->end = NULL; |
1005 | /* The end function will consume this reference */ | ||
1006 | __fuse_get_request(req); | 1058 | __fuse_get_request(req); |
1007 | spin_unlock(&fc->lock); | 1059 | spin_unlock(&fc->lock); |
1008 | wait_event(req->waitq, !req->locked); | 1060 | wait_event(req->waitq, !req->locked); |
1009 | end(fc, req); | 1061 | end(fc, req); |
1062 | fuse_put_request(fc, req); | ||
1010 | spin_lock(&fc->lock); | 1063 | spin_lock(&fc->lock); |
1011 | } | 1064 | } |
1012 | } | 1065 | } |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 95bc22bdd060..fdff346e96fd 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | FUSE: Filesystem in Userspace | 2 | FUSE: Filesystem in Userspace |
3 | Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> | 3 | Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> |
4 | 4 | ||
5 | This program can be distributed under the terms of the GNU GPL. | 5 | This program can be distributed under the terms of the GNU GPL. |
6 | See the file COPYING. | 6 | See the file COPYING. |
@@ -189,7 +189,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
189 | parent = dget_parent(entry); | 189 | parent = dget_parent(entry); |
190 | fuse_lookup_init(fc, req, get_node_id(parent->d_inode), | 190 | fuse_lookup_init(fc, req, get_node_id(parent->d_inode), |
191 | &entry->d_name, &outarg); | 191 | &entry->d_name, &outarg); |
192 | request_send(fc, req); | 192 | fuse_request_send(fc, req); |
193 | dput(parent); | 193 | dput(parent); |
194 | err = req->out.h.error; | 194 | err = req->out.h.error; |
195 | fuse_put_request(fc, req); | 195 | fuse_put_request(fc, req); |
@@ -204,7 +204,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
204 | return 0; | 204 | return 0; |
205 | } | 205 | } |
206 | spin_lock(&fc->lock); | 206 | spin_lock(&fc->lock); |
207 | fi->nlookup ++; | 207 | fi->nlookup++; |
208 | spin_unlock(&fc->lock); | 208 | spin_unlock(&fc->lock); |
209 | } | 209 | } |
210 | fuse_put_request(fc, forget_req); | 210 | fuse_put_request(fc, forget_req); |
@@ -283,7 +283,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, | |||
283 | attr_version = fuse_get_attr_version(fc); | 283 | attr_version = fuse_get_attr_version(fc); |
284 | 284 | ||
285 | fuse_lookup_init(fc, req, nodeid, name, outarg); | 285 | fuse_lookup_init(fc, req, nodeid, name, outarg); |
286 | request_send(fc, req); | 286 | fuse_request_send(fc, req); |
287 | err = req->out.h.error; | 287 | err = req->out.h.error; |
288 | fuse_put_request(fc, req); | 288 | fuse_put_request(fc, req); |
289 | /* Zero nodeid is same as -ENOENT, but with valid timeout */ | 289 | /* Zero nodeid is same as -ENOENT, but with valid timeout */ |
@@ -369,7 +369,7 @@ static void fuse_sync_release(struct fuse_conn *fc, struct fuse_file *ff, | |||
369 | { | 369 | { |
370 | fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE); | 370 | fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE); |
371 | ff->reserved_req->force = 1; | 371 | ff->reserved_req->force = 1; |
372 | request_send(fc, ff->reserved_req); | 372 | fuse_request_send(fc, ff->reserved_req); |
373 | fuse_put_request(fc, ff->reserved_req); | 373 | fuse_put_request(fc, ff->reserved_req); |
374 | kfree(ff); | 374 | kfree(ff); |
375 | } | 375 | } |
@@ -408,7 +408,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
408 | goto out_put_forget_req; | 408 | goto out_put_forget_req; |
409 | 409 | ||
410 | err = -ENOMEM; | 410 | err = -ENOMEM; |
411 | ff = fuse_file_alloc(); | 411 | ff = fuse_file_alloc(fc); |
412 | if (!ff) | 412 | if (!ff) |
413 | goto out_put_request; | 413 | goto out_put_request; |
414 | 414 | ||
@@ -432,7 +432,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
432 | req->out.args[0].value = &outentry; | 432 | req->out.args[0].value = &outentry; |
433 | req->out.args[1].size = sizeof(outopen); | 433 | req->out.args[1].size = sizeof(outopen); |
434 | req->out.args[1].value = &outopen; | 434 | req->out.args[1].value = &outopen; |
435 | request_send(fc, req); | 435 | fuse_request_send(fc, req); |
436 | err = req->out.h.error; | 436 | err = req->out.h.error; |
437 | if (err) { | 437 | if (err) { |
438 | if (err == -ENOSYS) | 438 | if (err == -ENOSYS) |
@@ -502,7 +502,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, | |||
502 | else | 502 | else |
503 | req->out.args[0].size = sizeof(outarg); | 503 | req->out.args[0].size = sizeof(outarg); |
504 | req->out.args[0].value = &outarg; | 504 | req->out.args[0].value = &outarg; |
505 | request_send(fc, req); | 505 | fuse_request_send(fc, req); |
506 | err = req->out.h.error; | 506 | err = req->out.h.error; |
507 | fuse_put_request(fc, req); | 507 | fuse_put_request(fc, req); |
508 | if (err) | 508 | if (err) |
@@ -631,15 +631,17 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) | |||
631 | req->in.numargs = 1; | 631 | req->in.numargs = 1; |
632 | req->in.args[0].size = entry->d_name.len + 1; | 632 | req->in.args[0].size = entry->d_name.len + 1; |
633 | req->in.args[0].value = entry->d_name.name; | 633 | req->in.args[0].value = entry->d_name.name; |
634 | request_send(fc, req); | 634 | fuse_request_send(fc, req); |
635 | err = req->out.h.error; | 635 | err = req->out.h.error; |
636 | fuse_put_request(fc, req); | 636 | fuse_put_request(fc, req); |
637 | if (!err) { | 637 | if (!err) { |
638 | struct inode *inode = entry->d_inode; | 638 | struct inode *inode = entry->d_inode; |
639 | 639 | ||
640 | /* Set nlink to zero so the inode can be cleared, if | 640 | /* |
641 | the inode does have more links this will be | 641 | * Set nlink to zero so the inode can be cleared, if the inode |
642 | discovered at the next lookup/getattr */ | 642 | * does have more links this will be discovered at the next |
643 | * lookup/getattr. | ||
644 | */ | ||
643 | clear_nlink(inode); | 645 | clear_nlink(inode); |
644 | fuse_invalidate_attr(inode); | 646 | fuse_invalidate_attr(inode); |
645 | fuse_invalidate_attr(dir); | 647 | fuse_invalidate_attr(dir); |
@@ -662,7 +664,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) | |||
662 | req->in.numargs = 1; | 664 | req->in.numargs = 1; |
663 | req->in.args[0].size = entry->d_name.len + 1; | 665 | req->in.args[0].size = entry->d_name.len + 1; |
664 | req->in.args[0].value = entry->d_name.name; | 666 | req->in.args[0].value = entry->d_name.name; |
665 | request_send(fc, req); | 667 | fuse_request_send(fc, req); |
666 | err = req->out.h.error; | 668 | err = req->out.h.error; |
667 | fuse_put_request(fc, req); | 669 | fuse_put_request(fc, req); |
668 | if (!err) { | 670 | if (!err) { |
@@ -695,7 +697,7 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, | |||
695 | req->in.args[1].value = oldent->d_name.name; | 697 | req->in.args[1].value = oldent->d_name.name; |
696 | req->in.args[2].size = newent->d_name.len + 1; | 698 | req->in.args[2].size = newent->d_name.len + 1; |
697 | req->in.args[2].value = newent->d_name.name; | 699 | req->in.args[2].value = newent->d_name.name; |
698 | request_send(fc, req); | 700 | fuse_request_send(fc, req); |
699 | err = req->out.h.error; | 701 | err = req->out.h.error; |
700 | fuse_put_request(fc, req); | 702 | fuse_put_request(fc, req); |
701 | if (!err) { | 703 | if (!err) { |
@@ -811,7 +813,7 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat, | |||
811 | else | 813 | else |
812 | req->out.args[0].size = sizeof(outarg); | 814 | req->out.args[0].size = sizeof(outarg); |
813 | req->out.args[0].value = &outarg; | 815 | req->out.args[0].value = &outarg; |
814 | request_send(fc, req); | 816 | fuse_request_send(fc, req); |
815 | err = req->out.h.error; | 817 | err = req->out.h.error; |
816 | fuse_put_request(fc, req); | 818 | fuse_put_request(fc, req); |
817 | if (!err) { | 819 | if (!err) { |
@@ -911,7 +913,7 @@ static int fuse_access(struct inode *inode, int mask) | |||
911 | req->in.numargs = 1; | 913 | req->in.numargs = 1; |
912 | req->in.args[0].size = sizeof(inarg); | 914 | req->in.args[0].size = sizeof(inarg); |
913 | req->in.args[0].value = &inarg; | 915 | req->in.args[0].value = &inarg; |
914 | request_send(fc, req); | 916 | fuse_request_send(fc, req); |
915 | err = req->out.h.error; | 917 | err = req->out.h.error; |
916 | fuse_put_request(fc, req); | 918 | fuse_put_request(fc, req); |
917 | if (err == -ENOSYS) { | 919 | if (err == -ENOSYS) { |
@@ -1033,7 +1035,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) | |||
1033 | req->num_pages = 1; | 1035 | req->num_pages = 1; |
1034 | req->pages[0] = page; | 1036 | req->pages[0] = page; |
1035 | fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR); | 1037 | fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR); |
1036 | request_send(fc, req); | 1038 | fuse_request_send(fc, req); |
1037 | nbytes = req->out.args[0].size; | 1039 | nbytes = req->out.args[0].size; |
1038 | err = req->out.h.error; | 1040 | err = req->out.h.error; |
1039 | fuse_put_request(fc, req); | 1041 | fuse_put_request(fc, req); |
@@ -1067,7 +1069,7 @@ static char *read_link(struct dentry *dentry) | |||
1067 | req->out.numargs = 1; | 1069 | req->out.numargs = 1; |
1068 | req->out.args[0].size = PAGE_SIZE - 1; | 1070 | req->out.args[0].size = PAGE_SIZE - 1; |
1069 | req->out.args[0].value = link; | 1071 | req->out.args[0].value = link; |
1070 | request_send(fc, req); | 1072 | fuse_request_send(fc, req); |
1071 | if (req->out.h.error) { | 1073 | if (req->out.h.error) { |
1072 | free_page((unsigned long) link); | 1074 | free_page((unsigned long) link); |
1073 | link = ERR_PTR(req->out.h.error); | 1075 | link = ERR_PTR(req->out.h.error); |
@@ -1273,7 +1275,7 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, | |||
1273 | else | 1275 | else |
1274 | req->out.args[0].size = sizeof(outarg); | 1276 | req->out.args[0].size = sizeof(outarg); |
1275 | req->out.args[0].value = &outarg; | 1277 | req->out.args[0].value = &outarg; |
1276 | request_send(fc, req); | 1278 | fuse_request_send(fc, req); |
1277 | err = req->out.h.error; | 1279 | err = req->out.h.error; |
1278 | fuse_put_request(fc, req); | 1280 | fuse_put_request(fc, req); |
1279 | if (err) { | 1281 | if (err) { |
@@ -1367,7 +1369,7 @@ static int fuse_setxattr(struct dentry *entry, const char *name, | |||
1367 | req->in.args[1].value = name; | 1369 | req->in.args[1].value = name; |
1368 | req->in.args[2].size = size; | 1370 | req->in.args[2].size = size; |
1369 | req->in.args[2].value = value; | 1371 | req->in.args[2].value = value; |
1370 | request_send(fc, req); | 1372 | fuse_request_send(fc, req); |
1371 | err = req->out.h.error; | 1373 | err = req->out.h.error; |
1372 | fuse_put_request(fc, req); | 1374 | fuse_put_request(fc, req); |
1373 | if (err == -ENOSYS) { | 1375 | if (err == -ENOSYS) { |
@@ -1413,7 +1415,7 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name, | |||
1413 | req->out.args[0].size = sizeof(outarg); | 1415 | req->out.args[0].size = sizeof(outarg); |
1414 | req->out.args[0].value = &outarg; | 1416 | req->out.args[0].value = &outarg; |
1415 | } | 1417 | } |
1416 | request_send(fc, req); | 1418 | fuse_request_send(fc, req); |
1417 | ret = req->out.h.error; | 1419 | ret = req->out.h.error; |
1418 | if (!ret) | 1420 | if (!ret) |
1419 | ret = size ? req->out.args[0].size : outarg.size; | 1421 | ret = size ? req->out.args[0].size : outarg.size; |
@@ -1463,7 +1465,7 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size) | |||
1463 | req->out.args[0].size = sizeof(outarg); | 1465 | req->out.args[0].size = sizeof(outarg); |
1464 | req->out.args[0].value = &outarg; | 1466 | req->out.args[0].value = &outarg; |
1465 | } | 1467 | } |
1466 | request_send(fc, req); | 1468 | fuse_request_send(fc, req); |
1467 | ret = req->out.h.error; | 1469 | ret = req->out.h.error; |
1468 | if (!ret) | 1470 | if (!ret) |
1469 | ret = size ? req->out.args[0].size : outarg.size; | 1471 | ret = size ? req->out.args[0].size : outarg.size; |
@@ -1496,7 +1498,7 @@ static int fuse_removexattr(struct dentry *entry, const char *name) | |||
1496 | req->in.numargs = 1; | 1498 | req->in.numargs = 1; |
1497 | req->in.args[0].size = strlen(name) + 1; | 1499 | req->in.args[0].size = strlen(name) + 1; |
1498 | req->in.args[0].value = name; | 1500 | req->in.args[0].value = name; |
1499 | request_send(fc, req); | 1501 | fuse_request_send(fc, req); |
1500 | err = req->out.h.error; | 1502 | err = req->out.h.error; |
1501 | fuse_put_request(fc, req); | 1503 | fuse_put_request(fc, req); |
1502 | if (err == -ENOSYS) { | 1504 | if (err == -ENOSYS) { |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 4c9ee7011265..e8162646a9b5 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | FUSE: Filesystem in Userspace | 2 | FUSE: Filesystem in Userspace |
3 | Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> | 3 | Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> |
4 | 4 | ||
5 | This program can be distributed under the terms of the GNU GPL. | 5 | This program can be distributed under the terms of the GNU GPL. |
6 | See the file COPYING. | 6 | See the file COPYING. |
@@ -39,14 +39,14 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir, | |||
39 | req->out.numargs = 1; | 39 | req->out.numargs = 1; |
40 | req->out.args[0].size = sizeof(*outargp); | 40 | req->out.args[0].size = sizeof(*outargp); |
41 | req->out.args[0].value = outargp; | 41 | req->out.args[0].value = outargp; |
42 | request_send(fc, req); | 42 | fuse_request_send(fc, req); |
43 | err = req->out.h.error; | 43 | err = req->out.h.error; |
44 | fuse_put_request(fc, req); | 44 | fuse_put_request(fc, req); |
45 | 45 | ||
46 | return err; | 46 | return err; |
47 | } | 47 | } |
48 | 48 | ||
49 | struct fuse_file *fuse_file_alloc(void) | 49 | struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) |
50 | { | 50 | { |
51 | struct fuse_file *ff; | 51 | struct fuse_file *ff; |
52 | ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL); | 52 | ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL); |
@@ -58,7 +58,12 @@ struct fuse_file *fuse_file_alloc(void) | |||
58 | } else { | 58 | } else { |
59 | INIT_LIST_HEAD(&ff->write_entry); | 59 | INIT_LIST_HEAD(&ff->write_entry); |
60 | atomic_set(&ff->count, 0); | 60 | atomic_set(&ff->count, 0); |
61 | spin_lock(&fc->lock); | ||
62 | ff->kh = ++fc->khctr; | ||
63 | spin_unlock(&fc->lock); | ||
61 | } | 64 | } |
65 | RB_CLEAR_NODE(&ff->polled_node); | ||
66 | init_waitqueue_head(&ff->poll_wait); | ||
62 | } | 67 | } |
63 | return ff; | 68 | return ff; |
64 | } | 69 | } |
@@ -79,7 +84,6 @@ static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req) | |||
79 | { | 84 | { |
80 | dput(req->misc.release.dentry); | 85 | dput(req->misc.release.dentry); |
81 | mntput(req->misc.release.vfsmount); | 86 | mntput(req->misc.release.vfsmount); |
82 | fuse_put_request(fc, req); | ||
83 | } | 87 | } |
84 | 88 | ||
85 | static void fuse_file_put(struct fuse_file *ff) | 89 | static void fuse_file_put(struct fuse_file *ff) |
@@ -89,7 +93,7 @@ static void fuse_file_put(struct fuse_file *ff) | |||
89 | struct inode *inode = req->misc.release.dentry->d_inode; | 93 | struct inode *inode = req->misc.release.dentry->d_inode; |
90 | struct fuse_conn *fc = get_fuse_conn(inode); | 94 | struct fuse_conn *fc = get_fuse_conn(inode); |
91 | req->end = fuse_release_end; | 95 | req->end = fuse_release_end; |
92 | request_send_background(fc, req); | 96 | fuse_request_send_background(fc, req); |
93 | kfree(ff); | 97 | kfree(ff); |
94 | } | 98 | } |
95 | } | 99 | } |
@@ -109,6 +113,7 @@ void fuse_finish_open(struct inode *inode, struct file *file, | |||
109 | 113 | ||
110 | int fuse_open_common(struct inode *inode, struct file *file, int isdir) | 114 | int fuse_open_common(struct inode *inode, struct file *file, int isdir) |
111 | { | 115 | { |
116 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
112 | struct fuse_open_out outarg; | 117 | struct fuse_open_out outarg; |
113 | struct fuse_file *ff; | 118 | struct fuse_file *ff; |
114 | int err; | 119 | int err; |
@@ -121,7 +126,7 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir) | |||
121 | if (err) | 126 | if (err) |
122 | return err; | 127 | return err; |
123 | 128 | ||
124 | ff = fuse_file_alloc(); | 129 | ff = fuse_file_alloc(fc); |
125 | if (!ff) | 130 | if (!ff) |
126 | return -ENOMEM; | 131 | return -ENOMEM; |
127 | 132 | ||
@@ -167,7 +172,11 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir) | |||
167 | 172 | ||
168 | spin_lock(&fc->lock); | 173 | spin_lock(&fc->lock); |
169 | list_del(&ff->write_entry); | 174 | list_del(&ff->write_entry); |
175 | if (!RB_EMPTY_NODE(&ff->polled_node)) | ||
176 | rb_erase(&ff->polled_node, &fc->polled_files); | ||
170 | spin_unlock(&fc->lock); | 177 | spin_unlock(&fc->lock); |
178 | |||
179 | wake_up_interruptible_sync(&ff->poll_wait); | ||
171 | /* | 180 | /* |
172 | * Normally this will send the RELEASE request, | 181 | * Normally this will send the RELEASE request, |
173 | * however if some asynchronous READ or WRITE requests | 182 | * however if some asynchronous READ or WRITE requests |
@@ -280,7 +289,7 @@ static int fuse_flush(struct file *file, fl_owner_t id) | |||
280 | req->in.args[0].size = sizeof(inarg); | 289 | req->in.args[0].size = sizeof(inarg); |
281 | req->in.args[0].value = &inarg; | 290 | req->in.args[0].value = &inarg; |
282 | req->force = 1; | 291 | req->force = 1; |
283 | request_send(fc, req); | 292 | fuse_request_send(fc, req); |
284 | err = req->out.h.error; | 293 | err = req->out.h.error; |
285 | fuse_put_request(fc, req); | 294 | fuse_put_request(fc, req); |
286 | if (err == -ENOSYS) { | 295 | if (err == -ENOSYS) { |
@@ -344,7 +353,7 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync, | |||
344 | req->in.numargs = 1; | 353 | req->in.numargs = 1; |
345 | req->in.args[0].size = sizeof(inarg); | 354 | req->in.args[0].size = sizeof(inarg); |
346 | req->in.args[0].value = &inarg; | 355 | req->in.args[0].value = &inarg; |
347 | request_send(fc, req); | 356 | fuse_request_send(fc, req); |
348 | err = req->out.h.error; | 357 | err = req->out.h.error; |
349 | fuse_put_request(fc, req); | 358 | fuse_put_request(fc, req); |
350 | if (err == -ENOSYS) { | 359 | if (err == -ENOSYS) { |
@@ -396,7 +405,7 @@ static size_t fuse_send_read(struct fuse_req *req, struct file *file, | |||
396 | inarg->read_flags |= FUSE_READ_LOCKOWNER; | 405 | inarg->read_flags |= FUSE_READ_LOCKOWNER; |
397 | inarg->lock_owner = fuse_lock_owner_id(fc, owner); | 406 | inarg->lock_owner = fuse_lock_owner_id(fc, owner); |
398 | } | 407 | } |
399 | request_send(fc, req); | 408 | fuse_request_send(fc, req); |
400 | return req->out.args[0].size; | 409 | return req->out.args[0].size; |
401 | } | 410 | } |
402 | 411 | ||
@@ -493,7 +502,6 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req) | |||
493 | } | 502 | } |
494 | if (req->ff) | 503 | if (req->ff) |
495 | fuse_file_put(req->ff); | 504 | fuse_file_put(req->ff); |
496 | fuse_put_request(fc, req); | ||
497 | } | 505 | } |
498 | 506 | ||
499 | static void fuse_send_readpages(struct fuse_req *req, struct file *file, | 507 | static void fuse_send_readpages(struct fuse_req *req, struct file *file, |
@@ -509,10 +517,11 @@ static void fuse_send_readpages(struct fuse_req *req, struct file *file, | |||
509 | struct fuse_file *ff = file->private_data; | 517 | struct fuse_file *ff = file->private_data; |
510 | req->ff = fuse_file_get(ff); | 518 | req->ff = fuse_file_get(ff); |
511 | req->end = fuse_readpages_end; | 519 | req->end = fuse_readpages_end; |
512 | request_send_background(fc, req); | 520 | fuse_request_send_background(fc, req); |
513 | } else { | 521 | } else { |
514 | request_send(fc, req); | 522 | fuse_request_send(fc, req); |
515 | fuse_readpages_end(fc, req); | 523 | fuse_readpages_end(fc, req); |
524 | fuse_put_request(fc, req); | ||
516 | } | 525 | } |
517 | } | 526 | } |
518 | 527 | ||
@@ -543,7 +552,7 @@ static int fuse_readpages_fill(void *_data, struct page *page) | |||
543 | } | 552 | } |
544 | } | 553 | } |
545 | req->pages[req->num_pages] = page; | 554 | req->pages[req->num_pages] = page; |
546 | req->num_pages ++; | 555 | req->num_pages++; |
547 | return 0; | 556 | return 0; |
548 | } | 557 | } |
549 | 558 | ||
@@ -636,7 +645,7 @@ static size_t fuse_send_write(struct fuse_req *req, struct file *file, | |||
636 | inarg->write_flags |= FUSE_WRITE_LOCKOWNER; | 645 | inarg->write_flags |= FUSE_WRITE_LOCKOWNER; |
637 | inarg->lock_owner = fuse_lock_owner_id(fc, owner); | 646 | inarg->lock_owner = fuse_lock_owner_id(fc, owner); |
638 | } | 647 | } |
639 | request_send(fc, req); | 648 | fuse_request_send(fc, req); |
640 | return req->misc.write.out.size; | 649 | return req->misc.write.out.size; |
641 | } | 650 | } |
642 | 651 | ||
@@ -1042,7 +1051,6 @@ static void fuse_writepage_free(struct fuse_conn *fc, struct fuse_req *req) | |||
1042 | { | 1051 | { |
1043 | __free_page(req->pages[0]); | 1052 | __free_page(req->pages[0]); |
1044 | fuse_file_put(req->ff); | 1053 | fuse_file_put(req->ff); |
1045 | fuse_put_request(fc, req); | ||
1046 | } | 1054 | } |
1047 | 1055 | ||
1048 | static void fuse_writepage_finish(struct fuse_conn *fc, struct fuse_req *req) | 1056 | static void fuse_writepage_finish(struct fuse_conn *fc, struct fuse_req *req) |
@@ -1060,6 +1068,8 @@ static void fuse_writepage_finish(struct fuse_conn *fc, struct fuse_req *req) | |||
1060 | 1068 | ||
1061 | /* Called under fc->lock, may release and reacquire it */ | 1069 | /* Called under fc->lock, may release and reacquire it */ |
1062 | static void fuse_send_writepage(struct fuse_conn *fc, struct fuse_req *req) | 1070 | static void fuse_send_writepage(struct fuse_conn *fc, struct fuse_req *req) |
1071 | __releases(&fc->lock) | ||
1072 | __acquires(&fc->lock) | ||
1063 | { | 1073 | { |
1064 | struct fuse_inode *fi = get_fuse_inode(req->inode); | 1074 | struct fuse_inode *fi = get_fuse_inode(req->inode); |
1065 | loff_t size = i_size_read(req->inode); | 1075 | loff_t size = i_size_read(req->inode); |
@@ -1079,13 +1089,14 @@ static void fuse_send_writepage(struct fuse_conn *fc, struct fuse_req *req) | |||
1079 | 1089 | ||
1080 | req->in.args[1].size = inarg->size; | 1090 | req->in.args[1].size = inarg->size; |
1081 | fi->writectr++; | 1091 | fi->writectr++; |
1082 | request_send_background_locked(fc, req); | 1092 | fuse_request_send_background_locked(fc, req); |
1083 | return; | 1093 | return; |
1084 | 1094 | ||
1085 | out_free: | 1095 | out_free: |
1086 | fuse_writepage_finish(fc, req); | 1096 | fuse_writepage_finish(fc, req); |
1087 | spin_unlock(&fc->lock); | 1097 | spin_unlock(&fc->lock); |
1088 | fuse_writepage_free(fc, req); | 1098 | fuse_writepage_free(fc, req); |
1099 | fuse_put_request(fc, req); | ||
1089 | spin_lock(&fc->lock); | 1100 | spin_lock(&fc->lock); |
1090 | } | 1101 | } |
1091 | 1102 | ||
@@ -1096,6 +1107,8 @@ static void fuse_send_writepage(struct fuse_conn *fc, struct fuse_req *req) | |||
1096 | * Called with fc->lock | 1107 | * Called with fc->lock |
1097 | */ | 1108 | */ |
1098 | void fuse_flush_writepages(struct inode *inode) | 1109 | void fuse_flush_writepages(struct inode *inode) |
1110 | __releases(&fc->lock) | ||
1111 | __acquires(&fc->lock) | ||
1099 | { | 1112 | { |
1100 | struct fuse_conn *fc = get_fuse_conn(inode); | 1113 | struct fuse_conn *fc = get_fuse_conn(inode); |
1101 | struct fuse_inode *fi = get_fuse_inode(inode); | 1114 | struct fuse_inode *fi = get_fuse_inode(inode); |
@@ -1325,7 +1338,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl) | |||
1325 | req->out.numargs = 1; | 1338 | req->out.numargs = 1; |
1326 | req->out.args[0].size = sizeof(outarg); | 1339 | req->out.args[0].size = sizeof(outarg); |
1327 | req->out.args[0].value = &outarg; | 1340 | req->out.args[0].value = &outarg; |
1328 | request_send(fc, req); | 1341 | fuse_request_send(fc, req); |
1329 | err = req->out.h.error; | 1342 | err = req->out.h.error; |
1330 | fuse_put_request(fc, req); | 1343 | fuse_put_request(fc, req); |
1331 | if (!err) | 1344 | if (!err) |
@@ -1357,7 +1370,7 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock) | |||
1357 | return PTR_ERR(req); | 1370 | return PTR_ERR(req); |
1358 | 1371 | ||
1359 | fuse_lk_fill(req, file, fl, opcode, pid, flock); | 1372 | fuse_lk_fill(req, file, fl, opcode, pid, flock); |
1360 | request_send(fc, req); | 1373 | fuse_request_send(fc, req); |
1361 | err = req->out.h.error; | 1374 | err = req->out.h.error; |
1362 | /* locking is restartable */ | 1375 | /* locking is restartable */ |
1363 | if (err == -EINTR) | 1376 | if (err == -EINTR) |
@@ -1433,7 +1446,7 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block) | |||
1433 | req->out.numargs = 1; | 1446 | req->out.numargs = 1; |
1434 | req->out.args[0].size = sizeof(outarg); | 1447 | req->out.args[0].size = sizeof(outarg); |
1435 | req->out.args[0].value = &outarg; | 1448 | req->out.args[0].value = &outarg; |
1436 | request_send(fc, req); | 1449 | fuse_request_send(fc, req); |
1437 | err = req->out.h.error; | 1450 | err = req->out.h.error; |
1438 | fuse_put_request(fc, req); | 1451 | fuse_put_request(fc, req); |
1439 | if (err == -ENOSYS) | 1452 | if (err == -ENOSYS) |
@@ -1470,6 +1483,406 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin) | |||
1470 | return retval; | 1483 | return retval; |
1471 | } | 1484 | } |
1472 | 1485 | ||
1486 | static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, | ||
1487 | unsigned int nr_segs, size_t bytes, bool to_user) | ||
1488 | { | ||
1489 | struct iov_iter ii; | ||
1490 | int page_idx = 0; | ||
1491 | |||
1492 | if (!bytes) | ||
1493 | return 0; | ||
1494 | |||
1495 | iov_iter_init(&ii, iov, nr_segs, bytes, 0); | ||
1496 | |||
1497 | while (iov_iter_count(&ii)) { | ||
1498 | struct page *page = pages[page_idx++]; | ||
1499 | size_t todo = min_t(size_t, PAGE_SIZE, iov_iter_count(&ii)); | ||
1500 | void *kaddr, *map; | ||
1501 | |||
1502 | kaddr = map = kmap(page); | ||
1503 | |||
1504 | while (todo) { | ||
1505 | char __user *uaddr = ii.iov->iov_base + ii.iov_offset; | ||
1506 | size_t iov_len = ii.iov->iov_len - ii.iov_offset; | ||
1507 | size_t copy = min(todo, iov_len); | ||
1508 | size_t left; | ||
1509 | |||
1510 | if (!to_user) | ||
1511 | left = copy_from_user(kaddr, uaddr, copy); | ||
1512 | else | ||
1513 | left = copy_to_user(uaddr, kaddr, copy); | ||
1514 | |||
1515 | if (unlikely(left)) | ||
1516 | return -EFAULT; | ||
1517 | |||
1518 | iov_iter_advance(&ii, copy); | ||
1519 | todo -= copy; | ||
1520 | kaddr += copy; | ||
1521 | } | ||
1522 | |||
1523 | kunmap(map); | ||
1524 | } | ||
1525 | |||
1526 | return 0; | ||
1527 | } | ||
1528 | |||
1529 | /* | ||
1530 | * For ioctls, there is no generic way to determine how much memory | ||
1531 | * needs to be read and/or written. Furthermore, ioctls are allowed | ||
1532 | * to dereference the passed pointer, so the parameter requires deep | ||
1533 | * copying but FUSE has no idea whatsoever about what to copy in or | ||
1534 | * out. | ||
1535 | * | ||
1536 | * This is solved by allowing FUSE server to retry ioctl with | ||
1537 | * necessary in/out iovecs. Let's assume the ioctl implementation | ||
1538 | * needs to read in the following structure. | ||
1539 | * | ||
1540 | * struct a { | ||
1541 | * char *buf; | ||
1542 | * size_t buflen; | ||
1543 | * } | ||
1544 | * | ||
1545 | * On the first callout to FUSE server, inarg->in_size and | ||
1546 | * inarg->out_size will be NULL; then, the server completes the ioctl | ||
1547 | * with FUSE_IOCTL_RETRY set in out->flags, out->in_iovs set to 1 and | ||
1548 | * the actual iov array to | ||
1549 | * | ||
1550 | * { { .iov_base = inarg.arg, .iov_len = sizeof(struct a) } } | ||
1551 | * | ||
1552 | * which tells FUSE to copy in the requested area and retry the ioctl. | ||
1553 | * On the second round, the server has access to the structure and | ||
1554 | * from that it can tell what to look for next, so on the invocation, | ||
1555 | * it sets FUSE_IOCTL_RETRY, out->in_iovs to 2 and iov array to | ||
1556 | * | ||
1557 | * { { .iov_base = inarg.arg, .iov_len = sizeof(struct a) }, | ||
1558 | * { .iov_base = a.buf, .iov_len = a.buflen } } | ||
1559 | * | ||
1560 | * FUSE will copy both struct a and the pointed buffer from the | ||
1561 | * process doing the ioctl and retry ioctl with both struct a and the | ||
1562 | * buffer. | ||
1563 | * | ||
1564 | * This time, FUSE server has everything it needs and completes ioctl | ||
1565 | * without FUSE_IOCTL_RETRY which finishes the ioctl call. | ||
1566 | * | ||
1567 | * Copying data out works the same way. | ||
1568 | * | ||
1569 | * Note that if FUSE_IOCTL_UNRESTRICTED is clear, the kernel | ||
1570 | * automatically initializes in and out iovs by decoding @cmd with | ||
1571 | * _IOC_* macros and the server is not allowed to request RETRY. This | ||
1572 | * limits ioctl data transfers to well-formed ioctls and is the forced | ||
1573 | * behavior for all FUSE servers. | ||
1574 | */ | ||
1575 | static long fuse_file_do_ioctl(struct file *file, unsigned int cmd, | ||
1576 | unsigned long arg, unsigned int flags) | ||
1577 | { | ||
1578 | struct inode *inode = file->f_dentry->d_inode; | ||
1579 | struct fuse_file *ff = file->private_data; | ||
1580 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
1581 | struct fuse_ioctl_in inarg = { | ||
1582 | .fh = ff->fh, | ||
1583 | .cmd = cmd, | ||
1584 | .arg = arg, | ||
1585 | .flags = flags | ||
1586 | }; | ||
1587 | struct fuse_ioctl_out outarg; | ||
1588 | struct fuse_req *req = NULL; | ||
1589 | struct page **pages = NULL; | ||
1590 | struct page *iov_page = NULL; | ||
1591 | struct iovec *in_iov = NULL, *out_iov = NULL; | ||
1592 | unsigned int in_iovs = 0, out_iovs = 0, num_pages = 0, max_pages; | ||
1593 | size_t in_size, out_size, transferred; | ||
1594 | int err; | ||
1595 | |||
1596 | /* assume all the iovs returned by client always fits in a page */ | ||
1597 | BUILD_BUG_ON(sizeof(struct iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE); | ||
1598 | |||
1599 | if (!fuse_allow_task(fc, current)) | ||
1600 | return -EACCES; | ||
1601 | |||
1602 | err = -EIO; | ||
1603 | if (is_bad_inode(inode)) | ||
1604 | goto out; | ||
1605 | |||
1606 | err = -ENOMEM; | ||
1607 | pages = kzalloc(sizeof(pages[0]) * FUSE_MAX_PAGES_PER_REQ, GFP_KERNEL); | ||
1608 | iov_page = alloc_page(GFP_KERNEL); | ||
1609 | if (!pages || !iov_page) | ||
1610 | goto out; | ||
1611 | |||
1612 | /* | ||
1613 | * If restricted, initialize IO parameters as encoded in @cmd. | ||
1614 | * RETRY from server is not allowed. | ||
1615 | */ | ||
1616 | if (!(flags & FUSE_IOCTL_UNRESTRICTED)) { | ||
1617 | struct iovec *iov = page_address(iov_page); | ||
1618 | |||
1619 | iov->iov_base = (void __user *)arg; | ||
1620 | iov->iov_len = _IOC_SIZE(cmd); | ||
1621 | |||
1622 | if (_IOC_DIR(cmd) & _IOC_WRITE) { | ||
1623 | in_iov = iov; | ||
1624 | in_iovs = 1; | ||
1625 | } | ||
1626 | |||
1627 | if (_IOC_DIR(cmd) & _IOC_READ) { | ||
1628 | out_iov = iov; | ||
1629 | out_iovs = 1; | ||
1630 | } | ||
1631 | } | ||
1632 | |||
1633 | retry: | ||
1634 | inarg.in_size = in_size = iov_length(in_iov, in_iovs); | ||
1635 | inarg.out_size = out_size = iov_length(out_iov, out_iovs); | ||
1636 | |||
1637 | /* | ||
1638 | * Out data can be used either for actual out data or iovs, | ||
1639 | * make sure there always is at least one page. | ||
1640 | */ | ||
1641 | out_size = max_t(size_t, out_size, PAGE_SIZE); | ||
1642 | max_pages = DIV_ROUND_UP(max(in_size, out_size), PAGE_SIZE); | ||
1643 | |||
1644 | /* make sure there are enough buffer pages and init request with them */ | ||
1645 | err = -ENOMEM; | ||
1646 | if (max_pages > FUSE_MAX_PAGES_PER_REQ) | ||
1647 | goto out; | ||
1648 | while (num_pages < max_pages) { | ||
1649 | pages[num_pages] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); | ||
1650 | if (!pages[num_pages]) | ||
1651 | goto out; | ||
1652 | num_pages++; | ||
1653 | } | ||
1654 | |||
1655 | req = fuse_get_req(fc); | ||
1656 | if (IS_ERR(req)) { | ||
1657 | err = PTR_ERR(req); | ||
1658 | req = NULL; | ||
1659 | goto out; | ||
1660 | } | ||
1661 | memcpy(req->pages, pages, sizeof(req->pages[0]) * num_pages); | ||
1662 | req->num_pages = num_pages; | ||
1663 | |||
1664 | /* okay, let's send it to the client */ | ||
1665 | req->in.h.opcode = FUSE_IOCTL; | ||
1666 | req->in.h.nodeid = get_node_id(inode); | ||
1667 | req->in.numargs = 1; | ||
1668 | req->in.args[0].size = sizeof(inarg); | ||
1669 | req->in.args[0].value = &inarg; | ||
1670 | if (in_size) { | ||
1671 | req->in.numargs++; | ||
1672 | req->in.args[1].size = in_size; | ||
1673 | req->in.argpages = 1; | ||
1674 | |||
1675 | err = fuse_ioctl_copy_user(pages, in_iov, in_iovs, in_size, | ||
1676 | false); | ||
1677 | if (err) | ||
1678 | goto out; | ||
1679 | } | ||
1680 | |||
1681 | req->out.numargs = 2; | ||
1682 | req->out.args[0].size = sizeof(outarg); | ||
1683 | req->out.args[0].value = &outarg; | ||
1684 | req->out.args[1].size = out_size; | ||
1685 | req->out.argpages = 1; | ||
1686 | req->out.argvar = 1; | ||
1687 | |||
1688 | fuse_request_send(fc, req); | ||
1689 | err = req->out.h.error; | ||
1690 | transferred = req->out.args[1].size; | ||
1691 | fuse_put_request(fc, req); | ||
1692 | req = NULL; | ||
1693 | if (err) | ||
1694 | goto out; | ||
1695 | |||
1696 | /* did it ask for retry? */ | ||
1697 | if (outarg.flags & FUSE_IOCTL_RETRY) { | ||
1698 | char *vaddr; | ||
1699 | |||
1700 | /* no retry if in restricted mode */ | ||
1701 | err = -EIO; | ||
1702 | if (!(flags & FUSE_IOCTL_UNRESTRICTED)) | ||
1703 | goto out; | ||
1704 | |||
1705 | in_iovs = outarg.in_iovs; | ||
1706 | out_iovs = outarg.out_iovs; | ||
1707 | |||
1708 | /* | ||
1709 | * Make sure things are in boundary, separate checks | ||
1710 | * are to protect against overflow. | ||
1711 | */ | ||
1712 | err = -ENOMEM; | ||
1713 | if (in_iovs > FUSE_IOCTL_MAX_IOV || | ||
1714 | out_iovs > FUSE_IOCTL_MAX_IOV || | ||
1715 | in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV) | ||
1716 | goto out; | ||
1717 | |||
1718 | err = -EIO; | ||
1719 | if ((in_iovs + out_iovs) * sizeof(struct iovec) != transferred) | ||
1720 | goto out; | ||
1721 | |||
1722 | /* okay, copy in iovs and retry */ | ||
1723 | vaddr = kmap_atomic(pages[0], KM_USER0); | ||
1724 | memcpy(page_address(iov_page), vaddr, transferred); | ||
1725 | kunmap_atomic(vaddr, KM_USER0); | ||
1726 | |||
1727 | in_iov = page_address(iov_page); | ||
1728 | out_iov = in_iov + in_iovs; | ||
1729 | |||
1730 | goto retry; | ||
1731 | } | ||
1732 | |||
1733 | err = -EIO; | ||
1734 | if (transferred > inarg.out_size) | ||
1735 | goto out; | ||
1736 | |||
1737 | err = fuse_ioctl_copy_user(pages, out_iov, out_iovs, transferred, true); | ||
1738 | out: | ||
1739 | if (req) | ||
1740 | fuse_put_request(fc, req); | ||
1741 | if (iov_page) | ||
1742 | __free_page(iov_page); | ||
1743 | while (num_pages) | ||
1744 | __free_page(pages[--num_pages]); | ||
1745 | kfree(pages); | ||
1746 | |||
1747 | return err ? err : outarg.result; | ||
1748 | } | ||
1749 | |||
1750 | static long fuse_file_ioctl(struct file *file, unsigned int cmd, | ||
1751 | unsigned long arg) | ||
1752 | { | ||
1753 | return fuse_file_do_ioctl(file, cmd, arg, 0); | ||
1754 | } | ||
1755 | |||
1756 | static long fuse_file_compat_ioctl(struct file *file, unsigned int cmd, | ||
1757 | unsigned long arg) | ||
1758 | { | ||
1759 | return fuse_file_do_ioctl(file, cmd, arg, FUSE_IOCTL_COMPAT); | ||
1760 | } | ||
1761 | |||
1762 | /* | ||
1763 | * All files which have been polled are linked to RB tree | ||
1764 | * fuse_conn->polled_files which is indexed by kh. Walk the tree and | ||
1765 | * find the matching one. | ||
1766 | */ | ||
1767 | static struct rb_node **fuse_find_polled_node(struct fuse_conn *fc, u64 kh, | ||
1768 | struct rb_node **parent_out) | ||
1769 | { | ||
1770 | struct rb_node **link = &fc->polled_files.rb_node; | ||
1771 | struct rb_node *last = NULL; | ||
1772 | |||
1773 | while (*link) { | ||
1774 | struct fuse_file *ff; | ||
1775 | |||
1776 | last = *link; | ||
1777 | ff = rb_entry(last, struct fuse_file, polled_node); | ||
1778 | |||
1779 | if (kh < ff->kh) | ||
1780 | link = &last->rb_left; | ||
1781 | else if (kh > ff->kh) | ||
1782 | link = &last->rb_right; | ||
1783 | else | ||
1784 | return link; | ||
1785 | } | ||
1786 | |||
1787 | if (parent_out) | ||
1788 | *parent_out = last; | ||
1789 | return link; | ||
1790 | } | ||
1791 | |||
1792 | /* | ||
1793 | * The file is about to be polled. Make sure it's on the polled_files | ||
1794 | * RB tree. Note that files once added to the polled_files tree are | ||
1795 | * not removed before the file is released. This is because a file | ||
1796 | * polled once is likely to be polled again. | ||
1797 | */ | ||
1798 | static void fuse_register_polled_file(struct fuse_conn *fc, | ||
1799 | struct fuse_file *ff) | ||
1800 | { | ||
1801 | spin_lock(&fc->lock); | ||
1802 | if (RB_EMPTY_NODE(&ff->polled_node)) { | ||
1803 | struct rb_node **link, *parent; | ||
1804 | |||
1805 | link = fuse_find_polled_node(fc, ff->kh, &parent); | ||
1806 | BUG_ON(*link); | ||
1807 | rb_link_node(&ff->polled_node, parent, link); | ||
1808 | rb_insert_color(&ff->polled_node, &fc->polled_files); | ||
1809 | } | ||
1810 | spin_unlock(&fc->lock); | ||
1811 | } | ||
1812 | |||
1813 | static unsigned fuse_file_poll(struct file *file, poll_table *wait) | ||
1814 | { | ||
1815 | struct inode *inode = file->f_dentry->d_inode; | ||
1816 | struct fuse_file *ff = file->private_data; | ||
1817 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
1818 | struct fuse_poll_in inarg = { .fh = ff->fh, .kh = ff->kh }; | ||
1819 | struct fuse_poll_out outarg; | ||
1820 | struct fuse_req *req; | ||
1821 | int err; | ||
1822 | |||
1823 | if (fc->no_poll) | ||
1824 | return DEFAULT_POLLMASK; | ||
1825 | |||
1826 | poll_wait(file, &ff->poll_wait, wait); | ||
1827 | |||
1828 | /* | ||
1829 | * Ask for notification iff there's someone waiting for it. | ||
1830 | * The client may ignore the flag and always notify. | ||
1831 | */ | ||
1832 | if (waitqueue_active(&ff->poll_wait)) { | ||
1833 | inarg.flags |= FUSE_POLL_SCHEDULE_NOTIFY; | ||
1834 | fuse_register_polled_file(fc, ff); | ||
1835 | } | ||
1836 | |||
1837 | req = fuse_get_req(fc); | ||
1838 | if (IS_ERR(req)) | ||
1839 | return PTR_ERR(req); | ||
1840 | |||
1841 | req->in.h.opcode = FUSE_POLL; | ||
1842 | req->in.h.nodeid = get_node_id(inode); | ||
1843 | req->in.numargs = 1; | ||
1844 | req->in.args[0].size = sizeof(inarg); | ||
1845 | req->in.args[0].value = &inarg; | ||
1846 | req->out.numargs = 1; | ||
1847 | req->out.args[0].size = sizeof(outarg); | ||
1848 | req->out.args[0].value = &outarg; | ||
1849 | fuse_request_send(fc, req); | ||
1850 | err = req->out.h.error; | ||
1851 | fuse_put_request(fc, req); | ||
1852 | |||
1853 | if (!err) | ||
1854 | return outarg.revents; | ||
1855 | if (err == -ENOSYS) { | ||
1856 | fc->no_poll = 1; | ||
1857 | return DEFAULT_POLLMASK; | ||
1858 | } | ||
1859 | return POLLERR; | ||
1860 | } | ||
1861 | |||
1862 | /* | ||
1863 | * This is called from fuse_handle_notify() on FUSE_NOTIFY_POLL and | ||
1864 | * wakes up the poll waiters. | ||
1865 | */ | ||
1866 | int fuse_notify_poll_wakeup(struct fuse_conn *fc, | ||
1867 | struct fuse_notify_poll_wakeup_out *outarg) | ||
1868 | { | ||
1869 | u64 kh = outarg->kh; | ||
1870 | struct rb_node **link; | ||
1871 | |||
1872 | spin_lock(&fc->lock); | ||
1873 | |||
1874 | link = fuse_find_polled_node(fc, kh, NULL); | ||
1875 | if (*link) { | ||
1876 | struct fuse_file *ff; | ||
1877 | |||
1878 | ff = rb_entry(*link, struct fuse_file, polled_node); | ||
1879 | wake_up_interruptible_sync(&ff->poll_wait); | ||
1880 | } | ||
1881 | |||
1882 | spin_unlock(&fc->lock); | ||
1883 | return 0; | ||
1884 | } | ||
1885 | |||
1473 | static const struct file_operations fuse_file_operations = { | 1886 | static const struct file_operations fuse_file_operations = { |
1474 | .llseek = fuse_file_llseek, | 1887 | .llseek = fuse_file_llseek, |
1475 | .read = do_sync_read, | 1888 | .read = do_sync_read, |
@@ -1484,6 +1897,9 @@ static const struct file_operations fuse_file_operations = { | |||
1484 | .lock = fuse_file_lock, | 1897 | .lock = fuse_file_lock, |
1485 | .flock = fuse_file_flock, | 1898 | .flock = fuse_file_flock, |
1486 | .splice_read = generic_file_splice_read, | 1899 | .splice_read = generic_file_splice_read, |
1900 | .unlocked_ioctl = fuse_file_ioctl, | ||
1901 | .compat_ioctl = fuse_file_compat_ioctl, | ||
1902 | .poll = fuse_file_poll, | ||
1487 | }; | 1903 | }; |
1488 | 1904 | ||
1489 | static const struct file_operations fuse_direct_io_file_operations = { | 1905 | static const struct file_operations fuse_direct_io_file_operations = { |
@@ -1496,6 +1912,9 @@ static const struct file_operations fuse_direct_io_file_operations = { | |||
1496 | .fsync = fuse_fsync, | 1912 | .fsync = fuse_fsync, |
1497 | .lock = fuse_file_lock, | 1913 | .lock = fuse_file_lock, |
1498 | .flock = fuse_file_flock, | 1914 | .flock = fuse_file_flock, |
1915 | .unlocked_ioctl = fuse_file_ioctl, | ||
1916 | .compat_ioctl = fuse_file_compat_ioctl, | ||
1917 | .poll = fuse_file_poll, | ||
1499 | /* no mmap and splice_read */ | 1918 | /* no mmap and splice_read */ |
1500 | }; | 1919 | }; |
1501 | 1920 | ||
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 35accfdd747f..5e64b815a5a1 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | FUSE: Filesystem in Userspace | 2 | FUSE: Filesystem in Userspace |
3 | Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> | 3 | Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> |
4 | 4 | ||
5 | This program can be distributed under the terms of the GNU GPL. | 5 | This program can be distributed under the terms of the GNU GPL. |
6 | See the file COPYING. | 6 | See the file COPYING. |
@@ -19,6 +19,8 @@ | |||
19 | #include <linux/backing-dev.h> | 19 | #include <linux/backing-dev.h> |
20 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
21 | #include <linux/rwsem.h> | 21 | #include <linux/rwsem.h> |
22 | #include <linux/rbtree.h> | ||
23 | #include <linux/poll.h> | ||
22 | 24 | ||
23 | /** Max number of pages that can be used in a single read request */ | 25 | /** Max number of pages that can be used in a single read request */ |
24 | #define FUSE_MAX_PAGES_PER_REQ 32 | 26 | #define FUSE_MAX_PAGES_PER_REQ 32 |
@@ -100,6 +102,9 @@ struct fuse_file { | |||
100 | /** Request reserved for flush and release */ | 102 | /** Request reserved for flush and release */ |
101 | struct fuse_req *reserved_req; | 103 | struct fuse_req *reserved_req; |
102 | 104 | ||
105 | /** Kernel file handle guaranteed to be unique */ | ||
106 | u64 kh; | ||
107 | |||
103 | /** File handle used by userspace */ | 108 | /** File handle used by userspace */ |
104 | u64 fh; | 109 | u64 fh; |
105 | 110 | ||
@@ -108,6 +113,12 @@ struct fuse_file { | |||
108 | 113 | ||
109 | /** Entry on inode's write_files list */ | 114 | /** Entry on inode's write_files list */ |
110 | struct list_head write_entry; | 115 | struct list_head write_entry; |
116 | |||
117 | /** RB node to be linked on fuse_conn->polled_files */ | ||
118 | struct rb_node polled_node; | ||
119 | |||
120 | /** Wait queue head for poll */ | ||
121 | wait_queue_head_t poll_wait; | ||
111 | }; | 122 | }; |
112 | 123 | ||
113 | /** One input argument of a request */ | 124 | /** One input argument of a request */ |
@@ -322,6 +333,12 @@ struct fuse_conn { | |||
322 | /** The list of requests under I/O */ | 333 | /** The list of requests under I/O */ |
323 | struct list_head io; | 334 | struct list_head io; |
324 | 335 | ||
336 | /** The next unique kernel file handle */ | ||
337 | u64 khctr; | ||
338 | |||
339 | /** rbtree of fuse_files waiting for poll events indexed by ph */ | ||
340 | struct rb_root polled_files; | ||
341 | |||
325 | /** Number of requests currently in the background */ | 342 | /** Number of requests currently in the background */ |
326 | unsigned num_background; | 343 | unsigned num_background; |
327 | 344 | ||
@@ -355,19 +372,19 @@ struct fuse_conn { | |||
355 | /** Connection failed (version mismatch). Cannot race with | 372 | /** Connection failed (version mismatch). Cannot race with |
356 | setting other bitfields since it is only set once in INIT | 373 | setting other bitfields since it is only set once in INIT |
357 | reply, before any other request, and never cleared */ | 374 | reply, before any other request, and never cleared */ |
358 | unsigned conn_error : 1; | 375 | unsigned conn_error:1; |
359 | 376 | ||
360 | /** Connection successful. Only set in INIT */ | 377 | /** Connection successful. Only set in INIT */ |
361 | unsigned conn_init : 1; | 378 | unsigned conn_init:1; |
362 | 379 | ||
363 | /** Do readpages asynchronously? Only set in INIT */ | 380 | /** Do readpages asynchronously? Only set in INIT */ |
364 | unsigned async_read : 1; | 381 | unsigned async_read:1; |
365 | 382 | ||
366 | /** Do not send separate SETATTR request before open(O_TRUNC) */ | 383 | /** Do not send separate SETATTR request before open(O_TRUNC) */ |
367 | unsigned atomic_o_trunc : 1; | 384 | unsigned atomic_o_trunc:1; |
368 | 385 | ||
369 | /** Filesystem supports NFS exporting. Only set in INIT */ | 386 | /** Filesystem supports NFS exporting. Only set in INIT */ |
370 | unsigned export_support : 1; | 387 | unsigned export_support:1; |
371 | 388 | ||
372 | /* | 389 | /* |
373 | * The following bitfields are only for optimization purposes | 390 | * The following bitfields are only for optimization purposes |
@@ -375,43 +392,46 @@ struct fuse_conn { | |||
375 | */ | 392 | */ |
376 | 393 | ||
377 | /** Is fsync not implemented by fs? */ | 394 | /** Is fsync not implemented by fs? */ |
378 | unsigned no_fsync : 1; | 395 | unsigned no_fsync:1; |
379 | 396 | ||
380 | /** Is fsyncdir not implemented by fs? */ | 397 | /** Is fsyncdir not implemented by fs? */ |
381 | unsigned no_fsyncdir : 1; | 398 | unsigned no_fsyncdir:1; |
382 | 399 | ||
383 | /** Is flush not implemented by fs? */ | 400 | /** Is flush not implemented by fs? */ |
384 | unsigned no_flush : 1; | 401 | unsigned no_flush:1; |
385 | 402 | ||
386 | /** Is setxattr not implemented by fs? */ | 403 | /** Is setxattr not implemented by fs? */ |
387 | unsigned no_setxattr : 1; | 404 | unsigned no_setxattr:1; |
388 | 405 | ||
389 | /** Is getxattr not implemented by fs? */ | 406 | /** Is getxattr not implemented by fs? */ |
390 | unsigned no_getxattr : 1; | 407 | unsigned no_getxattr:1; |
391 | 408 | ||
392 | /** Is listxattr not implemented by fs? */ | 409 | /** Is listxattr not implemented by fs? */ |
393 | unsigned no_listxattr : 1; | 410 | unsigned no_listxattr:1; |
394 | 411 | ||
395 | /** Is removexattr not implemented by fs? */ | 412 | /** Is removexattr not implemented by fs? */ |
396 | unsigned no_removexattr : 1; | 413 | unsigned no_removexattr:1; |
397 | 414 | ||
398 | /** Are file locking primitives not implemented by fs? */ | 415 | /** Are file locking primitives not implemented by fs? */ |
399 | unsigned no_lock : 1; | 416 | unsigned no_lock:1; |
400 | 417 | ||
401 | /** Is access not implemented by fs? */ | 418 | /** Is access not implemented by fs? */ |
402 | unsigned no_access : 1; | 419 | unsigned no_access:1; |
403 | 420 | ||
404 | /** Is create not implemented by fs? */ | 421 | /** Is create not implemented by fs? */ |
405 | unsigned no_create : 1; | 422 | unsigned no_create:1; |
406 | 423 | ||
407 | /** Is interrupt not implemented by fs? */ | 424 | /** Is interrupt not implemented by fs? */ |
408 | unsigned no_interrupt : 1; | 425 | unsigned no_interrupt:1; |
409 | 426 | ||
410 | /** Is bmap not implemented by fs? */ | 427 | /** Is bmap not implemented by fs? */ |
411 | unsigned no_bmap : 1; | 428 | unsigned no_bmap:1; |
429 | |||
430 | /** Is poll not implemented by fs? */ | ||
431 | unsigned no_poll:1; | ||
412 | 432 | ||
413 | /** Do multi-page cached writes */ | 433 | /** Do multi-page cached writes */ |
414 | unsigned big_writes : 1; | 434 | unsigned big_writes:1; |
415 | 435 | ||
416 | /** The number of requests waiting for completion */ | 436 | /** The number of requests waiting for completion */ |
417 | atomic_t num_waiting; | 437 | atomic_t num_waiting; |
@@ -445,6 +465,9 @@ struct fuse_conn { | |||
445 | 465 | ||
446 | /** Version counter for attribute changes */ | 466 | /** Version counter for attribute changes */ |
447 | u64 attr_version; | 467 | u64 attr_version; |
468 | |||
469 | /** Called on final put */ | ||
470 | void (*release)(struct fuse_conn *); | ||
448 | }; | 471 | }; |
449 | 472 | ||
450 | static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) | 473 | static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) |
@@ -499,7 +522,7 @@ void fuse_read_fill(struct fuse_req *req, struct file *file, | |||
499 | */ | 522 | */ |
500 | int fuse_open_common(struct inode *inode, struct file *file, int isdir); | 523 | int fuse_open_common(struct inode *inode, struct file *file, int isdir); |
501 | 524 | ||
502 | struct fuse_file *fuse_file_alloc(void); | 525 | struct fuse_file *fuse_file_alloc(struct fuse_conn *fc); |
503 | void fuse_file_free(struct fuse_file *ff); | 526 | void fuse_file_free(struct fuse_file *ff); |
504 | void fuse_finish_open(struct inode *inode, struct file *file, | 527 | void fuse_finish_open(struct inode *inode, struct file *file, |
505 | struct fuse_file *ff, struct fuse_open_out *outarg); | 528 | struct fuse_file *ff, struct fuse_open_out *outarg); |
@@ -519,6 +542,12 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync, | |||
519 | int isdir); | 542 | int isdir); |
520 | 543 | ||
521 | /** | 544 | /** |
545 | * Notify poll wakeup | ||
546 | */ | ||
547 | int fuse_notify_poll_wakeup(struct fuse_conn *fc, | ||
548 | struct fuse_notify_poll_wakeup_out *outarg); | ||
549 | |||
550 | /** | ||
522 | * Initialize file operations on a regular file | 551 | * Initialize file operations on a regular file |
523 | */ | 552 | */ |
524 | void fuse_init_file_inode(struct inode *inode); | 553 | void fuse_init_file_inode(struct inode *inode); |
@@ -593,19 +622,20 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req); | |||
593 | /** | 622 | /** |
594 | * Send a request (synchronous) | 623 | * Send a request (synchronous) |
595 | */ | 624 | */ |
596 | void request_send(struct fuse_conn *fc, struct fuse_req *req); | 625 | void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req); |
597 | 626 | ||
598 | /** | 627 | /** |
599 | * Send a request with no reply | 628 | * Send a request with no reply |
600 | */ | 629 | */ |
601 | void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req); | 630 | void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req); |
602 | 631 | ||
603 | /** | 632 | /** |
604 | * Send a request in the background | 633 | * Send a request in the background |
605 | */ | 634 | */ |
606 | void request_send_background(struct fuse_conn *fc, struct fuse_req *req); | 635 | void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req); |
607 | 636 | ||
608 | void request_send_background_locked(struct fuse_conn *fc, struct fuse_req *req); | 637 | void fuse_request_send_background_locked(struct fuse_conn *fc, |
638 | struct fuse_req *req); | ||
609 | 639 | ||
610 | /* Abort all requests */ | 640 | /* Abort all requests */ |
611 | void fuse_abort_conn(struct fuse_conn *fc); | 641 | void fuse_abort_conn(struct fuse_conn *fc); |
@@ -623,6 +653,11 @@ void fuse_invalidate_entry_cache(struct dentry *entry); | |||
623 | struct fuse_conn *fuse_conn_get(struct fuse_conn *fc); | 653 | struct fuse_conn *fuse_conn_get(struct fuse_conn *fc); |
624 | 654 | ||
625 | /** | 655 | /** |
656 | * Initialize fuse_conn | ||
657 | */ | ||
658 | int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb); | ||
659 | |||
660 | /** | ||
626 | * Release reference to fuse_conn | 661 | * Release reference to fuse_conn |
627 | */ | 662 | */ |
628 | void fuse_conn_put(struct fuse_conn *fc); | 663 | void fuse_conn_put(struct fuse_conn *fc); |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 2e99f34b4435..47c96fdca1ac 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | FUSE: Filesystem in Userspace | 2 | FUSE: Filesystem in Userspace |
3 | Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> | 3 | Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> |
4 | 4 | ||
5 | This program can be distributed under the terms of the GNU GPL. | 5 | This program can be distributed under the terms of the GNU GPL. |
6 | See the file COPYING. | 6 | See the file COPYING. |
@@ -37,10 +37,10 @@ struct fuse_mount_data { | |||
37 | unsigned rootmode; | 37 | unsigned rootmode; |
38 | unsigned user_id; | 38 | unsigned user_id; |
39 | unsigned group_id; | 39 | unsigned group_id; |
40 | unsigned fd_present : 1; | 40 | unsigned fd_present:1; |
41 | unsigned rootmode_present : 1; | 41 | unsigned rootmode_present:1; |
42 | unsigned user_id_present : 1; | 42 | unsigned user_id_present:1; |
43 | unsigned group_id_present : 1; | 43 | unsigned group_id_present:1; |
44 | unsigned flags; | 44 | unsigned flags; |
45 | unsigned max_read; | 45 | unsigned max_read; |
46 | unsigned blksize; | 46 | unsigned blksize; |
@@ -94,7 +94,7 @@ void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, | |||
94 | req->in.numargs = 1; | 94 | req->in.numargs = 1; |
95 | req->in.args[0].size = sizeof(struct fuse_forget_in); | 95 | req->in.args[0].size = sizeof(struct fuse_forget_in); |
96 | req->in.args[0].value = inarg; | 96 | req->in.args[0].value = inarg; |
97 | request_send_noreply(fc, req); | 97 | fuse_request_send_noreply(fc, req); |
98 | } | 98 | } |
99 | 99 | ||
100 | static void fuse_clear_inode(struct inode *inode) | 100 | static void fuse_clear_inode(struct inode *inode) |
@@ -250,7 +250,7 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid, | |||
250 | 250 | ||
251 | fi = get_fuse_inode(inode); | 251 | fi = get_fuse_inode(inode); |
252 | spin_lock(&fc->lock); | 252 | spin_lock(&fc->lock); |
253 | fi->nlookup ++; | 253 | fi->nlookup++; |
254 | spin_unlock(&fc->lock); | 254 | spin_unlock(&fc->lock); |
255 | fuse_change_attributes(inode, attr, attr_valid, attr_version); | 255 | fuse_change_attributes(inode, attr, attr_valid, attr_version); |
256 | 256 | ||
@@ -269,7 +269,7 @@ static void fuse_send_destroy(struct fuse_conn *fc) | |||
269 | fc->destroy_req = NULL; | 269 | fc->destroy_req = NULL; |
270 | req->in.h.opcode = FUSE_DESTROY; | 270 | req->in.h.opcode = FUSE_DESTROY; |
271 | req->force = 1; | 271 | req->force = 1; |
272 | request_send(fc, req); | 272 | fuse_request_send(fc, req); |
273 | fuse_put_request(fc, req); | 273 | fuse_put_request(fc, req); |
274 | } | 274 | } |
275 | } | 275 | } |
@@ -334,7 +334,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
334 | req->out.args[0].size = | 334 | req->out.args[0].size = |
335 | fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg); | 335 | fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg); |
336 | req->out.args[0].value = &outarg; | 336 | req->out.args[0].value = &outarg; |
337 | request_send(fc, req); | 337 | fuse_request_send(fc, req); |
338 | err = req->out.h.error; | 338 | err = req->out.h.error; |
339 | if (!err) | 339 | if (!err) |
340 | convert_fuse_statfs(buf, &outarg.st); | 340 | convert_fuse_statfs(buf, &outarg.st); |
@@ -462,68 +462,69 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
462 | return 0; | 462 | return 0; |
463 | } | 463 | } |
464 | 464 | ||
465 | static struct fuse_conn *new_conn(struct super_block *sb) | 465 | int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb) |
466 | { | 466 | { |
467 | struct fuse_conn *fc; | ||
468 | int err; | 467 | int err; |
469 | 468 | ||
470 | fc = kzalloc(sizeof(*fc), GFP_KERNEL); | 469 | memset(fc, 0, sizeof(*fc)); |
471 | if (fc) { | 470 | spin_lock_init(&fc->lock); |
472 | spin_lock_init(&fc->lock); | 471 | mutex_init(&fc->inst_mutex); |
473 | mutex_init(&fc->inst_mutex); | 472 | atomic_set(&fc->count, 1); |
474 | atomic_set(&fc->count, 1); | 473 | init_waitqueue_head(&fc->waitq); |
475 | init_waitqueue_head(&fc->waitq); | 474 | init_waitqueue_head(&fc->blocked_waitq); |
476 | init_waitqueue_head(&fc->blocked_waitq); | 475 | init_waitqueue_head(&fc->reserved_req_waitq); |
477 | init_waitqueue_head(&fc->reserved_req_waitq); | 476 | INIT_LIST_HEAD(&fc->pending); |
478 | INIT_LIST_HEAD(&fc->pending); | 477 | INIT_LIST_HEAD(&fc->processing); |
479 | INIT_LIST_HEAD(&fc->processing); | 478 | INIT_LIST_HEAD(&fc->io); |
480 | INIT_LIST_HEAD(&fc->io); | 479 | INIT_LIST_HEAD(&fc->interrupts); |
481 | INIT_LIST_HEAD(&fc->interrupts); | 480 | INIT_LIST_HEAD(&fc->bg_queue); |
482 | INIT_LIST_HEAD(&fc->bg_queue); | 481 | INIT_LIST_HEAD(&fc->entry); |
483 | atomic_set(&fc->num_waiting, 0); | 482 | atomic_set(&fc->num_waiting, 0); |
484 | fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; | 483 | fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; |
485 | fc->bdi.unplug_io_fn = default_unplug_io_fn; | 484 | fc->bdi.unplug_io_fn = default_unplug_io_fn; |
486 | /* fuse does it's own writeback accounting */ | 485 | /* fuse does it's own writeback accounting */ |
487 | fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; | 486 | fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; |
488 | fc->dev = sb->s_dev; | 487 | fc->khctr = 0; |
489 | err = bdi_init(&fc->bdi); | 488 | fc->polled_files = RB_ROOT; |
490 | if (err) | 489 | fc->dev = sb->s_dev; |
491 | goto error_kfree; | 490 | err = bdi_init(&fc->bdi); |
492 | if (sb->s_bdev) { | 491 | if (err) |
493 | err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk", | 492 | goto error_mutex_destroy; |
494 | MAJOR(fc->dev), MINOR(fc->dev)); | 493 | if (sb->s_bdev) { |
495 | } else { | 494 | err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk", |
496 | err = bdi_register_dev(&fc->bdi, fc->dev); | 495 | MAJOR(fc->dev), MINOR(fc->dev)); |
497 | } | 496 | } else { |
498 | if (err) | 497 | err = bdi_register_dev(&fc->bdi, fc->dev); |
499 | goto error_bdi_destroy; | ||
500 | /* | ||
501 | * For a single fuse filesystem use max 1% of dirty + | ||
502 | * writeback threshold. | ||
503 | * | ||
504 | * This gives about 1M of write buffer for memory maps on a | ||
505 | * machine with 1G and 10% dirty_ratio, which should be more | ||
506 | * than enough. | ||
507 | * | ||
508 | * Privileged users can raise it by writing to | ||
509 | * | ||
510 | * /sys/class/bdi/<bdi>/max_ratio | ||
511 | */ | ||
512 | bdi_set_max_ratio(&fc->bdi, 1); | ||
513 | fc->reqctr = 0; | ||
514 | fc->blocked = 1; | ||
515 | fc->attr_version = 1; | ||
516 | get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); | ||
517 | } | 498 | } |
518 | return fc; | 499 | if (err) |
500 | goto error_bdi_destroy; | ||
501 | /* | ||
502 | * For a single fuse filesystem use max 1% of dirty + | ||
503 | * writeback threshold. | ||
504 | * | ||
505 | * This gives about 1M of write buffer for memory maps on a | ||
506 | * machine with 1G and 10% dirty_ratio, which should be more | ||
507 | * than enough. | ||
508 | * | ||
509 | * Privileged users can raise it by writing to | ||
510 | * | ||
511 | * /sys/class/bdi/<bdi>/max_ratio | ||
512 | */ | ||
513 | bdi_set_max_ratio(&fc->bdi, 1); | ||
514 | fc->reqctr = 0; | ||
515 | fc->blocked = 1; | ||
516 | fc->attr_version = 1; | ||
517 | get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); | ||
519 | 518 | ||
520 | error_bdi_destroy: | 519 | return 0; |
520 | |||
521 | error_bdi_destroy: | ||
521 | bdi_destroy(&fc->bdi); | 522 | bdi_destroy(&fc->bdi); |
522 | error_kfree: | 523 | error_mutex_destroy: |
523 | mutex_destroy(&fc->inst_mutex); | 524 | mutex_destroy(&fc->inst_mutex); |
524 | kfree(fc); | 525 | return err; |
525 | return NULL; | ||
526 | } | 526 | } |
527 | EXPORT_SYMBOL_GPL(fuse_conn_init); | ||
527 | 528 | ||
528 | void fuse_conn_put(struct fuse_conn *fc) | 529 | void fuse_conn_put(struct fuse_conn *fc) |
529 | { | 530 | { |
@@ -532,7 +533,7 @@ void fuse_conn_put(struct fuse_conn *fc) | |||
532 | fuse_request_free(fc->destroy_req); | 533 | fuse_request_free(fc->destroy_req); |
533 | mutex_destroy(&fc->inst_mutex); | 534 | mutex_destroy(&fc->inst_mutex); |
534 | bdi_destroy(&fc->bdi); | 535 | bdi_destroy(&fc->bdi); |
535 | kfree(fc); | 536 | fc->release(fc); |
536 | } | 537 | } |
537 | } | 538 | } |
538 | 539 | ||
@@ -542,7 +543,7 @@ struct fuse_conn *fuse_conn_get(struct fuse_conn *fc) | |||
542 | return fc; | 543 | return fc; |
543 | } | 544 | } |
544 | 545 | ||
545 | static struct inode *get_root_inode(struct super_block *sb, unsigned mode) | 546 | static struct inode *fuse_get_root_inode(struct super_block *sb, unsigned mode) |
546 | { | 547 | { |
547 | struct fuse_attr attr; | 548 | struct fuse_attr attr; |
548 | memset(&attr, 0, sizeof(attr)); | 549 | memset(&attr, 0, sizeof(attr)); |
@@ -553,8 +554,7 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode) | |||
553 | return fuse_iget(sb, 1, 0, &attr, 0, 0); | 554 | return fuse_iget(sb, 1, 0, &attr, 0, 0); |
554 | } | 555 | } |
555 | 556 | ||
556 | struct fuse_inode_handle | 557 | struct fuse_inode_handle { |
557 | { | ||
558 | u64 nodeid; | 558 | u64 nodeid; |
559 | u32 generation; | 559 | u32 generation; |
560 | }; | 560 | }; |
@@ -761,7 +761,6 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
761 | fc->max_write = max_t(unsigned, 4096, fc->max_write); | 761 | fc->max_write = max_t(unsigned, 4096, fc->max_write); |
762 | fc->conn_init = 1; | 762 | fc->conn_init = 1; |
763 | } | 763 | } |
764 | fuse_put_request(fc, req); | ||
765 | fc->blocked = 0; | 764 | fc->blocked = 0; |
766 | wake_up_all(&fc->blocked_waitq); | 765 | wake_up_all(&fc->blocked_waitq); |
767 | } | 766 | } |
@@ -787,7 +786,12 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) | |||
787 | req->out.args[0].size = sizeof(struct fuse_init_out); | 786 | req->out.args[0].size = sizeof(struct fuse_init_out); |
788 | req->out.args[0].value = &req->misc.init_out; | 787 | req->out.args[0].value = &req->misc.init_out; |
789 | req->end = process_init_reply; | 788 | req->end = process_init_reply; |
790 | request_send_background(fc, req); | 789 | fuse_request_send_background(fc, req); |
790 | } | ||
791 | |||
792 | static void fuse_free_conn(struct fuse_conn *fc) | ||
793 | { | ||
794 | kfree(fc); | ||
791 | } | 795 | } |
792 | 796 | ||
793 | static int fuse_fill_super(struct super_block *sb, void *data, int silent) | 797 | static int fuse_fill_super(struct super_block *sb, void *data, int silent) |
@@ -828,10 +832,17 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
828 | if (file->f_op != &fuse_dev_operations) | 832 | if (file->f_op != &fuse_dev_operations) |
829 | return -EINVAL; | 833 | return -EINVAL; |
830 | 834 | ||
831 | fc = new_conn(sb); | 835 | fc = kmalloc(sizeof(*fc), GFP_KERNEL); |
832 | if (!fc) | 836 | if (!fc) |
833 | return -ENOMEM; | 837 | return -ENOMEM; |
834 | 838 | ||
839 | err = fuse_conn_init(fc, sb); | ||
840 | if (err) { | ||
841 | kfree(fc); | ||
842 | return err; | ||
843 | } | ||
844 | |||
845 | fc->release = fuse_free_conn; | ||
835 | fc->flags = d.flags; | 846 | fc->flags = d.flags; |
836 | fc->user_id = d.user_id; | 847 | fc->user_id = d.user_id; |
837 | fc->group_id = d.group_id; | 848 | fc->group_id = d.group_id; |
@@ -841,7 +852,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
841 | sb->s_fs_info = fc; | 852 | sb->s_fs_info = fc; |
842 | 853 | ||
843 | err = -ENOMEM; | 854 | err = -ENOMEM; |
844 | root = get_root_inode(sb, d.rootmode); | 855 | root = fuse_get_root_inode(sb, d.rootmode); |
845 | if (!root) | 856 | if (!root) |
846 | goto err; | 857 | goto err; |
847 | 858 | ||
@@ -952,7 +963,7 @@ static inline void unregister_fuseblk(void) | |||
952 | 963 | ||
953 | static void fuse_inode_init_once(void *foo) | 964 | static void fuse_inode_init_once(void *foo) |
954 | { | 965 | { |
955 | struct inode * inode = foo; | 966 | struct inode *inode = foo; |
956 | 967 | ||
957 | inode_init_once(inode); | 968 | inode_init_once(inode); |
958 | } | 969 | } |
@@ -1031,7 +1042,7 @@ static int __init fuse_init(void) | |||
1031 | { | 1042 | { |
1032 | int res; | 1043 | int res; |
1033 | 1044 | ||
1034 | printk("fuse init (API version %i.%i)\n", | 1045 | printk(KERN_INFO "fuse init (API version %i.%i)\n", |
1035 | FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); | 1046 | FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); |
1036 | 1047 | ||
1037 | INIT_LIST_HEAD(&fuse_conn_list); | 1048 | INIT_LIST_HEAD(&fuse_conn_list); |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 0ab0c6f5f438..6903d37af037 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -252,6 +252,7 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf, | |||
252 | for (;;) { | 252 | for (;;) { |
253 | struct page *page; | 253 | struct page *page; |
254 | unsigned long nr, ret; | 254 | unsigned long nr, ret; |
255 | int ra; | ||
255 | 256 | ||
256 | /* nr is the maximum number of bytes to copy from this page */ | 257 | /* nr is the maximum number of bytes to copy from this page */ |
257 | nr = huge_page_size(h); | 258 | nr = huge_page_size(h); |
@@ -274,16 +275,19 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf, | |||
274 | */ | 275 | */ |
275 | ret = len < nr ? len : nr; | 276 | ret = len < nr ? len : nr; |
276 | if (clear_user(buf, ret)) | 277 | if (clear_user(buf, ret)) |
277 | ret = -EFAULT; | 278 | ra = -EFAULT; |
279 | else | ||
280 | ra = 0; | ||
278 | } else { | 281 | } else { |
279 | /* | 282 | /* |
280 | * We have the page, copy it to user space buffer. | 283 | * We have the page, copy it to user space buffer. |
281 | */ | 284 | */ |
282 | ret = hugetlbfs_read_actor(page, offset, buf, len, nr); | 285 | ra = hugetlbfs_read_actor(page, offset, buf, len, nr); |
286 | ret = ra; | ||
283 | } | 287 | } |
284 | if (ret < 0) { | 288 | if (ra < 0) { |
285 | if (retval == 0) | 289 | if (retval == 0) |
286 | retval = ret; | 290 | retval = ra; |
287 | if (page) | 291 | if (page) |
288 | page_cache_release(page); | 292 | page_cache_release(page); |
289 | goto out; | 293 | goto out; |
diff --git a/fs/inode.c b/fs/inode.c index bd48e5e6d3e8..7a6e8c2ff7b1 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -110,8 +110,8 @@ static void wake_up_inode(struct inode *inode) | |||
110 | 110 | ||
111 | /** | 111 | /** |
112 | * inode_init_always - perform inode structure intialisation | 112 | * inode_init_always - perform inode structure intialisation |
113 | * @sb - superblock inode belongs to. | 113 | * @sb: superblock inode belongs to |
114 | * @inode - inode to initialise | 114 | * @inode: inode to initialise |
115 | * | 115 | * |
116 | * These are initializations that need to be done on every inode | 116 | * These are initializations that need to be done on every inode |
117 | * allocation as the fields are not initialised by slab allocation. | 117 | * allocation as the fields are not initialised by slab allocation. |
@@ -166,7 +166,7 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode) | |||
166 | mapping->a_ops = &empty_aops; | 166 | mapping->a_ops = &empty_aops; |
167 | mapping->host = inode; | 167 | mapping->host = inode; |
168 | mapping->flags = 0; | 168 | mapping->flags = 0; |
169 | mapping_set_gfp_mask(mapping, GFP_HIGHUSER_PAGECACHE); | 169 | mapping_set_gfp_mask(mapping, GFP_HIGHUSER_MOVABLE); |
170 | mapping->assoc_mapping = NULL; | 170 | mapping->assoc_mapping = NULL; |
171 | mapping->backing_dev_info = &default_backing_dev_info; | 171 | mapping->backing_dev_info = &default_backing_dev_info; |
172 | mapping->writeback_index = 0; | 172 | mapping->writeback_index = 0; |
@@ -576,8 +576,8 @@ __inode_add_to_lists(struct super_block *sb, struct hlist_head *head, | |||
576 | 576 | ||
577 | /** | 577 | /** |
578 | * inode_add_to_lists - add a new inode to relevant lists | 578 | * inode_add_to_lists - add a new inode to relevant lists |
579 | * @sb - superblock inode belongs to. | 579 | * @sb: superblock inode belongs to |
580 | * @inode - inode to mark in use | 580 | * @inode: inode to mark in use |
581 | * | 581 | * |
582 | * When an inode is allocated it needs to be accounted for, added to the in use | 582 | * When an inode is allocated it needs to be accounted for, added to the in use |
583 | * list, the owning superblock and the inode hash. This needs to be done under | 583 | * list, the owning superblock and the inode hash. This needs to be done under |
@@ -601,7 +601,7 @@ EXPORT_SYMBOL_GPL(inode_add_to_lists); | |||
601 | * @sb: superblock | 601 | * @sb: superblock |
602 | * | 602 | * |
603 | * Allocates a new inode for given superblock. The default gfp_mask | 603 | * Allocates a new inode for given superblock. The default gfp_mask |
604 | * for allocations related to inode->i_mapping is GFP_HIGHUSER_PAGECACHE. | 604 | * for allocations related to inode->i_mapping is GFP_HIGHUSER_MOVABLE. |
605 | * If HIGHMEM pages are unsuitable or it is known that pages allocated | 605 | * If HIGHMEM pages are unsuitable or it is known that pages allocated |
606 | * for the page cache are not reclaimable or migratable, | 606 | * for the page cache are not reclaimable or migratable, |
607 | * mapping_set_gfp_mask() must be called with suitable flags on the | 607 | * mapping_set_gfp_mask() must be called with suitable flags on the |
diff --git a/fs/minix/dir.c b/fs/minix/dir.c index f70433816a38..d4946c4c90e2 100644 --- a/fs/minix/dir.c +++ b/fs/minix/dir.c | |||
@@ -280,7 +280,7 @@ int minix_add_link(struct dentry *dentry, struct inode *inode) | |||
280 | return -EINVAL; | 280 | return -EINVAL; |
281 | 281 | ||
282 | got_it: | 282 | got_it: |
283 | pos = (page->index >> PAGE_CACHE_SHIFT) + p - (char*)page_address(page); | 283 | pos = page_offset(page) + p - (char *)page_address(page); |
284 | err = __minix_write_begin(NULL, page->mapping, pos, sbi->s_dirsize, | 284 | err = __minix_write_begin(NULL, page->mapping, pos, sbi->s_dirsize, |
285 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | 285 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); |
286 | if (err) | 286 | if (err) |
diff --git a/fs/mpage.c b/fs/mpage.c index 552b80b3facc..16c3ef37eae3 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
@@ -241,7 +241,6 @@ do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages, | |||
241 | first_hole = page_block; | 241 | first_hole = page_block; |
242 | page_block++; | 242 | page_block++; |
243 | block_in_file++; | 243 | block_in_file++; |
244 | clear_buffer_mapped(map_bh); | ||
245 | continue; | 244 | continue; |
246 | } | 245 | } |
247 | 246 | ||
@@ -308,7 +307,10 @@ alloc_new: | |||
308 | goto alloc_new; | 307 | goto alloc_new; |
309 | } | 308 | } |
310 | 309 | ||
311 | if (buffer_boundary(map_bh) || (first_hole != blocks_per_page)) | 310 | relative_block = block_in_file - *first_logical_block; |
311 | nblocks = map_bh->b_size >> blkbits; | ||
312 | if ((buffer_boundary(map_bh) && relative_block == nblocks) || | ||
313 | (first_hole != blocks_per_page)) | ||
312 | bio = mpage_bio_submit(READ, bio); | 314 | bio = mpage_bio_submit(READ, bio); |
313 | else | 315 | else |
314 | *last_block_in_bio = blocks[blocks_per_page - 1]; | 316 | *last_block_in_bio = blocks[blocks_per_page - 1]; |
diff --git a/fs/ncpfs/getopt.c b/fs/ncpfs/getopt.c index 335b003dddf9..0af3349de851 100644 --- a/fs/ncpfs/getopt.c +++ b/fs/ncpfs/getopt.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * @opts: an array of &struct option entries controlling parser operations | 16 | * @opts: an array of &struct option entries controlling parser operations |
17 | * @optopt: output; will contain the current option | 17 | * @optopt: output; will contain the current option |
18 | * @optarg: output; will contain the value (if one exists) | 18 | * @optarg: output; will contain the value (if one exists) |
19 | * @flag: output; may be NULL; should point to a long for or'ing flags | ||
20 | * @value: output; may be NULL; will be overwritten with the integer value | 19 | * @value: output; may be NULL; will be overwritten with the integer value |
21 | * of the current argument. | 20 | * of the current argument. |
22 | * | 21 | * |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 6d5b213b8a9b..5198ada67398 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -384,9 +384,9 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
384 | 384 | ||
385 | dname = dev_name(ddev); | 385 | dname = dev_name(ddev); |
386 | if (isdigit(dname[strlen(dname) - 1])) | 386 | if (isdigit(dname[strlen(dname) - 1])) |
387 | snprintf(pdev->bus_id, BUS_ID_SIZE, "%sp%d", dname, partno); | 387 | dev_set_name(pdev, "%sp%d", dname, partno); |
388 | else | 388 | else |
389 | snprintf(pdev->bus_id, BUS_ID_SIZE, "%s%d", dname, partno); | 389 | dev_set_name(pdev, "%s%d", dname, partno); |
390 | 390 | ||
391 | device_initialize(pdev); | 391 | device_initialize(pdev); |
392 | pdev->class = &block_class; | 392 | pdev->class = &block_class; |
@@ -447,16 +447,11 @@ void register_disk(struct gendisk *disk) | |||
447 | struct block_device *bdev; | 447 | struct block_device *bdev; |
448 | struct disk_part_iter piter; | 448 | struct disk_part_iter piter; |
449 | struct hd_struct *part; | 449 | struct hd_struct *part; |
450 | char *s; | ||
451 | int err; | 450 | int err; |
452 | 451 | ||
453 | ddev->parent = disk->driverfs_dev; | 452 | ddev->parent = disk->driverfs_dev; |
454 | 453 | ||
455 | strlcpy(ddev->bus_id, disk->disk_name, BUS_ID_SIZE); | 454 | dev_set_name(ddev, disk->disk_name); |
456 | /* ewww... some of these buggers have / in the name... */ | ||
457 | s = strchr(ddev->bus_id, '/'); | ||
458 | if (s) | ||
459 | *s = '!'; | ||
460 | 455 | ||
461 | /* delay uevents, until we scanned partition table */ | 456 | /* delay uevents, until we scanned partition table */ |
462 | ddev->uevent_suppress = 1; | 457 | ddev->uevent_suppress = 1; |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 3a8bdd7f5756..94063840832a 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -396,7 +396,9 @@ static int show_smap(struct seq_file *m, void *v) | |||
396 | "Private_Clean: %8lu kB\n" | 396 | "Private_Clean: %8lu kB\n" |
397 | "Private_Dirty: %8lu kB\n" | 397 | "Private_Dirty: %8lu kB\n" |
398 | "Referenced: %8lu kB\n" | 398 | "Referenced: %8lu kB\n" |
399 | "Swap: %8lu kB\n", | 399 | "Swap: %8lu kB\n" |
400 | "KernelPageSize: %8lu kB\n" | ||
401 | "MMUPageSize: %8lu kB\n", | ||
400 | (vma->vm_end - vma->vm_start) >> 10, | 402 | (vma->vm_end - vma->vm_start) >> 10, |
401 | mss.resident >> 10, | 403 | mss.resident >> 10, |
402 | (unsigned long)(mss.pss >> (10 + PSS_SHIFT)), | 404 | (unsigned long)(mss.pss >> (10 + PSS_SHIFT)), |
@@ -405,7 +407,9 @@ static int show_smap(struct seq_file *m, void *v) | |||
405 | mss.private_clean >> 10, | 407 | mss.private_clean >> 10, |
406 | mss.private_dirty >> 10, | 408 | mss.private_dirty >> 10, |
407 | mss.referenced >> 10, | 409 | mss.referenced >> 10, |
408 | mss.swap >> 10); | 410 | mss.swap >> 10, |
411 | vma_kernel_pagesize(vma) >> 10, | ||
412 | vma_mmu_pagesize(vma) >> 10); | ||
409 | 413 | ||
410 | if (m->count < m->size) /* vma is copied successfully */ | 414 | if (m->count < m->size) /* vma is copied successfully */ |
411 | m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0; | 415 | m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0; |
diff --git a/fs/select.c b/fs/select.c index 87df51eadcf2..08b91beed806 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -109,11 +109,11 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, | |||
109 | void poll_initwait(struct poll_wqueues *pwq) | 109 | void poll_initwait(struct poll_wqueues *pwq) |
110 | { | 110 | { |
111 | init_poll_funcptr(&pwq->pt, __pollwait); | 111 | init_poll_funcptr(&pwq->pt, __pollwait); |
112 | pwq->polling_task = current; | ||
112 | pwq->error = 0; | 113 | pwq->error = 0; |
113 | pwq->table = NULL; | 114 | pwq->table = NULL; |
114 | pwq->inline_index = 0; | 115 | pwq->inline_index = 0; |
115 | } | 116 | } |
116 | |||
117 | EXPORT_SYMBOL(poll_initwait); | 117 | EXPORT_SYMBOL(poll_initwait); |
118 | 118 | ||
119 | static void free_poll_entry(struct poll_table_entry *entry) | 119 | static void free_poll_entry(struct poll_table_entry *entry) |
@@ -142,12 +142,10 @@ void poll_freewait(struct poll_wqueues *pwq) | |||
142 | free_page((unsigned long) old); | 142 | free_page((unsigned long) old); |
143 | } | 143 | } |
144 | } | 144 | } |
145 | |||
146 | EXPORT_SYMBOL(poll_freewait); | 145 | EXPORT_SYMBOL(poll_freewait); |
147 | 146 | ||
148 | static struct poll_table_entry *poll_get_entry(poll_table *_p) | 147 | static struct poll_table_entry *poll_get_entry(struct poll_wqueues *p) |
149 | { | 148 | { |
150 | struct poll_wqueues *p = container_of(_p, struct poll_wqueues, pt); | ||
151 | struct poll_table_page *table = p->table; | 149 | struct poll_table_page *table = p->table; |
152 | 150 | ||
153 | if (p->inline_index < N_INLINE_POLL_ENTRIES) | 151 | if (p->inline_index < N_INLINE_POLL_ENTRIES) |
@@ -159,7 +157,6 @@ static struct poll_table_entry *poll_get_entry(poll_table *_p) | |||
159 | new_table = (struct poll_table_page *) __get_free_page(GFP_KERNEL); | 157 | new_table = (struct poll_table_page *) __get_free_page(GFP_KERNEL); |
160 | if (!new_table) { | 158 | if (!new_table) { |
161 | p->error = -ENOMEM; | 159 | p->error = -ENOMEM; |
162 | __set_current_state(TASK_RUNNING); | ||
163 | return NULL; | 160 | return NULL; |
164 | } | 161 | } |
165 | new_table->entry = new_table->entries; | 162 | new_table->entry = new_table->entries; |
@@ -171,20 +168,75 @@ static struct poll_table_entry *poll_get_entry(poll_table *_p) | |||
171 | return table->entry++; | 168 | return table->entry++; |
172 | } | 169 | } |
173 | 170 | ||
171 | static int pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key) | ||
172 | { | ||
173 | struct poll_wqueues *pwq = wait->private; | ||
174 | DECLARE_WAITQUEUE(dummy_wait, pwq->polling_task); | ||
175 | |||
176 | /* | ||
177 | * Although this function is called under waitqueue lock, LOCK | ||
178 | * doesn't imply write barrier and the users expect write | ||
179 | * barrier semantics on wakeup functions. The following | ||
180 | * smp_wmb() is equivalent to smp_wmb() in try_to_wake_up() | ||
181 | * and is paired with set_mb() in poll_schedule_timeout. | ||
182 | */ | ||
183 | smp_wmb(); | ||
184 | pwq->triggered = 1; | ||
185 | |||
186 | /* | ||
187 | * Perform the default wake up operation using a dummy | ||
188 | * waitqueue. | ||
189 | * | ||
190 | * TODO: This is hacky but there currently is no interface to | ||
191 | * pass in @sync. @sync is scheduled to be removed and once | ||
192 | * that happens, wake_up_process() can be used directly. | ||
193 | */ | ||
194 | return default_wake_function(&dummy_wait, mode, sync, key); | ||
195 | } | ||
196 | |||
174 | /* Add a new entry */ | 197 | /* Add a new entry */ |
175 | static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, | 198 | static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, |
176 | poll_table *p) | 199 | poll_table *p) |
177 | { | 200 | { |
178 | struct poll_table_entry *entry = poll_get_entry(p); | 201 | struct poll_wqueues *pwq = container_of(p, struct poll_wqueues, pt); |
202 | struct poll_table_entry *entry = poll_get_entry(pwq); | ||
179 | if (!entry) | 203 | if (!entry) |
180 | return; | 204 | return; |
181 | get_file(filp); | 205 | get_file(filp); |
182 | entry->filp = filp; | 206 | entry->filp = filp; |
183 | entry->wait_address = wait_address; | 207 | entry->wait_address = wait_address; |
184 | init_waitqueue_entry(&entry->wait, current); | 208 | init_waitqueue_func_entry(&entry->wait, pollwake); |
209 | entry->wait.private = pwq; | ||
185 | add_wait_queue(wait_address, &entry->wait); | 210 | add_wait_queue(wait_address, &entry->wait); |
186 | } | 211 | } |
187 | 212 | ||
213 | int poll_schedule_timeout(struct poll_wqueues *pwq, int state, | ||
214 | ktime_t *expires, unsigned long slack) | ||
215 | { | ||
216 | int rc = -EINTR; | ||
217 | |||
218 | set_current_state(state); | ||
219 | if (!pwq->triggered) | ||
220 | rc = schedule_hrtimeout_range(expires, slack, HRTIMER_MODE_ABS); | ||
221 | __set_current_state(TASK_RUNNING); | ||
222 | |||
223 | /* | ||
224 | * Prepare for the next iteration. | ||
225 | * | ||
226 | * The following set_mb() serves two purposes. First, it's | ||
227 | * the counterpart rmb of the wmb in pollwake() such that data | ||
228 | * written before wake up is always visible after wake up. | ||
229 | * Second, the full barrier guarantees that triggered clearing | ||
230 | * doesn't pass event check of the next iteration. Note that | ||
231 | * this problem doesn't exist for the first iteration as | ||
232 | * add_wait_queue() has full barrier semantics. | ||
233 | */ | ||
234 | set_mb(pwq->triggered, 0); | ||
235 | |||
236 | return rc; | ||
237 | } | ||
238 | EXPORT_SYMBOL(poll_schedule_timeout); | ||
239 | |||
188 | /** | 240 | /** |
189 | * poll_select_set_timeout - helper function to setup the timeout value | 241 | * poll_select_set_timeout - helper function to setup the timeout value |
190 | * @to: pointer to timespec variable for the final timeout | 242 | * @to: pointer to timespec variable for the final timeout |
@@ -340,8 +392,6 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
340 | for (;;) { | 392 | for (;;) { |
341 | unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp; | 393 | unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp; |
342 | 394 | ||
343 | set_current_state(TASK_INTERRUPTIBLE); | ||
344 | |||
345 | inp = fds->in; outp = fds->out; exp = fds->ex; | 395 | inp = fds->in; outp = fds->out; exp = fds->ex; |
346 | rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex; | 396 | rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex; |
347 | 397 | ||
@@ -411,10 +461,10 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
411 | to = &expire; | 461 | to = &expire; |
412 | } | 462 | } |
413 | 463 | ||
414 | if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)) | 464 | if (!poll_schedule_timeout(&table, TASK_INTERRUPTIBLE, |
465 | to, slack)) | ||
415 | timed_out = 1; | 466 | timed_out = 1; |
416 | } | 467 | } |
417 | __set_current_state(TASK_RUNNING); | ||
418 | 468 | ||
419 | poll_freewait(&table); | 469 | poll_freewait(&table); |
420 | 470 | ||
@@ -666,7 +716,6 @@ static int do_poll(unsigned int nfds, struct poll_list *list, | |||
666 | for (;;) { | 716 | for (;;) { |
667 | struct poll_list *walk; | 717 | struct poll_list *walk; |
668 | 718 | ||
669 | set_current_state(TASK_INTERRUPTIBLE); | ||
670 | for (walk = list; walk != NULL; walk = walk->next) { | 719 | for (walk = list; walk != NULL; walk = walk->next) { |
671 | struct pollfd * pfd, * pfd_end; | 720 | struct pollfd * pfd, * pfd_end; |
672 | 721 | ||
@@ -709,10 +758,9 @@ static int do_poll(unsigned int nfds, struct poll_list *list, | |||
709 | to = &expire; | 758 | to = &expire; |
710 | } | 759 | } |
711 | 760 | ||
712 | if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)) | 761 | if (!poll_schedule_timeout(wait, TASK_INTERRUPTIBLE, to, slack)) |
713 | timed_out = 1; | 762 | timed_out = 1; |
714 | } | 763 | } |
715 | __set_current_state(TASK_RUNNING); | ||
716 | return count; | 764 | return count; |
717 | } | 765 | } |
718 | 766 | ||
@@ -295,7 +295,7 @@ int do_sync_mapping_range(struct address_space *mapping, loff_t offset, | |||
295 | 295 | ||
296 | if (flags & SYNC_FILE_RANGE_WRITE) { | 296 | if (flags & SYNC_FILE_RANGE_WRITE) { |
297 | ret = __filemap_fdatawrite_range(mapping, offset, endbyte, | 297 | ret = __filemap_fdatawrite_range(mapping, offset, endbyte, |
298 | WB_SYNC_NONE); | 298 | WB_SYNC_ALL); |
299 | if (ret < 0) | 299 | if (ret < 0) |
300 | goto out; | 300 | goto out; |
301 | } | 301 | } |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 0d7564b95f8e..89556ee72518 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -432,12 +432,19 @@ static int ubifs_sync_fs(struct super_block *sb, int wait) | |||
432 | int i, err; | 432 | int i, err; |
433 | struct ubifs_info *c = sb->s_fs_info; | 433 | struct ubifs_info *c = sb->s_fs_info; |
434 | struct writeback_control wbc = { | 434 | struct writeback_control wbc = { |
435 | .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_HOLD, | 435 | .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_NONE, |
436 | .range_start = 0, | 436 | .range_start = 0, |
437 | .range_end = LLONG_MAX, | 437 | .range_end = LLONG_MAX, |
438 | .nr_to_write = LONG_MAX, | 438 | .nr_to_write = LONG_MAX, |
439 | }; | 439 | }; |
440 | 440 | ||
441 | /* | ||
442 | * Note by akpm about WB_SYNC_NONE used above: zero @wait is just an | ||
443 | * advisory thing to help the file system shove lots of data into the | ||
444 | * queues. If some gets missed then it'll be picked up on the second | ||
445 | * '->sync_fs()' call, with non-zero @wait. | ||
446 | */ | ||
447 | |||
441 | if (sb->s_flags & MS_RDONLY) | 448 | if (sb->s_flags & MS_RDONLY) |
442 | return 0; | 449 | return 0; |
443 | 450 | ||