linux/fs/ntfs3/fsntfs.c

// SPDX-License-Identifier: GPL-2.0
/*
 *
 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
 *
 */

#include <linux/blkdev.h>
#include <linux/buffer_head.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/nls.h>

#include "debug.h"
#include "ntfs.h"
#include "ntfs_fs.h"

// clang-format off
const struct cpu_str NAME_MFT =;
const struct cpu_str NAME_MIRROR =;
const struct cpu_str NAME_LOGFILE =;
const struct cpu_str NAME_VOLUME =;
const struct cpu_str NAME_ATTRDEF =;
const struct cpu_str NAME_ROOT =;
const struct cpu_str NAME_BITMAP =;
const struct cpu_str NAME_BOOT =;
const struct cpu_str NAME_BADCLUS =;
const struct cpu_str NAME_QUOTA =;
const struct cpu_str NAME_SECURE =;
const struct cpu_str NAME_UPCASE =;
const struct cpu_str NAME_EXTEND =;
const struct cpu_str NAME_OBJID =;
const struct cpu_str NAME_REPARSE =;
const struct cpu_str NAME_USNJRNL =;
const __le16 BAD_NAME[4] =;
const __le16 I30_NAME[4] =;
const __le16 SII_NAME[4] =;
const __le16 SDH_NAME[4] =;
const __le16 SDS_NAME[4] =;
const __le16 SO_NAME[2] =;
const __le16 SQ_NAME[2] =;
const __le16 SR_NAME[2] =;

#ifdef CONFIG_NTFS3_LZX_XPRESS
const __le16 WOF_NAME[17] =;
#endif

static const __le16 CON_NAME[3] =;

static const __le16 NUL_NAME[3] =;

static const __le16 AUX_NAME[3] =;

static const __le16 PRN_NAME[3] =;

static const __le16 COM_NAME[3] =;

static const __le16 LPT_NAME[3] =;

// clang-format on

/*
 * ntfs_fix_pre_write - Insert fixups into @rhdr before writing to disk.
 */
bool ntfs_fix_pre_write(struct NTFS_RECORD_HEADER *rhdr, size_t bytes)
{}

/*
 * ntfs_fix_post_read - Remove fixups after reading from disk.
 *
 * Return: < 0 if error, 0 if ok, 1 if need to update fixups.
 */
int ntfs_fix_post_read(struct NTFS_RECORD_HEADER *rhdr, size_t bytes,
		       bool simple)
{}

/*
 * ntfs_extend_init - Load $Extend file.
 */
int ntfs_extend_init(struct ntfs_sb_info *sbi)
{}

int ntfs_loadlog_and_replay(struct ntfs_inode *ni, struct ntfs_sb_info *sbi)
{}

/*
 * ntfs_look_for_free_space - Look for a free space in bitmap.
 */
int ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len,
			     CLST *new_lcn, CLST *new_len,
			     enum ALLOCATE_OPT opt)
{}

/*
 * ntfs_check_for_free_space
 *
 * Check if it is possible to allocate 'clen' clusters and 'mlen' Mft records
 */
bool ntfs_check_for_free_space(struct ntfs_sb_info *sbi, CLST clen, CLST mlen)
{}

/*
 * ntfs_extend_mft - Allocate additional MFT records.
 *
 * sbi->mft.bitmap is locked for write.
 *
 * NOTE: recursive:
 *	ntfs_look_free_mft ->
 *	ntfs_extend_mft ->
 *	attr_set_size ->
 *	ni_insert_nonresident ->
 *	ni_insert_attr ->
 *	ni_ins_attr_ext ->
 *	ntfs_look_free_mft ->
 *	ntfs_extend_mft
 *
 * To avoid recursive always allocate space for two new MFT records
 * see attrib.c: "at least two MFT to avoid recursive loop".
 */
static int ntfs_extend_mft(struct ntfs_sb_info *sbi)
{}

/*
 * ntfs_look_free_mft - Look for a free MFT record.
 */
int ntfs_look_free_mft(struct ntfs_sb_info *sbi, CLST *rno, bool mft,
		       struct ntfs_inode *ni, struct mft_inode **mi)
{}

/*
 * ntfs_mark_rec_free - Mark record as free.
 * is_mft - true if we are changing MFT
 */
void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft)
{}

/*
 * ntfs_clear_mft_tail - Format empty records [from, to).
 *
 * sbi->mft.bitmap is locked for write.
 */
int ntfs_clear_mft_tail(struct ntfs_sb_info *sbi, size_t from, size_t to)
{}

/*
 * ntfs_refresh_zone - Refresh MFT zone.
 *
 * sbi->used.bitmap is locked for rw.
 * sbi->mft.bitmap is locked for write.
 * sbi->mft.ni->file.run_lock for write.
 */
int ntfs_refresh_zone(struct ntfs_sb_info *sbi)
{}

/*
 * ntfs_update_mftmirr - Update $MFTMirr data.
 */
void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait)
{}

/*
 * ntfs_bad_inode
 *
 * Marks inode as bad and marks fs as 'dirty'
 */
void ntfs_bad_inode(struct inode *inode, const char *hint)
{}

/*
 * ntfs_set_state
 *
 * Mount: ntfs_set_state(NTFS_DIRTY_DIRTY)
 * Umount: ntfs_set_state(NTFS_DIRTY_CLEAR)
 * NTFS error: ntfs_set_state(NTFS_DIRTY_ERROR)
 */
int ntfs_set_state(struct ntfs_sb_info *sbi, enum NTFS_DIRTY_FLAGS dirty)
{}

/*
 * security_hash - Calculates a hash of security descriptor.
 */
static inline __le32 security_hash(const void *sd, size_t bytes)
{}

/*
 * simple wrapper for sb_bread_unmovable.
 */
