示例#1
0
文件: super.c 项目: pipul/simplefs
static void simplefs_delete_inode(struct inode *inode) {
	printk(KERN_INFO "simplefs_delete_inode: %ld\n", inode->i_ino);
	truncate_inode_pages(&inode->i_data, 0);
	inode->i_size = 0;
	simplefs_truncate(inode);
	simplefs_free_inode(inode);
}
示例#2
0
/*
 * Handle all mappings that got truncated by a "truncate()"
 * system call.
 *
 * NOTE! We have to be ready to update the memory sharing
 * between the file and the memory map for a potential last
 * incomplete page.  Ugly, but necessary.
 */
void vmtruncate(struct inode * inode, unsigned long offset)
{
	struct vm_area_struct * mpnt;

	truncate_inode_pages(inode, offset);
	if (!inode->i_mmap)
		return;
	mpnt = inode->i_mmap;
	do {
		unsigned long start = mpnt->vm_start;
		unsigned long len = mpnt->vm_end - start;
		unsigned long diff;

		/* mapping wholly truncated? */
		if (mpnt->vm_offset >= offset) {
			zap_page_range(mpnt->vm_mm, start, len);
			continue;
		}
		/* mapping wholly unaffected? */
		diff = offset - mpnt->vm_offset;
		if (diff >= len)
			continue;
		/* Ok, partially affected.. */
		start += diff;
		len = (len - diff) & PAGE_MASK;
		if (start & ~PAGE_MASK) {
			partial_clear(mpnt, start);
			start = (start + ~PAGE_MASK) & PAGE_MASK;
		}
		zap_page_range(mpnt->vm_mm, start, len);
	} while ((mpnt = mpnt->vm_next_share) != inode->i_mmap);
}
示例#3
0
static void
cifs_evict_inode(struct inode *inode)
{
	truncate_inode_pages(&inode->i_data, 0);
	end_writeback(inode);
	cifs_fscache_release_inode_cookie(inode);
}
示例#4
0
void
mvfs_evict_inode(struct inode *inode_p)
{
    mvfs_clear_inode(inode_p);
    truncate_inode_pages(&inode_p->i_data, 0);
    end_writeback(inode_p);
}
示例#5
0
文件: inode.c 项目: cilynx/dd-wrt
static void minix_delete_inode(struct inode *inode)
{
	truncate_inode_pages(&inode->i_data, 0);
	inode->i_size = 0;
	minix_truncate(inode);
	minix_free_inode(inode);
}
示例#6
0
/**
 * vxfs_evict_inode - remove inode from main memory
 * @ip:		inode to discard.
 *
 * Description:
 *  vxfs_evict_inode() is called on the final iput and frees the private
 *  inode area.
 */
