diff options
author | Christoph Hellwig <hch@infradead.org> | 2012-02-29 04:53:55 -0500 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-03-13 18:18:14 -0400 |
commit | 8f639ddea0c4978ae9b4e46ea041c9e5afe0ee8d (patch) | |
tree | d2b90c868fd3ad818317e3fff8448d6940afb3d5 /fs/xfs | |
parent | f5d8d5c4bf29c9f7754d9cbe5e27c785106ba872 (diff) |
xfs: reimplement fdatasync support
Add an in-memory only flag to say we logged timestamps only, and use it to
check if fdatasync can optimize away the log force.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_file.c | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_inode_item.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_inode_item.h | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 2 |
4 files changed, 18 insertions, 5 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 78d8b0299592..54a67dd9ac0a 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -197,8 +197,11 @@ xfs_file_fsync( | |||
197 | * to flush the log up to the latest LSN that touched the inode. | 197 | * to flush the log up to the latest LSN that touched the inode. |
198 | */ | 198 | */ |
199 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 199 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
200 | if (xfs_ipincount(ip)) | 200 | if (xfs_ipincount(ip)) { |
201 | lsn = ip->i_itemp->ili_last_lsn; | 201 | if (!datasync || |
202 | (ip->i_itemp->ili_fields & ~XFS_ILOG_TIMESTAMP)) | ||
203 | lsn = ip->i_itemp->ili_last_lsn; | ||
204 | } | ||
202 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 205 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
203 | 206 | ||
204 | if (lsn) | 207 | if (lsn) |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 8becef4f9e6a..05d924efceaf 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -438,7 +438,8 @@ out: | |||
438 | * games in recovery easier, which isn't a big deal as just about any | 438 | * games in recovery easier, which isn't a big deal as just about any |
439 | * transaction would dirty it anyway. | 439 | * transaction would dirty it anyway. |
440 | */ | 440 | */ |
441 | iip->ili_format.ilf_fields = XFS_ILOG_CORE | iip->ili_fields; | 441 | iip->ili_format.ilf_fields = XFS_ILOG_CORE | |
442 | (iip->ili_fields & ~XFS_ILOG_TIMESTAMP); | ||
442 | iip->ili_format.ilf_size = nvecs; | 443 | iip->ili_format.ilf_size = nvecs; |
443 | } | 444 | } |
444 | 445 | ||
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index bc183d81ad32..41d61c3b7a36 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h | |||
@@ -86,6 +86,15 @@ typedef struct xfs_inode_log_format_64 { | |||
86 | #define XFS_ILOG_AEXT 0x080 /* log i_af.if_extents */ | 86 | #define XFS_ILOG_AEXT 0x080 /* log i_af.if_extents */ |
87 | #define XFS_ILOG_ABROOT 0x100 /* log i_af.i_broot */ | 87 | #define XFS_ILOG_ABROOT 0x100 /* log i_af.i_broot */ |
88 | 88 | ||
89 | |||
90 | /* | ||
91 | * The timestamps are dirty, but not necessarily anything else in the inode | ||
92 | * core. Unlike the other fields above this one must never make it to disk | ||
93 | * in the ilf_fields of the inode_log_format, but is purely store in-memory in | ||
94 | * ili_fields in the inode_log_item. | ||
95 | */ | ||
96 | #define XFS_ILOG_TIMESTAMP 0x4000 | ||
97 | |||
89 | #define XFS_ILOG_NONCORE (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ | 98 | #define XFS_ILOG_NONCORE (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ |
90 | XFS_ILOG_DBROOT | XFS_ILOG_DEV | \ | 99 | XFS_ILOG_DBROOT | XFS_ILOG_DEV | \ |
91 | XFS_ILOG_UUID | XFS_ILOG_ADATA | \ | 100 | XFS_ILOG_UUID | XFS_ILOG_ADATA | \ |
@@ -101,7 +110,7 @@ typedef struct xfs_inode_log_format_64 { | |||
101 | XFS_ILOG_DEXT | XFS_ILOG_DBROOT | \ | 110 | XFS_ILOG_DEXT | XFS_ILOG_DBROOT | \ |
102 | XFS_ILOG_DEV | XFS_ILOG_UUID | \ | 111 | XFS_ILOG_DEV | XFS_ILOG_UUID | \ |
103 | XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ | 112 | XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ |
104 | XFS_ILOG_ABROOT) | 113 | XFS_ILOG_ABROOT | XFS_ILOG_TIMESTAMP) |
105 | 114 | ||
106 | static inline int xfs_ilog_fbroot(int w) | 115 | static inline int xfs_ilog_fbroot(int w) |
107 | { | 116 | { |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index e602c8c67c5c..e9ad7894648e 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -907,7 +907,7 @@ xfs_fs_dirty_inode( | |||
907 | ip->i_d.di_mtime.t_nsec = (__int32_t)inode->i_mtime.tv_nsec; | 907 | ip->i_d.di_mtime.t_nsec = (__int32_t)inode->i_mtime.tv_nsec; |
908 | 908 | ||
909 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 909 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); |
910 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 910 | xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP); |
911 | error = xfs_trans_commit(tp, 0); | 911 | error = xfs_trans_commit(tp, 0); |
912 | if (error) | 912 | if (error) |
913 | goto trouble; | 913 | goto trouble; |