Ejemplo n.º 1
0
/*
 * If we're not journaling and this is a just-created file, we have to
 * sync our parent directory (if it was freshly created) since
 * otherwise it will only be written by writeback, leaving a huge
 * window during which a crash may lose the file.  This may apply for
 * the parent directory's parent as well, and so on recursively, if
 * they are also freshly created.
 */
static int ext4_sync_parent(struct inode *inode)
{
	struct dentry *dentry = NULL;
	struct inode *next;
	int ret = 0;

	if (!ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY))
		return 0;
	inode = igrab(inode);
	while (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) {
		ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY);
		dentry = d_find_any_alias(inode);
		if (!dentry)
			break;
		next = igrab(dentry->d_parent->d_inode);
		dput(dentry);
		if (!next)
			break;
		iput(inode);
		inode = next;
		ret = sync_mapping_buffers(inode->i_mapping);
		if (ret)
			break;
		ret = sync_inode_metadata(inode, 1);
		if (ret)
			break;
	}
	iput(inode);
	return ret;
}
static int fat_cont_expand(struct inode *inode, loff_t size)
{
	struct address_space *mapping = inode->i_mapping;
	loff_t start = inode->i_size, count = size - inode->i_size;
	int err;

	err = generic_cont_expand_simple(inode, size);
	if (err)
		goto out;

	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
	mark_inode_dirty(inode);
	if (IS_SYNC(inode)) {
		int err2;

		/*
		 * Opencode syncing since we don't have a file open to use
		 * standard fsync path.
		 */
		err = filemap_fdatawrite_range(mapping, start,
					       start + count - 1);
		err2 = sync_mapping_buffers(mapping);
		if (!err)
			err = err2;
		err2 = write_inode_now(inode, 1);
		if (!err)
			err = err2;
		if (!err) {
			err =  filemap_fdatawait_range(mapping, start,
						       start + count - 1);
		}
	}
out:
	return err;
}
Ejemplo n.º 3
0
/*
 * If we're not journaling and this is a just-created file, we have to
 * sync our parent directory (if it was freshly created) since
 * otherwise it will only be written by writeback, leaving a huge
 * window during which a crash may lose the file.  This may apply for
 * the parent directory's parent as well, and so on recursively, if
 * they are also freshly created.
 */
static int ext4_sync_parent(struct inode *inode)
{
	struct writeback_control wbc;
	struct dentry *dentry = NULL;
	struct inode *next;
	int ret = 0;

	if (!ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY))
		return 0;
	inode = igrab(inode);
	while (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) {
		ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY);
		dentry = d_find_any_alias(inode);
		if (!dentry)
			break;
		next = igrab(dentry->d_parent->d_inode);
		dput(dentry);
		if (!next)
			break;
		iput(inode);
		inode = next;
		ret = sync_mapping_buffers(inode->i_mapping);
		if (ret)
			break;
		memset(&wbc, 0, sizeof(wbc));
		wbc.sync_mode = WB_SYNC_ALL;
		wbc.nr_to_write = 0;         /* only write out the inode */
		ret = sync_inode(inode, &wbc);
		if (ret)
			break;
	}
	iput(inode);
	return ret;
}
Ejemplo n.º 4
0
int fat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
{
	struct inode *inode = filp->f_mapping->host;
	int res, err;

	res = generic_file_fsync(filp, start, end, datasync);
	err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping);

	return res ? res : err;
}
Ejemplo n.º 5
0
/*
 * If we're not journaling and this is a just-created file, we have to
 * sync our parent directory (if it was freshly created) since
 * otherwise it will only be written by writeback, leaving a huge
 * window during which a crash may lose the file.  This may apply for
 * the parent directory's parent as well, and so on recursively, if
 * they are also freshly created.
 */
static void ext4_sync_parent(struct inode *inode)
{
	struct dentry *dentry = NULL;

	while (inode && ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) {
		ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY);
		dentry = list_entry(inode->i_dentry.next,
				    struct dentry, d_alias);
		if (!dentry || !dentry->d_parent || !dentry->d_parent->d_inode)
			break;
		inode = dentry->d_parent->d_inode;
		sync_mapping_buffers(inode->i_mapping);
	}
}
Ejemplo n.º 6
0
int sysv_sync_file(struct file * file, struct dentry *dentry, int datasync)
{
    struct inode *inode = dentry->d_inode;
    int err;

    err = sync_mapping_buffers(inode->i_mapping);
    if (!(inode->i_state & I_DIRTY))
        return err;
    if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
        return err;

    err |= sysv_sync_inode(inode);
    return err ? -EIO : 0;
}
Ejemplo n.º 7
0
/**
 * __sync_file - generic_file_fsync without the locking and filemap_write
 * @inode:	inode to sync
 * @datasync:	only sync essential metadata if true
 *
 * This is just generic_file_fsync without the locking.  This is needed for
 * nojournal mode to make sure this inodes data/metadata makes it to disk
 * properly.  The i_mutex should be held already.
 */