void
vxfs_evict_inode(struct inode *ip)
{
	truncate_inode_pages(&ip->i_data, 0);
	end_writeback(ip);
	call_rcu(&ip->i_rcu, vxfs_i_callback);
}
示例#7
0
文件: super.c 项目: phuang/test
static void phuang_evict_inode(struct inode *inode)
{
    printk(KERN_DEBUG "%s", __func__);

    truncate_inode_pages(&inode->i_data, 0);
    end_writeback(inode);
}
示例#8
0
void
xfs_relse_buftarg(
	xfs_buftarg_t		*btp)
{
	invalidate_bdev(btp->pbr_bdev, 1);
	truncate_inode_pages(btp->pbr_mapping, 0LL);
}
示例#9
0
void
affs_evict_inode(struct inode *inode)
{
    unsigned long cache_page;
    pr_debug("AFFS: evict_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
    truncate_inode_pages(&inode->i_data, 0);

    if (!inode->i_nlink) {
        inode->i_size = 0;
        affs_truncate(inode);
    }

    invalidate_inode_buffers(inode);
    end_writeback(inode);
    affs_free_prealloc(inode);
    cache_page = (unsigned long)AFFS_I(inode)->i_lc;
    if (cache_page) {
        pr_debug("AFFS: freeing ext cache\n");
        AFFS_I(inode)->i_lc = NULL;
        AFFS_I(inode)->i_ac = NULL;
        free_page(cache_page);
    }
    affs_brelse(AFFS_I(inode)->i_ext_bh);
    AFFS_I(inode)->i_ext_last = ~1;
    AFFS_I(inode)->i_ext_bh = NULL;

    if (!inode->i_nlink)
        affs_free_block(inode->i_sb, inode->i_ino);
}
示例#10
0
void fuse_truncate(struct address_space *mapping, loff_t offset)
{
	/* See vmtruncate() */
	unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
	truncate_inode_pages(mapping, offset);
	unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
}
示例#11
0
/*
 * Handle all mappings that got truncated by a "truncate()"
 * system call.
 *
 * NOTE! We have to be ready to update the memory sharing
 * between the file and the memory map for a potential last
 * incomplete page.  Ugly, but necessary.
 */
int vmtruncate(struct inode * inode, loff_t offset)
{
	struct address_space *mapping = inode->i_mapping;
	unsigned long limit;

	if (inode->i_size < offset)
		goto do_expand;
	inode->i_size = offset;

	truncate_inode_pages(mapping, offset);
	goto out_truncate;

do_expand:
	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
	if (limit != RLIM_INFINITY && offset > limit)
		goto out_sig;
	if (offset > inode->i_sb->s_maxbytes)
		goto out;
	inode->i_size = offset;

out_truncate:
	if (inode->i_op && inode->i_op->truncate) {
		lock_kernel();
		inode->i_op->truncate(inode);
		unlock_kernel();
	}
	return 0;
out_sig:
	send_sig(SIGXFSZ, current, 0);
out:
	return -EFBIG;
}
示例#12
0
/*
 * Called at the last iput() if i_nlink is zero
 */
void f2fs_evict_inode(struct inode *inode)
{
	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);

	trace_f2fs_evict_inode(inode);
	truncate_inode_pages(&inode->i_data, 0);

	if (inode->i_ino == F2FS_NODE_INO(sbi) ||
			inode->i_ino == F2FS_META_INO(sbi))
		goto no_delete;

	f2fs_bug_on(get_dirty_dents(inode));
	remove_dirty_dir_inode(inode);

	if (inode->i_nlink || is_bad_inode(inode))
		goto no_delete;

	set_inode_flag(F2FS_I(inode), FI_NO_ALLOC);
	i_size_write(inode, 0);

	if (F2FS_HAS_BLOCKS(inode))
		f2fs_truncate(inode);

	f2fs_lock_op(sbi);
	remove_inode_page(inode);
	stat_dec_inline_inode(inode);
	f2fs_unlock_op(sbi);

no_delete:
	end_writeback(inode);
}
示例#13
0
void hpfs_delete_inode(struct inode *inode)
{
	truncate_inode_pages(&inode->i_data, 0);
	lock_kernel();
	hpfs_remove_fnode(inode->i_sb, inode->i_ino);
	unlock_kernel();
	clear_inode(inode);
}
示例#14
0
/*
 * The sysfs_dirent serves as both an inode and a directory entry for sysfs.
 * To prevent the sysfs inode numbers from being freed prematurely we take a
 * reference to sysfs_dirent from the sysfs inode.  A
 * super_operations.delete_inode() implementation is needed to drop that
 * reference upon inode destruction.
 */
void sysfs_delete_inode(struct inode *inode)
{
	struct sysfs_dirent *sd  = inode->i_private;

	truncate_inode_pages(&inode->i_data, 0);
	clear_inode(inode);
	sysfs_put(sd);
}
示例#15
0
/*
 * The kernfs_node serves as both an inode and a directory entry for
 * kernfs.  To prevent the kernfs inode numbers from being freed
 * prematurely we take a reference to kernfs_node from the kernfs inode.  A
 * super_operations.evict_inode() implementation is needed to drop that
 * reference upon inode destruction.
 */
void kernfs_evict_inode(struct inode *inode)
{
	struct kernfs_node *kn = inode->i_private;

	truncate_inode_pages(&inode->i_data, 0);
	clear_inode(inode);
	kernfs_put(kn);
}
示例#16
0
文件: super.c 项目: XavatarX/code
/**
 * tierfs_evict_inode
 * @inode - The tierfs inode
 *
 * Called by iput() when the inode reference count reached zero
 * and the inode is not hashed anywhere.  Used to clear anything
 * that needs to be, before the inode is completely destroyed and put
 * on the inode free list. We use this to drop out reference to the
 * lower inode.
 */
static void tierfs_evict_inode(struct inode *inode)
{
	TRACE_ENTRY();
	truncate_inode_pages(&inode->i_data, 0);
	clear_inode(inode);
	iput(tierfs_inode_to_lower(inode));
	TRACE_EXIT();
}
示例#17
0
/*
 * The sysfs_dirent serves as both an inode and a directory entry for sysfs.
 * To prevent the sysfs inode numbers from being freed prematurely we take a
 * reference to sysfs_dirent from the sysfs inode.  A
 * super_operations.evict_inode() implementation is needed to drop that
 * reference upon inode destruction.
 */
