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

📄 inode.c

📁 ocfs1.2.7 源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	     OCFS2_I(inode)->ip_blkno, sync_data);#ifndef OCFS2_DELETE_INODE_WORKAROUND	if (sync_data)		write_inode_now(inode, 1);	truncate_inode_pages(&inode->i_data, 0);#endif}void ocfs2_delete_inode(struct inode *inode){	int wipe, status;	sigset_t blocked, oldset;	struct buffer_head *di_bh = NULL;	mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);	if (is_bad_inode(inode)) {		mlog(0, "Skipping delete of bad inode\n");		goto bail;	}	if (!ocfs2_inode_is_valid_to_delete(inode)) {		/* It's probably not necessary to truncate_inode_pages		 * here but we do it for safety anyway (it will most		 * likely be a no-op anyway) */		ocfs2_cleanup_delete_inode(inode, 0);		goto bail;	}	/* We want to block signals in delete_inode as the lock and	 * messaging paths may return us -ERESTARTSYS. Which would	 * cause us to exit early, resulting in inodes being orphaned	 * forever. */	sigfillset(&blocked);	status = sigprocmask(SIG_BLOCK, &blocked, &oldset);	if (status < 0) {		mlog_errno(status);		ocfs2_cleanup_delete_inode(inode, 1);		goto bail;	}	/* Lock down the inode. This gives us an up to date view of	 * it's metadata (for verification), and allows us to	 * serialize delete_inode votes. */	status = ocfs2_meta_lock(inode, NULL, &di_bh, 1);	if (status < 0) {		if (status != -ENOENT)			mlog_errno(status);		ocfs2_cleanup_delete_inode(inode, 0);		goto bail_unblock;	}	/* Query the cluster. This will be the final decision made	 * before we go ahead and wipe the inode. */	status = ocfs2_query_inode_wipe(inode, di_bh, &wipe);	if (!wipe || status < 0) {		/* Error and inode busy vote both mean we won't be		 * removing the inode, so they take almost the same		 * path. */		if (status < 0)			mlog_errno(status);		/* Someone in the cluster has voted to not wipe this		 * inode, or it was never completely orphaned. Write		 * out the pages and exit now. */		ocfs2_cleanup_delete_inode(inode, 1);		goto bail_unlock_inode;	}	ocfs2_cleanup_delete_inode(inode, 0);	status = ocfs2_wipe_inode(inode, di_bh);	if (status < 0) {		if (status != -EDEADLK)			mlog_errno(status);		goto bail_unlock_inode;	}	/* Mark the inode as successfully deleted. This is important	 * for ocfs2_clear_inode as it will check this flag and skip	 * any checkpointing work */	OCFS2_I(inode)->ip_flags |= OCFS2_INODE_DELETED;bail_unlock_inode:	ocfs2_meta_unlock(inode, 1);	brelse(di_bh);bail_unblock:	status = sigprocmask(SIG_SETMASK, &oldset, NULL);	if (status < 0)		mlog_errno(status);bail:	clear_inode(inode);	mlog_exit_void();}void ocfs2_clear_inode(struct inode *inode){	int status;	struct ocfs2_inode_info *oi = OCFS2_I(inode);	mlog_entry_void();	if (!inode)		goto bail;	mlog(0, "Clearing inode: %"MLFu64", nlink = %u\n",	     OCFS2_I(inode)->ip_blkno, inode->i_nlink);	mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL,			"Inode=%lu\n", inode->i_ino);	/* Do these before all the other work so that we don't bounce	 * the vote thread while waiting to destroy the locks. */	ocfs2_mark_lockres_freeing(&oi->ip_meta_lockres);	ocfs2_mark_lockres_freeing(&oi->ip_data_lockres);	/* We very well may get a clear_inode before all an inodes	 * metadata has hit disk. Of course, we can't drop any cluster	 * locks until the journal has finished with it. The only	 * exception here are successfully wiped inodes - their	 * metadata can now be considered to be part of the system	 * inodes from which it came. */	if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED))		ocfs2_checkpoint_inode(inode);	mlog_bug_on_msg(!list_empty(&oi->ip_io_markers),			"Clear inode of %"MLFu64", inode has io markers\n",			oi->ip_blkno);	ocfs2_extent_map_drop(inode, 0);	ocfs2_extent_map_init(inode);	status = ocfs2_drop_inode_locks(inode);	if (status < 0)		mlog_errno(status);	ocfs2_lock_res_free(&oi->ip_meta_lockres);	ocfs2_lock_res_free(&oi->ip_data_lockres);	ocfs2_metadata_cache_purge(inode);	mlog_bug_on_msg(oi->ip_metadata_cache.ci_num_cached,			"Clear inode of %"MLFu64", inode has %u cache items\n",			oi->ip_blkno, oi->ip_metadata_cache.ci_num_cached);	mlog_bug_on_msg(!(oi->ip_flags & OCFS2_INODE_CACHE_INLINE),			"Clear inode of %"MLFu64", inode has a bad flag\n",			oi->ip_blkno);	mlog_bug_on_msg(spin_is_locked(&oi->ip_lock),			"Clear inode of %"MLFu64", inode is locked\n",			oi->ip_blkno);	mlog_bug_on_msg(down_trylock(&oi->ip_io_sem),			"Clear inode of %"MLFu64", io_sem is locked\n",			oi->ip_blkno);	up(&oi->ip_io_sem);	/*	 * down_trylock() returns 0, down_write_trylock() returns 1	 * kernel 1, world 0	 */	mlog_bug_on_msg(!down_write_trylock(&oi->ip_alloc_sem),			"Clear inode of %"MLFu64", alloc_sem is locked\n",			oi->ip_blkno);	up_write(&oi->ip_alloc_sem);	mlog_bug_on_msg(oi->ip_open_count,			"Clear inode of %"MLFu64" has open count %d\n",			oi->ip_blkno, oi->ip_open_count);	mlog_bug_on_msg(!list_empty(&oi->ip_handle_list),			"Clear inode of %"MLFu64" has non empty handle list\n",			oi->ip_blkno);	mlog_bug_on_msg(oi->ip_handle,			"Clear inode of %"MLFu64" has non empty handle pointer\n",			oi->ip_blkno);	/* Clear all other flags. */	oi->ip_flags = OCFS2_INODE_CACHE_INLINE;	oi->ip_created_trans = 0;	oi->ip_last_trans = 0;	oi->ip_dir_start_lookup = 0;	oi->ip_blkno = 0ULL;bail:	mlog_exit_void();}/* Called under inode_lock, with no more references on the * struct inode, so it's safe here to check the flags field * and to manipulate i_nlink without any other locks. */void ocfs2_drop_inode(struct inode *inode){	struct ocfs2_inode_info *oi = OCFS2_I(inode);	mlog_entry_void();	mlog(0, "Drop inode %"MLFu64", nlink = %u, ip_flags = 0x%x\n",	     oi->ip_blkno, inode->i_nlink, oi->ip_flags);	/* Testing ip_orphaned_slot here wouldn't work because we may	 * not have gotten a delete_inode vote from any other nodes	 * yet. */	if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED) {		mlog(0, "Inode was orphaned on another node, clearing nlink.\n");		inode->i_nlink = 0;	}	generic_drop_inode(inode);	mlog_exit_void();}/* * TODO: this should probably be merged into ocfs2_get_block * * However, you now need to pay attention to the cont_prepare_write() * stuff in ocfs2_get_block (that is, ocfs2_get_block pretty much * expects never to extend). */struct buffer_head *ocfs2_bread(struct inode *inode,				int block, int *err, int reada){	struct buffer_head *bh = NULL;	int tmperr;	u64 p_blkno;	int readflags = OCFS2_BH_CACHED;#if 0	/* only turn this on if we know we can deal with read_block	 * returning nothing */	if (reada)		readflags |= OCFS2_BH_READAHEAD;#endif	if (((u64)block << inode->i_sb->s_blocksize_bits) >=	    i_size_read(inode)) {		BUG_ON(!reada);		return NULL;	}	down_read(&OCFS2_I(inode)->ip_alloc_sem);	tmperr = ocfs2_extent_map_get_blocks(inode, block, 1,					     &p_blkno, NULL);	up_read(&OCFS2_I(inode)->ip_alloc_sem);	if (tmperr < 0) {		mlog_errno(tmperr);		goto fail;	}	tmperr = ocfs2_read_block(OCFS2_SB(inode->i_sb), p_blkno, &bh,				  readflags, inode);	if (tmperr < 0)		goto fail;	tmperr = 0;	*err = 0;	return bh;fail:	if (bh) {		brelse(bh);		bh = NULL;	}	*err = -EIO;	return NULL;}/* * This is called from our getattr. */int ocfs2_inode_revalidate(struct dentry *dentry){	struct inode *inode = dentry->d_inode;	int status = 0;	mlog_entry("(inode = 0x%p, ino = %"MLFu64")\n", inode,		   inode ? OCFS2_I(inode)->ip_blkno : 0ULL);	if (!inode) {		mlog(0, "eep, no inode!\n");		status = -ENOENT;		goto bail;	}	spin_lock(&OCFS2_I(inode)->ip_lock);	if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {		spin_unlock(&OCFS2_I(inode)->ip_lock);		mlog(0, "inode deleted!\n");		status = -ENOENT;		goto bail;	}	spin_unlock(&OCFS2_I(inode)->ip_lock);	/* Let ocfs2_meta_lock do the work of updating our struct	 * inode for us. */	status = ocfs2_meta_lock(inode, NULL, NULL, 0);	if (status < 0) {		if (status != -ENOENT)			mlog_errno(status);		goto bail;	}	ocfs2_meta_unlock(inode, 0);bail:	mlog_exit(status);	return status;}/* * Updates a disk inode from a * struct inode. * Only takes ip_lock. */int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle,			   struct inode *inode,			   struct buffer_head *bh){	int status;	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data;	mlog_entry("(inode %"MLFu64")\n", OCFS2_I(inode)->ip_blkno);	status = ocfs2_journal_access(handle, inode, bh,				      OCFS2_JOURNAL_ACCESS_WRITE);	if (status < 0) {		mlog_errno(status);		goto leave;	}	spin_lock(&OCFS2_I(inode)->ip_lock);	fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters);	spin_unlock(&OCFS2_I(inode)->ip_lock);	fe->i_size = cpu_to_le64(i_size_read(inode));	fe->i_links_count = cpu_to_le16(inode->i_nlink);	fe->i_uid = cpu_to_le32(inode->i_uid);	fe->i_gid = cpu_to_le32(inode->i_gid);	fe->i_mode = cpu_to_le16(inode->i_mode);	fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec);	fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);	fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);	fe->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);	fe->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec);	fe->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);	status = ocfs2_journal_dirty(handle, bh);	if (status < 0)		mlog_errno(status);	status = 0;leave:	mlog_exit(status);	return status;}/* * * Updates a struct inode from a disk inode. * does no i/o, only takes ip_lock. */void ocfs2_refresh_inode(struct inode *inode,			 struct ocfs2_dinode *fe){	spin_lock(&OCFS2_I(inode)->ip_lock);	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);	i_size_write(inode, le64_to_cpu(fe->i_size));	if (S_ISREG(inode->i_mode)) {		OCFS2_I(inode)->ip_mmu_private = i_size_read(inode);	}	inode->i_nlink = le16_to_cpu(fe->i_links_count);	inode->i_uid = le32_to_cpu(fe->i_uid);	inode->i_gid = le32_to_cpu(fe->i_gid);	inode->i_mode = le16_to_cpu(fe->i_mode);#ifdef INODE_HAS_BLKSIZE	inode->i_blksize = (u32) OCFS2_SB(inode->i_sb)->s_clustersize;#endif	if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)		inode->i_blocks = 0;	else		inode->i_blocks = ocfs2_align_bytes_to_sectors(i_size_read(inode));	inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);	inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);	inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime);	inode->i_mtime.tv_nsec = le32_to_cpu(fe->i_mtime_nsec);	inode->i_ctime.tv_sec = le64_to_cpu(fe->i_ctime);	inode->i_ctime.tv_nsec = le32_to_cpu(fe->i_ctime_nsec);	spin_unlock(&OCFS2_I(inode)->ip_lock);}

⌨️ 快捷键说明

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