static int __sync_inode(struct inode *inode, int datasync)
{
	int err;
	int ret;

	ret = sync_mapping_buffers(inode->i_mapping);
	if (!(inode->i_state & I_DIRTY))
		return ret;
	if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
		return ret;

	err = sync_inode_metadata(inode, 1);
	if (ret == 0)
		ret = err;
	return ret;
}
Ejemplo n.º 8
0
int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync)
{
	struct inode *inode = dentry->d_inode;
	int err;
	int ret;

	ret = sync_mapping_buffers(inode->i_mapping);
	if (!(inode->i_state & I_DIRTY))
		return ret;
	if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
		return ret;

	err = ufs_sync_inode(inode);
	if (ret == 0)
		ret = err;
	return ret;
}
Ejemplo n.º 9
0
static int reiserfs_sync_file(
			      struct file   * p_s_filp,
			      struct dentry * p_s_dentry,
			      int datasync
			      ) {
  struct inode * p_s_inode = p_s_dentry->d_inode;
  int n_err;

  reiserfs_write_lock(p_s_inode->i_sb);

  if (!S_ISREG(p_s_inode->i_mode))
      BUG ();

  n_err = sync_mapping_buffers(p_s_inode->i_mapping) ;
  reiserfs_commit_for_inode(p_s_inode) ;
  reiserfs_write_unlock(p_s_inode->i_sb);
  return ( n_err < 0 ) ? -EIO : 0;
}
Ejemplo n.º 10
0
Archivo: fsync.c Proyecto: mdamt/linux
/*
 * If we're not journaling and this is a just-created file, we have to
 * sync our parent directory (if it was freshly created) since
 * otherwise it will only be written by writeback, leaving a huge
 * window during which a crash may lose the file.  This may apply for
 * the parent directory's parent as well, and so on recursively, if
 * they are also freshly created.
 */
static int ext4_sync_parent(struct inode *inode)
{
	struct dentry *dentry = NULL;
	struct inode *next;
	int ret = 0;

	if (!ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY))
		return 0;
	inode = igrab(inode);
	while (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) {
		ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY);
		dentry = d_find_any_alias(inode);
		if (!dentry)
			break;
		next = igrab(d_inode(dentry->d_parent));
		dput(dentry);
		if (!next)
			break;
		iput(inode);
		inode = next;
		/*
		 * The directory inode may have gone through rmdir by now. But
		 * the inode itself and its blocks are still allocated (we hold
		 * a reference to the inode so it didn't go through
		 * ext4_evict_inode()) and so we are safe to flush metadata
		 * blocks and the inode.
		 */
		ret = sync_mapping_buffers(inode->i_mapping);
		if (ret)
			break;
		ret = sync_inode_metadata(inode, 1);
		if (ret)
			break;
	}
	iput(inode);
	return ret;
}
Ejemplo n.º 11
0
static int ocfs2_sync_inode(struct inode *inode)
{
	filemap_fdatawrite(inode->i_mapping);
	return sync_mapping_buffers(inode->i_mapping);
}
Ejemplo n.º 12
0
int 
xixfs_sync_inode(struct inode *inode)
{
	struct writeback_control wbc = {
		.sync_mode = WB_SYNC_ALL,
		.nr_to_write = 0,	/* sys_fsync did this */
	};
	return sync_inode(inode, &wbc);
}
#endif





