一个简单的linux文件系统

  • C9_229195
    了解作者
  • 7.9KB
    文件大小
  • gz
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-05-25 12:08
    上传日期
编译后可以作为模块直接加入系统,这个是UNIX Filesystems Evolution, Design, and Implementation这本书后附带的代码~ ps:这本书也是相当不错的
uxfs_rh8.tar.gz
  • uxfs_rh8
  • kern
  • ux_fs.h
    2.4KB
  • ux_dir.c
    12.8KB
  • ux_alloc.c
    2.1KB
  • ux_inode.c
    8.6KB
  • ux_file.c
    2.6KB
  • Makefile
    461B
  • cmds
  • fsdb.c
    4.4KB
  • mkfs.c
    4.9KB
内容介绍
/*--------------------------------------------------------------*/ /*---------------------------- ux_dir.c ------------------------*/ /*--------------------------------------------------------------*/ #include <linux/sched.h> #include <linux/string.h> #include <linux/locks.h> #include "ux_fs.h" /* * Add "name" to the directory "dip" */ int ux_diradd(struct inode *dip, const char *name, int inum) { struct ux_inode *uip = (struct ux_inode *) &dip->i_private; struct buffer_head *bh; struct super_block *sb = dip->i_sb; struct ux_dirent *dirent; __u32 blk = 0; int i, pos; for (blk=0 ; blk < uip->i_blocks ; blk++) { bh = sb_bread(sb, uip->i_addr[blk]); dirent = (struct ux_dirent *)bh->b_data; for (i=0 ; i < UX_DIRS_PER_BLOCK ; i++) { if (dirent->d_ino != 0) { dirent++; continue; } else { dirent->d_ino = inum; strcpy(dirent->d_name, name); mark_buffer_dirty(bh); mark_inode_dirty(dip); brelse(bh); return 0; } } brelse(bh); } /* * We didn't find an empty slot so need to allocate * a new block if there's space in the inode. */ if (uip->i_blocks < UX_DIRECT_BLOCKS) { pos = uip->i_blocks; blk = ux_block_alloc(sb); uip->i_blocks++; uip->i_size += UX_BSIZE; dip->i_size += UX_BSIZE; dip->i_blocks++; uip->i_addr[pos] = blk; bh = sb_bread(sb, blk); memset(bh->b_data, 0, UX_BSIZE); mark_inode_dirty(dip); dirent = (struct ux_dirent *)bh->b_data; dirent->d_ino = inum; strcpy(dirent->d_name, name); mark_buffer_dirty(bh); brelse(bh); } return 0; } /* * Remove "name" from the specified directory. */ int ux_dirdel(struct inode *dip, char *name) { struct ux_inode *uip = (struct ux_inode *) &dip->i_private; struct buffer_head *bh; struct super_block *sb = dip->i_sb; struct ux_dirent *dirent; __u32 blk = 0; int i; while (blk < uip->i_blocks) { bh = sb_bread(sb, uip->i_addr[blk]); blk++; dirent = (struct ux_dirent *)bh->b_data; for (i=0 ; i < UX_DIRS_PER_BLOCK ; i++) { if (strcmp(dirent->d_name, name) != 0) { dirent++; continue; } else { dirent->d_ino = 0; dirent->d_name[0] = '\0'; mark_buffer_dirty(bh); dip->i_nlink--; mark_inode_dirty(dip); break; } } brelse(bh); } return 0; } int ux_readdir(struct file *filp, void *dirent, filldir_t filldir) { unsigned long pos; struct inode *inode = filp->f_dentry->d_inode; struct ux_inode *uip = (struct ux_inode *) &inode->i_private; struct ux_dirent *udir; struct buffer_head *bh; __u32 blk; start_again: pos = filp->f_pos; if (pos >= inode->i_size) { return 0; } blk = (pos + 1) / UX_BSIZE; blk = uip->i_addr[blk]; bh = sb_bread(inode->i_sb, blk); udir = (struct ux_dirent *)(bh->b_data + pos % UX_BSIZE); /* * Skip over 'null' directory entries. */ if (udir->d_ino == 0) { filp->f_pos += sizeof(struct ux_dirent); brelse(bh); goto start_again; } else { filldir(dirent, udir->d_name, sizeof(udir->d_name), pos, udir->d_ino, DT_UNKNOWN); } filp->f_pos += sizeof(struct ux_dirent); brelse(bh); return 0; } struct file_operations ux_dir_operations = { read: generic_read_dir, readdir: ux_readdir, fsync: file_fsync, }; /* * When we reach this point, ux_lookup() has already been called * to create a negative entry in the dcache. Thus, we need to * allocate a new inode on disk and associate it with the dentry. */ int ux_create(struct inode *dip, struct dentry *dentry, int mode) { struct ux_inode *nip; struct super_block *sb = dip->i_sb; struct inode *inode; ino_t inum = 0; /* * See if the entry exists. If not, create a new * disk inode, and incore inode. The add the new * entry to the directory. */ inum = ux_find_entry(dip, (char *)dentry->d_name.name); if (inum) { return -EEXIST; } inode = new_inode(sb); if (!inode) { return -ENOSPC; } inum = ux_ialloc(sb); if (!inum) { iput(inode); return -ENOSPC; } ux_diradd(dip, (char *)dentry->d_name.name, inum); /* * Increment the parent link count and intialize the inode. */ dip->i_nlink++; inode->i_uid = current->fsuid; inode->i_gid = (dip->i_mode & S_ISGID) ? dip->i_gid : current->fsgid; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_blocks = inode->i_blksize = 0; inode->i_op = &ux_file_inops; inode->i_fop = &ux_file_operations; inode->i_mapping->a_ops = &ux_aops; inode->i_mode = mode; inode->i_nlink = 1; inode->i_ino = inum; insert_inode_hash(inode); nip = (struct ux_inode *)&inode->i_private; nip->i_mode = mode; nip->i_nlink = 1; nip->i_atime = nip->i_ctime = nip->i_mtime = CURRENT_TIME; nip->i_uid = inode->i_gid; nip->i_gid = inode->i_gid; nip->i_size = 0; nip->i_blocks = 0; memset(nip->i_addr, 0, UX_DIRECT_BLOCKS); d_instantiate(dentry, inode); mark_inode_dirty(dip); mark_inode_dirty(inode); return 0; } /* * Make a new directory. We already have a negative dentry * so must create the directory and instantiate it. */ int ux_mkdir(struct inode *dip, struct dentry *dentry, int mode) { struct ux_inode *nip; struct buffer_head *bh; struct super_block *sb = dip->i_sb; struct ux_dirent *dirent; struct inode *inode; ino_t inum = 0; int blk; /* * Make sure there isn't already an entry. If not, * allocate one, a new inode and new incore inode. */ inum = ux_find_entry(dip, (char *)dentry->d_name.name); if (inum) { return -EEXIST; } inode = new_inode(sb); if (!inode) { return -ENOSPC; } inum = ux_ialloc(sb); if (!inum) { iput(inode);
评论
    相关推荐