cregit-Linux how code gets into the kernel

Release 4.11 fs/bfs/file.c

Directory: fs/bfs
/*
 *      fs/bfs/file.c
 *      BFS file operations.
 *      Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com>
 *
 *      Make the file block allocation algorithm understand the size
 *      of the underlying block device.
 *      Copyright (C) 2007 Dmitri Vorobiev <dmitri.vorobiev@gmail.com>
 *
 */

#include <linux/fs.h>
#include <linux/buffer_head.h>
#include "bfs.h"


#undef DEBUG

#ifdef DEBUG

#define dprintf(x...)	printf(x)
#else

#define dprintf(x...)
#endif


const struct file_operations bfs_file_operations = {
	.llseek 	= generic_file_llseek,
	.read_iter	= generic_file_read_iter,
	.write_iter	= generic_file_write_iter,
	.mmap		= generic_file_mmap,
	.splice_read	= generic_file_splice_read,
};


static int bfs_move_block(unsigned long from, unsigned long to, struct super_block *sb) { struct buffer_head *bh, *new; bh = sb_bread(sb, from); if (!bh) return -EIO; new = sb_getblk(sb, to); memcpy(new->b_data, bh->b_data, bh->b_size); mark_buffer_dirty(new); bforget(bh); brelse(new); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)7990.80%150.00%
Linus Torvalds89.20%150.00%
Total87100.00%2100.00%


static int bfs_move_blocks(struct super_block *sb, unsigned long start, unsigned long end, unsigned long where) { unsigned long i; dprintf("%08lx-%08lx->%08lx\n", start, end, where); for (i = start; i <= end; i++) if(bfs_move_block(i, where + i, sb)) { dprintf("failed to move block %08lx -> %08lx\n", i, where + i); return -EIO; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)7994.05%150.00%
Linus Torvalds55.95%150.00%
Total84100.00%2100.00%


static int bfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create) { unsigned long phys; int err; struct super_block *sb = inode->i_sb; struct bfs_sb_info *info = BFS_SB(sb); struct bfs_inode_info *bi = BFS_I(inode); phys = bi->i_sblock + block; if (!create) { if (phys <= bi->i_eblock) { dprintf("c=%d, b=%08lx, phys=%09lx (granted)\n", create, (unsigned long)block, phys); map_bh(bh_result, sb, phys); } return 0; } /* * If the file is not empty and the requested block is within the * range of blocks allocated for this file, we can grant it. */ if (bi->i_sblock && (phys <= bi->i_eblock)) { dprintf("c=%d, b=%08lx, phys=%08lx (interim block granted)\n", create, (unsigned long)block, phys); map_bh(bh_result, sb, phys); return 0; } /* The file will be extended, so let's see if there is enough space. */ if (phys >= info->si_blocks) return -ENOSPC; /* The rest has to be protected against itself. */ mutex_lock(&info->bfs_lock); /* * If the last data block for this file is the last allocated * block, we can extend the file trivially, without moving it * anywhere. */ if (bi->i_eblock == info->si_lf_eblk) { dprintf("c=%d, b=%08lx, phys=%08lx (simple extension)\n", create, (unsigned long)block, phys); map_bh(bh_result, sb, phys); info->si_freeb -= phys - bi->i_eblock; info->si_lf_eblk = bi->i_eblock = phys; mark_inode_dirty(inode); err = 0; goto out; } /* Ok, we have to move this entire file to the next free block. */ phys = info->si_lf_eblk + 1; if (phys + block >= info->si_blocks) { err = -ENOSPC; goto out; } if (bi->i_sblock) { err = bfs_move_blocks(inode->i_sb, bi->i_sblock, bi->i_eblock, phys); if (err) { dprintf("failed to move ino=%08lx -> fs corruption\n", inode->i_ino); goto out; } } else err = 0; dprintf("c=%d, b=%08lx, phys=%08lx (moved)\n", create, (unsigned long)block, phys); bi->i_sblock = phys; phys += block; info->si_lf_eblk = bi->i_eblock = phys; /* * This assumes nothing can write the inode back while we are here * and thus update inode->i_blocks! (XXX) */ info->si_freeb -= bi->i_eblock - bi->i_sblock + 1 - inode->i_blocks; mark_inode_dirty(inode); map_bh(bh_result, sb, phys); out: mutex_unlock(&info->bfs_lock); return err; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)24861.23%646.15%
Linus Torvalds6115.06%323.08%
Dmitri Vorobiev5613.83%215.38%
Dave Jones225.43%17.69%
Andrew Stribblehill184.44%17.69%
Total405100.00%13100.00%


static int bfs_writepage(struct page *page, struct writeback_control *wbc) { return block_write_full_page(page, bfs_get_block, wbc); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)1973.08%150.00%
Andrew Morton726.92%150.00%
Total26100.00%2100.00%


static int bfs_readpage(struct file *file, struct page *page) { return block_read_full_page(page, bfs_get_block); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)24100.00%2100.00%
Total24100.00%2100.00%


static void bfs_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); }

Contributors

PersonTokensPropCommitsCommitProp
Marco Stornelli40100.00%1100.00%
Total40100.00%1100.00%


static int bfs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) { int ret; ret = block_write_begin(mapping, pos, len, flags, pagep, bfs_get_block); if (unlikely(ret)) bfs_write_failed(mapping, pos + len); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Nicholas Piggin3040.00%120.00%
Linus Torvalds (pre-git)2229.33%240.00%
Christoph Hellwig2026.67%120.00%
Marco Stornelli34.00%120.00%
Total75100.00%5100.00%


static sector_t bfs_bmap(struct address_space *mapping, sector_t block) { return generic_block_bmap(mapping, block, bfs_get_block); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2291.67%150.00%
Andrew Morton28.33%150.00%
Total24100.00%2100.00%

const struct address_space_operations bfs_aops = { .readpage = bfs_readpage, .writepage = bfs_writepage, .write_begin = bfs_write_begin, .write_end = generic_write_end, .bmap = bfs_bmap, }; const struct inode_operations bfs_file_inops;

Overall Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)55764.10%927.27%
Linus Torvalds778.86%412.12%
Dmitri Vorobiev576.56%26.06%
Marco Stornelli434.95%13.03%
Nicholas Piggin343.91%13.03%
Christoph Hellwig242.76%515.15%
Dave Jones222.53%13.03%
Andrew Stribblehill182.07%13.03%
Art Haas182.07%13.03%
Andrew Morton91.04%26.06%
Al Viro40.46%26.06%
Badari Pulavarty20.23%13.03%
Arjan van de Ven20.23%26.06%
Jens Axboe20.23%13.03%
Total869100.00%33100.00%
Directory: fs/bfs
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.