@@ -590,11 +590,10 @@ static u64 apfs_free_queue_oldest_xid(struct apfs_node *root)
590590 * apfs_flush_free_queue - Free ip blocks queued by old transactions
591591 * @sb: superblock structure
592592 * @qid: queue to be freed
593- * @force: flush as much as possible
594593 *
595594 * Returns 0 on success or a negative error code in case of failure.
596595 */
597- static int apfs_flush_free_queue (struct super_block * sb , unsigned int qid , bool force )
596+ static int apfs_flush_free_queue (struct super_block * sb , unsigned int qid )
598597{
599598 struct apfs_nxsb_info * nxi = APFS_NXI (sb );
600599 struct apfs_spaceman * sm = APFS_SM (sb );
@@ -612,19 +611,15 @@ static int apfs_flush_free_queue(struct super_block *sb, unsigned int qid, bool
612611 }
613612
614613 while (oldest ) {
615- u64 sfq_count ;
616-
617614 /*
618- * Try to preserve one transaction here. I don't really know
619- * what free queues are for so this is probably silly.
615+ * Blocks freed in the current transaction can't be reused
616+ * safely until after the commit, but I don't think there is
617+ * any point in preserving old transacions. I'm guessing the
618+ * official driver keeps multiple transactions going at the
619+ * same time, that must be why they need a free queue.
620620 */
621- if (force ) {
622- if (oldest == nxi -> nx_xid )
623- break ;
624- } else {
625- if (oldest + 1 >= nxi -> nx_xid )
626- break ;
627- }
621+ if (oldest == nxi -> nx_xid )
622+ break ;
628623
629624 while (true) {
630625 u64 count = 0 ;
@@ -643,22 +638,6 @@ static int apfs_flush_free_queue(struct super_block *sb, unsigned int qid, bool
643638 }
644639 oldest = apfs_free_queue_oldest_xid (fq_root );
645640 fq -> sfq_oldest_xid = cpu_to_le64 (oldest );
646-
647- if (force )
648- continue ;
649-
650- /*
651- * Flushing a single transaction may not be enough to avoid
652- * running out of space in the ip, but it's probably best not
653- * to flush all the old transactions at once either. We use a
654- * harsher version of the apfs_transaction_need_commit() check,
655- * to make sure we won't be forced to commit again right away.
656- */
657- sfq_count = le64_to_cpu (fq -> sfq_count );
658- if (qid == APFS_SFQ_IP && sfq_count * 6 <= le64_to_cpu (sm_raw -> sm_ip_block_count ))
659- break ;
660- if (qid == APFS_SFQ_MAIN && sfq_count <= APFS_TRANS_MAIN_QUEUE_MAX - 200 )
661- break ;
662641 }
663642
664643fail :
@@ -787,12 +766,16 @@ int apfs_read_spaceman(struct super_block *sb)
787766 goto fail ;
788767 }
789768
790- err = apfs_flush_free_queue (sb , APFS_SFQ_IP , false /* force */ );
769+ /*
770+ * We flush free queues whole when each transaction begins, to make it
771+ * harder for the btrees to become too unbalanced.
772+ */
773+ err = apfs_flush_free_queue (sb , APFS_SFQ_IP );
791774 if (err ) {
792775 apfs_err (sb , "failed to flush ip fq" );
793776 goto fail ;
794777 }
795- err = apfs_flush_free_queue (sb , APFS_SFQ_MAIN , false /* force */ );
778+ err = apfs_flush_free_queue (sb , APFS_SFQ_MAIN );
796779 if (err ) {
797780 apfs_err (sb , "failed to flush main fq" );
798781 goto fail ;
@@ -926,8 +909,7 @@ static inline int apfs_chunk_mark_free(struct super_block *sb, char *bitmap,
926909 * @count: number of consecutive blocks to free
927910 *
928911 * Same as apfs_free_queue_insert_nocache(), except that this one can also fail
929- * with -EAGAIN if there is no room for the new record, so that the caller can
930- * flush the queue and retry.
912+ * with -ENOSPC if there is no room for the new record.
931913 */
932914static int apfs_free_queue_try_insert (struct super_block * sb , u64 bno , u64 count )
933915{
@@ -978,7 +960,7 @@ static int apfs_free_queue_try_insert(struct super_block *sb, u64 bno, u64 count
978960 if (node_count == node_limit ) {
979961 needed_room = sizeof (raw_key ) + (ghost ? 0 : sizeof (raw_val ));
980962 if (!apfs_node_has_room (query -> node , needed_room , false /* replace */ )) {
981- err = - EAGAIN ;
963+ err = - ENOSPC ;
982964 goto fail ;
983965 }
984966 }
@@ -1020,25 +1002,16 @@ static int apfs_free_queue_try_insert(struct super_block *sb, u64 bno, u64 count
10201002 */
10211003int apfs_free_queue_insert_nocache (struct super_block * sb , u64 bno , u64 count )
10221004{
1023- struct apfs_spaceman * sm = APFS_SM (sb );
10241005 unsigned int qid ;
10251006 int err ;
10261007
10271008 err = apfs_free_queue_try_insert (sb , bno , count );
1028- if (err == - EAGAIN ) {
1029- qid = apfs_block_in_ip (sm , bno ) ? APFS_SFQ_IP : APFS_SFQ_MAIN ;
1030- err = apfs_flush_free_queue (sb , qid , true /* force */ );
1031- if (err ) {
1032- apfs_err (sb , "failed to flush fq to make room" );
1033- return err ;
1034- }
1035- err = apfs_free_queue_try_insert (sb , bno , count );
1009+ if (err == - ENOSPC ) {
1010+ qid = apfs_block_in_ip (APFS_SM (sb ), bno ) ? APFS_SFQ_IP : APFS_SFQ_MAIN ;
1011+ apfs_alert (sb , "free queue (%u) seems full - bug!" , qid );
1012+ err = - EFSCORRUPTED ;
10361013 }
10371014 if (err ) {
1038- if (err == - EAGAIN ) {
1039- apfs_alert (sb , "failed to make room in fq - bug!" );
1040- err = - EFSCORRUPTED ;
1041- }
10421015 apfs_err (sb , "fq insert failed (0x%llx-0x%llx)" , bno , count );
10431016 return err ;
10441017 }
0 commit comments