int 
xixfs_sync_file(
		struct file *file, 
		struct dentry *dentry, 
		int datasync
)
{
	struct inode *inode = dentry->d_inode;
	PXIXFS_LINUX_FCB		pFCB = NULL;
	PXIXFS_LINUX_VCB		pVCB = NULL;
	int err = 0;
	int ret = 0;
	
	

	XIXCORE_ASSERT(inode);
	pVCB = XIXFS_SB(inode->i_sb);
	XIXFS_ASSERT_VCB(pVCB);
	
	pFCB = XIXFS_I(inode);
	XIXFS_ASSERT_FCB(pFCB);

	DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), 
		("ENTER xixfs_sync_file (%s).\n", file->f_dentry->d_name.name));	


	if(pVCB->XixcoreVcb.IsVolumeWriteProtected){
		DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, 
			("ERROR xixfs_sync_file : is read only .\n"));	
		return -EPERM;
	}

	if(XIXCORE_TEST_FLAGS( pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_CHANGE_DELETED )){
		DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
			("ERROR DELETED FILE \n"));
		
		return -EPERM;
	}


		

	XIXCORE_ASSERT(pFCB->XixcoreFcb.FCBType == FCB_TYPE_FILE);

	if(pFCB->XixcoreFcb.HasLock == INODE_FILE_LOCK_HAS) {
#if LINUX_VERSION_25_ABOVE
		ret = sync_mapping_buffers(inode->i_mapping);
		if (!(inode->i_state & I_DIRTY))
			return ret;
		if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
			return ret;
		
	
		xixfs_sync_inode(inode);
#endif
		

		
		if(XIXCORE_TEST_FLAGS(pFCB->XixcoreFcb.FCBFlags,XIXCORE_FCB_MODIFIED_FILE)){
#if LINUX_VERSION_25_ABOVE
			err = xixfs_write_inode(inode, 1);
#else
			xixfs_write_inode(inode, 1);
#endif
			if(pFCB->XixcoreFcb.WriteStartOffset != -1){

					printk(KERN_DEBUG "Set Update Information!!!\n");
					xixfs_SendFileChangeRC(
							pVCB->XixcoreVcb.HostMac, 
							pFCB->XixcoreFcb.LotNumber, 
							pVCB->XixcoreVcb.VolumeId, 
							i_size_read(inode), 
							pFCB->XixcoreFcb.RealAllocationSize,
							pFCB->XixcoreFcb.WriteStartOffset
					);
					
					pFCB->XixcoreFcb.WriteStartOffset = -1;
				
			}
			
			if (ret == 0)
				ret = err;
			
			return ret;
			

		}



	
	}else {
		return -EPERM;
	}

	
	return ret;
}


#if LINUX_VERSION_25_ABOVE


#if LINUX_VERSION_2_6_19_REPLACE_INTERFACE
ssize_t
xixfs_file_splice_read(
		struct file *in, 
		loff_t *ppos,
		struct pipe_inode_info *pipe, 
		size_t len,
		unsigned int flags
)
{
	return generic_file_splice_read(in, ppos, pipe, len, flags);
	
}

ssize_t
xixfs_file_splice_write(
		struct pipe_inode_info *pipe, 
		struct file *out,
		loff_t *ppos, 
		size_t len, 
		unsigned int flags
)
{
	ssize_t 				RC = 0;
	int64				index = 0;
	struct address_space *mapping = out->f_mapping;
	struct inode *inode = mapping->host;
	PXIXFS_LINUX_FCB	pFCB = NULL;
	PXIXFS_LINUX_VCB	pVCB = NULL;

	XIXCORE_ASSERT(inode);
	pVCB = XIXFS_SB(inode->i_sb);
	XIXFS_ASSERT_VCB(pVCB);
	
	pFCB = XIXFS_I(inode);
	XIXFS_ASSERT_FCB(pFCB);


	DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), 
		("ENTER xixfs_file_splice_write (%s).\n", out->f_dentry->d_name.name));	

	if(pVCB->XixcoreVcb.IsVolumeWriteProtected){
		DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, 
			("ERROR xixfs_file_splice_write : is read only .\n"));	
		return -EPERM;
	}


	if(XIXCORE_TEST_FLAGS( pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_CHANGE_DELETED )){
		DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
			("ERROR DELETED FILE \n"));
		
		return -EPERM;
	}


	XIXCORE_ASSERT(pFCB->XixcoreFcb.FCBType == FCB_TYPE_FILE);
	if(pFCB->XixcoreFcb.HasLock == INODE_FILE_LOCK_HAS) {

		index =(int64) (*ppos);
		
		RC =  generic_file_splice_write(pipe, out, ppos, len, flags);

		if(RC > 0  ) {
			if(pFCB->XixcoreFcb.WriteStartOffset ==  -1) {
				pFCB->XixcoreFcb.WriteStartOffset = index;
				XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE);
			}

			if(pFCB->XixcoreFcb.WriteStartOffset > index ){
				pFCB->XixcoreFcb.WriteStartOffset = index;
				XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE);
			}							
		}
		
		DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), 
			("EXIT xixfs_file_writev (%d).\n", RC));	

		return RC;
	}

	DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), 
		("EXIT xixfs_file_writev ERROR.\n"));	

	return -EPERM;
}