Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw:
  GFS2: Don't use _raw version of RCU dereference
  GFS2: Adding missing unlock_page()
  GFS2: Update to AIL list locking
  GFS2: introduce AIL lock
  GFS2: fix block allocation check for fallocate
  GFS2: Optimize glock multiple-dequeue code
  GFS2: Remove potential race in flock code
  GFS2: Fix glock deallocation race
  GFS2: quota allows exceeding hard limit
  GFS2: deallocation performance patch
  GFS2: panics on quotacheck update
  GFS2: Improve cluster mmap scalability
  GFS2: Fix glock queue trace point
  GFS2: Post-VFS scale update for RCU path walk
  GFS2: Use RCU for glock hash table
  • Loading branch information
Linus Torvalds committed Mar 16, 2011
2 parents 26a992d + 7e32d02 commit 3ae2a1c
Show file tree
Hide file tree
Showing 18 changed files with 351 additions and 378 deletions.
7 changes: 5 additions & 2 deletions fs/gfs2/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ int gfs2_check_acl(struct inode *inode, int mask, unsigned int flags)
struct posix_acl *acl;
int error;

if (flags & IPERM_FLAG_RCU)
return -ECHILD;
if (flags & IPERM_FLAG_RCU) {
if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
return -ECHILD;
return -EAGAIN;
}

acl = gfs2_acl_get(GFS2_I(inode), ACL_TYPE_ACCESS);
if (IS_ERR(acl))
Expand Down
1 change: 1 addition & 0 deletions fs/gfs2/aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
if (error == 0)
return 0;

unlock_page(page);
page_cache_release(page);

gfs2_trans_end(sdp);
Expand Down
20 changes: 15 additions & 5 deletions fs/gfs2/bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "meta_io.h"
#include "quota.h"
#include "rgrp.h"
#include "super.h"
#include "trans.h"
#include "dir.h"
#include "util.h"
Expand Down Expand Up @@ -757,7 +758,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_rgrp_list rlist;
u64 bn, bstart;
u32 blen;
u32 blen, btotal;
__be64 *p;
unsigned int rg_blocks = 0;
int metadata;
Expand Down Expand Up @@ -839,6 +840,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,

bstart = 0;
blen = 0;
btotal = 0;

for (p = top; p < bottom; p++) {
if (!*p)
Expand All @@ -851,9 +853,11 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
else {
if (bstart) {
if (metadata)
gfs2_free_meta(ip, bstart, blen);
__gfs2_free_meta(ip, bstart, blen);
else
gfs2_free_data(ip, bstart, blen);
__gfs2_free_data(ip, bstart, blen);

btotal += blen;
}

bstart = bn;
Expand All @@ -865,11 +869,17 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
}
if (bstart) {
if (metadata)
gfs2_free_meta(ip, bstart, blen);
__gfs2_free_meta(ip, bstart, blen);
else
gfs2_free_data(ip, bstart, blen);
__gfs2_free_data(ip, bstart, blen);

btotal += blen;
}

gfs2_statfs_change(sdp, 0, +btotal, 0);
gfs2_quota_change(ip, -(s64)btotal, ip->i_inode.i_uid,
ip->i_inode.i_gid);

ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;

gfs2_dinode_out(ip, dibh->b_data);
Expand Down
77 changes: 45 additions & 32 deletions fs/gfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,15 +448,20 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
{
struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);

if (!(file->f_flags & O_NOATIME)) {
if (!(file->f_flags & O_NOATIME) &&
!IS_NOATIME(&ip->i_inode)) {
struct gfs2_holder i_gh;
int error;

gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
error = gfs2_glock_nq(&i_gh);
file_accessed(file);
if (error == 0)
gfs2_glock_dq_uninit(&i_gh);
if (error == 0) {
file_accessed(file);
gfs2_glock_dq(&i_gh);
}
gfs2_holder_uninit(&i_gh);
if (error)
return error;
}
vma->vm_ops = &gfs2_vm_ops;
vma->vm_flags |= VM_CAN_NONLINEAR;
Expand Down Expand Up @@ -617,8 +622,7 @@ static void empty_write_end(struct page *page, unsigned from,
{
struct gfs2_inode *ip = GFS2_I(page->mapping->host);

page_zero_new_buffers(page, from, to);
flush_dcache_page(page);
zero_user(page, from, to-from);
mark_page_accessed(page);

if (!gfs2_is_writeback(ip))
Expand All @@ -627,50 +631,57 @@ static void empty_write_end(struct page *page, unsigned from,
block_commit_write(page, from, to);
}

static int write_empty_blocks(struct page *page, unsigned from, unsigned to)
static int needs_empty_write(sector_t block, struct inode *inode)
{
unsigned start, end, next;
struct buffer_head *bh, *head;
int error;
struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 };

if (!page_has_buffers(page)) {
error = __block_write_begin(page, from, to - from, gfs2_block_map);
if (unlikely(error))
return error;
bh_map.b_size = 1 << inode->i_blkbits;
error = gfs2_block_map(inode, block, &bh_map, 0);
if (unlikely(error))
return error;
return !buffer_mapped(&bh_map);
}

empty_write_end(page, from, to);
return 0;
}
static int write_empty_blocks(struct page *page, unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
unsigned start, end, next, blksize;
sector_t block = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
int ret;

bh = head = page_buffers(page);
blksize = 1 << inode->i_blkbits;
next = end = 0;
while (next < from) {
next += bh->b_size;
bh = bh->b_this_page;
next += blksize;
block++;
}
start = next;
do {
next += bh->b_size;
if (buffer_mapped(bh)) {
next += blksize;
ret = needs_empty_write(block, inode);
if (unlikely(ret < 0))
return ret;
if (ret == 0) {
if (end) {
error = __block_write_begin(page, start, end - start,
gfs2_block_map);
if (unlikely(error))
return error;
ret = __block_write_begin(page, start, end - start,
gfs2_block_map);
if (unlikely(ret))
return ret;
empty_write_end(page, start, end);
end = 0;
}
start = next;
}
else
end = next;
bh = bh->b_this_page;
block++;
} while (next < to);

if (end) {
error = __block_write_begin(page, start, end - start, gfs2_block_map);
if (unlikely(error))
return error;
ret = __block_write_begin(page, start, end - start, gfs2_block_map);
if (unlikely(ret))
return ret;
empty_write_end(page, start, end);
}

Expand Down Expand Up @@ -976,8 +987,10 @@ static void do_unflock(struct file *file, struct file_lock *fl)

mutex_lock(&fp->f_fl_mutex);
flock_lock_file_wait(file, fl);
if (fl_gh->gh_gl)
gfs2_glock_dq_uninit(fl_gh);
if (fl_gh->gh_gl) {
gfs2_glock_dq_wait(fl_gh);
gfs2_holder_uninit(fl_gh);
}
mutex_unlock(&fp->f_fl_mutex);
}

Expand Down
Loading

0 comments on commit 3ae2a1c

Please sign in to comment.