<commit_before>/*
 *  linux/fs/fat/inode.c
 *
 *  Written 1992,1993 by <NAME>
 *  VFAT extensions by <NAME>, merged with msdos fs by <NAME>
 *  Rewritten for the constant inumbers support by <NAME>
 *
 *  Fixes:
 *
 *	Max Cohan: Fixed invalid FSINFO offset when info_sector is 0
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/msdos_fs.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/mount.h>
#include <linux/vfs.h>
#include <linux/parser.h>
#include <asm/unaligned.h>

#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
/* if user don't select VFAT, this is undefined. */
#define CONFIG_FAT_DEFAULT_IOCHARSET	""
#endif

static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE;
static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET;


static int fat_add_cluster(struct inode *inode)
{
	int err, cluster;

	err = fat_alloc_clusters(inode, &cluster, 1);
	if (err)
		return err;
	/* FIXME: this cluster should be added after data of this
	 * cluster is writed */
	err = fat_chain_add(inode, cluster, 1);
	if (err)
		fat_free_clusters(inode, cluster);
	return err;
}

static int fat_get_block(struct inode *inode, sector_t iblock,
			 struct buffer_head *bh_result, int create)
{
	struct super_block *sb = inode->i_sb;
	sector_t phys;
	int err;

	err = fat_bmap(inode, iblock, &phys);
	if (err)
		return err;
	if (phys) {
		map_bh(bh_result, sb, phys);
		return 0;
	}
	if (!create)
		return 0;
	if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
		fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
			     MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
		return -EIO;
	}
	if (!((unsigned long)iblock & (MSDOS_SB(sb)->sec_per_clus - 1))) {
		err = fat_add_cluster(inode);
		if (err)
			return err;
	}
	MSDOS_I(inode)->mmu_private += sb->s_blocksize;
	err = fat_bmap(inode, iblock, &phys);
	if (err)
		return err;
	if (!phys)
		BUG();
	set_buffer_new(bh_result);
	map_bh(bh_result, sb, phys);
	return 0;
}

static int fat_writepage(struct page *page, struct writeback_control *wbc)
{
	return block_write_full_page(page, fat_get_block, wbc);
}

static int fat_readpage(struct file *file, struct page *page)
{
	return block_read_full_page(page, fat_get_block);
}

static int fat_prepare_write(struct file *file, struct page *page,
			     unsigned from, unsigned to)
{
	return cont_prepare_write(page, from, to, fat_get_block,
				  &MSDOS_I(page->mapping->host)->mmu_private);
}

static int fat_commit_write(struct file *file, struct page *page,
			    unsigned from, unsigned to)
{
	struct inode *inode = page->mapping->host;
	int err = generic_commit_write(file, page, from, to);
	if (!err && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
		inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
		MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
		mark_inode_dirty(inode);
	}
	return err;
}

static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
{
	return generic_block_bmap(mapping, block, fat_get_block);
}

static struct address_space_operations fat_aops = {
	.readpage	= fat_readpage,
	.writepage	= fat_writepage,
	.sync_page	= block_sync_page,
	.prepare_write	= fat_prepare_write,
	.commit_write	= fat_commit_write,
	.bmap		= _fat_bmap
};

/*
 * New FAT inode stuff. We do the following:
 *	a) i_ino is constant and has nothing with on-disk location.
 *	b) FAT manages its own cache of directory entries.
 *	c) *This* cache is indexed by on-disk location.
 *	d) inode has an associated directory entry, all right, but
 *		it may be unhashed.
 *	e) currently entries are stored within struct inode. That should
 *		change.
 *	f) we deal with races in the following way:
 *		1. readdir() and lookup() do FAT-dir-cache lookup.
 *		2. rename() unhashes the F-d-c entry and rehashes it in
 *			a new place.
 *		3. unlink() and rmdir() unhash F-d-c entry.
 *		4. fat_write_inode() checks whether the thing is unhashed.
 *			If it is we silently return. If it isn't we do bread(),
 *			check if the location is still valid and retry if it<commit_msg>[PATCH] fat: add the read/writepages()<commit_after>/*
 *  linux/fs/fat/inode.c
 *
 *  Written 1992,1993 by <NAME>
 *  VFAT extensions by <NAME>, merged with msdos fs by <NAME>
 *  Rewritten for the constant inumbers support by <NAME>
 *
 *  Fixes:
 *
 *	Max Cohan: Fixed invalid FSINFO offset when info_sector is 0
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/msdos_fs.h>
#include <linux/pagemap.h>
#include <linux/mpage.h>
#include <linux/buffer_head.h>
#include <linux/mount.h>
#include <linux/vfs.h>
#include <linux/parser.h>
#include <asm/unaligned.h>

#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
/* if user don't select VFAT, this is undefined. */
#define CONFIG_FAT_DEFAULT_IOCHARSET	""
#endif