struct buffer_head *ntfs_bread(struct super_block *sb, sector_t block)
{}

int ntfs_sb_read(struct super_block *sb, u64 lbo, size_t bytes, void *buffer)
{}

int ntfs_sb_write(struct super_block *sb, u64 lbo, size_t bytes,
		  const void *buf, int wait)
{}

int ntfs_sb_write_run(struct ntfs_sb_info *sbi, const struct runs_tree *run,
		      u64 vbo, const void *buf, size_t bytes, int sync)
{}

struct buffer_head *ntfs_bread_run(struct ntfs_sb_info *sbi,
				   const struct runs_tree *run, u64 vbo)
{}

int ntfs_read_run_nb(struct ntfs_sb_info *sbi, const struct runs_tree *run,
		     u64 vbo, void *buf, u32 bytes, struct ntfs_buffers *nb)
{}

/*
 * ntfs_read_bh
 *
 * Return: < 0 if error, 0 if ok, -E_NTFS_FIXUP if need to update fixups.
 */
int ntfs_read_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo,
		 struct NTFS_RECORD_HEADER *rhdr, u32 bytes,
		 struct ntfs_buffers *nb)
{}

int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo,
		u32 bytes, struct ntfs_buffers *nb)
{}

int ntfs_write_bh(struct ntfs_sb_info *sbi, struct NTFS_RECORD_HEADER *rhdr,
		  struct ntfs_buffers *nb, int sync)
{}

/*
 * ntfs_bio_pages - Read/write pages from/to disk.
 */
int ntfs_bio_pages(struct ntfs_sb_info *sbi, const struct runs_tree *run,
		   struct page **pages, u32 nr_pages, u64 vbo, u32 bytes,
		   enum req_op op)
{}

/*
 * ntfs_bio_fill_1 - Helper for ntfs_loadlog_and_replay().
 *
 * Fill on-disk logfile range by (-1)
 * this means empty logfile.
 */
int ntfs_bio_fill_1(struct ntfs_sb_info *sbi, const struct runs_tree *run)
{}

int ntfs_vbo_to_lbo(struct ntfs_sb_info *sbi, const struct runs_tree *run,
		    u64 vbo, u64 *lbo, u64 *bytes)
{}

struct ntfs_inode *ntfs_new_inode(struct ntfs_sb_info *sbi, CLST rno,
				  enum RECORD_FLAG flag)
{}

/*
 * O:BAG:BAD:(A;OICI;FA;;;WD)
 * Owner S-1-5-32-544 (Administrators)
 * Group S-1-5-32-544 (Administrators)
 * ACE: allow S-1-1-0 (Everyone) with FILE_ALL_ACCESS
 */
const u8 s_default_security[] __aligned(8) =;

static_assert();

static inline u32 sid_length(const struct SID *sid)
{}

/*
 * is_acl_valid
 *
 * Thanks Mark Harmstone for idea.
 */
static bool is_acl_valid(const struct ACL *acl, u32 len)
{}

bool is_sd_valid(const struct SECURITY_DESCRIPTOR_RELATIVE *sd, u32 len)
{}

/*
 * ntfs_security_init - Load and parse $Secure.
 */
int ntfs_security_init(struct ntfs_sb_info *sbi)
{}

/*
 * ntfs_get_security_by_id - Read security descriptor by id.
 */
int ntfs_get_security_by_id(struct ntfs_sb_info *sbi, __le32 security_id,
			    struct SECURITY_DESCRIPTOR_RELATIVE **sd,
			    size_t *size)
{}

/*
 * ntfs_insert_security - Insert security descriptor into $Secure::SDS.
 *
 * SECURITY Descriptor Stream data is organized into chunks of 256K bytes
 * and it contains a mirror copy of each security descriptor.  When writing
 * to a security descriptor at location X, another copy will be written at
 * location (X+256K).
 * When writing a security descriptor that will cross the 256K boundary,
 * the pointer will be advanced by 256K to skip
 * over the mirror portion.
 */
int ntfs_insert_security(struct ntfs_sb_info *sbi,
			 const struct SECURITY_DESCRIPTOR_RELATIVE *sd,
			 u32 size_sd, __le32 *security_id, bool *inserted)
{}

/*
 * ntfs_reparse_init - Load and parse $Extend/$Reparse.
 */
int ntfs_reparse_init(struct ntfs_sb_info *sbi)
{}

/*
 * ntfs_objid_init - Load and parse $Extend/$ObjId.
 */
int ntfs_objid_init(struct ntfs_sb_info *sbi)
{}

int ntfs_objid_remove(struct ntfs_sb_info *sbi, struct GUID *guid)
{}

int ntfs_insert_reparse(struct ntfs_sb_info *sbi, __le32 rtag,
			const struct MFT_REF *ref)
{}

int ntfs_remove_reparse(struct ntfs_sb_info *sbi, __le32 rtag,
			const struct MFT_REF *ref)
{}

static inline void ntfs_unmap_and_discard(struct ntfs_sb_info *sbi, CLST lcn,
					  CLST len)
{}

void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim)
{}

/*
 * run_deallocate - Deallocate clusters.
 */
int run_deallocate(struct ntfs_sb_info *sbi, const struct runs_tree *run,
		   bool trim)
{}

static inline bool name_has_forbidden_chars(const struct le_str *fname)
{}

static inline bool is_reserved_name(const struct ntfs_sb_info *sbi,
				    const struct le_str *fname)
{}

/*
 * valid_windows_name - Check if a file name is valid in Windows.
 */
bool valid_windows_name(struct ntfs_sb_info *sbi, const struct le_str *fname)
{}

/*
 * ntfs_set_label - updates current ntfs label.
 */
int ntfs_set_label(struct ntfs_sb_info *sbi, u8 *label, int len)
{}