void sysfs_evict_inode(struct inode *inode)
{
	struct sysfs_dirent *sd  = inode->i_private;

	truncate_inode_pages(&inode->i_data, 0);
	end_writeback(inode);
	sysfs_put(sd);
}
示例#18
0
文件: inode.c 项目: Tigrouzen/k1099
static void bfs_delete_inode(struct inode *inode)
{
    unsigned long ino = inode->i_ino;
    struct bfs_inode *di;
    struct buffer_head *bh;
    int block, off;
    struct super_block *s = inode->i_sb;
    struct bfs_sb_info *info = BFS_SB(s);
    struct bfs_inode_info *bi = BFS_I(inode);

    dprintf("ino=%08lx\n", ino);

    truncate_inode_pages(&inode->i_data, 0);

    if ((ino < BFS_ROOT_INO) || (ino > info->si_lasti)) {
        printf("invalid ino=%08lx\n", ino);
        return;
    }

    inode->i_size = 0;
    inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
    lock_kernel();
    mark_inode_dirty(inode);

    block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
    bh = sb_bread(s, block);
    if (!bh) {
        printf("Unable to read inode %s:%08lx\n",
               inode->i_sb->s_id, ino);
        unlock_kernel();
        return;
    }
    off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
    di = (struct bfs_inode *)bh->b_data + off;
    memset((void *)di, 0, sizeof(struct bfs_inode));
    mark_buffer_dirty(bh);
    brelse(bh);

    if (bi->i_dsk_ino) {
        if (bi->i_sblock)
            info->si_freeb += bi->i_eblock + 1 - bi->i_sblock;
        info->si_freei++;
        clear_bit(ino, info->si_imap);
        dump_imap("delete_inode", s);
    }

    /*
     * If this was the last file, make the previous block
     * "last block of the last file" even if there is no
     * real file there, saves us 1 gap.
     */
    if (info->si_lf_eblk == bi->i_eblock) {
        info->si_lf_eblk = bi->i_sblock - 1;
        mark_buffer_dirty(info->si_sbh);
    }
    unlock_kernel();
    clear_inode(inode);
}
示例#19
0
/*
 * Called at the last iput() if i_nlink is zero
 */
void f2fs_evict_inode(struct inode *inode)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	struct f2fs_inode_info *fi = F2FS_I(inode);
	nid_t xnid = fi->i_xattr_nid;

	/* some remained atomic pages should discarded */
	if (f2fs_is_atomic_file(inode))
		commit_inmem_pages(inode, true);

	trace_f2fs_evict_inode(inode);
	truncate_inode_pages(&inode->i_data, 0);

	if (inode->i_ino == F2FS_NODE_INO(sbi) ||
			inode->i_ino == F2FS_META_INO(sbi))
		goto out_clear;

	f2fs_bug_on(sbi, get_dirty_pages(inode));
	remove_dirty_dir_inode(inode);

	f2fs_destroy_extent_tree(inode);

	if (inode->i_nlink || is_bad_inode(inode))
		goto no_delete;

	set_inode_flag(fi, FI_NO_ALLOC);
	i_size_write(inode, 0);

	if (F2FS_HAS_BLOCKS(inode))
		f2fs_truncate(inode, true);

	f2fs_lock_op(sbi);
	remove_inode_page(inode);
	f2fs_unlock_op(sbi);

no_delete:
	stat_dec_inline_xattr(inode);
	stat_dec_inline_dir(inode);
	stat_dec_inline_inode(inode);

	invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino);
	if (xnid)
		invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid);
	if (is_inode_flag_set(fi, FI_APPEND_WRITE))
		add_dirty_inode(sbi, inode->i_ino, APPEND_INO);
	if (is_inode_flag_set(fi, FI_UPDATE_WRITE))
		add_dirty_inode(sbi, inode->i_ino, UPDATE_INO);
	if (is_inode_flag_set(fi, FI_FREE_NID)) {
		alloc_nid_failed(sbi, inode->i_ino);
		clear_inode_flag(fi, FI_FREE_NID);
	}
out_clear:
#ifdef CONFIG_F2FS_FS_ENCRYPTION
	if (fi->i_crypt_info)
		f2fs_free_encryption_info(inode, fi->i_crypt_info);
#endif
	end_writeback(inode);
}
示例#20
0
static void plgfs_evict_inode(struct inode *i)
{
	if (i->i_data.nrpages)
		truncate_inode_pages(&i->i_data, 0);

	clear_inode(i);

	iput(plgfs_ih(i));
}
示例#21
0
/* Support function for ocfs2_delete_inode. Will help us keep the
 * inode data in a consistent state for clear_inode. Always truncates
 * pages, optionally sync's them first. */
