📄 inode.c
字号:
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) pi->i_type.dev.rdev = inode->i_rdev; pram_unlock_inode(inode->i_sb, pi); return retval;}/* * NOTE! When we get the inode, we're the only people * that have access to it, and as such there are no * race conditions we have to worry about. The inode * is not on the hash-lists, and it cannot be reached * through the filesystem because the directory entry * has been deleted earlier. */void pram_free_inode (struct inode * inode){ struct super_block * sb = inode->i_sb; struct pram_super_block * ps; struct pram_inode * pi; unsigned long inode_nr; /* * Note: we must free any quota before locking the superblock, * as writing the quota to disk may need the lock as well. */ if (!is_bad_inode(inode)) { /* Quota is already initialized in iput() */ DQUOT_FREE_INODE(inode); DQUOT_DROP(inode); } lock_super (sb); truncate_inode_pages(&inode->i_data, 0); clear_inode (inode); inode_nr = (inode->i_ino - PRAM_ROOT_INO) >> PRAM_INODE_BITS; pi = pram_get_inode(sb, inode->i_ino); pram_lock_inode(sb, pi); pi->i_dtime = get_seconds(); pi->i_type.reg.row_block = 0;#ifdef CONFIG_PRAMFS_VNVRAM memset(pi, 0, PRAM_INODE_SIZE);#endif pram_unlock_inode(sb, pi); // increment s_free_inodes_count ps = pram_get_super(sb); pram_lock_super(sb); if (inode_nr < pram_get_free_inode_hint(sb)) pram_set_free_inode_hint(sb, inode_nr); pram_inc_free_inodes_count(sb); if (pram_get_free_inodes_count(sb) == ps->s_inodes_count - 1) { // filesystem is empty pram_dbg ("fs is empty!\n"); pram_set_free_inode_hint(sb, 1); } pram_unlock_super(sb); unlock_super (sb);}struct inode *pram_fill_new_inode(struct super_block *sb, struct pram_inode * pi){ struct inode * inode = new_inode(sb); if (inode) pram_fill_inode(inode, pi); return inode;}/* * Called at each iput() */void pram_put_inode (struct inode * inode){ // nothing to do}/* * Called at the last iput() if i_nlink is zero. */void pram_delete_inode (struct inode * inode){ lock_kernel(); if (is_bad_inode(inode)) goto no_delete; pram_lock_failsafe(inode->i_sb, PRAM_FAILSAFE_OP_DELETE_INODE, inode->i_ino, 0, 0); // unlink from chain in the inode's directory pram_remove_link(inode); inode->i_size = 0; if (inode->i_blocks) pram_do_truncate(inode, 0 /* do_lock */); pram_free_inode(inode); pram_unlock_failsafe(inode->i_sb); unlock_kernel(); return; no_delete: unlock_kernel(); truncate_inode_pages(&inode->i_data, 0); clear_inode(inode); /* We must guarantee clearing of inode... */}struct inode * pram_new_inode (const struct inode * dir, int mode){ struct super_block * sb; struct pram_super_block * ps; struct inode * inode; struct pram_inode * pi = NULL; int i, errval; ino_t ino=0; sb = dir->i_sb; inode = new_inode(sb); if (!inode) return ERR_PTR(-ENOMEM); lock_super (sb); ps = pram_get_super(sb); if (pram_get_free_inodes_count(sb)) { /* find the oldest unused pram inode */ for (i=pram_get_free_inode_hint(sb); i < ps->s_inodes_count; i++) { ino = PRAM_ROOT_INO + (i << PRAM_INODE_BITS); pi = pram_get_inode(sb, ino); /* check if the inode is active. */ if (pram_inode_is_free(pi)) { /* this inode is deleted */ break; } } if (i >= ps->s_inodes_count) { pram_err("free inodes count != 0 but none free!?\n"); errval = -ENOSPC; goto fail; } pram_dbg ("allocating inode %lu\n", ino); pram_lock_super(sb); pram_dec_free_inodes_count(sb); pram_set_free_inode_hint(sb, (i < ps->s_inodes_count-1) ? i+1 : 0); pram_unlock_super(sb); } else { pram_err("no space left to create new inode!\n"); errval = -ENOSPC; goto fail; } // chosen inode is in ino inode->i_ino = ino; inode->i_uid = current->fsuid; if (dir->i_mode & S_ISGID) { inode->i_gid = dir->i_gid; if (S_ISDIR(mode)) mode |= S_ISGID; } else inode->i_gid = current->fsgid; inode->i_mode = mode; inode->i_blocks = inode->i_size = 0; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; pram_lock_inode(sb, pi); pi->i_d.d_next = 0; pi->i_d.d_prev = 0; pram_unlock_inode(sb, pi); insert_inode_hash(inode); pram_write_inode_sync(inode); unlock_super (sb); if(DQUOT_ALLOC_INODE(inode)) { DQUOT_DROP(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; iput(inode); return ERR_PTR(-EDQUOT); } return inode;fail: unlock_super(sb); make_bad_inode(inode); iput(inode); return ERR_PTR(errval);}void pram_read_inode (struct inode * inode){ struct pram_inode * pi; pi = pram_get_inode(inode->i_sb, inode->i_ino); pram_fill_inode(inode, pi);}int pram_do_truncate (struct inode * inode, int do_lock){ int blocksize, blocksize_bits; int blocknr; if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) return -EINVAL; if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return -EINVAL; blocksize_bits = inode->i_sb->s_blocksize_bits; blocksize = 1 << blocksize_bits; blocknr = (inode->i_size + blocksize-1) >> blocksize_bits; if (do_lock) { lock_kernel(); pram_lock_failsafe(inode->i_sb, PRAM_FAILSAFE_OP_TRUNCATE, inode->i_ino, inode->i_size, 0); } pram_truncate_blocks(inode, blocknr); inode->i_mtime = inode->i_ctime = CURRENT_TIME; pram_update_inode(inode); if (do_lock) { pram_unlock_failsafe(inode->i_sb); unlock_kernel(); } return 0;}void pram_truncate (struct inode * inode){ pram_do_truncate(inode, 1 /* do_lock */);}int pram_write_inode_sync (struct inode * inode){ //lock_kernel(); //FIXME pram_update_inode(inode); //unlock_kernel(); //FIXME return 0;}int pram_write_inode (struct inode * inode, int wait){ lock_kernel(); pram_lock_failsafe(inode->i_sb, PRAM_FAILSAFE_OP_WRITE_INODE, inode->i_ino, 0, 0); pram_update_inode(inode); pram_unlock_failsafe(inode->i_sb); unlock_kernel(); return 0;}/* * dirty_inode() is called from __mark_inode_dirty() */void pram_dirty_inode(struct inode * inode){ lock_kernel(); pram_lock_failsafe(inode->i_sb, PRAM_FAILSAFE_OP_DIRTY_INODE, inode->i_ino, 0, 0); pram_write_inode_sync(inode); pram_unlock_failsafe(inode->i_sb); unlock_kernel();}static int pram_get_and_update_block(struct inode *inode, sector_t iblock, struct buffer_head *bh, int create){ struct super_block * sb = inode->i_sb; unsigned int blocksize = 1 << inode->i_blkbits; int err = -EIO; pram_off_t block; void* bp; lock_kernel(); block = pram_find_data_block(inode, iblock); if (!block) { if (!create) goto out; pram_lock_failsafe(sb, PRAM_FAILSAFE_OP_ALLOC_BLOCKS, inode->i_ino, iblock, 1); err = pram_alloc_blocks(inode, iblock, 1); pram_unlock_failsafe(sb); if (err) goto out; block = pram_find_data_block(inode, iblock); if (!block) { err = -EIO; goto out; } set_buffer_new(bh); } bh->b_blocknr = block; set_buffer_mapped(bh); /* now update the buffer synchronously */ bp = pram_get_block(sb, block); if (buffer_new(bh)) { /* no need to backup. FIXME: should be zeroed. */ pram_lock_block(sb, bp); memset(bp, 0, blocksize); pram_unlock_block(sb, bp); memset(bh->b_data, 0, blocksize); } else { memcpy(bh->b_data, bp, blocksize); } set_buffer_uptodate(bh); err = 0; out: unlock_kernel(); return err;}#if 0static int pram_writepage(struct page *page){ return 0;}static int pram_bmap(struct address_space *mapping, long block){ return 0;}#endifstatic int pram_readpage(struct file *file, struct page *page){ return block_read_full_page(page, pram_get_and_update_block);}const struct address_space_operations pram_aops = { .readpage = pram_readpage,// .writepage = pram_writepage,// .bmap = pram_bmap, .direct_IO = pram_direct_IO,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -