• Home
  • Raw
  • Download

Lines Matching +full:multi +full:- +full:word

2  * logfile.c - NTFS kernel journal handling. Part of the Linux-NTFS project.
4 * Copyright (c) 2002-2007 Anton Altaparmakov
17 * along with this program (in the main directory of the Linux-NTFS
19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 * ntfs_check_restart_page_header - check the page header for consistency
64 logfile_system_page_size = le32_to_cpu(rp->system_page_size); in ntfs_check_restart_page_header()
65 logfile_log_page_size = le32_to_cpu(rp->log_page_size); in ntfs_check_restart_page_header()
69 (logfile_system_page_size - 1) || in ntfs_check_restart_page_header()
71 ntfs_error(vi->i_sb, "$LogFile uses unsupported page size."); in ntfs_check_restart_page_header()
79 ntfs_error(vi->i_sb, "Found restart area in incorrect " in ntfs_check_restart_page_header()
84 if (sle16_to_cpu(rp->major_ver) != 1 || in ntfs_check_restart_page_header()
85 sle16_to_cpu(rp->minor_ver) != 1) { in ntfs_check_restart_page_header()
86 ntfs_error(vi->i_sb, "$LogFile version %i.%i is not " in ntfs_check_restart_page_header()
88 "1.1 only.)", (int)sle16_to_cpu(rp->major_ver), in ntfs_check_restart_page_header()
89 (int)sle16_to_cpu(rp->minor_ver)); in ntfs_check_restart_page_header()
96 if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) { in ntfs_check_restart_page_header()
102 if (usa_count != le16_to_cpu(rp->usa_count)) { in ntfs_check_restart_page_header()
103 ntfs_error(vi->i_sb, "$LogFile restart page specifies " in ntfs_check_restart_page_header()
108 usa_ofs = le16_to_cpu(rp->usa_ofs); in ntfs_check_restart_page_header()
111 usa_end > NTFS_BLOCK_SIZE - sizeof(u16)) { in ntfs_check_restart_page_header()
112 ntfs_error(vi->i_sb, "$LogFile restart page specifies " in ntfs_check_restart_page_header()
119 * - aligned to 8-byte boundary, in ntfs_check_restart_page_header()
120 * - after the update sequence array, and in ntfs_check_restart_page_header()
121 * - within the system page size. in ntfs_check_restart_page_header()
123 ra_ofs = le16_to_cpu(rp->restart_area_offset); in ntfs_check_restart_page_header()
127 ntfs_error(vi->i_sb, "$LogFile restart page specifies " in ntfs_check_restart_page_header()
135 if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) { in ntfs_check_restart_page_header()
136 ntfs_error(vi->i_sb, "$LogFile restart page is not modified " in ntfs_check_restart_page_header()
145 * ntfs_check_restart_area - check the restart area for consistency
166 ra_ofs = le16_to_cpu(rp->restart_area_offset); in ntfs_check_restart_area()
169 * Everything before ra->file_size must be before the first word in ntfs_check_restart_area()
171 * safe to access ra->client_array_offset. in ntfs_check_restart_area()
174 NTFS_BLOCK_SIZE - sizeof(u16)) { in ntfs_check_restart_area()
175 ntfs_error(vi->i_sb, "$LogFile restart area specifies " in ntfs_check_restart_area()
180 * Now that we can access ra->client_array_offset, make sure everything in ntfs_check_restart_area()
181 * up to the log client array is before the first word protected by an in ntfs_check_restart_area()
184 * aligned to an 8-byte boundary. in ntfs_check_restart_area()
186 ca_ofs = le16_to_cpu(ra->client_array_offset); in ntfs_check_restart_area()
188 ra_ofs + ca_ofs > NTFS_BLOCK_SIZE - sizeof(u16)) { in ntfs_check_restart_area()
189 ntfs_error(vi->i_sb, "$LogFile restart area specifies " in ntfs_check_restart_area()
195 * calculated manually and as specified by ra->restart_area_length. in ntfs_check_restart_area()
198 ra_len = ca_ofs + le16_to_cpu(ra->log_clients) * in ntfs_check_restart_area()
200 if (ra_ofs + ra_len > le32_to_cpu(rp->system_page_size) || in ntfs_check_restart_area()
201 ra_ofs + le16_to_cpu(ra->restart_area_length) > in ntfs_check_restart_area()
202 le32_to_cpu(rp->system_page_size) || in ntfs_check_restart_area()
203 ra_len > le16_to_cpu(ra->restart_area_length)) { in ntfs_check_restart_area()
204 ntfs_error(vi->i_sb, "$LogFile restart area is out of bounds " in ntfs_check_restart_area()
211 * The ra->client_free_list and ra->client_in_use_list must be either in ntfs_check_restart_area()
212 * LOGFILE_NO_CLIENT or less than ra->log_clients or they are in ntfs_check_restart_area()
215 if ((ra->client_free_list != LOGFILE_NO_CLIENT && in ntfs_check_restart_area()
216 le16_to_cpu(ra->client_free_list) >= in ntfs_check_restart_area()
217 le16_to_cpu(ra->log_clients)) || in ntfs_check_restart_area()
218 (ra->client_in_use_list != LOGFILE_NO_CLIENT && in ntfs_check_restart_area()
219 le16_to_cpu(ra->client_in_use_list) >= in ntfs_check_restart_area()
220 le16_to_cpu(ra->log_clients))) { in ntfs_check_restart_area()
221 ntfs_error(vi->i_sb, "$LogFile restart area specifies " in ntfs_check_restart_area()
226 * Check ra->seq_number_bits against ra->file_size for consistency. in ntfs_check_restart_area()
229 file_size = (u64)sle64_to_cpu(ra->file_size); in ntfs_check_restart_area()
235 if (le32_to_cpu(ra->seq_number_bits) != 67 - fs_bits) { in ntfs_check_restart_area()
236 ntfs_error(vi->i_sb, "$LogFile restart area specifies " in ntfs_check_restart_area()
241 if (((le16_to_cpu(ra->log_record_header_length) + 7) & ~7) != in ntfs_check_restart_area()
242 le16_to_cpu(ra->log_record_header_length)) { in ntfs_check_restart_area()
243 ntfs_error(vi->i_sb, "$LogFile restart area specifies " in ntfs_check_restart_area()
248 if (((le16_to_cpu(ra->log_page_data_offset) + 7) & ~7) != in ntfs_check_restart_area()
249 le16_to_cpu(ra->log_page_data_offset)) { in ntfs_check_restart_area()
250 ntfs_error(vi->i_sb, "$LogFile restart area specifies " in ntfs_check_restart_area()
259 * ntfs_check_log_client_array - check the log client array for consistency
270 * function needs @rp->system_page_size bytes in @rp, i.e. it requires the full
271 * restart page and the page must be multi sector transfer deprotected.
282 ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset)); in ntfs_check_log_client_array()
284 le16_to_cpu(ra->client_array_offset)); in ntfs_check_log_client_array()
286 * Check the ra->client_free_list first and then check the in ntfs_check_log_client_array()
287 * ra->client_in_use_list. Check each of the log client records in in ntfs_check_log_client_array()
289 * ra->log_clients value. Also keep track of the number of records in ntfs_check_log_client_array()
290 * visited as there cannot be more than ra->log_clients records and in ntfs_check_log_client_array()
293 nr_clients = le16_to_cpu(ra->log_clients); in ntfs_check_log_client_array()
294 idx = le16_to_cpu(ra->client_free_list); in ntfs_check_log_client_array()
297 for (idx_is_first = true; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--, in ntfs_check_log_client_array()
298 idx = le16_to_cpu(cr->next_client)) { in ntfs_check_log_client_array()
299 if (!nr_clients || idx >= le16_to_cpu(ra->log_clients)) in ntfs_check_log_client_array()
305 if (cr->prev_client != LOGFILE_NO_CLIENT) in ntfs_check_log_client_array()
313 idx = le16_to_cpu(ra->client_in_use_list); in ntfs_check_log_client_array()
319 ntfs_error(vi->i_sb, "$LogFile log client array is corrupt."); in ntfs_check_log_client_array()
324 * ntfs_check_and_load_restart_page - check the restart page for consistency
328 * @wrp: [OUT] copy of the multi sector transfer deprotected restart page
332 * and -errno otherwise. The restart page may have been modified by chkdsk in
339 * copy of the complete multi sector transfer deprotected page. On failure,
346 * -EINVAL - The restart page is inconsistent.
347 * -ENOMEM - Not enough memory to load the restart page.
348 * -EIO - Failed to reading from $LogFile.
362 return -EINVAL; in ntfs_check_and_load_restart_page()
367 return -EINVAL; in ntfs_check_and_load_restart_page()
369 ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset)); in ntfs_check_and_load_restart_page()
371 * Allocate a buffer to store the whole restart page so we can multi in ntfs_check_and_load_restart_page()
374 trp = ntfs_malloc_nofs(le32_to_cpu(rp->system_page_size)); in ntfs_check_and_load_restart_page()
376 ntfs_error(vi->i_sb, "Failed to allocate memory for $LogFile " in ntfs_check_and_load_restart_page()
378 return -ENOMEM; in ntfs_check_and_load_restart_page()
385 size = PAGE_SIZE - (pos & ~PAGE_MASK); in ntfs_check_and_load_restart_page()
386 if (size >= le32_to_cpu(rp->system_page_size)) { in ntfs_check_and_load_restart_page()
387 memcpy(trp, rp, le32_to_cpu(rp->system_page_size)); in ntfs_check_and_load_restart_page()
397 to_read = le32_to_cpu(rp->system_page_size) - size; in ntfs_check_and_load_restart_page()
401 page = ntfs_map_page(vi->i_mapping, idx); in ntfs_check_and_load_restart_page()
403 ntfs_error(vi->i_sb, "Error mapping $LogFile " in ntfs_check_and_load_restart_page()
406 if (err != -EIO && err != -ENOMEM) in ntfs_check_and_load_restart_page()
407 err = -EIO; in ntfs_check_and_load_restart_page()
414 to_read -= size; in ntfs_check_and_load_restart_page()
419 * Perform the multi sector transfer deprotection on the buffer if the in ntfs_check_and_load_restart_page()
422 if ((!ntfs_is_chkd_record(trp->magic) || le16_to_cpu(trp->usa_count)) in ntfs_check_and_load_restart_page()
424 le32_to_cpu(rp->system_page_size))) { in ntfs_check_and_load_restart_page()
426 * A multi sector tranfer error was detected. We only need to in ntfs_check_and_load_restart_page()
427 * abort if the restart page contents exceed the multi sector in ntfs_check_and_load_restart_page()
430 if (le16_to_cpu(rp->restart_area_offset) + in ntfs_check_and_load_restart_page()
431 le16_to_cpu(ra->restart_area_length) > in ntfs_check_and_load_restart_page()
432 NTFS_BLOCK_SIZE - sizeof(u16)) { in ntfs_check_and_load_restart_page()
433 ntfs_error(vi->i_sb, "Multi sector transfer error " in ntfs_check_and_load_restart_page()
435 err = -EINVAL; in ntfs_check_and_load_restart_page()
445 if (ntfs_is_rstr_record(rp->magic) && in ntfs_check_and_load_restart_page()
446 ra->client_in_use_list != LOGFILE_NO_CLIENT) { in ntfs_check_and_load_restart_page()
448 err = -EINVAL; in ntfs_check_and_load_restart_page()
453 if (ntfs_is_rstr_record(rp->magic)) in ntfs_check_and_load_restart_page()
454 *lsn = sle64_to_cpu(ra->current_lsn); in ntfs_check_and_load_restart_page()
455 else /* if (ntfs_is_chkd_record(rp->magic)) */ in ntfs_check_and_load_restart_page()
456 *lsn = sle64_to_cpu(rp->chkdsk_lsn); in ntfs_check_and_load_restart_page()
469 * ntfs_check_logfile - check the journal for consistency
489 ntfs_volume *vol = NTFS_SB(log_vi->i_sb); in ntfs_check_logfile()
490 struct address_space *mapping = log_vi->i_mapping; in ntfs_check_logfile()
518 log_page_mask = log_page_size - 1; in ntfs_check_logfile()
523 log_page_bits = ntfs_ffs(log_page_size) - 1; in ntfs_check_logfile()
524 size &= ~(s64)(log_page_size - 1); in ntfs_check_logfile()
529 if (size < log_page_size * 2 || (size - log_page_size * 2) >> in ntfs_check_logfile()
531 ntfs_error(vol->sb, "$LogFile is too small."); in ntfs_check_logfile()
544 if (!page || page->index != idx) { in ntfs_check_logfile()
549 ntfs_error(vol->sb, "Error mapping $LogFile " in ntfs_check_logfile()
556 * A non-empty block means the logfile is not empty while an in ntfs_check_logfile()
557 * empty block after a non-empty block has been encountered in ntfs_check_logfile()
579 * and get a copy of the complete multi sector transfer in ntfs_check_logfile()
606 if (err != -EINVAL) { in ntfs_check_logfile()
624 ntfs_error(vol->sb, "Did not find any restart pages in " in ntfs_check_logfile()
661 * ntfs_is_logfile_clean - check in the journal if the volume is clean
672 * not have any pending, non-check-pointed i/o, i.e. they were completely idle
682 ntfs_volume *vol = NTFS_SB(log_vi->i_sb); in ntfs_is_logfile_clean()
692 if (!ntfs_is_rstr_record(rp->magic) && in ntfs_is_logfile_clean()
693 !ntfs_is_chkd_record(rp->magic)) { in ntfs_is_logfile_clean()
694 ntfs_error(vol->sb, "Restart page buffer is invalid. This is " in ntfs_is_logfile_clean()
700 ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset)); in ntfs_is_logfile_clean()
706 if (ra->client_in_use_list != LOGFILE_NO_CLIENT && in ntfs_is_logfile_clean()
707 !(ra->flags & RESTART_VOLUME_IS_CLEAN)) { in ntfs_is_logfile_clean()
717 * ntfs_empty_logfile - empty the contents of the $LogFile journal
731 ntfs_volume *vol = log_ni->vol; in ntfs_empty_logfile()
732 struct super_block *sb = vol->sb; in ntfs_empty_logfile()
751 block_size = sb->s_blocksize; in ntfs_empty_logfile()
752 block_size_bits = sb->s_blocksize_bits; in ntfs_empty_logfile()
754 read_lock_irqsave(&log_ni->size_lock, flags); in ntfs_empty_logfile()
755 end_vcn = (log_ni->initialized_size + vol->cluster_size_mask) >> in ntfs_empty_logfile()
756 vol->cluster_size_bits; in ntfs_empty_logfile()
757 read_unlock_irqrestore(&log_ni->size_lock, flags); in ntfs_empty_logfile()
758 truncate_inode_pages(log_vi->i_mapping, 0); in ntfs_empty_logfile()
759 down_write(&log_ni->runlist.lock); in ntfs_empty_logfile()
760 rl = log_ni->runlist.rl; in ntfs_empty_logfile()
761 if (unlikely(!rl || vcn < rl->vcn || !rl->length)) { in ntfs_empty_logfile()
766 "%d).", -err); in ntfs_empty_logfile()
769 rl = log_ni->runlist.rl; in ntfs_empty_logfile()
770 BUG_ON(!rl || vcn < rl->vcn || !rl->length); in ntfs_empty_logfile()
773 while (rl->length && vcn >= rl[1].vcn) in ntfs_empty_logfile()
784 lcn = rl->lcn; in ntfs_empty_logfile()
786 vcn = rl->vcn; in ntfs_empty_logfile()
790 if (unlikely(!rl->length || lcn < LCN_HOLE)) in ntfs_empty_logfile()
795 block = lcn << vol->cluster_size_bits >> block_size_bits; in ntfs_empty_logfile()
796 len = rl->length; in ntfs_empty_logfile()
798 len = end_vcn - rl->vcn; in ntfs_empty_logfile()
799 end_block = (lcn + len) << vol->cluster_size_bits >> in ntfs_empty_logfile()
810 bh->b_end_io = end_buffer_write_sync; in ntfs_empty_logfile()
813 memset(bh->b_data, -1, block_size); in ntfs_empty_logfile()
834 } while ((++rl)->vcn < end_vcn); in ntfs_empty_logfile()
835 up_write(&log_ni->runlist.lock); in ntfs_empty_logfile()
844 truncate_inode_pages(log_vi->i_mapping, 0); in ntfs_empty_logfile()
856 err = -EIO; in ntfs_empty_logfile()
858 up_write(&log_ni->runlist.lock); in ntfs_empty_logfile()
860 -err); in ntfs_empty_logfile()