diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/glock.c | 2 | ||||
-rw-r--r-- | fs/gfs2/glock.h | 1 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 2 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 107 | ||||
-rw-r--r-- | fs/gfs2/inode.h | 1 | ||||
-rw-r--r-- | fs/gfs2/ops_address.c | 16 | ||||
-rw-r--r-- | fs/gfs2/ops_file.c | 16 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 23 | ||||
-rw-r--r-- | fs/gfs2/ops_super.c | 53 | ||||
-rw-r--r-- | fs/gfs2/sys.c | 11 |
10 files changed, 65 insertions, 167 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 806e1eb0aa0d..c962283d4e7f 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -1580,8 +1580,6 @@ static const char *hflags2str(char *buf, unsigned flags, unsigned long iflags) | |||
1580 | *p++ = 'a'; | 1580 | *p++ = 'a'; |
1581 | if (flags & GL_EXACT) | 1581 | if (flags & GL_EXACT) |
1582 | *p++ = 'E'; | 1582 | *p++ = 'E'; |
1583 | if (flags & GL_ATIME) | ||
1584 | *p++ = 'a'; | ||
1585 | if (flags & GL_NOCACHE) | 1583 | if (flags & GL_NOCACHE) |
1586 | *p++ = 'c'; | 1584 | *p++ = 'c'; |
1587 | if (test_bit(HIF_HOLDER, &iflags)) | 1585 | if (test_bit(HIF_HOLDER, &iflags)) |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 971d92af70fc..695c6b193611 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -24,7 +24,6 @@ | |||
24 | #define GL_ASYNC 0x00000040 | 24 | #define GL_ASYNC 0x00000040 |
25 | #define GL_EXACT 0x00000080 | 25 | #define GL_EXACT 0x00000080 |
26 | #define GL_SKIP 0x00000100 | 26 | #define GL_SKIP 0x00000100 |
27 | #define GL_ATIME 0x00000200 | ||
28 | #define GL_NOCACHE 0x00000400 | 27 | #define GL_NOCACHE 0x00000400 |
29 | 28 | ||
30 | #define GLR_TRYFAILED 13 | 29 | #define GLR_TRYFAILED 13 |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index b2c5784092cf..f1ed3a1bf8aa 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -420,7 +420,6 @@ struct gfs2_tune { | |||
420 | unsigned int gt_quota_scale_den; /* Denominator */ | 420 | unsigned int gt_quota_scale_den; /* Denominator */ |
421 | unsigned int gt_quota_cache_secs; | 421 | unsigned int gt_quota_cache_secs; |
422 | unsigned int gt_quota_quantum; /* Secs between syncs to quota file */ | 422 | unsigned int gt_quota_quantum; /* Secs between syncs to quota file */ |
423 | unsigned int gt_atime_quantum; /* Min secs between atime updates */ | ||
424 | unsigned int gt_new_files_jdata; | 423 | unsigned int gt_new_files_jdata; |
425 | unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */ | 424 | unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */ |
426 | unsigned int gt_stall_secs; /* Detects trouble! */ | 425 | unsigned int gt_stall_secs; /* Detects trouble! */ |
@@ -433,7 +432,6 @@ enum { | |||
433 | SDF_JOURNAL_CHECKED = 0, | 432 | SDF_JOURNAL_CHECKED = 0, |
434 | SDF_JOURNAL_LIVE = 1, | 433 | SDF_JOURNAL_LIVE = 1, |
435 | SDF_SHUTDOWN = 2, | 434 | SDF_SHUTDOWN = 2, |
436 | SDF_NOATIME = 3, | ||
437 | }; | 435 | }; |
438 | 436 | ||
439 | #define GFS2_FSNAME_LEN 256 | 437 | #define GFS2_FSNAME_LEN 256 |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index c8a959c09f1e..7cee695fa441 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/crc32.h> | 18 | #include <linux/crc32.h> |
19 | #include <linux/lm_interface.h> | 19 | #include <linux/lm_interface.h> |
20 | #include <linux/security.h> | 20 | #include <linux/security.h> |
21 | #include <linux/time.h> | ||
21 | 22 | ||
22 | #include "gfs2.h" | 23 | #include "gfs2.h" |
23 | #include "incore.h" | 24 | #include "incore.h" |
@@ -249,6 +250,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
249 | { | 250 | { |
250 | struct gfs2_dinode_host *di = &ip->i_di; | 251 | struct gfs2_dinode_host *di = &ip->i_di; |
251 | const struct gfs2_dinode *str = buf; | 252 | const struct gfs2_dinode *str = buf; |
253 | struct timespec atime; | ||
252 | u16 height, depth; | 254 | u16 height, depth; |
253 | 255 | ||
254 | if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) | 256 | if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) |
@@ -275,8 +277,10 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
275 | di->di_size = be64_to_cpu(str->di_size); | 277 | di->di_size = be64_to_cpu(str->di_size); |
276 | i_size_write(&ip->i_inode, di->di_size); | 278 | i_size_write(&ip->i_inode, di->di_size); |
277 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); | 279 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); |
278 | ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); | 280 | atime.tv_sec = be64_to_cpu(str->di_atime); |
279 | ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); | 281 | atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); |
282 | if (timespec_compare(&ip->i_inode.i_atime, &atime) < 0) | ||
283 | ip->i_inode.i_atime = atime; | ||
280 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); | 284 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); |
281 | ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); | 285 | ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); |
282 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); | 286 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); |
@@ -1157,8 +1161,8 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) | |||
1157 | unsigned int x; | 1161 | unsigned int x; |
1158 | int error; | 1162 | int error; |
1159 | 1163 | ||
1160 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); | 1164 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); |
1161 | error = gfs2_glock_nq_atime(&i_gh); | 1165 | error = gfs2_glock_nq(&i_gh); |
1162 | if (error) { | 1166 | if (error) { |
1163 | gfs2_holder_uninit(&i_gh); | 1167 | gfs2_holder_uninit(&i_gh); |
1164 | return error; | 1168 | return error; |
@@ -1193,101 +1197,6 @@ out: | |||
1193 | return error; | 1197 | return error; |
1194 | } | 1198 | } |
1195 | 1199 | ||
1196 | /** | ||
1197 | * gfs2_glock_nq_atime - Acquire a hold on an inode's glock, and | ||
1198 | * conditionally update the inode's atime | ||
1199 | * @gh: the holder to acquire | ||
1200 | * | ||
1201 | * Tests atime (access time) for gfs2_read, gfs2_readdir and gfs2_mmap | ||
1202 | * Update if the difference between the current time and the inode's current | ||
1203 | * atime is greater than an interval specified at mount. | ||
1204 | * | ||
1205 | * Returns: errno | ||
1206 | */ | ||
1207 | |||
1208 | int gfs2_glock_nq_atime(struct gfs2_holder *gh) | ||
1209 | { | ||
1210 | struct gfs2_glock *gl = gh->gh_gl; | ||
1211 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
1212 | struct gfs2_inode *ip = gl->gl_object; | ||
1213 | s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum); | ||
1214 | unsigned int state; | ||
1215 | int flags; | ||
1216 | int error; | ||
1217 | struct timespec tv = CURRENT_TIME; | ||
1218 | |||
1219 | if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) || | ||
1220 | gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) || | ||
1221 | gfs2_assert_warn(sdp, gl->gl_ops == &gfs2_inode_glops)) | ||
1222 | return -EINVAL; | ||
1223 | |||
1224 | state = gh->gh_state; | ||
1225 | flags = gh->gh_flags; | ||
1226 | |||
1227 | error = gfs2_glock_nq(gh); | ||
1228 | if (error) | ||
1229 | return error; | ||
1230 | |||
1231 | if (test_bit(SDF_NOATIME, &sdp->sd_flags) || | ||
1232 | (sdp->sd_vfs->s_flags & MS_RDONLY)) | ||
1233 | return 0; | ||
1234 | |||
1235 | if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { | ||
1236 | gfs2_glock_dq(gh); | ||
1237 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, | ||
1238 | gh); | ||
1239 | error = gfs2_glock_nq(gh); | ||
1240 | if (error) | ||
1241 | return error; | ||
1242 | |||
1243 | /* Verify that atime hasn't been updated while we were | ||
1244 | trying to get exclusive lock. */ | ||
1245 | |||
1246 | tv = CURRENT_TIME; | ||
1247 | if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { | ||
1248 | struct buffer_head *dibh; | ||
1249 | struct gfs2_dinode *di; | ||
1250 | |||
1251 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); | ||
1252 | if (error == -EROFS) | ||
1253 | return 0; | ||
1254 | if (error) | ||
1255 | goto fail; | ||
1256 | |||
1257 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
1258 | if (error) | ||
1259 | goto fail_end_trans; | ||
1260 | |||
1261 | ip->i_inode.i_atime = tv; | ||
1262 | |||
1263 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
1264 | di = (struct gfs2_dinode *)dibh->b_data; | ||
1265 | di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); | ||
1266 | di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); | ||
1267 | brelse(dibh); | ||
1268 | |||
1269 | gfs2_trans_end(sdp); | ||
1270 | } | ||
1271 | |||
1272 | /* If someone else has asked for the glock, | ||
1273 | unlock and let them have it. Then reacquire | ||
1274 | in the original state. */ | ||
1275 | if (gfs2_glock_is_blocking(gl)) { | ||
1276 | gfs2_glock_dq(gh); | ||
1277 | gfs2_holder_reinit(state, flags, gh); | ||
1278 | return gfs2_glock_nq(gh); | ||
1279 | } | ||
1280 | } | ||
1281 | |||
1282 | return 0; | ||
1283 | |||
1284 | fail_end_trans: | ||
1285 | gfs2_trans_end(sdp); | ||
1286 | fail: | ||
1287 | gfs2_glock_dq(gh); | ||
1288 | return error; | ||
1289 | } | ||
1290 | |||
1291 | static int | 1200 | static int |
1292 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 1201 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1293 | { | 1202 | { |
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index bfd2afc0c906..2d43f69610a0 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -92,7 +92,6 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
92 | const struct gfs2_inode *ip); | 92 | const struct gfs2_inode *ip); |
93 | int gfs2_permission(struct inode *inode, int mask); | 93 | int gfs2_permission(struct inode *inode, int mask); |
94 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); | 94 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); |
95 | int gfs2_glock_nq_atime(struct gfs2_holder *gh); | ||
96 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); | 95 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); |
97 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | 96 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); |
98 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); | 97 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); |
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index ae7126aeb447..27563816e1c5 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -512,8 +512,8 @@ static int gfs2_readpage(struct file *file, struct page *page) | |||
512 | int error; | 512 | int error; |
513 | 513 | ||
514 | unlock_page(page); | 514 | unlock_page(page); |
515 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); | 515 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh); |
516 | error = gfs2_glock_nq_atime(&gh); | 516 | error = gfs2_glock_nq(&gh); |
517 | if (unlikely(error)) | 517 | if (unlikely(error)) |
518 | goto out; | 518 | goto out; |
519 | error = AOP_TRUNCATED_PAGE; | 519 | error = AOP_TRUNCATED_PAGE; |
@@ -594,8 +594,8 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping, | |||
594 | struct gfs2_holder gh; | 594 | struct gfs2_holder gh; |
595 | int ret; | 595 | int ret; |
596 | 596 | ||
597 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); | 597 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh); |
598 | ret = gfs2_glock_nq_atime(&gh); | 598 | ret = gfs2_glock_nq(&gh); |
599 | if (unlikely(ret)) | 599 | if (unlikely(ret)) |
600 | goto out_uninit; | 600 | goto out_uninit; |
601 | if (!gfs2_is_stuffed(ip)) | 601 | if (!gfs2_is_stuffed(ip)) |
@@ -636,8 +636,8 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, | |||
636 | unsigned to = from + len; | 636 | unsigned to = from + len; |
637 | struct page *page; | 637 | struct page *page; |
638 | 638 | ||
639 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME, &ip->i_gh); | 639 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); |
640 | error = gfs2_glock_nq_atime(&ip->i_gh); | 640 | error = gfs2_glock_nq(&ip->i_gh); |
641 | if (unlikely(error)) | 641 | if (unlikely(error)) |
642 | goto out_uninit; | 642 | goto out_uninit; |
643 | 643 | ||
@@ -1000,8 +1000,8 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, | |||
1000 | * unfortunately have the option of only flushing a range like | 1000 | * unfortunately have the option of only flushing a range like |
1001 | * the VFS does. | 1001 | * the VFS does. |
1002 | */ | 1002 | */ |
1003 | gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, GL_ATIME, &gh); | 1003 | gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, 0, &gh); |
1004 | rv = gfs2_glock_nq_atime(&gh); | 1004 | rv = gfs2_glock_nq(&gh); |
1005 | if (rv) | 1005 | if (rv) |
1006 | return rv; | 1006 | return rv; |
1007 | rv = gfs2_ok_for_dio(ip, rw, offset); | 1007 | rv = gfs2_ok_for_dio(ip, rw, offset); |
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index e9a366d4411c..3a747f8e2188 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -89,8 +89,8 @@ static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
89 | u64 offset = file->f_pos; | 89 | u64 offset = file->f_pos; |
90 | int error; | 90 | int error; |
91 | 91 | ||
92 | gfs2_holder_init(dip->i_gl, LM_ST_SHARED, GL_ATIME, &d_gh); | 92 | gfs2_holder_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); |
93 | error = gfs2_glock_nq_atime(&d_gh); | 93 | error = gfs2_glock_nq(&d_gh); |
94 | if (error) { | 94 | if (error) { |
95 | gfs2_holder_uninit(&d_gh); | 95 | gfs2_holder_uninit(&d_gh); |
96 | return error; | 96 | return error; |
@@ -153,8 +153,8 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
153 | int error; | 153 | int error; |
154 | u32 fsflags; | 154 | u32 fsflags; |
155 | 155 | ||
156 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); | 156 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh); |
157 | error = gfs2_glock_nq_atime(&gh); | 157 | error = gfs2_glock_nq(&gh); |
158 | if (error) | 158 | if (error) |
159 | return error; | 159 | return error; |
160 | 160 | ||
@@ -351,8 +351,8 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
351 | struct gfs2_alloc *al; | 351 | struct gfs2_alloc *al; |
352 | int ret; | 352 | int ret; |
353 | 353 | ||
354 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME, &gh); | 354 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
355 | ret = gfs2_glock_nq_atime(&gh); | 355 | ret = gfs2_glock_nq(&gh); |
356 | if (ret) | 356 | if (ret) |
357 | goto out; | 357 | goto out; |
358 | 358 | ||
@@ -434,8 +434,8 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma) | |||
434 | struct gfs2_holder i_gh; | 434 | struct gfs2_holder i_gh; |
435 | int error; | 435 | int error; |
436 | 436 | ||
437 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); | 437 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); |
438 | error = gfs2_glock_nq_atime(&i_gh); | 438 | error = gfs2_glock_nq(&i_gh); |
439 | if (error) { | 439 | if (error) { |
440 | gfs2_holder_uninit(&i_gh); | 440 | gfs2_holder_uninit(&i_gh); |
441 | return error; | 441 | return error; |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index ae35f097aa6a..b117fcf2c4f5 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -70,7 +70,6 @@ static void gfs2_tune_init(struct gfs2_tune *gt) | |||
70 | gt->gt_quota_scale_den = 1; | 70 | gt->gt_quota_scale_den = 1; |
71 | gt->gt_quota_cache_secs = 300; | 71 | gt->gt_quota_cache_secs = 300; |
72 | gt->gt_quota_quantum = 60; | 72 | gt->gt_quota_quantum = 60; |
73 | gt->gt_atime_quantum = 3600; | ||
74 | gt->gt_new_files_jdata = 0; | 73 | gt->gt_new_files_jdata = 0; |
75 | gt->gt_max_readahead = 1 << 18; | 74 | gt->gt_max_readahead = 1 << 18; |
76 | gt->gt_stall_secs = 600; | 75 | gt->gt_stall_secs = 600; |
@@ -135,22 +134,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
135 | return sdp; | 134 | return sdp; |
136 | } | 135 | } |
137 | 136 | ||
138 | static void init_vfs(struct super_block *sb, unsigned noatime) | ||
139 | { | ||
140 | struct gfs2_sbd *sdp = sb->s_fs_info; | ||
141 | |||
142 | sb->s_magic = GFS2_MAGIC; | ||
143 | sb->s_op = &gfs2_super_ops; | ||
144 | sb->s_export_op = &gfs2_export_ops; | ||
145 | sb->s_time_gran = 1; | ||
146 | sb->s_maxbytes = MAX_LFS_FILESIZE; | ||
147 | |||
148 | if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME)) | ||
149 | set_bit(noatime, &sdp->sd_flags); | ||
150 | |||
151 | /* Don't let the VFS update atimes. GFS2 handles this itself. */ | ||
152 | sb->s_flags |= MS_NOATIME | MS_NODIRATIME; | ||
153 | } | ||
154 | 137 | ||
155 | /** | 138 | /** |
156 | * gfs2_check_sb - Check superblock | 139 | * gfs2_check_sb - Check superblock |
@@ -1100,7 +1083,11 @@ static int fill_super(struct super_block *sb, void *data, int silent) | |||
1100 | goto fail; | 1083 | goto fail; |
1101 | } | 1084 | } |
1102 | 1085 | ||
1103 | init_vfs(sb, SDF_NOATIME); | 1086 | sb->s_magic = GFS2_MAGIC; |
1087 | sb->s_op = &gfs2_super_ops; | ||
1088 | sb->s_export_op = &gfs2_export_ops; | ||
1089 | sb->s_time_gran = 1; | ||
1090 | sb->s_maxbytes = MAX_LFS_FILESIZE; | ||
1104 | 1091 | ||
1105 | /* Set up the buffer cache and fill in some fake block size values | 1092 | /* Set up the buffer cache and fill in some fake block size values |
1106 | to allow us to read-in the on-disk superblock. */ | 1093 | to allow us to read-in the on-disk superblock. */ |
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index 8f332d26b5dd..d5355d9b5926 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/gfs2_ondisk.h> | 20 | #include <linux/gfs2_ondisk.h> |
21 | #include <linux/crc32.h> | 21 | #include <linux/crc32.h> |
22 | #include <linux/lm_interface.h> | 22 | #include <linux/lm_interface.h> |
23 | #include <linux/time.h> | ||
23 | 24 | ||
24 | #include "gfs2.h" | 25 | #include "gfs2.h" |
25 | #include "incore.h" | 26 | #include "incore.h" |
@@ -38,6 +39,7 @@ | |||
38 | #include "dir.h" | 39 | #include "dir.h" |
39 | #include "eattr.h" | 40 | #include "eattr.h" |
40 | #include "bmap.h" | 41 | #include "bmap.h" |
42 | #include "meta_io.h" | ||
41 | 43 | ||
42 | /** | 44 | /** |
43 | * gfs2_write_inode - Make sure the inode is stable on the disk | 45 | * gfs2_write_inode - Make sure the inode is stable on the disk |
@@ -50,16 +52,41 @@ | |||
50 | static int gfs2_write_inode(struct inode *inode, int sync) | 52 | static int gfs2_write_inode(struct inode *inode, int sync) |
51 | { | 53 | { |
52 | struct gfs2_inode *ip = GFS2_I(inode); | 54 | struct gfs2_inode *ip = GFS2_I(inode); |
53 | 55 | struct gfs2_sbd *sdp = GFS2_SB(inode); | |
54 | /* Check this is a "normal" inode */ | 56 | struct gfs2_holder gh; |
55 | if (test_bit(GIF_USER, &ip->i_flags)) { | 57 | struct buffer_head *bh; |
56 | if (current->flags & PF_MEMALLOC) | 58 | struct timespec atime; |
57 | return 0; | 59 | struct gfs2_dinode *di; |
58 | if (sync) | 60 | int ret = 0; |
59 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); | 61 | |
62 | /* Check this is a "normal" inode, etc */ | ||
63 | if (!test_bit(GIF_USER, &ip->i_flags) || | ||
64 | (current->flags & PF_MEMALLOC)) | ||
65 | return 0; | ||
66 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
67 | if (ret) | ||
68 | goto do_flush; | ||
69 | ret = gfs2_trans_begin(sdp, RES_DINODE, 0); | ||
70 | if (ret) | ||
71 | goto do_unlock; | ||
72 | ret = gfs2_meta_inode_buffer(ip, &bh); | ||
73 | if (ret == 0) { | ||
74 | di = (struct gfs2_dinode *)bh->b_data; | ||
75 | atime.tv_sec = be64_to_cpu(di->di_atime); | ||
76 | atime.tv_nsec = be32_to_cpu(di->di_atime_nsec); | ||
77 | if (timespec_compare(&inode->i_atime, &atime) > 0) { | ||
78 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | ||
79 | gfs2_dinode_out(ip, bh->b_data); | ||
80 | } | ||
81 | brelse(bh); | ||
60 | } | 82 | } |
61 | 83 | gfs2_trans_end(sdp); | |
62 | return 0; | 84 | do_unlock: |
85 | gfs2_glock_dq_uninit(&gh); | ||
86 | do_flush: | ||
87 | if (sync != 0) | ||
88 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); | ||
89 | return ret; | ||
63 | } | 90 | } |
64 | 91 | ||
65 | /** | 92 | /** |
@@ -297,14 +324,6 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | |||
297 | } | 324 | } |
298 | } | 325 | } |
299 | 326 | ||
300 | if (*flags & (MS_NOATIME | MS_NODIRATIME)) | ||
301 | set_bit(SDF_NOATIME, &sdp->sd_flags); | ||
302 | else | ||
303 | clear_bit(SDF_NOATIME, &sdp->sd_flags); | ||
304 | |||
305 | /* Don't let the VFS update atimes. GFS2 handles this itself. */ | ||
306 | *flags |= MS_NOATIME | MS_NODIRATIME; | ||
307 | |||
308 | return error; | 327 | return error; |
309 | } | 328 | } |
310 | 329 | ||
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 74846559fc3f..7e1879f1a02c 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -269,14 +269,6 @@ ARGS_ATTR(quota, "%u\n"); | |||
269 | ARGS_ATTR(suiddir, "%d\n"); | 269 | ARGS_ATTR(suiddir, "%d\n"); |
270 | ARGS_ATTR(data, "%d\n"); | 270 | ARGS_ATTR(data, "%d\n"); |
271 | 271 | ||
272 | /* one oddball doesn't fit the macro mold */ | ||
273 | static ssize_t noatime_show(struct gfs2_sbd *sdp, char *buf) | ||
274 | { | ||
275 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
276 | !!test_bit(SDF_NOATIME, &sdp->sd_flags)); | ||
277 | } | ||
278 | static struct args_attr args_attr_noatime = __ATTR_RO(noatime); | ||
279 | |||
280 | static struct attribute *args_attrs[] = { | 272 | static struct attribute *args_attrs[] = { |
281 | &args_attr_lockproto.attr, | 273 | &args_attr_lockproto.attr, |
282 | &args_attr_locktable.attr, | 274 | &args_attr_locktable.attr, |
@@ -292,7 +284,6 @@ static struct attribute *args_attrs[] = { | |||
292 | &args_attr_quota.attr, | 284 | &args_attr_quota.attr, |
293 | &args_attr_suiddir.attr, | 285 | &args_attr_suiddir.attr, |
294 | &args_attr_data.attr, | 286 | &args_attr_data.attr, |
295 | &args_attr_noatime.attr, | ||
296 | NULL, | 287 | NULL, |
297 | }; | 288 | }; |
298 | 289 | ||
@@ -407,7 +398,6 @@ TUNE_ATTR(incore_log_blocks, 0); | |||
407 | TUNE_ATTR(log_flush_secs, 0); | 398 | TUNE_ATTR(log_flush_secs, 0); |
408 | TUNE_ATTR(quota_warn_period, 0); | 399 | TUNE_ATTR(quota_warn_period, 0); |
409 | TUNE_ATTR(quota_quantum, 0); | 400 | TUNE_ATTR(quota_quantum, 0); |
410 | TUNE_ATTR(atime_quantum, 0); | ||
411 | TUNE_ATTR(max_readahead, 0); | 401 | TUNE_ATTR(max_readahead, 0); |
412 | TUNE_ATTR(complain_secs, 0); | 402 | TUNE_ATTR(complain_secs, 0); |
413 | TUNE_ATTR(statfs_slow, 0); | 403 | TUNE_ATTR(statfs_slow, 0); |
@@ -427,7 +417,6 @@ static struct attribute *tune_attrs[] = { | |||
427 | &tune_attr_log_flush_secs.attr, | 417 | &tune_attr_log_flush_secs.attr, |
428 | &tune_attr_quota_warn_period.attr, | 418 | &tune_attr_quota_warn_period.attr, |
429 | &tune_attr_quota_quantum.attr, | 419 | &tune_attr_quota_quantum.attr, |
430 | &tune_attr_atime_quantum.attr, | ||
431 | &tune_attr_max_readahead.attr, | 420 | &tune_attr_max_readahead.attr, |
432 | &tune_attr_complain_secs.attr, | 421 | &tune_attr_complain_secs.attr, |
433 | &tune_attr_statfs_slow.attr, | 422 | &tune_attr_statfs_slow.attr, |