aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/dlmglue.c39
-rw-r--r--fs/ocfs2/dlmglue.h3
-rw-r--r--fs/ocfs2/file.c52
-rw-r--r--fs/ocfs2/file.h5
-rw-r--r--fs/ocfs2/inode.c1
-rw-r--r--fs/ocfs2/ocfs2.h2
-rw-r--r--fs/ocfs2/super.c15
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
1727int 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
1726void ocfs2_meta_unlock(struct inode *inode, 1765void 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);
81int ocfs2_rw_lock(struct inode *inode, int write); 81int ocfs2_rw_lock(struct inode *inode, int write);
82void ocfs2_rw_unlock(struct inode *inode, int write); 82void ocfs2_rw_unlock(struct inode *inode, int write);
83int ocfs2_meta_lock_atime(struct inode *inode,
84 struct vfsmount *vfsmnt,
85 int *level);
83int ocfs2_meta_lock_full(struct inode *inode, 86int 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
139int 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
163int 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);
185out:
186 mlog_exit(ret);
187 return ret;
188}
189
138int ocfs2_set_inode_size(handle_t *handle, 190int 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
57int ocfs2_should_update_atime(struct inode *inode,
58 struct vfsmount *vfsmnt);
59int 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;
366bail: 365bail:
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
184struct ocfs2_journal; 185struct ocfs2_journal;
185struct ocfs2_super 186struct 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