diff options
author | Nathan Scott <nathans@sgi.com> | 2005-11-01 19:43:58 -0500 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2005-11-01 19:43:58 -0500 |
commit | 4aeb664c2561c0bae18d7a3a141d7d2acf126da1 (patch) | |
tree | 832e72237a69b76bf4c965d7383cdbb9fc3f8939 /fs/xfs/linux-2.6/xfs_iops.c | |
parent | 0fdfb3757f27b6d802f85e962d9b0f875df17113 (diff) |
[XFS] Improve buffered read throughput by removing unnecessary timer calls
that showed in ´kernel profiles.
SGI-PV: 925163
SGI-Modid: xfs-linux:xfs-kern:23861a
Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_iops.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 77708a8c9f87..68c83ec31143 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -69,6 +69,137 @@ | |||
69 | #include <linux/xattr.h> | 69 | #include <linux/xattr.h> |
70 | #include <linux/namei.h> | 70 | #include <linux/namei.h> |
71 | 71 | ||
72 | /* | ||
73 | * Change the requested timestamp in the given inode. | ||
74 | * We don't lock across timestamp updates, and we don't log them but | ||
75 | * we do record the fact that there is dirty information in core. | ||
76 | * | ||
77 | * NOTE -- callers MUST combine XFS_ICHGTIME_MOD or XFS_ICHGTIME_CHG | ||
78 | * with XFS_ICHGTIME_ACC to be sure that access time | ||
79 | * update will take. Calling first with XFS_ICHGTIME_ACC | ||
80 | * and then XFS_ICHGTIME_MOD may fail to modify the access | ||
81 | * timestamp if the filesystem is mounted noacctm. | ||
82 | */ | ||
83 | void | ||
84 | xfs_ichgtime( | ||
85 | xfs_inode_t *ip, | ||
86 | int flags) | ||
87 | { | ||
88 | struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip)); | ||
89 | timespec_t tv; | ||
90 | |||
91 | /* | ||
92 | * We're not supposed to change timestamps in readonly-mounted | ||
93 | * filesystems. Throw it away if anyone asks us. | ||
94 | */ | ||
95 | if (unlikely(IS_RDONLY(inode))) | ||
96 | return; | ||
97 | |||
98 | /* | ||
99 | * Don't update access timestamps on reads if mounted "noatime". | ||
100 | * Throw it away if anyone asks us. | ||
101 | */ | ||
102 | if (unlikely( | ||
103 | (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) && | ||
104 | (flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) == | ||
105 | XFS_ICHGTIME_ACC)) | ||
106 | return; | ||
107 | |||
108 | nanotime(&tv); | ||
109 | if (flags & XFS_ICHGTIME_MOD) { | ||
110 | inode->i_mtime = tv; | ||
111 | ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; | ||
112 | ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; | ||
113 | } | ||
114 | if (flags & XFS_ICHGTIME_ACC) { | ||
115 | inode->i_atime = tv; | ||
116 | ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec; | ||
117 | ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec; | ||
118 | } | ||
119 | if (flags & XFS_ICHGTIME_CHG) { | ||
120 | inode->i_ctime = tv; | ||
121 | ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec; | ||
122 | ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec; | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * We update the i_update_core field _after_ changing | ||
127 | * the timestamps in order to coordinate properly with | ||
128 | * xfs_iflush() so that we don't lose timestamp updates. | ||
129 | * This keeps us from having to hold the inode lock | ||
130 | * while doing this. We use the SYNCHRONIZE macro to | ||
131 | * ensure that the compiler does not reorder the update | ||
132 | * of i_update_core above the timestamp updates above. | ||
133 | */ | ||
134 | SYNCHRONIZE(); | ||
135 | ip->i_update_core = 1; | ||
136 | if (!(inode->i_state & I_LOCK)) | ||
137 | mark_inode_dirty_sync(inode); | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * Variant on the above which avoids querying the system clock | ||
142 | * in situations where we know the Linux inode timestamps have | ||
143 | * just been updated (and so we can update our inode cheaply). | ||
144 | * We also skip the readonly and noatime checks here, they are | ||
145 | * also catered for already. | ||
146 | */ | ||
147 | void | ||
148 | xfs_ichgtime_fast( | ||
149 | xfs_inode_t *ip, | ||
150 | struct inode *inode, | ||
151 | int flags) | ||
152 | { | ||
153 | timespec_t *tvp; | ||
154 | |||
155 | /* | ||
156 | * We're not supposed to change timestamps in readonly-mounted | ||
157 | * filesystems. Throw it away if anyone asks us. | ||
158 | */ | ||
159 | if (unlikely(IS_RDONLY(inode))) | ||
160 | return; | ||
161 | |||
162 | /* | ||
163 | * Don't update access timestamps on reads if mounted "noatime". | ||
164 | * Throw it away if anyone asks us. | ||
165 | */ | ||
166 | if (unlikely( | ||
167 | (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) && | ||
168 | ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) == | ||
169 | XFS_ICHGTIME_ACC))) | ||
170 | return; | ||
171 | |||
172 | if (flags & XFS_ICHGTIME_MOD) { | ||
173 | tvp = &inode->i_mtime; | ||
174 | ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec; | ||
175 | ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec; | ||
176 | } | ||
177 | if (flags & XFS_ICHGTIME_ACC) { | ||
178 | tvp = &inode->i_atime; | ||
179 | ip->i_d.di_atime.t_sec = (__int32_t)tvp->tv_sec; | ||
180 | ip->i_d.di_atime.t_nsec = (__int32_t)tvp->tv_nsec; | ||
181 | } | ||
182 | if (flags & XFS_ICHGTIME_CHG) { | ||
183 | tvp = &inode->i_ctime; | ||
184 | ip->i_d.di_ctime.t_sec = (__int32_t)tvp->tv_sec; | ||
185 | ip->i_d.di_ctime.t_nsec = (__int32_t)tvp->tv_nsec; | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * We update the i_update_core field _after_ changing | ||
190 | * the timestamps in order to coordinate properly with | ||
191 | * xfs_iflush() so that we don't lose timestamp updates. | ||
192 | * This keeps us from having to hold the inode lock | ||
193 | * while doing this. We use the SYNCHRONIZE macro to | ||
194 | * ensure that the compiler does not reorder the update | ||
195 | * of i_update_core above the timestamp updates above. | ||
196 | */ | ||
197 | SYNCHRONIZE(); | ||
198 | ip->i_update_core = 1; | ||
199 | if (!(inode->i_state & I_LOCK)) | ||
200 | mark_inode_dirty_sync(inode); | ||
201 | } | ||
202 | |||
72 | 203 | ||
73 | /* | 204 | /* |
74 | * Pull the link count and size up from the xfs inode to the linux inode | 205 | * Pull the link count and size up from the xfs inode to the linux inode |