.. | .. |
---|
5 | 5 | |
---|
6 | 6 | #include <linux/blkdev.h> |
---|
7 | 7 | #include <linux/compat.h> |
---|
| 8 | +#include <linux/delay.h> |
---|
8 | 9 | #include <linux/file.h> |
---|
9 | 10 | #include <linux/fs.h> |
---|
10 | 11 | #include <linux/fs_stack.h> |
---|
.. | .. |
---|
477 | 478 | |
---|
478 | 479 | static int read_single_page_timeouts(struct data_file *df, struct file *f, |
---|
479 | 480 | int block_index, struct mem_range range, |
---|
480 | | - struct mem_range tmp) |
---|
| 481 | + struct mem_range tmp, |
---|
| 482 | + unsigned int *delayed_min_us) |
---|
481 | 483 | { |
---|
482 | 484 | struct mount_info *mi = df->df_mount_info; |
---|
483 | 485 | struct incfs_read_data_file_timeouts timeouts = { |
---|
.. | .. |
---|
509 | 511 | } |
---|
510 | 512 | |
---|
511 | 513 | return incfs_read_data_file_block(range, f, block_index, tmp, |
---|
512 | | - &timeouts); |
---|
| 514 | + &timeouts, delayed_min_us); |
---|
| 515 | +} |
---|
| 516 | + |
---|
| 517 | +static int usleep_interruptible(u32 us) |
---|
| 518 | +{ |
---|
| 519 | + /* See: |
---|
| 520 | + * https://www.kernel.org/doc/Documentation/timers/timers-howto.txt |
---|
| 521 | + * for explanation |
---|
| 522 | + */ |
---|
| 523 | + if (us < 10) { |
---|
| 524 | + udelay(us); |
---|
| 525 | + return 0; |
---|
| 526 | + } else if (us < 20000) { |
---|
| 527 | + usleep_range(us, us + us / 10); |
---|
| 528 | + return 0; |
---|
| 529 | + } else |
---|
| 530 | + return msleep_interruptible(us / 1000); |
---|
513 | 531 | } |
---|
514 | 532 | |
---|
515 | 533 | static int read_single_page(struct file *f, struct page *page) |
---|
.. | .. |
---|
522 | 540 | int result = 0; |
---|
523 | 541 | void *page_start; |
---|
524 | 542 | int block_index; |
---|
| 543 | + unsigned int delayed_min_us = 0; |
---|
525 | 544 | |
---|
526 | 545 | if (!df) { |
---|
527 | 546 | SetPageError(page); |
---|
.. | .. |
---|
547 | 566 | bytes_to_read = min_t(loff_t, size - offset, PAGE_SIZE); |
---|
548 | 567 | |
---|
549 | 568 | read_result = read_single_page_timeouts(df, f, block_index, |
---|
550 | | - range(page_start, bytes_to_read), tmp); |
---|
| 569 | + range(page_start, bytes_to_read), tmp, |
---|
| 570 | + &delayed_min_us); |
---|
551 | 571 | |
---|
552 | 572 | free_pages((unsigned long)tmp.data, get_order(tmp.len)); |
---|
553 | 573 | } else { |
---|
.. | .. |
---|
569 | 589 | flush_dcache_page(page); |
---|
570 | 590 | kunmap(page); |
---|
571 | 591 | unlock_page(page); |
---|
| 592 | + if (delayed_min_us) |
---|
| 593 | + usleep_interruptible(delayed_min_us); |
---|
572 | 594 | return result; |
---|
573 | 595 | } |
---|
574 | 596 | |
---|
.. | .. |
---|
662 | 684 | dput(file); |
---|
663 | 685 | } |
---|
664 | 686 | |
---|
665 | | -static void maybe_delete_incomplete_file(struct file *f, |
---|
666 | | - struct data_file *df) |
---|
| 687 | +static void handle_file_completed(struct file *f, struct data_file *df) |
---|
667 | 688 | { |
---|
668 | 689 | struct backing_file_context *bfc; |
---|
669 | 690 | struct mount_info *mi = df->df_mount_info; |
---|
.. | .. |
---|
671 | 692 | struct dentry *incomplete_file_dentry = NULL; |
---|
672 | 693 | const struct cred *old_cred = override_creds(mi->mi_owner); |
---|
673 | 694 | int error; |
---|
674 | | - |
---|
675 | | - if (atomic_read(&df->df_data_blocks_written) < df->df_data_block_count) |
---|
676 | | - goto out; |
---|
677 | 695 | |
---|
678 | 696 | /* Truncate file to remove any preallocated space */ |
---|
679 | 697 | bfc = df->df_backing_file_context; |
---|
.. | .. |
---|
733 | 751 | u8 *data_buf = NULL; |
---|
734 | 752 | ssize_t error = 0; |
---|
735 | 753 | int i = 0; |
---|
| 754 | + bool complete = false; |
---|
736 | 755 | |
---|
737 | 756 | if (!df) |
---|
738 | 757 | return -EBADF; |
---|
.. | .. |
---|
774 | 793 | data_buf); |
---|
775 | 794 | } else { |
---|
776 | 795 | error = incfs_process_new_data_block(df, &fill_block, |
---|
777 | | - data_buf); |
---|
| 796 | + data_buf, &complete); |
---|
778 | 797 | } |
---|
779 | 798 | if (error) |
---|
780 | 799 | break; |
---|
.. | .. |
---|
783 | 802 | if (data_buf) |
---|
784 | 803 | free_pages((unsigned long)data_buf, get_order(data_buf_size)); |
---|
785 | 804 | |
---|
786 | | - maybe_delete_incomplete_file(f, df); |
---|
| 805 | + if (complete) |
---|
| 806 | + handle_file_completed(f, df); |
---|
787 | 807 | |
---|
788 | 808 | /* |
---|
789 | 809 | * Only report the error if no records were processed, otherwise |
---|
.. | .. |
---|
1908 | 1928 | |
---|
1909 | 1929 | pr_debug("incfs: unmount\n"); |
---|
1910 | 1930 | |
---|
| 1931 | + /* |
---|
| 1932 | + * We must kill the super before freeing mi, since killing the super |
---|
| 1933 | + * triggers inode eviction, which triggers the final update of the |
---|
| 1934 | + * backing file, which uses certain information for mi |
---|
| 1935 | + */ |
---|
| 1936 | + kill_anon_super(sb); |
---|
| 1937 | + |
---|
1911 | 1938 | if (mi) { |
---|
1912 | 1939 | if (mi->mi_backing_dir_path.dentry) |
---|
1913 | 1940 | dinode = d_inode(mi->mi_backing_dir_path.dentry); |
---|
.. | .. |
---|
1923 | 1950 | incfs_free_mount_info(mi); |
---|
1924 | 1951 | sb->s_fs_info = NULL; |
---|
1925 | 1952 | } |
---|
1926 | | - kill_anon_super(sb); |
---|
1927 | 1953 | } |
---|
1928 | 1954 | |
---|
1929 | 1955 | static int show_options(struct seq_file *m, struct dentry *root) |
---|