diff options
Diffstat (limited to 'fs/ubifs/budget.c')
-rw-r--r-- | fs/ubifs/budget.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index 7851480a6cea..101d278c591d 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
@@ -747,14 +747,24 @@ long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free) | |||
747 | } | 747 | } |
748 | 748 | ||
749 | /** | 749 | /** |
750 | * ubifs_budg_get_free_space - return amount of free space. | 750 | * ubifs_get_free_space - return amount of free space. |
751 | * @c: UBIFS file-system description object | 751 | * @c: UBIFS file-system description object |
752 | * | 752 | * |
753 | * This function returns amount of free space on the file-system. | 753 | * This function calculates amount of free space to report to user-space. |
754 | * | ||
755 | * Because UBIFS may introduce substantial overhead (the index, node headers, | ||
756 | * alighment, wastage at the end of eraseblocks, etc), it cannot report real | ||
757 | * amount of free flash space it has (well, because not all dirty space is | ||
758 | * reclamable, UBIFS does not actually know the real amount). If UBIFS did so, | ||
759 | * it would bread user expectetion about what free space is. Users seem to | ||
760 | * accustomed to assume that if the file-system reports N bytes of free space, | ||
761 | * they would be able to fit a file of N bytes to the FS. This almost works for | ||
762 | * traditional file-systems, because they have way less overhead than UBIFS. | ||
763 | * So, to keep users happy, UBIFS tries to take the overhead into account. | ||
754 | */ | 764 | */ |
755 | long long ubifs_budg_get_free_space(struct ubifs_info *c) | 765 | long long ubifs_get_free_space(struct ubifs_info *c) |
756 | { | 766 | { |
757 | int min_idx_lebs; | 767 | int min_idx_lebs, rsvd_idx_lebs, lebs; |
758 | long long available, outstanding, free; | 768 | long long available, outstanding, free; |
759 | 769 | ||
760 | spin_lock(&c->space_lock); | 770 | spin_lock(&c->space_lock); |
@@ -771,6 +781,26 @@ long long ubifs_budg_get_free_space(struct ubifs_info *c) | |||
771 | } | 781 | } |
772 | 782 | ||
773 | available = ubifs_calc_available(c, min_idx_lebs); | 783 | available = ubifs_calc_available(c, min_idx_lebs); |
784 | |||
785 | /* | ||
786 | * When reporting free space to user-space, UBIFS guarantees that it is | ||
787 | * possible to write a file of free space size. This means that for | ||
788 | * empty LEBs we may use more precise calculations than | ||
789 | * 'ubifs_calc_available()' is using. Namely, we know that in empty | ||
790 | * LEBs we would waste only @c->leb_overhead bytes, not @c->dark_wm. | ||
791 | * Thus, amend the available space. | ||
792 | * | ||
793 | * Note, the calculations below are similar to what we have in | ||
794 | * 'do_budget_space()', so refer there for comments. | ||
795 | */ | ||
796 | if (min_idx_lebs > c->lst.idx_lebs) | ||
797 | rsvd_idx_lebs = min_idx_lebs - c->lst.idx_lebs; | ||
798 | else | ||
799 | rsvd_idx_lebs = 0; | ||
800 | lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt - | ||
801 | c->lst.taken_empty_lebs; | ||
802 | lebs -= rsvd_idx_lebs; | ||
803 | available += lebs * (c->dark_wm - c->leb_overhead); | ||
774 | spin_unlock(&c->space_lock); | 804 | spin_unlock(&c->space_lock); |
775 | 805 | ||
776 | if (available > outstanding) | 806 | if (available > outstanding) |