Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes
Browse files Browse the repository at this point in the history
Pull gfs2 fixes from Steven Whitehouse:
 "Here are a number of GFS2 bug fixes.  There are three from Andy Price
  which fix various issues spotted by automated code analysis.  There
  are two from Lukas Czerner fixing my mistaken assumptions as to how
  FITRIM should work.  Finally Ben Marzinski has fixed a bug relating to
  mmap and atime and also a bug relating to a locking issue in the
  transaction code."

* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes:
  GFS2: Test bufdata with buffer locked and gfs2_log_lock held
  GFS2: Don't call file_accessed() with a shared glock
  GFS2: Fix FITRIM argument handling
  GFS2: Require user to provide argument for FITRIM
  GFS2: Clean up some unused assignments
  GFS2: Fix possible null pointer deref in gfs2_rs_alloc
  GFS2: Fix an unchecked error from gfs2_rs_alloc
  • Loading branch information
Linus Torvalds committed Nov 7, 2012
2 parents 826389d + 96e5d1d commit 0e4a43e
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 38 deletions.
14 changes: 5 additions & 9 deletions fs/gfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,15 +516,13 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
struct gfs2_holder i_gh;
int error;

gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
error = gfs2_glock_nq(&i_gh);
if (error == 0) {
file_accessed(file);
gfs2_glock_dq(&i_gh);
}
gfs2_holder_uninit(&i_gh);
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
&i_gh);
if (error)
return error;
/* grab lock to update inode */
gfs2_glock_dq_uninit(&i_gh);
file_accessed(file);
}
vma->vm_ops = &gfs2_vm_ops;

Expand Down Expand Up @@ -677,10 +675,8 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
size_t writesize = iov_length(iov, nr_segs);
struct dentry *dentry = file->f_dentry;
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
struct gfs2_sbd *sdp;
int ret;

sdp = GFS2_SB(file->f_mapping->host);
ret = gfs2_rs_alloc(ip);
if (ret)
return ret;
Expand Down
16 changes: 2 additions & 14 deletions fs/gfs2/lops.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,12 +393,10 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
struct gfs2_meta_header *mh;
struct gfs2_trans *tr;

lock_buffer(bd->bd_bh);
gfs2_log_lock(sdp);
tr = current->journal_info;
tr->tr_touched = 1;
if (!list_empty(&bd->bd_list))
goto out;
return;
set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
mh = (struct gfs2_meta_header *)bd->bd_bh->b_data;
Expand All @@ -414,9 +412,6 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
sdp->sd_log_num_buf++;
list_add(&bd->bd_list, &sdp->sd_log_le_buf);
tr->tr_num_buf_new++;
out:
gfs2_log_unlock(sdp);
unlock_buffer(bd->bd_bh);
}

static void gfs2_check_magic(struct buffer_head *bh)
Expand Down Expand Up @@ -621,7 +616,6 @@ static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)

static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
{
struct gfs2_log_descriptor *ld;
struct gfs2_meta_header *mh;
unsigned int offset;
struct list_head *head = &sdp->sd_log_le_revoke;
Expand All @@ -634,7 +628,6 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)

length = gfs2_struct2blk(sdp, sdp->sd_log_num_revoke, sizeof(u64));
page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE, length, sdp->sd_log_num_revoke);
ld = page_address(page);
offset = sizeof(struct gfs2_log_descriptor);

list_for_each_entry(bd, head, bd_list) {
Expand Down Expand Up @@ -777,12 +770,10 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
struct address_space *mapping = bd->bd_bh->b_page->mapping;
struct gfs2_inode *ip = GFS2_I(mapping->host);

lock_buffer(bd->bd_bh);
gfs2_log_lock(sdp);
if (tr)
tr->tr_touched = 1;
if (!list_empty(&bd->bd_list))
goto out;
return;
set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
if (gfs2_is_jdata(ip)) {
Expand All @@ -793,9 +784,6 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
} else {
list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered);
}
out:
gfs2_log_unlock(sdp);
unlock_buffer(bd->bd_bh);
}

