Merge tag 'gfs2-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/steve...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 11 Oct 2014 12:00:16 +0000 (08:00 -0400)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 11 Oct 2014 12:00:16 +0000 (08:00 -0400)
Pull gfs2 updates from Steven Whitehouse:
 "This time we have a couple of bug fixes, one relating to bad i_goal
  values which are now ignored (i_goal is basically a hint so it is safe
  to so this) and another relating to the saving of the dirent location
  during rename.

  There is one performance improvement, which is an optimisation in
  rgblk_free so that multiple block deallocations will now be more
  efficient, and one clean up patch to use _RET_IP_ rather than writing
  it out longhand"

* tag 'gfs2-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw:
  GFS2: use _RET_IP_ instead of (unsigned long)__builtin_return_address(0)
  GFS2: Use gfs2_rbm_incr in rgblk_free
  GFS2: Make rename not save dirent location
  GFS2: fix bad inode i_goal values during block allocation

fs/gfs2/dir.c
fs/gfs2/dir.h
fs/gfs2/glock.c
fs/gfs2/glops.c
fs/gfs2/inode.c
fs/gfs2/rgrp.c
fs/gfs2/rgrp.h
fs/gfs2/trans.c

index 1a349f9a9685a88c7dc67141ed0cee0c2374fec9..5d4261ff5d23ac98e83498e17fdcd3a7b7fa0d06 100644 (file)
@@ -2100,8 +2100,13 @@ int gfs2_diradd_alloc_required(struct inode *inode, const struct qstr *name,
        }
        if (IS_ERR(dent))
                return PTR_ERR(dent);
-       da->bh = bh;
-       da->dent = dent;
+
+       if (da->save_loc) {
+               da->bh = bh;
+               da->dent = dent;
+       } else {
+               brelse(bh);
+       }
        return 0;
 }
 
index 126c65dda0284080eb71a2eec146782745c8ee63..e1b309c24dab3417c513daf58bab3dd6f73ea884 100644 (file)
@@ -23,6 +23,7 @@ struct gfs2_diradd {
        unsigned nr_blocks;
        struct gfs2_dirent *dent;
        struct buffer_head *bh;
+       int save_loc;
 };
 
 extern struct inode *gfs2_dir_search(struct inode *dir,
index 7f513b1ceb2c7adc024b2dee16321a5c4d06b733..8f0c19d1d9439e3827ffd649e7f7d43f096afc89 100644 (file)
@@ -811,7 +811,7 @@ void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags,
 {
        INIT_LIST_HEAD(&gh->gh_list);
        gh->gh_gl = gl;
-       gh->gh_ip = (unsigned long)__builtin_return_address(0);
+       gh->gh_ip = _RET_IP_;
        gh->gh_owner_pid = get_pid(task_pid(current));
        gh->gh_state = state;
        gh->gh_flags = flags;
@@ -835,7 +835,7 @@ void gfs2_holder_reinit(unsigned int state, unsigned flags, struct gfs2_holder *
        gh->gh_state = state;
        gh->gh_flags = flags;
        gh->gh_iflags = 0;
-       gh->gh_ip = (unsigned long)__builtin_return_address(0);
+       gh->gh_ip = _RET_IP_;
        if (gh->gh_owner_pid)
                put_pid(gh->gh_owner_pid);
        gh->gh_owner_pid = get_pid(task_pid(current));
index 2ffc67dce87f268d0b5824414927c6a1bae90513..1cc0bba6313f21216202d81f8fc1bb283496003a 100644 (file)
@@ -93,7 +93,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
          * tr->alloced is not set since the transaction structure is
          * on the stack */
        tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64));
-       tr.tr_ip = (unsigned long)__builtin_return_address(0);
+       tr.tr_ip = _RET_IP_;
        sb_start_intwrite(sdp->sd_vfs);
        if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0) {
                sb_end_intwrite(sdp->sd_vfs);
index fc8ac2ee0667c8d66082aa48f05f9acee452a8ac..fcf42eadb69ceaea5644d93e673a82cb2a265f44 100644 (file)
@@ -600,7 +600,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        int error, free_vfs_inode = 0;
        u32 aflags = 0;
        unsigned blocks = 1;
-       struct gfs2_diradd da = { .bh = NULL, };
+       struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, };
 
        if (!name->len || name->len > GFS2_FNAMESIZE)
                return -ENAMETOOLONG;
@@ -672,6 +672,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        gfs2_set_inode_blocks(inode, 1);
        munge_mode_uid_gid(dip, inode);
+       check_and_update_goal(dip);
        ip->i_goal = dip->i_goal;
        ip->i_diskflags = 0;
        ip->i_eattr = 0;
@@ -899,7 +900,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_holder ghs[2];
        struct buffer_head *dibh;
-       struct gfs2_diradd da = { .bh = NULL, };
+       struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, };
        int error;
 
        if (S_ISDIR(inode->i_mode))
@@ -1337,7 +1338,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
        struct gfs2_rgrpd *nrgd;
        unsigned int num_gh;
        int dir_rename = 0;
-       struct gfs2_diradd da = { .nr_blocks = 0, };
+       struct gfs2_diradd da = { .nr_blocks = 0, .save_loc = 0, };
        unsigned int x;
        int error;
 
index f4cb9c0d6bbdce4bdfc4a82b20aa7aa2ac119829..7474c413ffd1e2c8da3d4396f3bbc31a0175805d 100644 (file)
@@ -577,6 +577,13 @@ struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd)
        return rgd;
 }
 
+void check_and_update_goal(struct gfs2_inode *ip)
+{
+       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+       if (!ip->i_goal || gfs2_blk2rgrpd(sdp, ip->i_goal, 1) == NULL)
+               ip->i_goal = ip->i_no_addr;
+}
+
 void gfs2_free_clones(struct gfs2_rgrpd *rgd)
 {
        int x;
@@ -1910,6 +1917,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *a
        } else if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) {
                rs->rs_rbm.rgd = begin = ip->i_rgd;
        } else {
+               check_and_update_goal(ip);
                rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1);
        }
        if (S_ISDIR(ip->i_inode.i_mode) && (ap->aflags & GFS2_AF_ORLOV))
@@ -2089,7 +2097,7 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
                                     u32 blen, unsigned char new_state)
 {
        struct gfs2_rbm rbm;
-       struct gfs2_bitmap *bi;
+       struct gfs2_bitmap *bi, *bi_prev = NULL;
 
        rbm.rgd = gfs2_blk2rgrpd(sdp, bstart, 1);
        if (!rbm.rgd) {
@@ -2098,18 +2106,22 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
                return NULL;
        }
 
+       gfs2_rbm_from_block(&rbm, bstart);
        while (blen--) {
-               gfs2_rbm_from_block(&rbm, bstart);
                bi = rbm_bi(&rbm);
-               bstart++;
-               if (!bi->bi_clone) {
-                       bi->bi_clone = kmalloc(bi->bi_bh->b_size,
-                                              GFP_NOFS | __GFP_NOFAIL);
-                       memcpy(bi->bi_clone + bi->bi_offset,
-                              bi->bi_bh->b_data + bi->bi_offset, bi->bi_len);
+               if (bi != bi_prev) {
+                       if (!bi->bi_clone) {
+                               bi->bi_clone = kmalloc(bi->bi_bh->b_size,
+                                                     GFP_NOFS | __GFP_NOFAIL);
+                               memcpy(bi->bi_clone + bi->bi_offset,
+                                      bi->bi_bh->b_data + bi->bi_offset,
+                                      bi->bi_len);
+                       }
+                       gfs2_trans_add_meta(rbm.rgd->rd_gl, bi->bi_bh);
+                       bi_prev = bi;
                }
-               gfs2_trans_add_meta(rbm.rgd->rd_gl, bi->bi_bh);
                gfs2_setbit(&rbm, false, new_state);
+               gfs2_rbm_incr(&rbm);
        }
 
        return rbm.rgd;
index 463ab2e95d1cb94cafd6e31118ae77000754bd71..5d8f085f7adea18f9acce4ea5ed7f9e15527a7d0 100644 (file)
@@ -80,4 +80,5 @@ static inline bool gfs2_rs_active(struct gfs2_blkreserv *rs)
        return rs && !RB_EMPTY_NODE(&rs->rs_node);
 }
 
+extern void check_and_update_goal(struct gfs2_inode *ip);
 #endif /* __RGRP_DOT_H__ */
index 0546ab4e28e8a3dcbcef555f8574e068b531531c..42bfd33619793fb5bdda021ba9a7b9a027585e86 100644 (file)
@@ -44,7 +44,7 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
        if (!tr)
                return -ENOMEM;
 
-       tr->tr_ip = (unsigned long)__builtin_return_address(0);
+       tr->tr_ip = _RET_IP_;
        tr->tr_blocks = blocks;
        tr->tr_revokes = revokes;
        tr->tr_reserved = 1;