Loading fs/xfs/linux-2.6/xfs_aops.c +28 −10 Original line number Diff line number Diff line Loading @@ -185,6 +185,24 @@ xfs_destroy_ioend( mempool_free(ioend, xfs_ioend_pool); } /* * If the end of the current ioend is beyond the current EOF, * return the new EOF value, otherwise zero. */ STATIC xfs_fsize_t xfs_ioend_new_eof( xfs_ioend_t *ioend) { xfs_inode_t *ip = XFS_I(ioend->io_inode); xfs_fsize_t isize; xfs_fsize_t bsize; bsize = ioend->io_offset + ioend->io_size; isize = MAX(ip->i_size, ip->i_new_size); isize = MIN(isize, bsize); return isize > ip->i_d.di_size ? isize : 0; } /* * Update on-disk file size now that data has been written to disk. * The current in-memory file size is i_size. If a write is beyond Loading @@ -192,13 +210,13 @@ xfs_destroy_ioend( * updated. If this write does not extend all the way to the valid * file size then restrict this update to the end of the write. */ STATIC void xfs_setfilesize( xfs_ioend_t *ioend) { xfs_inode_t *ip = XFS_I(ioend->io_inode); xfs_fsize_t isize; xfs_fsize_t bsize; ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); ASSERT(ioend->io_type != IOMAP_READ); Loading @@ -206,16 +224,10 @@ xfs_setfilesize( if (unlikely(ioend->io_error)) return; bsize = ioend->io_offset + ioend->io_size; xfs_ilock(ip, XFS_ILOCK_EXCL); isize = MAX(ip->i_size, ip->i_new_size); isize = MIN(isize, bsize); if (ip->i_d.di_size < isize) { isize = xfs_ioend_new_eof(ioend); if (isize) { ip->i_d.di_size = isize; ip->i_update_core = 1; xfs_mark_inode_dirty_sync(ip); } Loading Loading @@ -404,10 +416,16 @@ xfs_submit_ioend_bio( struct bio *bio) { atomic_inc(&ioend->io_remaining); bio->bi_private = ioend; bio->bi_end_io = xfs_end_bio; /* * If the I/O is beyond EOF we mark the inode dirty immediately * but don't update the inode size until I/O completion. */ if (xfs_ioend_new_eof(ioend)) xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode)); submit_bio(WRITE, bio); ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP)); bio_put(bio); Loading fs/xfs/linux-2.6/xfs_file.c +1 −8 Original line number Diff line number Diff line Loading @@ -176,14 +176,7 @@ xfs_file_fsync( struct dentry *dentry, int datasync) { struct inode *inode = dentry->d_inode; struct xfs_inode *ip = XFS_I(inode); int error; /* capture size updates in I/O completion before writing the inode. */ error = filemap_fdatawait(inode->i_mapping); if (error) return error; struct xfs_inode *ip = XFS_I(dentry->d_inode); xfs_iflags_clear(ip, XFS_ITRUNCATED); return -xfs_fsync(ip); Loading fs/xfs/linux-2.6/xfs_iops.c +15 −26 Original line number Diff line number Diff line Loading @@ -57,19 +57,22 @@ #include <linux/fiemap.h> /* * Bring the atime in the XFS inode uptodate. * Used before logging the inode to disk or when the Linux inode goes away. * Bring the timestamps in the XFS inode uptodate. * * Used before writing the inode to disk. */ void xfs_synchronize_atime( xfs_synchronize_times( xfs_inode_t *ip) { struct inode *inode = VFS_I(ip); if (!(inode->i_state & I_CLEAR)) { ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec; ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec; } ip->i_d.di_ctime.t_sec = (__int32_t)inode->i_ctime.tv_sec; ip->i_d.di_ctime.t_nsec = (__int32_t)inode->i_ctime.tv_nsec; ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec; ip->i_d.di_mtime.t_nsec = (__int32_t)inode->i_mtime.tv_nsec; } /* Loading Loading @@ -106,33 +109,21 @@ xfs_ichgtime( if ((flags & XFS_ICHGTIME_MOD) && !timespec_equal(&inode->i_mtime, &tv)) { inode->i_mtime = tv; ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; sync_it = 1; } if ((flags & XFS_ICHGTIME_CHG) && !timespec_equal(&inode->i_ctime, &tv)) { inode->i_ctime = tv; ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec; sync_it = 1; } /* * We update the i_update_core field _after_ changing * the timestamps in order to coordinate properly with * xfs_iflush() so that we don't lose timestamp updates. * This keeps us from having to hold the inode lock * while doing this. We use the SYNCHRONIZE macro to * ensure that the compiler does not reorder the update * of i_update_core above the timestamp updates above. * Update complete - now make sure everyone knows that the inode * is dirty. */ if (sync_it) { SYNCHRONIZE(); ip->i_update_core = 1; if (sync_it) xfs_mark_inode_dirty_sync(ip); } } /* * Hook in SELinux. This is not quite correct yet, what we really need Loading Loading @@ -506,10 +497,8 @@ xfs_vn_getattr( stat->gid = ip->i_d.di_gid; stat->ino = ip->i_ino; stat->atime = inode->i_atime; stat->mtime.tv_sec = ip->i_d.di_mtime.t_sec; stat->mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; stat->ctime.tv_sec = ip->i_d.di_ctime.t_sec; stat->ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; stat->mtime = inode->i_mtime; stat->ctime = inode->i_ctime; stat->blocks = XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks); Loading fs/xfs/linux-2.6/xfs_lrw.c +1 −1 Original line number Diff line number Diff line Loading @@ -667,7 +667,7 @@ start: xip->i_new_size = new_size; if (likely(!(ioflags & IO_INVIS))) xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); file_update_time(file); /* * If the offset is beyond the size of the file, we have a couple Loading fs/xfs/linux-2.6/xfs_super.c +41 −18 Original line number Diff line number Diff line Loading @@ -976,6 +976,28 @@ xfs_fs_inode_init_once( mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); } /* * Dirty the XFS inode when mark_inode_dirty_sync() is called so that * we catch unlogged VFS level updates to the inode. Care must be taken * here - the transaction code calls mark_inode_dirty_sync() to mark the * VFS inode dirty in a transaction and clears the i_update_core field; * it must clear the field after calling mark_inode_dirty_sync() to * correctly indicate that the dirty state has been propagated into the * inode log item. * * We need the barrier() to maintain correct ordering between unlogged * updates and the transaction commit code that clears the i_update_core * field. This requires all updates to be completed before marking the * inode dirty. */ STATIC void xfs_fs_dirty_inode( struct inode *inode) { barrier(); XFS_I(inode)->i_update_core = 1; } /* * Attempt to flush the inode, this will actually fail * if the inode is pinned, but we dirty the inode again Loading Loading @@ -1126,7 +1148,7 @@ xfs_fs_put_super( } STATIC int xfs_fs_sync_super( xfs_fs_sync_fs( struct super_block *sb, int wait) { Loading @@ -1134,23 +1156,23 @@ xfs_fs_sync_super( int error; /* * Treat a sync operation like a freeze. This is to work * around a race in sync_inodes() which works in two phases * - an asynchronous flush, which can write out an inode * without waiting for file size updates to complete, and a * synchronous flush, which wont do anything because the * async flush removed the inode's dirty flag. Also * sync_inodes() will not see any files that just have * outstanding transactions to be flushed because we don't * dirty the Linux inode until after the transaction I/O * completes. * Not much we can do for the first async pass. Writing out the * superblock would be counter-productive as we are going to redirty * when writing out other data and metadata (and writing out a single * block is quite fast anyway). * * Try to asynchronously kick off quota syncing at least. */ if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) if (!wait) { xfs_qm_sync(mp, SYNC_TRYLOCK); return 0; } error = xfs_quiesce_data(mp); else error = xfs_sync_fsdata(mp, 0); if (error) return -error; if (unlikely(laptop_mode)) { if (laptop_mode) { int prev_sync_seq = mp->m_sync_seq; /* Loading @@ -1169,7 +1191,7 @@ xfs_fs_sync_super( mp->m_sync_seq != prev_sync_seq); } return -error; return 0; } STATIC int Loading Loading @@ -1539,10 +1561,11 @@ xfs_fs_get_sb( static struct super_operations xfs_super_operations = { .alloc_inode = xfs_fs_alloc_inode, .destroy_inode = xfs_fs_destroy_inode, .dirty_inode = xfs_fs_dirty_inode, .write_inode = xfs_fs_write_inode, .clear_inode = xfs_fs_clear_inode, .put_super = xfs_fs_put_super, .sync_fs = xfs_fs_sync_super, .sync_fs = xfs_fs_sync_fs, .freeze_fs = xfs_fs_freeze, .statfs = xfs_fs_statfs, .remount_fs = xfs_fs_remount, Loading Loading
fs/xfs/linux-2.6/xfs_aops.c +28 −10 Original line number Diff line number Diff line Loading @@ -185,6 +185,24 @@ xfs_destroy_ioend( mempool_free(ioend, xfs_ioend_pool); } /* * If the end of the current ioend is beyond the current EOF, * return the new EOF value, otherwise zero. */ STATIC xfs_fsize_t xfs_ioend_new_eof( xfs_ioend_t *ioend) { xfs_inode_t *ip = XFS_I(ioend->io_inode); xfs_fsize_t isize; xfs_fsize_t bsize; bsize = ioend->io_offset + ioend->io_size; isize = MAX(ip->i_size, ip->i_new_size); isize = MIN(isize, bsize); return isize > ip->i_d.di_size ? isize : 0; } /* * Update on-disk file size now that data has been written to disk. * The current in-memory file size is i_size. If a write is beyond Loading @@ -192,13 +210,13 @@ xfs_destroy_ioend( * updated. If this write does not extend all the way to the valid * file size then restrict this update to the end of the write. */ STATIC void xfs_setfilesize( xfs_ioend_t *ioend) { xfs_inode_t *ip = XFS_I(ioend->io_inode); xfs_fsize_t isize; xfs_fsize_t bsize; ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); ASSERT(ioend->io_type != IOMAP_READ); Loading @@ -206,16 +224,10 @@ xfs_setfilesize( if (unlikely(ioend->io_error)) return; bsize = ioend->io_offset + ioend->io_size; xfs_ilock(ip, XFS_ILOCK_EXCL); isize = MAX(ip->i_size, ip->i_new_size); isize = MIN(isize, bsize); if (ip->i_d.di_size < isize) { isize = xfs_ioend_new_eof(ioend); if (isize) { ip->i_d.di_size = isize; ip->i_update_core = 1; xfs_mark_inode_dirty_sync(ip); } Loading Loading @@ -404,10 +416,16 @@ xfs_submit_ioend_bio( struct bio *bio) { atomic_inc(&ioend->io_remaining); bio->bi_private = ioend; bio->bi_end_io = xfs_end_bio; /* * If the I/O is beyond EOF we mark the inode dirty immediately * but don't update the inode size until I/O completion. */ if (xfs_ioend_new_eof(ioend)) xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode)); submit_bio(WRITE, bio); ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP)); bio_put(bio); Loading
fs/xfs/linux-2.6/xfs_file.c +1 −8 Original line number Diff line number Diff line Loading @@ -176,14 +176,7 @@ xfs_file_fsync( struct dentry *dentry, int datasync) { struct inode *inode = dentry->d_inode; struct xfs_inode *ip = XFS_I(inode); int error; /* capture size updates in I/O completion before writing the inode. */ error = filemap_fdatawait(inode->i_mapping); if (error) return error; struct xfs_inode *ip = XFS_I(dentry->d_inode); xfs_iflags_clear(ip, XFS_ITRUNCATED); return -xfs_fsync(ip); Loading
fs/xfs/linux-2.6/xfs_iops.c +15 −26 Original line number Diff line number Diff line Loading @@ -57,19 +57,22 @@ #include <linux/fiemap.h> /* * Bring the atime in the XFS inode uptodate. * Used before logging the inode to disk or when the Linux inode goes away. * Bring the timestamps in the XFS inode uptodate. * * Used before writing the inode to disk. */ void xfs_synchronize_atime( xfs_synchronize_times( xfs_inode_t *ip) { struct inode *inode = VFS_I(ip); if (!(inode->i_state & I_CLEAR)) { ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec; ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec; } ip->i_d.di_ctime.t_sec = (__int32_t)inode->i_ctime.tv_sec; ip->i_d.di_ctime.t_nsec = (__int32_t)inode->i_ctime.tv_nsec; ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec; ip->i_d.di_mtime.t_nsec = (__int32_t)inode->i_mtime.tv_nsec; } /* Loading Loading @@ -106,33 +109,21 @@ xfs_ichgtime( if ((flags & XFS_ICHGTIME_MOD) && !timespec_equal(&inode->i_mtime, &tv)) { inode->i_mtime = tv; ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; sync_it = 1; } if ((flags & XFS_ICHGTIME_CHG) && !timespec_equal(&inode->i_ctime, &tv)) { inode->i_ctime = tv; ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec; sync_it = 1; } /* * We update the i_update_core field _after_ changing * the timestamps in order to coordinate properly with * xfs_iflush() so that we don't lose timestamp updates. * This keeps us from having to hold the inode lock * while doing this. We use the SYNCHRONIZE macro to * ensure that the compiler does not reorder the update * of i_update_core above the timestamp updates above. * Update complete - now make sure everyone knows that the inode * is dirty. */ if (sync_it) { SYNCHRONIZE(); ip->i_update_core = 1; if (sync_it) xfs_mark_inode_dirty_sync(ip); } } /* * Hook in SELinux. This is not quite correct yet, what we really need Loading Loading @@ -506,10 +497,8 @@ xfs_vn_getattr( stat->gid = ip->i_d.di_gid; stat->ino = ip->i_ino; stat->atime = inode->i_atime; stat->mtime.tv_sec = ip->i_d.di_mtime.t_sec; stat->mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; stat->ctime.tv_sec = ip->i_d.di_ctime.t_sec; stat->ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; stat->mtime = inode->i_mtime; stat->ctime = inode->i_ctime; stat->blocks = XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks); Loading
fs/xfs/linux-2.6/xfs_lrw.c +1 −1 Original line number Diff line number Diff line Loading @@ -667,7 +667,7 @@ start: xip->i_new_size = new_size; if (likely(!(ioflags & IO_INVIS))) xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); file_update_time(file); /* * If the offset is beyond the size of the file, we have a couple Loading
fs/xfs/linux-2.6/xfs_super.c +41 −18 Original line number Diff line number Diff line Loading @@ -976,6 +976,28 @@ xfs_fs_inode_init_once( mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); } /* * Dirty the XFS inode when mark_inode_dirty_sync() is called so that * we catch unlogged VFS level updates to the inode. Care must be taken * here - the transaction code calls mark_inode_dirty_sync() to mark the * VFS inode dirty in a transaction and clears the i_update_core field; * it must clear the field after calling mark_inode_dirty_sync() to * correctly indicate that the dirty state has been propagated into the * inode log item. * * We need the barrier() to maintain correct ordering between unlogged * updates and the transaction commit code that clears the i_update_core * field. This requires all updates to be completed before marking the * inode dirty. */ STATIC void xfs_fs_dirty_inode( struct inode *inode) { barrier(); XFS_I(inode)->i_update_core = 1; } /* * Attempt to flush the inode, this will actually fail * if the inode is pinned, but we dirty the inode again Loading Loading @@ -1126,7 +1148,7 @@ xfs_fs_put_super( } STATIC int xfs_fs_sync_super( xfs_fs_sync_fs( struct super_block *sb, int wait) { Loading @@ -1134,23 +1156,23 @@ xfs_fs_sync_super( int error; /* * Treat a sync operation like a freeze. This is to work * around a race in sync_inodes() which works in two phases * - an asynchronous flush, which can write out an inode * without waiting for file size updates to complete, and a * synchronous flush, which wont do anything because the * async flush removed the inode's dirty flag. Also * sync_inodes() will not see any files that just have * outstanding transactions to be flushed because we don't * dirty the Linux inode until after the transaction I/O * completes. * Not much we can do for the first async pass. Writing out the * superblock would be counter-productive as we are going to redirty * when writing out other data and metadata (and writing out a single * block is quite fast anyway). * * Try to asynchronously kick off quota syncing at least. */ if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) if (!wait) { xfs_qm_sync(mp, SYNC_TRYLOCK); return 0; } error = xfs_quiesce_data(mp); else error = xfs_sync_fsdata(mp, 0); if (error) return -error; if (unlikely(laptop_mode)) { if (laptop_mode) { int prev_sync_seq = mp->m_sync_seq; /* Loading @@ -1169,7 +1191,7 @@ xfs_fs_sync_super( mp->m_sync_seq != prev_sync_seq); } return -error; return 0; } STATIC int Loading Loading @@ -1539,10 +1561,11 @@ xfs_fs_get_sb( static struct super_operations xfs_super_operations = { .alloc_inode = xfs_fs_alloc_inode, .destroy_inode = xfs_fs_destroy_inode, .dirty_inode = xfs_fs_dirty_inode, .write_inode = xfs_fs_write_inode, .clear_inode = xfs_fs_clear_inode, .put_super = xfs_fs_put_super, .sync_fs = xfs_fs_sync_super, .sync_fs = xfs_fs_sync_fs, .freeze_fs = xfs_fs_freeze, .statfs = xfs_fs_statfs, .remount_fs = xfs_fs_remount, Loading