⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inode.c

📁 嵌入式linux下基于SRAM的内存文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * FILE NAME fs/pramfs/inode.c * * BRIEF DESCRIPTION * * Inode methods (allocate/free/read/write). * * Author: Steve Longerbeam <stevel@mvista.com, or source@mvista.com> * * Copyright 2003 Sony Corporation * Copyright 2003 Matsushita Electric Industrial Co., Ltd. * 2003-2004 (c) MontaVista Software, Inc. This file is licensed under * the terms of the GNU General Public License version 2. This program * is licensed "as is" without any warranty of any kind, whether express * or implied. */#include <linux/fs.h>#include <linux/pram_fs.h>#include <linux/smp_lock.h>#include <linux/sched.h>#include <linux/highuid.h>#include <linux/quotaops.h>#include <linux/module.h>#include <linux/buffer_head.h>#include <linux/mpage.h>#include <linux/backing-dev.h>static struct backing_dev_info pram_backing_dev_info = {	.ra_pages       = 0,    /* No readahead */	/* Does not contribute to dirty memory */	.capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,};#if 0static void pram_dump_inode(struct inode * inode){	struct pram_inode * pi = pram_get_inode(inode->i_sb, inode->i_ino);	printk("uid         0x%08x\n", pi->i_uid);	printk("gid         0x%08x\n", pi->i_gid);	printk("mode        0x%08x\n", pi->i_mode);	printk("links_count 0x%08x\n", pi->i_links_count);	printk("blocks      0x%08x\n", pi->i_blocks);	printk("size        0x%08x\n", pi->i_size);	printk("atime       0x%08x\n", pi->i_atime);	printk("ctime       0x%08x\n", pi->i_ctime);	printk("mtime       0x%08x\n", pi->i_mtime);	printk("dtime       0x%08x\n", pi->i_dtime);	printk("row_block   0x%08lx\n", pi->i_type.reg.row_block);	printk("head        0x%08lx\n", pi->i_type.dir.head);	printk("tail        0x%08lx\n", pi->i_type.dir.tail);	printk("rdev        0x%08x\n", pi->i_type.dev.rdev);	printk("d_next      0x%08lx\n", pi->i_d.d_next);	printk("d_prev      0x%08lx\n", pi->i_d.d_prev);	printk("d_parent    0x%08lx\n", pi->i_d.d_parent);	printk("d_name      %s\n", pi->i_d.d_name);}#endif/* * allocate a data block for inode and return it's absolute blocknr. * Zeroes out the block if zero set. Increments inode->i_blocks. */static intpram_new_data_block (struct inode * inode, int* blocknr, int zero){	int errval = pram_new_block(inode->i_sb, blocknr, zero);	if (!errval) {		struct pram_inode * pi = pram_get_inode(inode->i_sb,							inode->i_ino);		inode->i_blocks++;		pram_lock_inode(inode->i_sb, pi);		pi->i_blocks = inode->i_blocks;		pram_unlock_inode(inode->i_sb, pi);	}	return errval;}/* * find the offset to the block represented by the given inode's file * relative block number. */pram_off_t pram_find_data_block(struct inode * inode, int file_blocknr){	struct super_block * sb = inode->i_sb;	struct pram_inode * pi;	pram_off_t * row; /* ptr to row block */	pram_off_t * col; /* ptr to column blocks */	pram_off_t bp = 0;	int i_row, i_col;	int N = sb->s_blocksize >> 2; // num block ptrs per block	int Nbits = sb->s_blocksize_bits - 2;	pi = pram_get_inode(sb, inode->i_ino);	i_row = file_blocknr >> Nbits;	i_col = file_blocknr & (N-1);	row = pram_get_block(sb, pi->i_type.reg.row_block);	if (row) {		col = pram_get_block(sb, row[i_row]);		if (col)			bp = col[i_col];	}	return bp;}/* * Free data blocks from inode starting at first_trunc_block. */static voidpram_truncate_blocks(struct inode * inode, int first_trunc_block){	struct super_block * sb = inode->i_sb;	struct pram_inode * pi = pram_get_inode(sb, inode->i_ino);	int N = sb->s_blocksize >> 2; // num block ptrs per block	int Nbits = sb->s_blocksize_bits - 2;	int first_row_index, last_row_index;	int i, j, first_blocknr, last_blocknr, blocknr;	pram_off_t * row; /* ptr to row block */	pram_off_t * col; /* ptr to column blocks */	if (first_trunc_block >= inode->i_blocks ||	    !inode->i_blocks || !pi->i_type.reg.row_block) {		return;	}	first_blocknr = first_trunc_block;	last_blocknr = inode->i_blocks - 1;	first_row_index = first_blocknr >> Nbits;	last_row_index  = last_blocknr >> Nbits;	row = pram_get_block(sb, pi->i_type.reg.row_block);	for (i=first_row_index; i <= last_row_index; i++) {		int first_col_index = (i == first_row_index) ?			first_blocknr & (N-1) : 0;		int last_col_index = (i == last_row_index) ?			last_blocknr & (N-1) : N-1;		col = pram_get_block(sb, row[i]);		for (j=first_col_index; j <= last_col_index; j++) {			blocknr = pram_get_blocknr(sb, col[j]);			pram_free_block(sb, blocknr);			pram_lock_block(sb, col);			col[j] = 0;			pram_unlock_block(sb, col);		}		if (first_col_index == 0) {			blocknr = pram_get_blocknr(sb, row[i]);			pram_free_block(sb, blocknr);			pram_lock_block(sb, row);			row[i] = 0;			pram_unlock_block(sb, row);		}	}	inode->i_blocks -= (last_blocknr - first_blocknr + 1);	if (first_blocknr == 0) {		blocknr = pram_get_blocknr(sb, pi->i_type.reg.row_block);		pram_free_block(sb, blocknr);		pram_lock_inode(sb, pi);		pi->i_type.reg.row_block = 0;		pram_unlock_inode(sb, pi);	}	pram_lock_inode(sb, pi);	pi->i_blocks = inode->i_blocks;	pram_unlock_inode(sb, pi);}/* * Allocate num data blocks for inode, starting at given file-relative * block number. Any unallocated file blocks before file_blocknr * are allocated. All blocks except the last are zeroed out. */int pram_alloc_blocks(struct inode * inode, int file_blocknr, int num){	struct super_block * sb = inode->i_sb;	struct pram_inode * pi = pram_get_inode(sb, inode->i_ino);	int N = sb->s_blocksize >> 2; // num block ptrs per block	int Nbits = sb->s_blocksize_bits - 2;	int first_file_blocknr;	int last_file_blocknr;	int first_row_index, last_row_index;	int i, j, blocknr, errval;	pram_off_t * row;	pram_off_t * col;	if (!pi->i_type.reg.row_block) {		/* alloc the 2nd order array block */		errval = pram_new_block(sb, &blocknr, 1);		if (errval) {			pram_err("failed to alloc 2nd order array block\n");			goto fail;		}		pram_lock_inode(sb, pi);		pi->i_type.reg.row_block = pram_get_block_off(sb, blocknr);		pram_unlock_inode(sb, pi);	}	row = pram_get_block(sb, pi->i_type.reg.row_block);	first_file_blocknr = (file_blocknr > inode->i_blocks) ?		inode->i_blocks : file_blocknr;	last_file_blocknr = file_blocknr + num - 1;	first_row_index = first_file_blocknr >> Nbits;	last_row_index  = last_file_blocknr >> Nbits;	if (last_row_index >= N || first_row_index >= N) {		errval = -ENOSPC;		goto fail;	}	for (i=first_row_index; i<=last_row_index; i++) {		int first_col_index, last_col_index;		/*		 * we are starting a new row, so make sure		 * there is a block allocated for the row.		 */		if (!row[i]) {			/* allocate the row block */			errval = pram_new_block(sb, &blocknr, 1);			if (errval) {				pram_err("failed to alloc row block\n");				goto fail;			}			pram_lock_block(sb, row);			row[i] = pram_get_block_off(sb, blocknr);			pram_unlock_block(sb, row);		}		col = pram_get_block(sb, row[i]);		first_col_index = (i == first_row_index) ?			first_file_blocknr & (N-1) : 0;		last_col_index = (i == last_row_index) ?			last_file_blocknr & (N-1) : N-1;		for (j=first_col_index; j<=last_col_index; j++) {			int last_block =				(i==last_row_index) && (j==last_col_index);			if (!col[j]) {				errval = pram_new_data_block(inode,							      &blocknr,							      !last_block);				if (errval) {					pram_err("failed to alloc "						  "data block\n");					goto fail;				}				pram_lock_block(sb, col);				col[j] = pram_get_block_off(sb, blocknr);				pram_unlock_block(sb, col);			}		}	}	errval = 0; fail:	return errval;}static intpram_fill_inode(struct inode * inode, struct pram_inode * pi){	int ret = -EIO;	if (pram_calc_checksum((u32*)pi, PRAM_INODE_SIZE>>2)) {		pram_err("checksum error in inode %08x\n",			  (u32)inode->i_ino);		goto bad_inode;	}	inode->i_mode = pi->i_mode;	inode->i_uid = pi->i_uid;	inode->i_gid = pi->i_gid;	inode->i_nlink = pi->i_links_count;	inode->i_size = pi->i_size;	inode->i_atime.tv_sec = pi->i_atime;	inode->i_ctime.tv_sec = pi->i_ctime;	inode->i_mtime.tv_sec = pi->i_mtime;	inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec =		inode->i_ctime.tv_nsec = 0;	/* check if the inode is active. */	if (inode->i_nlink == 0 && (inode->i_mode == 0 || pi->i_dtime)) {		/* this inode is deleted */		ret = -EINVAL;		goto bad_inode;	}	inode->i_blocks = pi->i_blocks;	inode->i_ino = pram_get_inodenr(inode->i_sb, pi);	inode->i_mapping->a_ops = &pram_aops;	inode->i_mapping->backing_dev_info = &pram_backing_dev_info;	insert_inode_hash(inode);	switch (inode->i_mode & S_IFMT) {	case S_IFREG:		inode->i_op = &pram_file_inode_operations;		inode->i_fop = &pram_file_operations;		break;	case S_IFDIR:		inode->i_op = &pram_dir_inode_operations;		inode->i_fop = &pram_dir_operations;		break;	case S_IFLNK:		inode->i_op = &pram_symlink_inode_operations;		break;	default:		inode->i_size = 0;		init_special_inode(inode, inode->i_mode,				   pi->i_type.dev.rdev);		break;	}	return 0; bad_inode:	make_bad_inode(inode);	return ret;}static int pram_update_inode(struct inode * inode){	struct pram_inode * pi;	int retval = 0;	pi = pram_get_inode(inode->i_sb, inode->i_ino);	if ((inode->i_sb->s_flags & MS_NOTIME) &&	    pi->i_mode == inode->i_mode &&	    pi->i_uid == inode->i_uid &&	    pi->i_gid == inode->i_gid &&	    pi->i_links_count == inode->i_nlink &&	    pi->i_size == inode->i_size &&	    pi->i_blocks == inode->i_blocks &&	    ((!S_ISCHR(inode->i_mode) && !S_ISBLK(inode->i_mode)) ||	     (pi->i_type.dev.rdev == inode->i_rdev)))		    return retval;	pram_lock_inode(inode->i_sb, pi);	pi->i_mode = inode->i_mode;	pi->i_uid = inode->i_uid;	pi->i_gid = inode->i_gid;	pi->i_links_count = inode->i_nlink;	pi->i_size = inode->i_size;	pi->i_blocks = inode->i_blocks;	pi->i_atime = inode->i_atime.tv_sec;	pi->i_ctime = inode->i_ctime.tv_sec;	pi->i_mtime = inode->i_mtime.tv_sec;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -