|
@@ -624,6 +624,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
|
|
|
{
|
|
|
struct gfs2_inode *ip = GFS2_I(mapping->host);
|
|
|
struct gfs2_sbd *sdp = GFS2_SB(mapping->host);
|
|
|
+ struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
|
|
|
unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
|
|
|
int alloc_required;
|
|
|
int error = 0;
|
|
@@ -637,6 +638,14 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
|
|
|
error = gfs2_glock_nq(&ip->i_gh);
|
|
|
if (unlikely(error))
|
|
|
goto out_uninit;
|
|
|
+ if (&ip->i_inode == sdp->sd_rindex) {
|
|
|
+ error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE,
|
|
|
+ GL_NOCACHE, &m_ip->i_gh);
|
|
|
+ if (unlikely(error)) {
|
|
|
+ gfs2_glock_dq(&ip->i_gh);
|
|
|
+ goto out_uninit;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
error = gfs2_write_alloc_required(ip, pos, len, &alloc_required);
|
|
|
if (error)
|
|
@@ -667,6 +676,8 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
|
|
|
rblocks += data_blocks ? data_blocks : 1;
|
|
|
if (ind_blocks || data_blocks)
|
|
|
rblocks += RES_STATFS + RES_QUOTA;
|
|
|
+ if (&ip->i_inode == sdp->sd_rindex)
|
|
|
+ rblocks += 2 * RES_STATFS;
|
|
|
|
|
|
error = gfs2_trans_begin(sdp, rblocks,
|
|
|
PAGE_CACHE_SIZE/sdp->sd_sb.sb_bsize);
|
|
@@ -712,6 +723,10 @@ out_alloc_put:
|
|
|
gfs2_alloc_put(ip);
|
|
|
}
|
|
|
out_unlock:
|
|
|
+ if (&ip->i_inode == sdp->sd_rindex) {
|
|
|
+ gfs2_glock_dq(&m_ip->i_gh);
|
|
|
+ gfs2_holder_uninit(&m_ip->i_gh);
|
|
|
+ }
|
|
|
gfs2_glock_dq(&ip->i_gh);
|
|
|
out_uninit:
|
|
|
gfs2_holder_uninit(&ip->i_gh);
|
|
@@ -725,14 +740,21 @@ out_uninit:
|
|
|
static void adjust_fs_space(struct inode *inode)
|
|
|
{
|
|
|
struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
|
|
|
+ struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
|
|
|
+ struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
|
|
|
struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
|
|
|
struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
|
|
|
+ struct buffer_head *m_bh, *l_bh;
|
|
|
u64 fs_total, new_free;
|
|
|
|
|
|
/* Total up the file system space, according to the latest rindex. */
|
|
|
fs_total = gfs2_ri_total(sdp);
|
|
|
+ if (gfs2_meta_inode_buffer(m_ip, &m_bh) != 0)
|
|
|
+ return;
|
|
|
|
|
|
spin_lock(&sdp->sd_statfs_spin);
|
|
|
+ gfs2_statfs_change_in(m_sc, m_bh->b_data +
|
|
|
+ sizeof(struct gfs2_dinode));
|
|
|
if (fs_total > (m_sc->sc_total + l_sc->sc_total))
|
|
|
new_free = fs_total - (m_sc->sc_total + l_sc->sc_total);
|
|
|
else
|
|
@@ -741,6 +763,13 @@ static void adjust_fs_space(struct inode *inode)
|
|
|
fs_warn(sdp, "File system extended by %llu blocks.\n",
|
|
|
(unsigned long long)new_free);
|
|
|
gfs2_statfs_change(sdp, new_free, new_free, 0);
|
|
|
+
|
|
|
+ if (gfs2_meta_inode_buffer(l_ip, &l_bh) != 0)
|
|
|
+ goto out;
|
|
|
+ update_statfs(sdp, m_bh, l_bh);
|
|
|
+ brelse(l_bh);
|
|
|
+out:
|
|
|
+ brelse(m_bh);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -763,6 +792,7 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
|
|
|
{
|
|
|
struct gfs2_inode *ip = GFS2_I(inode);
|
|
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
|
|
+ struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
|
|
|
u64 to = pos + copied;
|
|
|
void *kaddr;
|
|
|
unsigned char *buf = dibh->b_data + sizeof(struct gfs2_dinode);
|
|
@@ -794,6 +824,10 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
|
|
|
|
|
|
brelse(dibh);
|
|
|
gfs2_trans_end(sdp);
|
|
|
+ if (inode == sdp->sd_rindex) {
|
|
|
+ gfs2_glock_dq(&m_ip->i_gh);
|
|
|
+ gfs2_holder_uninit(&m_ip->i_gh);
|
|
|
+ }
|
|
|
gfs2_glock_dq(&ip->i_gh);
|
|
|
gfs2_holder_uninit(&ip->i_gh);
|
|
|
return copied;
|
|
@@ -823,6 +857,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
|
|
|
struct inode *inode = page->mapping->host;
|
|
|
struct gfs2_inode *ip = GFS2_I(inode);
|
|
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
|
|
+ struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
|
|
|
struct buffer_head *dibh;
|
|
|
struct gfs2_alloc *al = ip->i_alloc;
|
|
|
unsigned int from = pos & (PAGE_CACHE_SIZE - 1);
|
|
@@ -865,6 +900,10 @@ failed:
|
|
|
gfs2_quota_unlock(ip);
|
|
|
gfs2_alloc_put(ip);
|
|
|
}
|
|
|
+ if (inode == sdp->sd_rindex) {
|
|
|
+ gfs2_glock_dq(&m_ip->i_gh);
|
|
|
+ gfs2_holder_uninit(&m_ip->i_gh);
|
|
|
+ }
|
|
|
gfs2_glock_dq(&ip->i_gh);
|
|
|
gfs2_holder_uninit(&ip->i_gh);
|
|
|
return ret;
|