162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * usnjrnl.h - NTFS kernel transaction log ($UsnJrnl) handling.  Part of the
462306a36Sopenharmony_ci *	       Linux-NTFS project.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (c) 2005 Anton Altaparmakov
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#ifdef NTFS_RW
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/fs.h>
1262306a36Sopenharmony_ci#include <linux/highmem.h>
1362306a36Sopenharmony_ci#include <linux/mm.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include "aops.h"
1662306a36Sopenharmony_ci#include "debug.h"
1762306a36Sopenharmony_ci#include "endian.h"
1862306a36Sopenharmony_ci#include "time.h"
1962306a36Sopenharmony_ci#include "types.h"
2062306a36Sopenharmony_ci#include "usnjrnl.h"
2162306a36Sopenharmony_ci#include "volume.h"
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/**
2462306a36Sopenharmony_ci * ntfs_stamp_usnjrnl - stamp the transaction log ($UsnJrnl) on an ntfs volume
2562306a36Sopenharmony_ci * @vol:	ntfs volume on which to stamp the transaction log
2662306a36Sopenharmony_ci *
2762306a36Sopenharmony_ci * Stamp the transaction log ($UsnJrnl) on the ntfs volume @vol and return
2862306a36Sopenharmony_ci * 'true' on success and 'false' on error.
2962306a36Sopenharmony_ci *
3062306a36Sopenharmony_ci * This function assumes that the transaction log has already been loaded and
3162306a36Sopenharmony_ci * consistency checked by a call to fs/ntfs/super.c::load_and_init_usnjrnl().
3262306a36Sopenharmony_ci */
3362306a36Sopenharmony_cibool ntfs_stamp_usnjrnl(ntfs_volume *vol)
3462306a36Sopenharmony_ci{
3562306a36Sopenharmony_ci	ntfs_debug("Entering.");
3662306a36Sopenharmony_ci	if (likely(!NVolUsnJrnlStamped(vol))) {
3762306a36Sopenharmony_ci		sle64 stamp;
3862306a36Sopenharmony_ci		struct page *page;
3962306a36Sopenharmony_ci		USN_HEADER *uh;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci		page = ntfs_map_page(vol->usnjrnl_max_ino->i_mapping, 0);
4262306a36Sopenharmony_ci		if (IS_ERR(page)) {
4362306a36Sopenharmony_ci			ntfs_error(vol->sb, "Failed to read from "
4462306a36Sopenharmony_ci					"$UsnJrnl/$DATA/$Max attribute.");
4562306a36Sopenharmony_ci			return false;
4662306a36Sopenharmony_ci		}
4762306a36Sopenharmony_ci		uh = (USN_HEADER*)page_address(page);
4862306a36Sopenharmony_ci		stamp = get_current_ntfs_time();
4962306a36Sopenharmony_ci		ntfs_debug("Stamping transaction log ($UsnJrnl): old "
5062306a36Sopenharmony_ci				"journal_id 0x%llx, old lowest_valid_usn "
5162306a36Sopenharmony_ci				"0x%llx, new journal_id 0x%llx, new "
5262306a36Sopenharmony_ci				"lowest_valid_usn 0x%llx.",
5362306a36Sopenharmony_ci				(long long)sle64_to_cpu(uh->journal_id),
5462306a36Sopenharmony_ci				(long long)sle64_to_cpu(uh->lowest_valid_usn),
5562306a36Sopenharmony_ci				(long long)sle64_to_cpu(stamp),
5662306a36Sopenharmony_ci				i_size_read(vol->usnjrnl_j_ino));
5762306a36Sopenharmony_ci		uh->lowest_valid_usn =
5862306a36Sopenharmony_ci				cpu_to_sle64(i_size_read(vol->usnjrnl_j_ino));
5962306a36Sopenharmony_ci		uh->journal_id = stamp;
6062306a36Sopenharmony_ci		flush_dcache_page(page);
6162306a36Sopenharmony_ci		set_page_dirty(page);
6262306a36Sopenharmony_ci		ntfs_unmap_page(page);
6362306a36Sopenharmony_ci		/* Set the flag so we do not have to do it again on remount. */
6462306a36Sopenharmony_ci		NVolSetUsnJrnlStamped(vol);
6562306a36Sopenharmony_ci	}
6662306a36Sopenharmony_ci	ntfs_debug("Done.");
6762306a36Sopenharmony_ci	return true;
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci#endif /* NTFS_RW */
71