|
@@ -117,12 +117,14 @@ static void gfs2_pte_inval(struct gfs2_glock *gl)
|
|
|
|
|
|
static void meta_go_sync(struct gfs2_glock *gl)
|
|
static void meta_go_sync(struct gfs2_glock *gl)
|
|
{
|
|
{
|
|
|
|
+ if (gl->gl_state != LM_ST_EXCLUSIVE)
|
|
|
|
+ return;
|
|
|
|
+
|
|
if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) {
|
|
if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) {
|
|
gfs2_log_flush(gl->gl_sbd, gl);
|
|
gfs2_log_flush(gl->gl_sbd, gl);
|
|
gfs2_meta_sync(gl);
|
|
gfs2_meta_sync(gl);
|
|
gfs2_ail_empty_gl(gl);
|
|
gfs2_ail_empty_gl(gl);
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -141,6 +143,37 @@ static void meta_go_inval(struct gfs2_glock *gl, int flags)
|
|
gl->gl_vn++;
|
|
gl->gl_vn++;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * inode_go_sync - Sync the dirty data and/or metadata for an inode glock
|
|
|
|
+ * @gl: the glock protecting the inode
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+static void inode_go_sync(struct gfs2_glock *gl)
|
|
|
|
+{
|
|
|
|
+ struct gfs2_inode *ip = gl->gl_object;
|
|
|
|
+
|
|
|
|
+ if (ip && !S_ISREG(ip->i_inode.i_mode))
|
|
|
|
+ ip = NULL;
|
|
|
|
+
|
|
|
|
+ if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
|
|
|
|
+ gfs2_log_flush(gl->gl_sbd, gl);
|
|
|
|
+ if (ip)
|
|
|
|
+ filemap_fdatawrite(ip->i_inode.i_mapping);
|
|
|
|
+ gfs2_meta_sync(gl);
|
|
|
|
+ if (ip) {
|
|
|
|
+ struct address_space *mapping = ip->i_inode.i_mapping;
|
|
|
|
+ int error = filemap_fdatawait(mapping);
|
|
|
|
+ if (error == -ENOSPC)
|
|
|
|
+ set_bit(AS_ENOSPC, &mapping->flags);
|
|
|
|
+ else if (error)
|
|
|
|
+ set_bit(AS_EIO, &mapping->flags);
|
|
|
|
+ }
|
|
|
|
+ clear_bit(GLF_DIRTY, &gl->gl_flags);
|
|
|
|
+ gfs2_ail_empty_gl(gl);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* inode_go_xmote_th - promote/demote a glock
|
|
* inode_go_xmote_th - promote/demote a glock
|
|
* @gl: the glock
|
|
* @gl: the glock
|
|
@@ -149,12 +182,12 @@ static void meta_go_inval(struct gfs2_glock *gl, int flags)
|
|
*
|
|
*
|
|
*/
|
|
*/
|
|
|
|
|
|
-static void inode_go_xmote_th(struct gfs2_glock *gl, unsigned int state,
|
|
|
|
- int flags)
|
|
|
|
|
|
+static void inode_go_xmote_th(struct gfs2_glock *gl)
|
|
{
|
|
{
|
|
if (gl->gl_state != LM_ST_UNLOCKED)
|
|
if (gl->gl_state != LM_ST_UNLOCKED)
|
|
gfs2_pte_inval(gl);
|
|
gfs2_pte_inval(gl);
|
|
- gfs2_glock_xmote_th(gl, state, flags);
|
|
|
|
|
|
+ if (gl->gl_state == LM_ST_EXCLUSIVE)
|
|
|
|
+ inode_go_sync(gl);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -189,38 +222,8 @@ static void inode_go_xmote_bh(struct gfs2_glock *gl)
|
|
static void inode_go_drop_th(struct gfs2_glock *gl)
|
|
static void inode_go_drop_th(struct gfs2_glock *gl)
|
|
{
|
|
{
|
|
gfs2_pte_inval(gl);
|
|
gfs2_pte_inval(gl);
|
|
- gfs2_glock_drop_th(gl);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * inode_go_sync - Sync the dirty data and/or metadata for an inode glock
|
|
|
|
- * @gl: the glock protecting the inode
|
|
|
|
- *
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-static void inode_go_sync(struct gfs2_glock *gl)
|
|
|
|
-{
|
|
|
|
- struct gfs2_inode *ip = gl->gl_object;
|
|
|
|
-
|
|
|
|
- if (ip && !S_ISREG(ip->i_inode.i_mode))
|
|
|
|
- ip = NULL;
|
|
|
|
-
|
|
|
|
- if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
|
|
|
|
- gfs2_log_flush(gl->gl_sbd, gl);
|
|
|
|
- if (ip)
|
|
|
|
- filemap_fdatawrite(ip->i_inode.i_mapping);
|
|
|
|
- gfs2_meta_sync(gl);
|
|
|
|
- if (ip) {
|
|
|
|
- struct address_space *mapping = ip->i_inode.i_mapping;
|
|
|
|
- int error = filemap_fdatawait(mapping);
|
|
|
|
- if (error == -ENOSPC)
|
|
|
|
- set_bit(AS_ENOSPC, &mapping->flags);
|
|
|
|
- else if (error)
|
|
|
|
- set_bit(AS_EIO, &mapping->flags);
|
|
|
|
- }
|
|
|
|
- clear_bit(GLF_DIRTY, &gl->gl_flags);
|
|
|
|
- gfs2_ail_empty_gl(gl);
|
|
|
|
- }
|
|
|
|
|
|
+ if (gl->gl_state == LM_ST_EXCLUSIVE)
|
|
|
|
+ inode_go_sync(gl);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -365,8 +368,7 @@ static void rgrp_go_unlock(struct gfs2_holder *gh)
|
|
*
|
|
*
|
|
*/
|
|
*/
|
|
|
|
|
|
-static void trans_go_xmote_th(struct gfs2_glock *gl, unsigned int state,
|
|
|
|
- int flags)
|
|
|
|
|
|
+static void trans_go_xmote_th(struct gfs2_glock *gl)
|
|
{
|
|
{
|
|
struct gfs2_sbd *sdp = gl->gl_sbd;
|
|
struct gfs2_sbd *sdp = gl->gl_sbd;
|
|
|
|
|
|
@@ -375,8 +377,6 @@ static void trans_go_xmote_th(struct gfs2_glock *gl, unsigned int state,
|
|
gfs2_meta_syncfs(sdp);
|
|
gfs2_meta_syncfs(sdp);
|
|
gfs2_log_shutdown(sdp);
|
|
gfs2_log_shutdown(sdp);
|
|
}
|
|
}
|
|
-
|
|
|
|
- gfs2_glock_xmote_th(gl, state, flags);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -428,8 +428,6 @@ static void trans_go_drop_th(struct gfs2_glock *gl)
|
|
gfs2_meta_syncfs(sdp);
|
|
gfs2_meta_syncfs(sdp);
|
|
gfs2_log_shutdown(sdp);
|
|
gfs2_log_shutdown(sdp);
|
|
}
|
|
}
|
|
-
|
|
|
|
- gfs2_glock_drop_th(gl);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -445,8 +443,8 @@ static int quota_go_demote_ok(struct gfs2_glock *gl)
|
|
}
|
|
}
|
|
|
|
|
|
const struct gfs2_glock_operations gfs2_meta_glops = {
|
|
const struct gfs2_glock_operations gfs2_meta_glops = {
|
|
- .go_xmote_th = gfs2_glock_xmote_th,
|
|
|
|
- .go_drop_th = gfs2_glock_drop_th,
|
|
|
|
|
|
+ .go_xmote_th = meta_go_sync,
|
|
|
|
+ .go_drop_th = meta_go_sync,
|
|
.go_type = LM_TYPE_META,
|
|
.go_type = LM_TYPE_META,
|
|
};
|
|
};
|
|
|
|
|
|
@@ -454,7 +452,6 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
|
|
.go_xmote_th = inode_go_xmote_th,
|
|
.go_xmote_th = inode_go_xmote_th,
|
|
.go_xmote_bh = inode_go_xmote_bh,
|
|
.go_xmote_bh = inode_go_xmote_bh,
|
|
.go_drop_th = inode_go_drop_th,
|
|
.go_drop_th = inode_go_drop_th,
|
|
- .go_sync = inode_go_sync,
|
|
|
|
.go_inval = inode_go_inval,
|
|
.go_inval = inode_go_inval,
|
|
.go_demote_ok = inode_go_demote_ok,
|
|
.go_demote_ok = inode_go_demote_ok,
|
|
.go_lock = inode_go_lock,
|
|
.go_lock = inode_go_lock,
|
|
@@ -463,9 +460,6 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
|
|
};
|
|
};
|
|
|
|
|
|
const struct gfs2_glock_operations gfs2_rgrp_glops = {
|
|
const struct gfs2_glock_operations gfs2_rgrp_glops = {
|
|
- .go_xmote_th = gfs2_glock_xmote_th,
|
|
|
|
- .go_drop_th = gfs2_glock_drop_th,
|
|
|
|
- .go_sync = meta_go_sync,
|
|
|
|
.go_inval = meta_go_inval,
|
|
.go_inval = meta_go_inval,
|
|
.go_demote_ok = rgrp_go_demote_ok,
|
|
.go_demote_ok = rgrp_go_demote_ok,
|
|
.go_lock = rgrp_go_lock,
|
|
.go_lock = rgrp_go_lock,
|
|
@@ -481,33 +475,23 @@ const struct gfs2_glock_operations gfs2_trans_glops = {
|
|
};
|
|
};
|
|
|
|
|
|
const struct gfs2_glock_operations gfs2_iopen_glops = {
|
|
const struct gfs2_glock_operations gfs2_iopen_glops = {
|
|
- .go_xmote_th = gfs2_glock_xmote_th,
|
|
|
|
- .go_drop_th = gfs2_glock_drop_th,
|
|
|
|
.go_type = LM_TYPE_IOPEN,
|
|
.go_type = LM_TYPE_IOPEN,
|
|
};
|
|
};
|
|
|
|
|
|
const struct gfs2_glock_operations gfs2_flock_glops = {
|
|
const struct gfs2_glock_operations gfs2_flock_glops = {
|
|
- .go_xmote_th = gfs2_glock_xmote_th,
|
|
|
|
- .go_drop_th = gfs2_glock_drop_th,
|
|
|
|
.go_type = LM_TYPE_FLOCK,
|
|
.go_type = LM_TYPE_FLOCK,
|
|
};
|
|
};
|
|
|
|
|
|
const struct gfs2_glock_operations gfs2_nondisk_glops = {
|
|
const struct gfs2_glock_operations gfs2_nondisk_glops = {
|
|
- .go_xmote_th = gfs2_glock_xmote_th,
|
|
|
|
- .go_drop_th = gfs2_glock_drop_th,
|
|
|
|
.go_type = LM_TYPE_NONDISK,
|
|
.go_type = LM_TYPE_NONDISK,
|
|
};
|
|
};
|
|
|
|
|
|
const struct gfs2_glock_operations gfs2_quota_glops = {
|
|
const struct gfs2_glock_operations gfs2_quota_glops = {
|
|
- .go_xmote_th = gfs2_glock_xmote_th,
|
|
|
|
- .go_drop_th = gfs2_glock_drop_th,
|
|
|
|
.go_demote_ok = quota_go_demote_ok,
|
|
.go_demote_ok = quota_go_demote_ok,
|
|
.go_type = LM_TYPE_QUOTA,
|
|
.go_type = LM_TYPE_QUOTA,
|
|
};
|
|
};
|
|
|
|
|
|
const struct gfs2_glock_operations gfs2_journal_glops = {
|
|
const struct gfs2_glock_operations gfs2_journal_glops = {
|
|
- .go_xmote_th = gfs2_glock_xmote_th,
|
|
|
|
- .go_drop_th = gfs2_glock_drop_th,
|
|
|
|
.go_type = LM_TYPE_JOURNAL,
|
|
.go_type = LM_TYPE_JOURNAL,
|
|
};
|
|
};
|
|
|
|
|