diff options
-rw-r--r-- | fs/ocfs2/dlmglue.c | 39 | ||||
-rw-r--r-- | fs/ocfs2/dlmglue.h | 3 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 52 | ||||
-rw-r--r-- | fs/ocfs2/file.h | 5 | ||||
-rw-r--r-- | fs/ocfs2/inode.c | 1 | ||||
-rw-r--r-- | fs/ocfs2/ocfs2.h | 2 | ||||
-rw-r--r-- | fs/ocfs2/super.c | 15 |
7 files changed, 116 insertions, 1 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 7a22118ef046..69fba16efbd1 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include "dcache.h" | 49 | #include "dcache.h" |
50 | #include "dlmglue.h" | 50 | #include "dlmglue.h" |
51 | #include "extent_map.h" | 51 | #include "extent_map.h" |
52 | #include "file.h" | ||
52 | #include "heartbeat.h" | 53 | #include "heartbeat.h" |
53 | #include "inode.h" | 54 | #include "inode.h" |
54 | #include "journal.h" | 55 | #include "journal.h" |
@@ -1723,6 +1724,44 @@ int ocfs2_meta_lock_with_page(struct inode *inode, | |||
1723 | return ret; | 1724 | return ret; |
1724 | } | 1725 | } |
1725 | 1726 | ||
1727 | int ocfs2_meta_lock_atime(struct inode *inode, | ||
1728 | struct vfsmount *vfsmnt, | ||
1729 | int *level) | ||
1730 | { | ||
1731 | int ret; | ||
1732 | |||
1733 | mlog_entry_void(); | ||
1734 | ret = ocfs2_meta_lock(inode, NULL, 0); | ||
1735 | if (ret < 0) { | ||
1736 | mlog_errno(ret); | ||
1737 | return ret; | ||
1738 | } | ||
1739 | |||
1740 | /* | ||
1741 | * If we should update atime, we will get EX lock, | ||
1742 | * otherwise we just get PR lock. | ||
1743 | */ | ||
1744 | if (ocfs2_should_update_atime(inode, vfsmnt)) { | ||
1745 | struct buffer_head *bh = NULL; | ||
1746 | |||
1747 | ocfs2_meta_unlock(inode, 0); | ||
1748 | ret = ocfs2_meta_lock(inode, &bh, 1); | ||
1749 | if (ret < 0) { | ||
1750 | mlog_errno(ret); | ||
1751 | return ret; | ||
1752 | } | ||
1753 | *level = 1; | ||
1754 | if (ocfs2_should_update_atime(inode, vfsmnt)) | ||
1755 | ocfs2_update_inode_atime(inode, bh); | ||
1756 | if (bh) | ||
1757 | brelse(bh); | ||
1758 | } else | ||
1759 | *level = 0; | ||
1760 | |||
1761 | mlog_exit(ret); | ||
1762 | return ret; | ||
1763 | } | ||
1764 | |||
1726 | void ocfs2_meta_unlock(struct inode *inode, | 1765 | void ocfs2_meta_unlock(struct inode *inode, |
1727 | int ex) | 1766 | int ex) |
1728 | { | 1767 | { |
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h index a1165edef430..c343fca68cf1 100644 --- a/fs/ocfs2/dlmglue.h +++ b/fs/ocfs2/dlmglue.h | |||
@@ -80,6 +80,9 @@ void ocfs2_data_unlock(struct inode *inode, | |||
80 | int write); | 80 | int write); |
81 | int ocfs2_rw_lock(struct inode *inode, int write); | 81 | int ocfs2_rw_lock(struct inode *inode, int write); |
82 | void ocfs2_rw_unlock(struct inode *inode, int write); | 82 | void ocfs2_rw_unlock(struct inode *inode, int write); |
83 | int ocfs2_meta_lock_atime(struct inode *inode, | ||
84 | struct vfsmount *vfsmnt, | ||
85 | int *level); | ||
83 | int ocfs2_meta_lock_full(struct inode *inode, | 86 | int ocfs2_meta_lock_full(struct inode *inode, |
84 | struct buffer_head **ret_bh, | 87 | struct buffer_head **ret_bh, |
85 | int ex, | 88 | int ex, |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index b32cdb3bf7c5..e82288f7cf21 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/uio.h> | 32 | #include <linux/uio.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/pipe_fs_i.h> | 34 | #include <linux/pipe_fs_i.h> |
35 | #include <linux/mount.h> | ||
35 | 36 | ||
36 | #define MLOG_MASK_PREFIX ML_INODE | 37 | #define MLOG_MASK_PREFIX ML_INODE |
37 | #include <cluster/masklog.h> | 38 | #include <cluster/masklog.h> |
@@ -135,6 +136,57 @@ bail: | |||
135 | return (err < 0) ? -EIO : 0; | 136 | return (err < 0) ? -EIO : 0; |
136 | } | 137 | } |
137 | 138 | ||
139 | int ocfs2_should_update_atime(struct inode *inode, | ||
140 | struct vfsmount *vfsmnt) | ||
141 | { | ||
142 | struct timespec now; | ||
143 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
144 | |||
145 | if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) | ||
146 | return 0; | ||
147 | |||
148 | if ((inode->i_flags & S_NOATIME) || | ||
149 | ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))) | ||
150 | return 0; | ||
151 | |||
152 | if ((vfsmnt->mnt_flags & MNT_NOATIME) || | ||
153 | ((vfsmnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) | ||
154 | return 0; | ||
155 | |||
156 | now = CURRENT_TIME; | ||
157 | if ((now.tv_sec - inode->i_atime.tv_sec <= osb->s_atime_quantum)) | ||
158 | return 0; | ||
159 | else | ||
160 | return 1; | ||
161 | } | ||
162 | |||
163 | int ocfs2_update_inode_atime(struct inode *inode, | ||
164 | struct buffer_head *bh) | ||
165 | { | ||
166 | int ret; | ||
167 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
168 | handle_t *handle; | ||
169 | |||
170 | mlog_entry_void(); | ||
171 | |||
172 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
173 | if (handle == NULL) { | ||
174 | ret = -ENOMEM; | ||
175 | mlog_errno(ret); | ||
176 | goto out; | ||
177 | } | ||
178 | |||
179 | inode->i_atime = CURRENT_TIME; | ||
180 | ret = ocfs2_mark_inode_dirty(handle, inode, bh); | ||
181 | if (ret < 0) | ||
182 | mlog_errno(ret); | ||
183 | |||
184 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | ||
185 | out: | ||
186 | mlog_exit(ret); | ||
187 | return ret; | ||
188 | } | ||
189 | |||
138 | int ocfs2_set_inode_size(handle_t *handle, | 190 | int ocfs2_set_inode_size(handle_t *handle, |
139 | struct inode *inode, | 191 | struct inode *inode, |
140 | struct buffer_head *fe_bh, | 192 | struct buffer_head *fe_bh, |
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h index 84f8b974dcad..475ed8aee8b5 100644 --- a/fs/ocfs2/file.h +++ b/fs/ocfs2/file.h | |||
@@ -54,4 +54,9 @@ int ocfs2_set_inode_size(handle_t *handle, | |||
54 | struct buffer_head *fe_bh, | 54 | struct buffer_head *fe_bh, |
55 | u64 new_i_size); | 55 | u64 new_i_size); |
56 | 56 | ||
57 | int ocfs2_should_update_atime(struct inode *inode, | ||
58 | struct vfsmount *vfsmnt); | ||
59 | int ocfs2_update_inode_atime(struct inode *inode, | ||
60 | struct buffer_head *bh); | ||
61 | |||
57 | #endif /* OCFS2_FILE_H */ | 62 | #endif /* OCFS2_FILE_H */ |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index ad4d4a1df77b..42e361f3054f 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -360,7 +360,6 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
360 | inode); | 360 | inode); |
361 | 361 | ||
362 | ocfs2_set_inode_flags(inode); | 362 | ocfs2_set_inode_flags(inode); |
363 | inode->i_flags |= S_NOATIME; | ||
364 | 363 | ||
365 | status = 0; | 364 | status = 0; |
366 | bail: | 365 | bail: |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 553e7021b6a7..078883772bd6 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
@@ -180,6 +180,7 @@ enum ocfs2_mount_options | |||
180 | #define OCFS2_OSB_SOFT_RO 0x0001 | 180 | #define OCFS2_OSB_SOFT_RO 0x0001 |
181 | #define OCFS2_OSB_HARD_RO 0x0002 | 181 | #define OCFS2_OSB_HARD_RO 0x0002 |
182 | #define OCFS2_OSB_ERROR_FS 0x0004 | 182 | #define OCFS2_OSB_ERROR_FS 0x0004 |
183 | #define OCFS2_DEFAULT_ATIME_QUANTUM 60 | ||
183 | 184 | ||
184 | struct ocfs2_journal; | 185 | struct ocfs2_journal; |
185 | struct ocfs2_super | 186 | struct ocfs2_super |
@@ -218,6 +219,7 @@ struct ocfs2_super | |||
218 | unsigned long osb_flags; | 219 | unsigned long osb_flags; |
219 | 220 | ||
220 | unsigned long s_mount_opt; | 221 | unsigned long s_mount_opt; |
222 | unsigned int s_atime_quantum; | ||
221 | 223 | ||
222 | u16 max_slots; | 224 | u16 max_slots; |
223 | s16 node_num; | 225 | s16 node_num; |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index d9b1eb6a3c6e..b0992573dee2 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -139,6 +139,7 @@ enum { | |||
139 | Opt_hb_local, | 139 | Opt_hb_local, |
140 | Opt_data_ordered, | 140 | Opt_data_ordered, |
141 | Opt_data_writeback, | 141 | Opt_data_writeback, |
142 | Opt_atime_quantum, | ||
142 | Opt_err, | 143 | Opt_err, |
143 | }; | 144 | }; |
144 | 145 | ||
@@ -152,6 +153,7 @@ static match_table_t tokens = { | |||
152 | {Opt_hb_local, OCFS2_HB_LOCAL}, | 153 | {Opt_hb_local, OCFS2_HB_LOCAL}, |
153 | {Opt_data_ordered, "data=ordered"}, | 154 | {Opt_data_ordered, "data=ordered"}, |
154 | {Opt_data_writeback, "data=writeback"}, | 155 | {Opt_data_writeback, "data=writeback"}, |
156 | {Opt_atime_quantum, "atime_quantum=%u"}, | ||
155 | {Opt_err, NULL} | 157 | {Opt_err, NULL} |
156 | }; | 158 | }; |
157 | 159 | ||
@@ -705,6 +707,7 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
705 | while ((p = strsep(&options, ",")) != NULL) { | 707 | while ((p = strsep(&options, ",")) != NULL) { |
706 | int token, option; | 708 | int token, option; |
707 | substring_t args[MAX_OPT_ARGS]; | 709 | substring_t args[MAX_OPT_ARGS]; |
710 | struct ocfs2_super * osb = OCFS2_SB(sb); | ||
708 | 711 | ||
709 | if (!*p) | 712 | if (!*p) |
710 | continue; | 713 | continue; |
@@ -745,6 +748,16 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
745 | case Opt_data_writeback: | 748 | case Opt_data_writeback: |
746 | *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK; | 749 | *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK; |
747 | break; | 750 | break; |
751 | case Opt_atime_quantum: | ||
752 | if (match_int(&args[0], &option)) { | ||
753 | status = 0; | ||
754 | goto bail; | ||
755 | } | ||
756 | if (option >= 0) | ||
757 | osb->s_atime_quantum = option; | ||
758 | else | ||
759 | osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; | ||
760 | break; | ||
748 | default: | 761 | default: |
749 | mlog(ML_ERROR, | 762 | mlog(ML_ERROR, |
750 | "Unrecognized mount option \"%s\" " | 763 | "Unrecognized mount option \"%s\" " |
@@ -1265,6 +1278,8 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1265 | init_waitqueue_head(&osb->checkpoint_event); | 1278 | init_waitqueue_head(&osb->checkpoint_event); |
1266 | atomic_set(&osb->needs_checkpoint, 0); | 1279 | atomic_set(&osb->needs_checkpoint, 0); |
1267 | 1280 | ||
1281 | osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; | ||
1282 | |||
1268 | osb->node_num = O2NM_INVALID_NODE_NUM; | 1283 | osb->node_num = O2NM_INVALID_NODE_NUM; |
1269 | osb->slot_num = OCFS2_INVALID_SLOT; | 1284 | osb->slot_num = OCFS2_INVALID_SLOT; |
1270 | 1285 | ||