static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE;
static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET;


static int fat_add_cluster(struct inode *inode)
{
	int err, cluster;

	err = fat_alloc_clusters(inode, &cluster, 1);
	if (err)
		return err;
	/* FIXME: this cluster should be added after data of this
	 * cluster is writed */
	err = fat_chain_add(inode, cluster, 1);
	if (err)
		fat_free_clusters(inode, cluster);
	return err;
}

static int fat_get_block(struct inode *inode, sector_t iblock,
			 struct buffer_head *bh_result, int create)
{
	struct super_block *sb = inode->i_sb;
	sector_t phys;
	int err;

	err = fat_bmap(inode, iblock, &phys);
	if (err)
		return err;
	if (phys) {
		map_bh(bh_result, sb, phys);
		return 0;
	}
	if (!create)
		return 0;
	if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
		fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
			     MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
		return -EIO;
	}
	if (!((unsigned long)iblock & (MSDOS_SB(sb)->sec_per_clus - 1))) {
		err = fat_add_cluster(inode);
		if (err)
			return err;
	}
	MSDOS_I(inode)->mmu_private += sb->s_blocksize;
	err = fat_bmap(inode, iblock, &phys);
	if (err)
		return err;
	if (!phys)
		BUG();
	set_buffer_new(bh_result);
	map_bh(bh_result, sb, phys);
	return 0;
}

static int fat_writepage(struct page *page, struct writeback_control *wbc)
{
	return block_write_full_page(page, fat_get_block, wbc);
}

static int fat_writepages(struct address_space *mapping,
			  struct writeback_control *wbc)
{
	return mpage_writepages(mapping, wbc, fat_get_block);
}

static int fat_readpage(struct file *file, struct page *page)
{
	return mpage_readpage(page, fat_get_block);
}

static int fat_readpages(struct file *file, struct address_space *mapping,
			 struct list_head *pages, unsigned nr_pages)
{
	return mpage_readpages(mapping, pages, nr_pages, fat_get_block);
}

static int fat_prepare_write(struct file *file, struct page *page,
			     unsigned from, unsigned to)
{
	return cont_prepare_write(page, from, to, fat_get_block,
				  &MSDOS_I(page->mapping->host)->mmu_private);
}

static int fat_commit_write(struct file *file, struct page *page,
			    unsigned from, unsigned to)
{
	struct inode *inode = page->mapping->host;
	int err = generic_commit_write(file, page, from, to);
	if (!err && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
		inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
		MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
		mark_inode_dirty(inode);
	}
	return err;
}

static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
{
	return generic_block_bmap(mapping, block, fat_get_block);
}

static struct address_space_operations fat_aops = {
	.readpage	= fat_readpage,
	.readpages	= fat_readpages,
	.writepage	= fat_writepage,
	.writepages	= fat_writepages,
	.sync_page	= block_sync_page,
	.prepare_write	= fat_prepare_write,
	.commit_write	= fat_commit_write,
	.bmap		= _fat_bmap
};

/*
 * New FAT inode stuff. We do the following:
 *	a) i_ino is constant and has nothing with on-disk location.
 *	b) FAT manages its own cache of directory entries.
 *	c) *This* cache is indexed by on-disk location.
 *	d) inode has an associated directory entry, all right, but
 *		it may be unhashed.
 *	e) currently entries are stored within struct inode. That should
 *		change.
 *	f) we deal with races in the following way:
 *		1. readdir() and lookup() do FAT-dir-cache lookup.
 *		2. rename() unhashes the F-d-c entry and rehashes it in
 *			a new place.
 *		3. unlink() and rmdir() unhash F-d-c entry.
 *		4. fat_write_inode() checks whether the thing is unhashed.
 *			If it is we silently return. If it isn't we do bread(),
 *			check if the location is still valid and retry if it
{'fraction_non_alphanumeric': 0.11788291900561347, 'fraction_numerical': 0.0043533050750372325, 'mean_word_length': 4.418994413407821, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 76, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5850108', 'n_tokens_mistral': 3408, 'n_tokens_neox': 3247, 'n_words': 907}