Release 4.10 fs/fat/inode.c
/*
* linux/fs/fat/inode.c
*
* Written 1992,1993 by Werner Almesberger
* VFAT extensions by Gordon Chaffee, merged with msdos fs by Henrik Storner
* Rewritten for the constant inumbers support by Al Viro
*
* Fixes:
*
* Max Cohan: Fixed invalid FSINFO offset when info_sector is 0
*/
#include <linux/module.h>
#include <linux/pagemap.h>
#include <linux/mpage.h>
#include <linux/vfs.h>
#include <linux/seq_file.h>
#include <linux/parser.h>
#include <linux/uio.h>
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
#include <asm/unaligned.h>
#include "fat.h"
#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
/* if user don't select VFAT, this is undefined. */
#define CONFIG_FAT_DEFAULT_IOCHARSET ""
#endif
#define KB_IN_SECTORS 2
/*
* A deserialized copy of the on-disk structure laid out in struct
* fat_boot_sector.
*/
struct fat_bios_param_block {
u16 fat_sector_size;
u8 fat_sec_per_clus;
u16 fat_reserved;
u8 fat_fats;
u16 fat_dir_entries;
u16 fat_sectors;
u16 fat_fat_length;
u32 fat_total_sect;
u8 fat16_state;
u32 fat16_vol_id;
u32 fat32_length;
u32 fat32_root_cluster;
u16 fat32_info_sector;
u8 fat32_state;
u32 fat32_vol_id;
};
static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE;
static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET;
static struct fat_floppy_defaults {
unsigned nr_sectors;
unsigned sec_per_clus;
unsigned dir_entries;
unsigned media;
unsigned fat_length;
}
floppy_defaults[] = {
{
.nr_sectors = 160 * KB_IN_SECTORS,
.sec_per_clus = 1,
.dir_entries = 64,
.media = 0xFE,
.fat_length = 1,
},
{
.nr_sectors = 180 * KB_IN_SECTORS,
.sec_per_clus = 1,
.dir_entries = 64,
.media = 0xFC,
.fat_length = 2,
},
{
.nr_sectors = 320 * KB_IN_SECTORS,
.sec_per_clus = 2,
.dir_entries = 112,
.media = 0xFF,
.fat_length = 1,
},
{
.nr_sectors = 360 * KB_IN_SECTORS,
.sec_per_clus = 2,
.dir_entries = 112,
.media = 0xFD,
.fat_length = 2,
},
};
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;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 60 | 100.00% | 1 | 100.00% |
| Total | 60 | 100.00% | 1 | 100.00% |
static inline int __fat_get_block(struct inode *inode, sector_t iblock,
unsigned long *max_blocks,
struct buffer_head *bh_result, int create)
{
struct super_block *sb = inode->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
unsigned long mapped_blocks;
sector_t phys, last_block;
int err, offset;
err = fat_bmap(inode, iblock, &phys, &mapped_blocks, create, false);
if (err)
return err;
if (phys) {
map_bh(bh_result, sb, phys);
*max_blocks = min(mapped_blocks, *max_blocks);
return 0;
}
if (!create)
return 0;
if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
fat_fs_error(sb, "corrupted file size (i_pos %lld, %lld)",
MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
return -EIO;
}
last_block = inode->i_blocks >> (sb->s_blocksize_bits - 9);
offset = (unsigned long)iblock & (sbi->sec_per_clus - 1);
/*
* allocate a cluster according to the following.
* 1) no more available blocks
* 2) not part of fallocate region
*/
if (!offset && !(iblock < last_block)) {
/* TODO: multiple cluster allocation would be desirable. */
err = fat_add_cluster(inode);
if (err)
return err;
}
/* available blocks on this cluster */
mapped_blocks = sbi->sec_per_clus - offset;
*max_blocks = min(mapped_blocks, *max_blocks);
MSDOS_I(inode)->mmu_private += *max_blocks << sb->s_blocksize_bits;
err = fat_bmap(inode, iblock, &phys, &mapped_blocks, create, false);
if (err)
return err;
BUG_ON(!phys);
BUG_ON(*max_blocks != mapped_blocks);
set_buffer_new(bh_result);
map_bh(bh_result, sb, phys);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 227 | 71.61% | 7 | 36.84% |
pre-git | pre-git | 49 | 15.46% | 7 | 36.84% |
namjae jeon | namjae jeon | 28 | 8.83% | 2 | 10.53% |
christoph hellwig | christoph hellwig | 11 | 3.47% | 1 | 5.26% |
linus torvalds | linus torvalds | 1 | 0.32% | 1 | 5.26% |
denis karpov | denis karpov | 1 | 0.32% | 1 | 5.26% |
| Total | 317 | 100.00% | 19 | 100.00% |
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;
unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
int err;
err = __fat_get_block(inode, iblock, &max_blocks, bh_result, create);
if (err)
return err;
bh_result->b_size = max_blocks << sb->s_blocksize_bits;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 70 | 85.37% | 2 | 66.67% |
badari pulavarty | badari pulavarty | 12 | 14.63% | 1 | 33.33% |
| Total | 82 | 100.00% | 3 | 100.00% |
static int fat_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page, fat_get_block, wbc);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 18 | 69.23% | 2 | 66.67% |
pre-git | pre-git | 8 | 30.77% | 1 | 33.33% |
| Total | 26 | 100.00% | 3 | 100.00% |
static int fat_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{
return mpage_writepages(mapping, wbc, fat_get_block);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 26 | 100.00% | 1 | 100.00% |
| Total | 26 | 100.00% | 1 | 100.00% |
static int fat_readpage(struct file *file, struct page *page)
{
return mpage_readpage(page, fat_get_block);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 13 | 54.17% | 2 | 40.00% |
pre-git | pre-git | 11 | 45.83% | 3 | 60.00% |
| Total | 24 | 100.00% | 5 | 100.00% |
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);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 36 | 100.00% | 1 | 100.00% |
| Total | 36 | 100.00% | 1 | 100.00% |
static void fat_write_failed(struct address_space *mapping, loff_t to)
{
struct inode *inode = mapping->host;
if (to > inode->i_size) {
truncate_pagecache(inode, inode->i_size);
fat_truncate_blocks(inode, inode->i_size);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
nick piggin | nick piggin | 51 | 100.00% | 1 | 100.00% |
| Total | 51 | 100.00% | 1 | 100.00% |
static int fat_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
int err;
*pagep = NULL;
err = cont_write_begin(file, mapping, pos, len, flags,
pagep, fsdata, fat_get_block,
&MSDOS_I(mapping->host)->mmu_private);
if (err < 0)
fat_write_failed(mapping, pos + len);
return err;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
nick piggin | nick piggin | 58 | 62.37% | 2 | 33.33% |
hirofumi ogawa | hirofumi ogawa | 26 | 27.96% | 1 | 16.67% |
pre-git | pre-git | 8 | 8.60% | 2 | 33.33% |
christoph hellwig | christoph hellwig | 1 | 1.08% | 1 | 16.67% |
| Total | 93 | 100.00% | 6 | 100.00% |
static int fat_write_end(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *pagep, void *fsdata)
{
struct inode *inode = mapping->host;
int err;
err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata);
if (err < len)
fat_write_failed(mapping, pos + len);
if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
inode->i_mtime = inode->i_ctime = current_time(inode);
MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
mark_inode_dirty(inode);
}
return err;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 79 | 59.40% | 1 | 25.00% |
nick piggin | nick piggin | 50 | 37.59% | 2 | 50.00% |
deepa dinamani | deepa dinamani | 4 | 3.01% | 1 | 25.00% |
| Total | 133 | 100.00% | 4 | 100.00% |
static ssize_t fat_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
{
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
size_t count = iov_iter_count(iter);
loff_t offset = iocb->ki_pos;
ssize_t ret;
if (iov_iter_rw(iter) == WRITE) {
/*
* FIXME: blockdev_direct_IO() doesn't use ->write_begin(),
* so we need to update the ->mmu_private to block boundary.
*
* But we must fill the remaining area or hole by nul for
* updating ->mmu_private.
*
* Return 0, and fallback to normal buffered write.
*/
loff_t size = offset + count;
if (MSDOS_I(inode)->mmu_private < size)
return 0;
}
/*
* FAT need to use the DIO_LOCKING for avoiding the race
* condition of fat_get_block() and ->truncate().
*/
ret = blockdev_direct_IO(iocb, inode, iter, fat_get_block);
if (ret < 0 && iov_iter_rw(iter) == WRITE)
fat_write_failed(mapping, offset + count);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 69 | 51.88% | 3 | 30.00% |
nick piggin | nick piggin | 34 | 25.56% | 2 | 20.00% |
al viro | al viro | 13 | 9.77% | 2 | 20.00% |
omar sandoval | omar sandoval | 9 | 6.77% | 1 | 10.00% |
christoph hellwig | christoph hellwig | 8 | 6.02% | 2 | 20.00% |
| Total | 133 | 100.00% | 10 | 100.00% |
static int fat_get_block_bmap(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
struct super_block *sb = inode->i_sb;
unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
int err;
sector_t bmap;
unsigned long mapped_blocks;
BUG_ON(create != 0);
err = fat_bmap(inode, iblock, &bmap, &mapped_blocks, create, true);
if (err)
return err;
if (bmap) {
map_bh(bh_result, sb, bmap);
max_blocks = min(mapped_blocks, max_blocks);
}
bh_result->b_size = max_blocks << sb->s_blocksize_bits;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
namjae jeon | namjae jeon | 123 | 100.00% | 1 | 100.00% |
| Total | 123 | 100.00% | 1 | 100.00% |
static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
{
sector_t blocknr;
/* fat_get_cluster() assumes the requested blocknr isn't truncated. */
down_read(&MSDOS_I(mapping->host)->truncate_lock);
blocknr = generic_block_bmap(mapping, block, fat_get_block_bmap);
up_read(&MSDOS_I(mapping->host)->truncate_lock);
return blocknr;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 41 | 70.69% | 3 | 37.50% |
christoph hellwig | christoph hellwig | 9 | 15.52% | 2 | 25.00% |
pre-git | pre-git | 5 | 8.62% | 1 | 12.50% |
linus torvalds | linus torvalds | 2 | 3.45% | 1 | 12.50% |
namjae jeon | namjae jeon | 1 | 1.72% | 1 | 12.50% |
| Total | 58 | 100.00% | 8 | 100.00% |
/*
* fat_block_truncate_page() zeroes out a mapping from file offset `from'
* up to the end of the block which corresponds to `from'.
* This is required during truncate to physically zeroout the tail end
* of that block so it doesn't yield old data if the file is later grown.
* Also, avoid causing failure from fsx for cases of "data past EOF"
*/
int fat_block_truncate_page(struct inode *inode, loff_t from)
{
return block_truncate_page(inode->i_mapping, from, fat_get_block);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
namjae jeon | namjae jeon | 25 | 100.00% | 1 | 100.00% |
| Total | 25 | 100.00% | 1 | 100.00% |
static const struct address_space_operations fat_aops = {
.readpage = fat_readpage,
.readpages = fat_readpages,
.writepage = fat_writepage,
.writepages = fat_writepages,
.write_begin = fat_write_begin,
.write_end = fat_write_end,
.direct_IO = fat_direct_IO,
.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
* isn't. Otherwise we do changes.
* 5. Spinlock is used to protect hash/unhash/location check/lookup
* 6. fat_evict_inode() unhashes the F-d-c entry.
* 7. lookup() and readdir() do igrab() if they find a F-d-c entry
* and consider negative result as cache miss.
*/
static void fat_hash_init(struct super_block *sb)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);
int i;
spin_lock_init(&sbi->inode_hash_lock);
for (i = 0; i < FAT_HASH_SIZE; i++)
INIT_HLIST_HEAD(&sbi->inode_hashtable[i]);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 46 | 82.14% | 2 | 33.33% |
pre-git | pre-git | 7 | 12.50% | 2 | 33.33% |
linus torvalds | linus torvalds | 2 | 3.57% | 1 | 16.67% |
christoph hellwig | christoph hellwig | 1 | 1.79% | 1 | 16.67% |
| Total | 56 | 100.00% | 6 | 100.00% |
static inline unsigned long fat_hash(loff_t i_pos)
{
return hash_32(i_pos, FAT_HASH_BITS);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 19 | 100.00% | 2 | 100.00% |
| Total | 19 | 100.00% | 2 | 100.00% |
static void dir_hash_init(struct super_block *sb)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);
int i;
spin_lock_init(&sbi->dir_hash_lock);
for (i = 0; i < FAT_HASH_SIZE; i++)
INIT_HLIST_HEAD(&sbi->dir_hashtable[i]);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven j. magnani | steven j. magnani | 56 | 100.00% | 1 | 100.00% |
| Total | 56 | 100.00% | 1 | 100.00% |
void fat_attach(struct inode *inode, loff_t i_pos)
{
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
if (inode->i_ino != MSDOS_ROOT_INO) {
struct hlist_head *head = sbi->inode_hashtable
+ fat_hash(i_pos);
spin_lock(&sbi->inode_hash_lock);
MSDOS_I(inode)->i_pos = i_pos;
hlist_add_head(&MSDOS_I(inode)->i_fat_hash, head);
spin_unlock(&sbi->inode_hash_lock);
}
/* If NFS support is enabled, cache the mapping of start cluster
* to directory inode. This is used during reconnection of
* dentries to the filesystem root.
*/
if (S_ISDIR(inode->i_mode) && sbi->options.nfs) {
struct hlist_head *d_head = sbi->dir_hashtable;
d_head += fat_dir_hash(MSDOS_I(inode)->i_logstart);
spin_lock(&sbi->dir_hash_lock);
hlist_add_head(&MSDOS_I(inode)->i_dir_hash, d_head);
spin_unlock(&sbi->dir_hash_lock);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven j. magnani | steven j. magnani | 78 | 50.32% | 1 | 16.67% |
hirofumi ogawa | hirofumi ogawa | 52 | 33.55% | 3 | 50.00% |
pre-git | pre-git | 25 | 16.13% | 2 | 33.33% |
| Total | 155 | 100.00% | 6 | 100.00% |
EXPORT_SYMBOL_GPL(fat_attach);
void fat_detach(struct inode *inode)
{
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
spin_lock(&sbi->inode_hash_lock);
MSDOS_I(inode)->i_pos = 0;
hlist_del_init(&MSDOS_I(inode)->i_fat_hash);
spin_unlock(&sbi->inode_hash_lock);
if (S_ISDIR(inode->i_mode) && sbi->options.nfs) {
spin_lock(&sbi->dir_hash_lock);
hlist_del_init(&MSDOS_I(inode)->i_dir_hash);
spin_unlock(&sbi->dir_hash_lock);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven j. magnani | steven j. magnani | 44 | 43.14% | 1 | 16.67% |
hirofumi ogawa | hirofumi ogawa | 28 | 27.45% | 2 | 33.33% |
pre-git | pre-git | 23 | 22.55% | 2 | 33.33% |
brian gerst | brian gerst | 7 | 6.86% | 1 | 16.67% |
| Total | 102 | 100.00% | 6 | 100.00% |
EXPORT_SYMBOL_GPL(fat_detach);
struct inode *fat_iget(struct super_block *sb, loff_t i_pos)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);
struct hlist_head *head = sbi->inode_hashtable + fat_hash(i_pos);
struct msdos_inode_info *i;
struct inode *inode = NULL;
spin_lock(&sbi->inode_hash_lock);
hlist_for_each_entry(i, head, i_fat_hash) {
BUG_ON(i->vfs_inode.i_sb != sb);
if (i->i_pos != i_pos)
continue;
inode = igrab(&i->vfs_inode);
if (inode)
break;
}
spin_unlock(&sbi->inode_hash_lock);
return inode;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 114 | 99.13% | 4 | 80.00% |
linus torvalds | linus torvalds | 1 | 0.87% | 1 | 20.00% |
| Total | 115 | 100.00% | 5 | 100.00% |
static int is_exec(unsigned char *extension)
{
unsigned char exe_extensions[] = "EXECOMBAT", *walk;
for (walk = exe_extensions; *walk; walk += 3)
if (!strncmp(extension, walk, 3))
return 1;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 48 | 92.31% | 2 | 50.00% |
linus torvalds | linus torvalds | 3 | 5.77% | 1 | 25.00% |
manuel scholling | manuel scholling | 1 | 1.92% | 1 | 25.00% |
| Total | 52 | 100.00% | 4 | 100.00% |
static int fat_calc_dir_size(struct inode *inode)
{
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
int ret, fclus, dclus;
inode->i_size = 0;
if (MSDOS_I(inode)->i_start == 0)
return 0;
ret = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
if (ret < 0)
return ret;
inode->i_size = (fclus + 1) << sbi->cluster_bits;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 91 | 100.00% | 2 | 100.00% |
| Total | 91 | 100.00% | 2 | 100.00% |
static int fat_validate_dir(struct inode *dir)
{
struct super_block *sb = dir->i_sb;
if (dir->i_nlink < 2) {
/* Directory should have "."/".." entries at least. */
fat_fs_error(sb, "corrupted directory (invalid entries)");
return -EIO;
}
if (MSDOS_I(dir)->i_start == 0 ||
MSDOS_I(dir)->i_start == MSDOS_SB(sb)->root_cluster) {
/* Directory should point valid cluster. */
fat_fs_error(sb, "corrupted directory (invalid i_start)");
return -EIO;
}
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 84 | 100.00% | 1 | 100.00% |
| Total | 84 | 100.00% | 1 | 100.00% |
/* doesn't deal with root inode */
int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
{
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
int error;
MSDOS_I(inode)->i_pos = 0;
inode->i_uid = sbi->options.fs_uid;
inode->i_gid = sbi->options.fs_gid;
inode->i_version++;
inode->i_generation = get_seconds();
if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
inode->i_generation &= ~1;
inode->i_mode = fat_make_mode(sbi, de->attr, S_IRWXUGO);
inode->i_op = sbi->dir_ops;
inode->i_fop = &fat_dir_operations;
MSDOS_I(inode)->i_start = fat_get_start(sbi, de);
MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
error = fat_calc_dir_size(inode);
if (error < 0)
return error;
MSDOS_I(inode)->mmu_private = inode->i_size;
set_nlink(inode, fat_subdirs(inode));
error = fat_validate_dir(inode);
if (error < 0)
return error;
} else { /* not a directory */
inode->i_generation |= 1;
inode->i_mode = fat_make_mode(sbi, de->attr,
((sbi->options.showexec && !is_exec(de->name + 8))
? S_IRUGO|S_IWUGO : S_IRWXUGO));
MSDOS_I(inode)->i_start = fat_get_start(sbi, de);
MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
inode->i_size = le32_to_cpu(de->size);
inode->i_op = &fat_file_inode_operations;
inode->i_fop = &fat_file_operations;
inode->i_mapping->a_ops = &fat_aops;
MSDOS_I(inode)->mmu_private = inode->i_size;
}
if (de->attr & ATTR_SYS) {
if (sbi->options.sys_immutable)
inode->i_flags |= S_IMMUTABLE;
}
fat_save_attrs(inode, de->attr);
inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
& ~((loff_t)sbi->cluster_size - 1)) >> 9;
fat_time_fat2unix(sbi, &inode->i_mtime, de->time, de->date, 0);
if (sbi->options.isvfat) {
fat_time_fat2unix(sbi, &inode->i_ctime, de->ctime,
de->cdate, de->ctime_cs);
fat_time_fat2unix(sbi, &inode->i_atime, 0, de->adate, 0);
} else
inode->i_ctime = inode->i_atime = inode->i_mtime;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 456 | 94.21% | 7 | 58.33% |
stephane kardas | stephane kardas | 14 | 2.89% | 1 | 8.33% |
steven j. magnani | steven j. magnani | 4 | 0.83% | 1 | 8.33% |
joe peterson | joe peterson | 4 | 0.83% | 1 | 8.33% |
miklos szeredi | miklos szeredi | 4 | 0.83% | 1 | 8.33% |
andrew morton | andrew morton | 2 | 0.41% | 1 | 8.33% |
| Total | 484 | 100.00% | 12 | 100.00% |
static inline void fat_lock_build_inode(struct msdos_sb_info *sbi)
{
if (sbi->options.nfs == FAT_NFS_NOSTALE_RO)
mutex_lock(&sbi->nfs_build_inode_lock);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
namjae jeon | namjae jeon | 30 | 100.00% | 1 | 100.00% |
| Total | 30 | 100.00% | 1 | 100.00% |
static inline void fat_unlock_build_inode(struct msdos_sb_info *sbi)
{
if (sbi->options.nfs == FAT_NFS_NOSTALE_RO)
mutex_unlock(&sbi->nfs_build_inode_lock);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
namjae jeon | namjae jeon | 30 | 100.00% | 1 | 100.00% |
| Total | 30 | 100.00% | 1 | 100.00% |
struct inode *fat_build_inode(struct super_block *sb,
struct msdos_dir_entry *de, loff_t i_pos)
{
struct inode *inode;
int err;
fat_lock_build_inode(MSDOS_SB(sb));
inode = fat_iget(sb, i_pos);
if (inode)
goto out;
inode = new_inode(sb);
if (!inode) {
inode = ERR_PTR(-ENOMEM);
goto out;
}
inode->i_ino = iunique(sb, MSDOS_ROOT_INO);
inode->i_version = 1;
err = fat_fill_inode(inode, de);
if (err) {
iput(inode);
inode = ERR_PTR(err);
goto out;
}
fat_attach(inode, i_pos);
insert_inode_hash(inode);
out:
fat_unlock_build_inode(MSDOS_SB(sb));
return inode;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
hirofumi ogawa | hirofumi ogawa | 133 | 89.26% | 3 | 75.00% |
namjae jeon | namjae jeon | 16 | 10.74% | 1 | 25.00% |
| Total | 149 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL_GPL(fat_build_inode);
static int __fat_write_inode(struct inode *