diff options
-rw-r--r-- | fs/gfs2/ops_address.c | 17 | ||||
-rw-r--r-- | fs/gfs2/ops_file.c | 14 | ||||
-rw-r--r-- | fs/gfs2/ops_file.h | 2 |
3 files changed, 25 insertions, 8 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 74706f352780..39d03f3f2d54 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c @@ -28,6 +28,7 @@ #include "quota.h" #include "trans.h" #include "rgrp.h" +#include "ops_file.h" /** * gfs2_get_block - Fills in a buffer head with details about a block @@ -267,10 +268,12 @@ static int gfs2_readpage(struct file *file, struct page *page) atomic_inc(&sdp->sd_ops_address); - gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); - error = gfs2_glock_nq_m_atime(1, &gh); - if (error) - goto out_unlock; + if (file != &gfs2_internal_file_sentinal) { + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); + error = gfs2_glock_nq_m_atime(1, &gh); + if (error) + goto out_unlock; + } if (gfs2_is_stuffed(ip)) { if (!page->index) { @@ -284,8 +287,10 @@ static int gfs2_readpage(struct file *file, struct page *page) if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) error = -EIO; - gfs2_glock_dq_m(1, &gh); - gfs2_holder_uninit(&gh); + if (file != &gfs2_internal_file_sentinal) { + gfs2_glock_dq_m(1, &gh); + gfs2_holder_uninit(&gh); + } out: return error; out_unlock: diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index bcde7a0b76f1..b86037832299 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c @@ -67,6 +67,16 @@ struct filldir_reg { void *fdr_opaque; }; +/* + * Most fields left uninitialised to catch anybody who tries to + * use them. f_flags set to prevent file_accessed() from touching + * any other part of this. Its use is purely as a flag so that we + * know (in readpage()) whether or not do to locking. + */ +struct file gfs2_internal_file_sentinal = { + .f_flags = O_NOATIME|O_RDONLY, +}; + static int gfs2_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset, unsigned long size) { @@ -95,7 +105,9 @@ int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state, desc.arg.buf = buf; desc.count = size; desc.error = 0; - do_generic_mapping_read(inode->i_mapping, ra_state, NULL, pos, &desc, gfs2_read_actor); + do_generic_mapping_read(inode->i_mapping, ra_state, + &gfs2_internal_file_sentinal, pos, &desc, + gfs2_read_actor); return desc.written ? desc.written : desc.error; } diff --git a/fs/gfs2/ops_file.h b/fs/gfs2/ops_file.h index 3c237bfc143d..192577b411f0 100644 --- a/fs/gfs2/ops_file.h +++ b/fs/gfs2/ops_file.h @@ -9,7 +9,7 @@ #ifndef __OPS_FILE_DOT_H__ #define __OPS_FILE_DOT_H__ - +extern struct file gfs2_internal_file_sentinal; extern int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state, char *buf, loff_t *pos, unsigned size); |