]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/gfs2/bmap.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
[linux-2.6-omap-h63xx.git] / fs / gfs2 / bmap.c
index 113f6c9110c745c31a6759a613ef628b4a3f68cb..93fa427bb5f501cee6da6ab88afbfd921f584295 100644 (file)
@@ -7,7 +7,6 @@
  * of the GNU General Public License version 2.
  */
 
-#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
@@ -94,9 +93,10 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
                map_bh(bh, inode->i_sb, block);
 
        set_buffer_uptodate(bh);
+       if (!gfs2_is_jdata(ip))
+               mark_buffer_dirty(bh);
        if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
                gfs2_trans_add_bh(ip->i_gl, bh, 0);
-       mark_buffer_dirty(bh);
 
        if (release) {
                unlock_page(page);
@@ -719,7 +719,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
        for (x = 0; x < rlist.rl_rgrps; x++) {
                struct gfs2_rgrpd *rgd;
                rgd = rlist.rl_ghs[x].gh_gl->gl_object;
-               rg_blocks += rgd->rd_ri.ri_length;
+               rg_blocks += rgd->rd_length;
        }
 
        error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
@@ -773,7 +773,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
                        gfs2_free_data(ip, bstart, blen);
        }
 
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
 
        gfs2_dinode_out(ip, dibh->b_data);
 
@@ -825,7 +825,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size)
                goto out_gunlock_q;
 
        error = gfs2_trans_begin(sdp,
-                       sdp->sd_max_height + al->al_rgd->rd_ri.ri_length +
+                       sdp->sd_max_height + al->al_rgd->rd_length +
                        RES_JDATA + RES_DINODE + RES_STATFS + RES_QUOTA, 0);
        if (error)
                goto out_ipres;
@@ -848,7 +848,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size)
        }
 
        ip->i_di.di_size = size;
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
 
        error = gfs2_meta_inode_buffer(ip, &dibh);
        if (error)
@@ -886,7 +886,6 @@ static int gfs2_block_truncate_page(struct address_space *mapping)
        unsigned blocksize, iblock, length, pos;
        struct buffer_head *bh;
        struct page *page;
-       void *kaddr;
        int err;
 
        page = grab_cache_page(mapping, index);
@@ -929,15 +928,13 @@ static int gfs2_block_truncate_page(struct address_space *mapping)
                /* Uhhuh. Read error. Complain and punt. */
                if (!buffer_uptodate(bh))
                        goto unlock;
+               err = 0;
        }
 
        if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
                gfs2_trans_add_bh(ip->i_gl, bh, 0);
 
-       kaddr = kmap_atomic(page, KM_USER0);
-       memset(kaddr + offset, 0, length);
-       flush_dcache_page(page);
-       kunmap_atomic(kaddr, KM_USER0);
+       zero_user_page(page, offset, length, KM_USER0);
 
 unlock:
        unlock_page(page);
@@ -963,7 +960,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
 
        if (gfs2_is_stuffed(ip)) {
                ip->i_di.di_size = size;
-               ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+               ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                gfs2_dinode_out(ip, dibh->b_data);
                gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size);
@@ -975,7 +972,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
 
                if (!error) {
                        ip->i_di.di_size = size;
-                       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+                       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
                        ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG;
                        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                        gfs2_dinode_out(ip, dibh->b_data);
@@ -1045,10 +1042,10 @@ static int trunc_end(struct gfs2_inode *ip)
                ip->i_di.di_height = 0;
                ip->i_di.di_goal_meta =
                        ip->i_di.di_goal_data =
-                       ip->i_num.no_addr;
+                       ip->i_no_addr;
                gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
        }
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
        ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG;
 
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
@@ -1089,6 +1086,33 @@ static int do_shrink(struct gfs2_inode *ip, u64 size)
        return error;
 }
 
+static int do_touch(struct gfs2_inode *ip, u64 size)
+{
+       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+       struct buffer_head *dibh;
+       int error;
+
+       error = gfs2_trans_begin(sdp, RES_DINODE, 0);
+       if (error)
+               return error;
+
+       down_write(&ip->i_rw_mutex);
+
+       error = gfs2_meta_inode_buffer(ip, &dibh);
+       if (error)
+               goto do_touch_out;
+
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
+       gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+       gfs2_dinode_out(ip, dibh->b_data);
+       brelse(dibh);
+
+do_touch_out:
+       up_write(&ip->i_rw_mutex);
+       gfs2_trans_end(sdp);
+       return error;
+}
+
 /**
  * gfs2_truncatei - make a file a given size
  * @ip: the inode
@@ -1109,8 +1133,11 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size)
 
        if (size > ip->i_di.di_size)
                error = do_grow(ip, size);
-       else
+       else if (size < ip->i_di.di_size)
                error = do_shrink(ip, size);
+       else
+               /* update time stamps */
+               error = do_touch(ip, size);
 
        return error;
 }