static void ocfs2_cleanup_delete_inode(struct inode *inode,
				       int sync_data)
{
	trace_ocfs2_cleanup_delete_inode(
		(unsigned long long)OCFS2_I(inode)->ip_blkno, sync_data);
	if (sync_data)
		filemap_write_and_wait(inode->i_mapping);
	truncate_inode_pages(&inode->i_data, 0);
}
void nilfs_btnode_cache_clear(struct address_space *btnc)
{
#if NEED_INVALIDATE_INODE_PAGES
	invalidate_inode_pages(btnc);
#else
	invalidate_mapping_pages(btnc, 0, -1);
#endif
	truncate_inode_pages(btnc, 0);
}
示例#23
0
static void sysv_delete_inode(struct inode *inode)
{
	truncate_inode_pages(&inode->i_data, 0);
	inode->i_size = 0;
	sysv_truncate(inode);
	lock_kernel();
	sysv_free_inode(inode);
	unlock_kernel();
}
示例#24
0
/* Support function for ocfs2_delete_inode. Will help us keep the
 * inode data in a consistent state for clear_inode. Always truncates
 * pages, optionally sync's them first. */
static void ocfs2_cleanup_delete_inode(struct inode *inode,
				       int sync_data)
{
	mlog(0, "Cleanup inode %llu, sync = %d\n",
	     (unsigned long long)OCFS2_I(inode)->ip_blkno, sync_data);
	if (sync_data)
		write_inode_now(inode, 1);
	truncate_inode_pages(&inode->i_data, 0);
}
示例#25
0
static int cifs_file_clone_range(unsigned int xid, struct file *src_file,
			  struct file *dst_file)
{
	struct inode *src_inode = file_inode(src_file);
	struct inode *target_inode = file_inode(dst_file);
	struct cifsFileInfo *smb_file_src;
	struct cifsFileInfo *smb_file_target;
	struct cifs_tcon *src_tcon;
	struct cifs_tcon *target_tcon;
	int rc;

	cifs_dbg(FYI, "ioctl clone range\n");

	if (!src_file->private_data || !dst_file->private_data) {
		rc = -EBADF;
		cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
		goto out;
	}

	rc = -EXDEV;
	smb_file_target = dst_file->private_data;
	smb_file_src = src_file->private_data;
	src_tcon = tlink_tcon(smb_file_src->tlink);
	target_tcon = tlink_tcon(smb_file_target->tlink);

	if (src_tcon->ses != target_tcon->ses) {
		cifs_dbg(VFS, "source and target of copy not on same server\n");
		goto out;
	}

	/*
	 * Note: cifs case is easier than btrfs since server responsible for
	 * checks for proper open modes and file type and if it wants
	 * server could even support copy of range where source = target
	 */
	lock_two_nondirectories(target_inode, src_inode);

	cifs_dbg(FYI, "about to flush pages\n");
	/* should we flush first and last page first */
	truncate_inode_pages(&target_inode->i_data, 0);

	if (target_tcon->ses->server->ops->clone_range)
		rc = target_tcon->ses->server->ops->clone_range(xid,
			smb_file_src, smb_file_target, 0, src_inode->i_size, 0);
	else
		rc = -EOPNOTSUPP;

	/* force revalidate of size and timestamps of target file now
	   that target is updated on the server */
	CIFS_I(target_inode)->time = 0;
	/* although unlocking in the reverse order from locking is not
	   strictly necessary here it is a little cleaner to be consistent */
	unlock_two_nondirectories(src_inode, target_inode);
out:
	return rc;
}
示例#26
0
static void dazukofs_evict_inode(struct inode *inode)
{
	truncate_inode_pages(&inode->i_data, 0);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
	clear_inode(inode);
#else
	end_writeback(inode);
#endif
	iput(get_lower_inode(inode));
}
示例#27
0
///////////////////////////////////////////////////////////
// DropPages
//
//
///////////////////////////////////////////////////////////
void
DropPages(
    IN struct address_space* m
    )
{
  filemap_fdatawrite( m );
  unmap_mapping_range( m, 0, 0, 1 );
  truncate_inode_pages( m, 0 );
  unmap_mapping_range( m, 0, 0, 1 );
}
示例#28
0
void ocfs2_evict_inode(struct inode *inode)
{
	if (!inode->i_nlink ||
	    (OCFS2_I(inode)->ip_flags & OCFS2_INODE_MAYBE_ORPHANED)) {
		ocfs2_delete_inode(inode);
	} else {
		truncate_inode_pages(&inode->i_data, 0);
	}
	ocfs2_clear_inode(inode);
}
示例#29
0
void hpfs_evict_inode(struct inode *inode)
{
	truncate_inode_pages(&inode->i_data, 0);
	end_writeback(inode);
	if (!inode->i_nlink) {
		hpfs_lock(inode->i_sb);
		hpfs_remove_fnode(inode->i_sb, inode->i_ino);
		hpfs_unlock(inode->i_sb);
	}
}
示例#30
0
static void qnx4_delete_inode(struct inode *inode)
{
	QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino));
	truncate_inode_pages(&inode->i_data, 0);
	inode->i_size = 0;
	qnx4_truncate(inode);
	lock_kernel();
	qnx4_free_inode(inode);
	unlock_kernel();
}