Sets the refcount for a cluster. Returns freed cluster addresses.
(&mut self, address: u64, refcount: u64)
| 900 | |
| 901 | /// Sets the refcount for a cluster. Returns freed cluster addresses. |
| 902 | fn set_cluster_refcount(&mut self, address: u64, refcount: u64) -> io::Result<Vec<u64>> { |
| 903 | let mut added_clusters = Vec::new(); |
| 904 | let mut unref_clusters = Vec::new(); |
| 905 | let mut refcount_set = false; |
| 906 | let mut new_cluster = None; |
| 907 | |
| 908 | while !refcount_set { |
| 909 | match self.refcounts.set_cluster_refcount( |
| 910 | &mut self.raw_file, |
| 911 | address, |
| 912 | refcount, |
| 913 | new_cluster.take(), |
| 914 | ) { |
| 915 | Ok(None) => { |
| 916 | refcount_set = true; |
| 917 | } |
| 918 | Ok(Some(freed_cluster)) => { |
| 919 | let mut freed = self.set_cluster_refcount(freed_cluster, 0)?; |
| 920 | unref_clusters.append(&mut freed); |
| 921 | refcount_set = true; |
| 922 | } |
| 923 | Err(refcount::Error::EvictingRefCounts(e)) => { |
| 924 | return Err(e); |
| 925 | } |
| 926 | Err(refcount::Error::InvalidIndex) => { |
| 927 | self.set_corrupt_bit_best_effort(); |
| 928 | return Err(io::Error::from_raw_os_error(EINVAL)); |
| 929 | } |
| 930 | Err(refcount::Error::NeedCluster(addr)) => { |
| 931 | new_cluster = Some(( |
| 932 | addr, |
| 933 | VecCache::from_vec(self.raw_file.read_refcount_block(addr)?), |
| 934 | )); |
| 935 | } |
| 936 | Err(refcount::Error::NeedNewCluster) => { |
| 937 | let addr = self.get_new_cluster(None)?; |
| 938 | added_clusters.push(addr); |
| 939 | new_cluster = Some(( |
| 940 | addr, |
| 941 | VecCache::new(self.refcounts.refcounts_per_block() as usize), |
| 942 | )); |
| 943 | } |
| 944 | Err(refcount::Error::ReadingRefCounts(e)) => { |
| 945 | return Err(e); |
| 946 | } |
| 947 | Err(refcount::Error::RefcountOverflow { .. }) => { |
| 948 | return Err(io::Error::from_raw_os_error(EINVAL)); |
| 949 | } |
| 950 | Err(refcount::Error::RefblockUnaligned(_)) => { |
| 951 | self.set_corrupt_bit_best_effort(); |
| 952 | return Err(io::Error::from_raw_os_error(EIO)); |
| 953 | } |
| 954 | } |
| 955 | } |
| 956 | |
| 957 | for addr in added_clusters { |
| 958 | self.set_cluster_refcount(addr, 1)?; |
| 959 | } |
no test coverage detected