Lines Matching +full:multi +full:- +full:function
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (c) 2002-2007 Anton Altaparmakov
15 * ntfs_check_restart_page_header - check the page header for consistency
23 * This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not
38 logfile_system_page_size = le32_to_cpu(rp->system_page_size); in ntfs_check_restart_page_header()
39 logfile_log_page_size = le32_to_cpu(rp->log_page_size); in ntfs_check_restart_page_header()
43 (logfile_system_page_size - 1) || in ntfs_check_restart_page_header()
45 ntfs_error(vi->i_sb, "LogFile uses unsupported page size."); in ntfs_check_restart_page_header()
53 ntfs_error(vi->i_sb, "Found restart area in incorrect position in LogFile."); in ntfs_check_restart_page_header()
57 if (le16_to_cpu(rp->major_ver) != 1 || in ntfs_check_restart_page_header()
58 le16_to_cpu(rp->minor_ver) != 1) { in ntfs_check_restart_page_header()
59 ntfs_error(vi->i_sb, in ntfs_check_restart_page_header()
61 (int)le16_to_cpu(rp->major_ver), in ntfs_check_restart_page_header()
62 (int)le16_to_cpu(rp->minor_ver)); in ntfs_check_restart_page_header()
69 if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) { in ntfs_check_restart_page_header()
75 if (usa_count != le16_to_cpu(rp->usa_count)) { in ntfs_check_restart_page_header()
76 ntfs_error(vi->i_sb, in ntfs_check_restart_page_header()
81 usa_ofs = le16_to_cpu(rp->usa_ofs); in ntfs_check_restart_page_header()
84 usa_end > NTFS_BLOCK_SIZE - sizeof(u16)) { in ntfs_check_restart_page_header()
85 ntfs_error(vi->i_sb, in ntfs_check_restart_page_header()
92 * - aligned to 8-byte boundary, in ntfs_check_restart_page_header()
93 * - after the update sequence array, and in ntfs_check_restart_page_header()
94 * - within the system page size. in ntfs_check_restart_page_header()
96 ra_ofs = le16_to_cpu(rp->restart_area_offset); in ntfs_check_restart_page_header()
100 ntfs_error(vi->i_sb, in ntfs_check_restart_page_header()
108 if (!ntfs_is_chkd_record(rp->magic) && le64_to_cpu(rp->chkdsk_lsn)) { in ntfs_check_restart_page_header()
109 ntfs_error(vi->i_sb, in ntfs_check_restart_page_header()
118 * ntfs_check_restart_area - check the restart area for consistency
125 * This function assumes that the restart page header has already been
128 * This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not
139 ra_ofs = le16_to_cpu(rp->restart_area_offset); in ntfs_check_restart_area()
142 * Everything before ra->file_size must be before the first word in ntfs_check_restart_area()
144 * safe to access ra->client_array_offset. in ntfs_check_restart_area()
147 NTFS_BLOCK_SIZE - sizeof(u16)) { in ntfs_check_restart_area()
148 ntfs_error(vi->i_sb, in ntfs_check_restart_area()
153 * Now that we can access ra->client_array_offset, make sure everything in ntfs_check_restart_area()
157 * aligned to an 8-byte boundary. in ntfs_check_restart_area()
159 ca_ofs = le16_to_cpu(ra->client_array_offset); in ntfs_check_restart_area()
161 ra_ofs + ca_ofs > NTFS_BLOCK_SIZE - sizeof(u16)) { in ntfs_check_restart_area()
162 ntfs_error(vi->i_sb, in ntfs_check_restart_area()
168 * calculated manually and as specified by ra->restart_area_length. in ntfs_check_restart_area()
171 ra_len = ca_ofs + le16_to_cpu(ra->log_clients) * in ntfs_check_restart_area()
173 if (ra_ofs + ra_len > le32_to_cpu(rp->system_page_size) || in ntfs_check_restart_area()
174 ra_ofs + le16_to_cpu(ra->restart_area_length) > in ntfs_check_restart_area()
175 le32_to_cpu(rp->system_page_size) || in ntfs_check_restart_area()
176 ra_len > le16_to_cpu(ra->restart_area_length)) { in ntfs_check_restart_area()
177 ntfs_error(vi->i_sb, in ntfs_check_restart_area()
182 * The ra->client_free_list and ra->client_in_use_list must be either in ntfs_check_restart_area()
183 * LOGFILE_NO_CLIENT or less than ra->log_clients or they are in ntfs_check_restart_area()
186 if ((ra->client_free_list != LOGFILE_NO_CLIENT && in ntfs_check_restart_area()
187 le16_to_cpu(ra->client_free_list) >= in ntfs_check_restart_area()
188 le16_to_cpu(ra->log_clients)) || in ntfs_check_restart_area()
189 (ra->client_in_use_list != LOGFILE_NO_CLIENT && in ntfs_check_restart_area()
190 le16_to_cpu(ra->client_in_use_list) >= in ntfs_check_restart_area()
191 le16_to_cpu(ra->log_clients))) { in ntfs_check_restart_area()
192 ntfs_error(vi->i_sb, in ntfs_check_restart_area()
197 * Check ra->seq_number_bits against ra->file_size for consistency. in ntfs_check_restart_area()
200 file_size = le64_to_cpu(ra->file_size); in ntfs_check_restart_area()
206 if (le32_to_cpu(ra->seq_number_bits) != 67 - fs_bits) { in ntfs_check_restart_area()
207 ntfs_error(vi->i_sb, in ntfs_check_restart_area()
212 if (((le16_to_cpu(ra->log_record_header_length) + 7) & ~7) != in ntfs_check_restart_area()
213 le16_to_cpu(ra->log_record_header_length)) { in ntfs_check_restart_area()
214 ntfs_error(vi->i_sb, in ntfs_check_restart_area()
219 if (((le16_to_cpu(ra->log_page_data_offset) + 7) & ~7) != in ntfs_check_restart_area()
220 le16_to_cpu(ra->log_page_data_offset)) { in ntfs_check_restart_area()
221 ntfs_error(vi->i_sb, in ntfs_check_restart_area()
230 * ntfs_check_log_client_array - check the log client array for consistency
237 * This function assumes that the restart page header and the restart area have
241 * function needs @rp->system_page_size bytes in @rp, i.e. it requires the full
242 * restart page and the page must be multi sector transfer deprotected.
253 ra = (struct restart_area *)((u8 *)rp + le16_to_cpu(rp->restart_area_offset)); in ntfs_check_log_client_array()
255 le16_to_cpu(ra->client_array_offset)); in ntfs_check_log_client_array()
257 * Check the ra->client_free_list first and then check the in ntfs_check_log_client_array()
258 * ra->client_in_use_list. Check each of the log client records in in ntfs_check_log_client_array()
260 * ra->log_clients value. Also keep track of the number of records in ntfs_check_log_client_array()
261 * visited as there cannot be more than ra->log_clients records and in ntfs_check_log_client_array()
264 nr_clients = le16_to_cpu(ra->log_clients); in ntfs_check_log_client_array()
265 idx = le16_to_cpu(ra->client_free_list); in ntfs_check_log_client_array()
268 for (idx_is_first = true; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--, in ntfs_check_log_client_array()
269 idx = le16_to_cpu(cr->next_client)) { in ntfs_check_log_client_array()
270 if (!nr_clients || idx >= le16_to_cpu(ra->log_clients)) in ntfs_check_log_client_array()
276 if (cr->prev_client != LOGFILE_NO_CLIENT) in ntfs_check_log_client_array()
284 idx = le16_to_cpu(ra->client_in_use_list); in ntfs_check_log_client_array()
290 ntfs_error(vi->i_sb, "LogFile log client array is corrupt."); in ntfs_check_log_client_array()
295 * ntfs_check_and_load_restart_page - check the restart page for consistency
299 * @wrp: [OUT] copy of the multi sector transfer deprotected restart page
303 * and -errno otherwise. The restart page may have been modified by chkdsk in
306 * This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not
310 * copy of the complete multi sector transfer deprotected page. On failure,
317 * -EINVAL - The restart page is inconsistent.
318 * -ENOMEM - Not enough memory to load the restart page.
319 * -EIO - Failed to reading from LogFile.
332 /* Error output already done inside the function. */ in ntfs_check_and_load_restart_page()
333 return -EINVAL; in ntfs_check_and_load_restart_page()
337 /* Error output already done inside the function. */ in ntfs_check_and_load_restart_page()
338 return -EINVAL; in ntfs_check_and_load_restart_page()
340 ra = (struct restart_area *)((u8 *)rp + le16_to_cpu(rp->restart_area_offset)); in ntfs_check_and_load_restart_page()
342 * Allocate a buffer to store the whole restart page so we can multi in ntfs_check_and_load_restart_page()
345 trp = kvzalloc(le32_to_cpu(rp->system_page_size), GFP_NOFS); in ntfs_check_and_load_restart_page()
347 ntfs_error(vi->i_sb, "Failed to allocate memory for LogFile restart page buffer."); in ntfs_check_and_load_restart_page()
348 return -ENOMEM; in ntfs_check_and_load_restart_page()
355 size = PAGE_SIZE - (pos & ~PAGE_MASK); in ntfs_check_and_load_restart_page()
356 if (size >= le32_to_cpu(rp->system_page_size)) { in ntfs_check_and_load_restart_page()
357 memcpy(trp, rp, le32_to_cpu(rp->system_page_size)); in ntfs_check_and_load_restart_page()
367 to_read = le32_to_cpu(rp->system_page_size) - size; in ntfs_check_and_load_restart_page()
370 folio = read_mapping_folio(vi->i_mapping, idx, NULL); in ntfs_check_and_load_restart_page()
372 ntfs_error(vi->i_sb, "Error mapping LogFile page (index %lu).", in ntfs_check_and_load_restart_page()
375 if (err != -EIO && err != -ENOMEM) in ntfs_check_and_load_restart_page()
376 err = -EIO; in ntfs_check_and_load_restart_page()
383 to_read -= size; in ntfs_check_and_load_restart_page()
388 * Perform the multi sector transfer deprotection on the buffer if the in ntfs_check_and_load_restart_page()
391 if ((!ntfs_is_chkd_record(trp->magic) || le16_to_cpu(trp->usa_count)) && in ntfs_check_and_load_restart_page()
392 post_read_mst_fixup((struct ntfs_record *)trp, le32_to_cpu(rp->system_page_size))) { in ntfs_check_and_load_restart_page()
394 * A multi sector transfer error was detected. We only need to in ntfs_check_and_load_restart_page()
395 * abort if the restart page contents exceed the multi sector in ntfs_check_and_load_restart_page()
398 if (le16_to_cpu(rp->restart_area_offset) + in ntfs_check_and_load_restart_page()
399 le16_to_cpu(ra->restart_area_length) > in ntfs_check_and_load_restart_page()
400 NTFS_BLOCK_SIZE - sizeof(u16)) { in ntfs_check_and_load_restart_page()
401 ntfs_error(vi->i_sb, in ntfs_check_and_load_restart_page()
402 "Multi sector transfer error detected in LogFile restart page."); in ntfs_check_and_load_restart_page()
403 err = -EINVAL; in ntfs_check_and_load_restart_page()
413 if (ntfs_is_rstr_record(rp->magic) && in ntfs_check_and_load_restart_page()
414 ra->client_in_use_list != LOGFILE_NO_CLIENT) { in ntfs_check_and_load_restart_page()
416 err = -EINVAL; in ntfs_check_and_load_restart_page()
421 if (ntfs_is_rstr_record(rp->magic)) in ntfs_check_and_load_restart_page()
422 *lsn = le64_to_cpu(ra->current_lsn); in ntfs_check_and_load_restart_page()
423 else /* if (ntfs_is_chkd_record(rp->magic)) */ in ntfs_check_and_load_restart_page()
424 *lsn = le64_to_cpu(rp->chkdsk_lsn); in ntfs_check_and_load_restart_page()
437 * ntfs_check_logfile - check the journal for consistency
457 struct ntfs_volume *vol = NTFS_SB(log_vi->i_sb); in ntfs_check_logfile()
458 struct address_space *mapping = log_vi->i_mapping; in ntfs_check_logfile()
490 log_page_bits = ntfs_ffs(log_page_size) - 1; in ntfs_check_logfile()
491 size &= ~(s64)(log_page_size - 1); in ntfs_check_logfile()
496 if (size < log_page_size * 2 || (size - log_page_size * 2) >> in ntfs_check_logfile()
498 ntfs_error(vol->sb, "LogFile is too small."); in ntfs_check_logfile()
512 if (!folio || folio->index != idx) { in ntfs_check_logfile()
519 ntfs_error(vol->sb, "Error mapping LogFile page (index %lu).", in ntfs_check_logfile()
526 * A non-empty block means the logfile is not empty while an in ntfs_check_logfile()
527 * empty block after a non-empty block has been encountered in ntfs_check_logfile()
549 * and get a copy of the complete multi sector transfer in ntfs_check_logfile()
572 * Error output already done inside the function. Note, we do in ntfs_check_logfile()
576 if (err != -EINVAL) { in ntfs_check_logfile()
596 ntfs_error(vol->sb, in ntfs_check_logfile()
630 * ntfs_empty_logfile - empty the contents of the LogFile journal
636 * This function assumes that the LogFile journal has already been consistency
644 struct ntfs_volume *vol = log_ni->vol; in ntfs_empty_logfile()
645 struct super_block *sb = vol->sb; in ntfs_empty_logfile()
667 read_lock_irqsave(&log_ni->size_lock, flags); in ntfs_empty_logfile()
668 end_vcn = (log_ni->initialized_size + vol->cluster_size_mask) >> in ntfs_empty_logfile()
669 vol->cluster_size_bits; in ntfs_empty_logfile()
670 read_unlock_irqrestore(&log_ni->size_lock, flags); in ntfs_empty_logfile()
671 truncate_inode_pages(log_vi->i_mapping, 0); in ntfs_empty_logfile()
672 down_write(&log_ni->runlist.lock); in ntfs_empty_logfile()
673 rl = log_ni->runlist.rl; in ntfs_empty_logfile()
674 if (unlikely(!rl || vcn < rl->vcn || !rl->length)) { in ntfs_empty_logfile()
678 ntfs_error(sb, "Failed to map runlist fragment (error %d).", -err); in ntfs_empty_logfile()
681 rl = log_ni->runlist.rl; in ntfs_empty_logfile()
684 while (rl->length && vcn >= rl[1].vcn) in ntfs_empty_logfile()
687 err = -ENOMEM; in ntfs_empty_logfile()
688 empty_buf = kvzalloc(vol->cluster_size, GFP_NOFS); in ntfs_empty_logfile()
692 memset(empty_buf, 0xff, vol->cluster_size); in ntfs_empty_logfile()
698 file_ra_state_init(ra, sb->s_bdev->bd_mapping); in ntfs_empty_logfile()
708 lcn = rl->lcn; in ntfs_empty_logfile()
710 vcn = rl->vcn; in ntfs_empty_logfile()
718 if (unlikely(!rl->length || lcn < LCN_HOLE)) in ntfs_empty_logfile()
724 len = rl->length; in ntfs_empty_logfile()
726 len = end_vcn - rl->vcn; in ntfs_empty_logfile()
729 page_cache_sync_readahead(sb->s_bdev->bd_mapping, ra, NULL, in ntfs_empty_logfile()
730 start >> PAGE_SHIFT, (end - start) >> PAGE_SHIFT); in ntfs_empty_logfile()
734 vol->cluster_size); in ntfs_empty_logfile()
749 err = filemap_write_and_wait_range(sb->s_bdev->bd_mapping, in ntfs_empty_logfile()
750 start, start + vol->cluster_size); in ntfs_empty_logfile()
754 start += vol->cluster_size; in ntfs_empty_logfile()
756 } while ((++rl)->vcn < end_vcn); in ntfs_empty_logfile()
757 up_write(&log_ni->runlist.lock); in ntfs_empty_logfile()
760 truncate_inode_pages(log_vi->i_mapping, 0); in ntfs_empty_logfile()
772 err = -EIO; in ntfs_empty_logfile()
776 up_write(&log_ni->runlist.lock); in ntfs_empty_logfile()
778 -err); in ntfs_empty_logfile()