diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2007-07-20 14:24:53 -0400 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2007-08-09 20:23:50 -0400 |
commit | c11e9fafb398411af7558fca913c2fa4a10b1f48 (patch) | |
tree | de1879d52677c612f2efa8e98df8c218cd477230 /fs/ocfs2 | |
parent | 6adb31c90c47262c8a25bf5097de9b3426caf3ae (diff) |
ocfs2: Restrict inode changes in ocfs2_update_inode_atime()
ocfs2_update_inode_atime() calls ocfs2_mark_inode_dirty() to push changes
from the struct inode into the ocfs2 disk inode. The problem is,
ocfs2_mark_inode_dirty() might change other fields, depending on what
happened to the struct inode. Since we don't always have locking to
serialize changes to other fields (like i_size, etc), just fix things up to
only touch the atime field.
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/file.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index c4034f693e7b..992eb567cb4d 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -187,6 +187,7 @@ int ocfs2_update_inode_atime(struct inode *inode, | |||
187 | int ret; | 187 | int ret; |
188 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 188 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
189 | handle_t *handle; | 189 | handle_t *handle; |
190 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) bh->b_data; | ||
190 | 191 | ||
191 | mlog_entry_void(); | 192 | mlog_entry_void(); |
192 | 193 | ||
@@ -197,11 +198,27 @@ int ocfs2_update_inode_atime(struct inode *inode, | |||
197 | goto out; | 198 | goto out; |
198 | } | 199 | } |
199 | 200 | ||
201 | ret = ocfs2_journal_access(handle, inode, bh, | ||
202 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
203 | if (ret) { | ||
204 | mlog_errno(ret); | ||
205 | goto out_commit; | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * Don't use ocfs2_mark_inode_dirty() here as we don't always | ||
210 | * have i_mutex to guard against concurrent changes to other | ||
211 | * inode fields. | ||
212 | */ | ||
200 | inode->i_atime = CURRENT_TIME; | 213 | inode->i_atime = CURRENT_TIME; |
201 | ret = ocfs2_mark_inode_dirty(handle, inode, bh); | 214 | di->i_atime = cpu_to_le64(inode->i_atime.tv_sec); |
215 | di->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); | ||
216 | |||
217 | ret = ocfs2_journal_dirty(handle, bh); | ||
202 | if (ret < 0) | 218 | if (ret < 0) |
203 | mlog_errno(ret); | 219 | mlog_errno(ret); |
204 | 220 | ||
221 | out_commit: | ||
205 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | 222 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
206 | out: | 223 | out: |
207 | mlog_exit(ret); | 224 | mlog_exit(ret); |