/**
Expand Down
7 changes: 5 additions & 2 deletions fs/gfs2/quota.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,11 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
struct gfs2_quota_data **qd;
int error;

if (ip->i_res == NULL)
gfs2_rs_alloc(ip);
if (ip->i_res == NULL) {
error = gfs2_rs_alloc(ip);
if (error)
return error;
}

qd = ip->i_res->rs_qa_qd;

Expand Down
33 changes: 21 additions & 12 deletions fs/gfs2/rgrp.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,15 +553,14 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd)
*/
int gfs2_rs_alloc(struct gfs2_inode *ip)
{
int error = 0;
struct gfs2_blkreserv *res;

if (ip->i_res)
return 0;

res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS);
if (!res)
error = -ENOMEM;
return -ENOMEM;

RB_CLEAR_NODE(&res->rs_node);

Expand All @@ -571,7 +570,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip)
else
ip->i_res = res;
up_write(&ip->i_rw_mutex);
return error;
return 0;
}

static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs)
Expand Down Expand Up @@ -1263,27 +1262,35 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
int ret = 0;
u64 amt;
u64 trimmed = 0;
u64 start, end, minlen;
unsigned int x;
unsigned bs_shift = sdp->sd_sb.sb_bsize_shift;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;

if (!blk_queue_discard(q))
return -EOPNOTSUPP;

if (argp == NULL) {
r.start = 0;
r.len = ULLONG_MAX;
r.minlen = 0;
} else if (copy_from_user(&r, argp, sizeof(r)))
if (copy_from_user(&r, argp, sizeof(r)))
return -EFAULT;

ret = gfs2_rindex_update(sdp);
if (ret)
return ret;

rgd = gfs2_blk2rgrpd(sdp, r.start, 0);
rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0);
start = r.start >> bs_shift;
end = start + (r.len >> bs_shift);
minlen = max_t(u64, r.minlen,
q->limits.discard_granularity) >> bs_shift;

rgd = gfs2_blk2rgrpd(sdp, start, 0);
rgd_end = gfs2_blk2rgrpd(sdp, end - 1, 0);

if (end <= start ||
minlen > sdp->sd_max_rg_data ||
start > rgd_end->rd_data0 + rgd_end->rd_data)
return -EINVAL;

while (1) {

Expand All @@ -1295,7 +1302,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
/* Trim each bitmap in the rgrp */
for (x = 0; x < rgd->rd_length; x++) {
struct gfs2_bitmap *bi = rgd->rd_bits + x;
ret = gfs2_rgrp_send_discards(sdp, rgd->rd_data0, NULL, bi, r.minlen, &amt);
ret = gfs2_rgrp_send_discards(sdp,
rgd->rd_data0, NULL, bi, minlen,
&amt);
if (ret) {
gfs2_glock_dq_uninit(&gh);
goto out;
Expand Down Expand Up @@ -1324,7 +1333,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp)

out:
r.len = trimmed << 9;
if (argp && copy_to_user(argp, &r, sizeof(r)))
if (copy_to_user(argp, &r, sizeof(r)))
return -EFAULT;

return ret;
Expand Down
3 changes: 2 additions & 1 deletion fs/gfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,8 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
return;
}
need_unlock = 1;
}
} else if (WARN_ON_ONCE(ip->i_gl->gl_state != LM_ST_EXCLUSIVE))
return;

if (current->journal_info == NULL) {
ret = gfs2_trans_begin(sdp, RES_DINODE, 0);
Expand Down
8 changes: 8 additions & 0 deletions fs/gfs2/trans.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,22 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta)
struct gfs2_sbd *sdp = gl->gl_sbd;
struct gfs2_bufdata *bd;

lock_buffer(bh);
gfs2_log_lock(sdp);
bd = bh->b_private;
if (bd)
gfs2_assert(sdp, bd->bd_gl == gl);
else {
gfs2_log_unlock(sdp);
unlock_buffer(bh);
gfs2_attach_bufdata(gl, bh, meta);
bd = bh->b_private;
lock_buffer(bh);
gfs2_log_lock(sdp);
}
lops_add(sdp, bd);
gfs2_log_unlock(sdp);
unlock_buffer(bh);
}

void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
Expand Down

0 comments on commit 0e4a43e

Please sign in to comment.