From dfe4d34b39b80faff52489f950a18523da7581bf Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Thu, 27 Oct 2011 12:16:06 -0400 Subject: GFS2: Add readahead to sequential directory traversal This patch adds read-ahead capability to GFS2's directory hash table management. It greatly improves performance for some directory operations. For example: In one of my file systems that has 1000 directories, each of which has 1000 files, time to execute a recursive ls (time ls -fR /mnt/gfs2 > /dev/null) was reduced from 2m2.814s on a stock kernel to 0m45.938s. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/gfs2/file.c') diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index ce36a56dfeac..46f6f9ac1ebc 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -105,7 +105,7 @@ static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir) return error; } - error = gfs2_dir_read(dir, &offset, dirent, filldir); + error = gfs2_dir_read(dir, &offset, dirent, filldir, &file->f_ra); gfs2_glock_dq_uninit(&d_gh); -- cgit From 87654896ca619ff64f94d3881d6bd0ec7b29e25f Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Tue, 8 Nov 2011 14:04:20 +0000 Subject: GFS2: More automated code analysis fixes A potentially uninitialised variable, some unreachable code, and the main part of this, fixing the error path in the unlink function. Signed-off-by: Steven Whitehouse --- fs/gfs2/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/gfs2/file.c') diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 46f6f9ac1ebc..6336bc6bf458 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -609,7 +609,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end, struct inode *inode = mapping->host; int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); struct gfs2_inode *ip = GFS2_I(inode); - int ret, ret1 = 0; + int ret = 0, ret1 = 0; if (mapping->nrpages) { ret1 = filemap_fdatawrite_range(mapping, start, end); -- cgit From 4442f2e03ed9646664c94e197e637b03324a6664 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 21 Nov 2011 10:01:25 +0000 Subject: GFS2: O_(D)SYNC support for fallocate Add sync of metadata after fallocate for O_SYNC files to ensure that we meet expectations for everything being on disk in this case. Unfortunately, the offset and len parameters are modified during the course of the fallocate function, so I've had to add a couple of new variables to call generic_write_sync() at the end. I know that potentially this will sync data as well within the range, but I think that is a fairly harmless side-effect overall, since we would not normally expect there to be any dirty data within the range in question. Signed-off-by: Steven Whitehouse Cc: Christoph Hellwig Cc: Benjamin Marzinski --- fs/gfs2/file.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'fs/gfs2/file.c') diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 6336bc6bf458..9b6c6ac351a8 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -752,6 +752,8 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t bytes, max_bytes; struct gfs2_alloc *al; int error; + const loff_t pos = offset; + const loff_t count = len; loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1); loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift; loff_t max_chunk_size = UINT_MAX & bsize_mask; @@ -834,6 +836,9 @@ retry: gfs2_quota_unlock(ip); gfs2_alloc_put(ip); } + + if (error == 0) + error = generic_write_sync(file, pos, count); goto out_unlock; out_trans_fail: -- cgit From 564e12b1157215171e7f3af5b70611ec7154327c Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Mon, 21 Nov 2011 13:36:17 -0500 Subject: GFS2: decouple quota allocations from block allocations This patch separates the code pertaining to allocations into two parts: quota-related information and block reservations. This patch also moves all the block reservation structure allocations to function gfs2_inplace_reserve to simplify the code, and moves the frees to function gfs2_inplace_release. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/file.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'fs/gfs2/file.c') diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 9b6c6ac351a8..42ceb23651e5 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -365,7 +365,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) u64 pos = page->index << PAGE_CACHE_SHIFT; unsigned int data_blocks, ind_blocks, rblocks; struct gfs2_holder gh; - struct gfs2_alloc *al; + struct gfs2_qadata *qa; loff_t size; int ret; @@ -393,16 +393,15 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) } ret = -ENOMEM; - al = gfs2_alloc_get(ip); - if (al == NULL) + qa = gfs2_qadata_get(ip); + if (qa == NULL) goto out_unlock; ret = gfs2_quota_lock_check(ip); if (ret) goto out_alloc_put; gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); - al->al_requested = data_blocks + ind_blocks; - ret = gfs2_inplace_reserve(ip); + ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks); if (ret) goto out_quota_unlock; @@ -448,7 +447,7 @@ out_trans_fail: out_quota_unlock: gfs2_quota_unlock(ip); out_alloc_put: - gfs2_alloc_put(ip); + gfs2_qadata_put(ip); out_unlock: gfs2_glock_dq(&gh); out: @@ -750,7 +749,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, struct gfs2_inode *ip = GFS2_I(inode); unsigned int data_blocks = 0, ind_blocks = 0, rblocks; loff_t bytes, max_bytes; - struct gfs2_alloc *al; + struct gfs2_qadata *qa; int error; const loff_t pos = offset; const loff_t count = len; @@ -784,8 +783,8 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, while (len > 0) { if (len < bytes) bytes = len; - al = gfs2_alloc_get(ip); - if (!al) { + qa = gfs2_qadata_get(ip); + if (!qa) { error = -ENOMEM; goto out_unlock; } @@ -797,8 +796,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, retry: gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); - al->al_requested = data_blocks + ind_blocks; - error = gfs2_inplace_reserve(ip); + error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks); if (error) { if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) { bytes >>= 1; @@ -812,7 +810,6 @@ retry: max_bytes = bytes; calc_max_reserv(ip, (len > max_chunk_size)? max_chunk_size: len, &max_bytes, &data_blocks, &ind_blocks); - al->al_requested = data_blocks + ind_blocks; rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA + RES_RG_HDR + gfs2_rg_blocks(ip); @@ -834,7 +831,7 @@ retry: offset += max_bytes; gfs2_inplace_release(ip); gfs2_quota_unlock(ip); - gfs2_alloc_put(ip); + gfs2_qadata_put(ip); } if (error == 0) @@ -846,7 +843,7 @@ out_trans_fail: out_qunlock: gfs2_quota_unlock(ip); out_alloc_put: - gfs2_alloc_put(ip); + gfs2_qadata_put(ip); out_unlock: gfs2_glock_dq(&ip->i_gh); out_uninit: -- cgit From a561be7100cd610bd2e082f3211c1dfb45835817 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 23 Nov 2011 11:57:51 -0500 Subject: switch a bunch of places to mnt_want_write_file() it's both faster (in case when file has been opened for write) and cleaner. Signed-off-by: Al Viro --- fs/gfs2/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/gfs2/file.c') diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index ce36a56dfeac..28fc6e3855f3 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -223,7 +223,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) int error; u32 new_flags, flags; - error = mnt_want_write(filp->f_path.mnt); + error = mnt_want_write_file(filp); if (error) return error; -- cgit From 2a79f17e4a641a2f463cb512cb0ec349844a147b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 9 Dec 2011 08:06:57 -0500 Subject: vfs: mnt_drop_write_file() new helper (wrapper around mnt_drop_write()) to be used in pair with mnt_want_write_file(). Signed-off-by: Al Viro --- fs/gfs2/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/gfs2/file.c') diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 28fc6e3855f3..b8927d4f3bf2 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -285,7 +285,7 @@ out_trans_end: out: gfs2_glock_dq_uninit(&gh); out_drop_write: - mnt_drop_write(filp->f_path.mnt); + mnt_drop_write_file(filp); return error; } -- cgit