From: swhiteho@redhat.com <swhiteho@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 09/18] GFS2: Support generation of discard requests
Date: Wed, 18 Mar 2009 12:23:44 +0000 [thread overview]
Message-ID: <1237379033-28095-10-git-send-email-swhiteho@redhat.com> (raw)
In-Reply-To: <1237379033-28095-9-git-send-email-swhiteho@redhat.com>
From: Steven Whitehouse <swhiteho@redhat.com>
This patch allows GFS2 to generate discard requests for blocks which are
no longer useful to the filesystem (i.e. those which have been freed as
the result of an unlink operation). The requests are generated at the
time which those blocks become available for reuse in the filesystem.
In order to use this new feature, you have to specify the "discard"
mount option. The code coalesces adjacent blocks into a single extent
when generating the discard requests, thus generating the minimum
number.
If an error occurs when the request has been sent to the block device,
then it will print a message and turn off the requests for that
filesystem. If the problem is temporary, then you can use remount to
turn the option back on again. There is also a nodiscard mount option
so that you can use remount to turn discard requests off, if required.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 8fe0675..3f29bd2 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -416,7 +416,7 @@ struct gfs2_args {
unsigned int ar_suiddir:1; /* suiddir support */
unsigned int ar_data:2; /* ordered/writeback */
unsigned int ar_meta:1; /* mount metafs */
- unsigned int ar_num_glockd; /* Number of glockd threads */
+ unsigned int ar_discard:1; /* discard requests */
};
struct gfs2_tune {
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c
index fba502a..ee69701 100644
--- a/fs/gfs2/mount.c
+++ b/fs/gfs2/mount.c
@@ -41,6 +41,8 @@ enum {
Opt_data_writeback,
Opt_data_ordered,
Opt_meta,
+ Opt_discard,
+ Opt_nodiscard,
Opt_err,
};
@@ -65,6 +67,8 @@ static const match_table_t tokens = {
{Opt_data_writeback, "data=writeback"},
{Opt_data_ordered, "data=ordered"},
{Opt_meta, "meta"},
+ {Opt_discard, "discard"},
+ {Opt_nodiscard, "nodiscard"},
{Opt_err, NULL}
};
@@ -157,6 +161,12 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
case Opt_meta:
args->ar_meta = 1;
break;
+ case Opt_discard:
+ args->ar_discard = 1;
+ break;
+ case Opt_nodiscard:
+ args->ar_discard = 0;
+ break;
case Opt_err:
default:
fs_info(sdp, "invalid mount option: %s\n", o);
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 4ecdad0..4580195 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -608,6 +608,8 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
}
seq_printf(s, ",data=%s", state);
}
+ if (args->ar_discard)
+ seq_printf(s, ",discard");
return 0;
}
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index ba5a021..789953a 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -14,6 +14,7 @@
#include <linux/fs.h>
#include <linux/gfs2_ondisk.h>
#include <linux/prefetch.h>
+#include <linux/blkdev.h>
#include "gfs2.h"
#include "incore.h"
@@ -830,6 +831,58 @@ void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd)
spin_unlock(&sdp->sd_rindex_spin);
}
+static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
+ const struct gfs2_bitmap *bi)
+{
+ struct super_block *sb = sdp->sd_vfs;
+ struct block_device *bdev = sb->s_bdev;
+ const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize /
+ bdev_hardsect_size(sb->s_bdev);
+ u64 blk;
+ sector_t start;
+ sector_t nr_sects = 0;
+ int rv;
+ unsigned int x;
+
+ for (x = 0; x < bi->bi_len; x++) {
+ const u8 *orig = bi->bi_bh->b_data + bi->bi_offset + x;
+ const u8 *clone = bi->bi_clone + bi->bi_offset + x;
+ u8 diff = ~(*orig | (*orig >> 1)) & (*clone | (*clone >> 1));
+ diff &= 0x55;
+ if (diff == 0)
+ continue;
+ blk = offset + ((bi->bi_start + x) * GFS2_NBBY);
+ blk *= sects_per_blk; /* convert to sectors */
+ while(diff) {
+ if (diff & 1) {
+ if (nr_sects == 0)
+ goto start_new_extent;
+ if ((start + nr_sects) != blk) {
+ rv = blkdev_issue_discard(bdev, start,
+ nr_sects, GFP_NOFS);
+ if (rv)
+ goto fail;
+ nr_sects = 0;
+start_new_extent:
+ start = blk;
+ }
+ nr_sects += sects_per_blk;
+ }
+ diff >>= 2;
+ blk += sects_per_blk;
+ }
+ }
+ if (nr_sects) {
+ rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS);
+ if (rv)
+ goto fail;
+ }
+ return;
+fail:
+ fs_warn(sdp, "error %d on discard request, turning discards off for this filesystem", rv);
+ sdp->sd_args.ar_discard = 0;
+}
+
void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd)
{
struct gfs2_sbd *sdp = rgd->rd_sbd;
@@ -840,6 +893,8 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd)
struct gfs2_bitmap *bi = rgd->rd_bits + x;
if (!bi->bi_clone)
continue;
+ if (sdp->sd_args.ar_discard)
+ gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bi);
memcpy(bi->bi_clone + bi->bi_offset,
bi->bi_bh->b_data + bi->bi_offset, bi->bi_len);
}
--
1.6.0.3
next prev parent reply other threads:[~2009-03-18 12:23 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-18 12:23 [Cluster-devel] [GFS2] Pre-pull patch posting swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 01/18] GFS2: Fix remount argument parsing swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 02/18] GFS2: Bring back lvb-related stuff to lock_nolock to support quotas swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 03/18] GFS2: change gfs2_quota_scan into a shrinker swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 04/18] GFS2: Remove "double" locking in quota swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 05/18] GFS2: Merge lock_dlm module into GFS2 swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 06/18] GFS2: Remove unused field from glock swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 07/18] GFS2: Fix error path ref counting for root inode swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 08/18] GFS2: Fix deadlock on journal flush swhiteho
2009-03-18 12:23 ` swhiteho [this message]
2009-03-18 12:23 ` [Cluster-devel] [PATCH 10/18] GFS2: Expose UUID via sysfs/uevent swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 11/18] GFS2: Add a "demote a glock" interface to sysfs swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 12/18] GFS2: Fix alignment issue and tidy gfs2_bitfit swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 13/18] GFS2: Support quota/noquota mount arguments swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 14/18] GFS2: fix sparse warnings: constant is so big it is swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 15/18] GFS2: fix sparse warning: Should it be static? swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 16/18] GFS2: Pagecache usage optimization on GFS2 swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 17/18] GFS2: Fix locking bug in failed shared to exclusive conversion swhiteho
2009-03-18 12:23 ` [Cluster-devel] [PATCH 18/18] GFS2: Clean up of glops.c swhiteho
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1237379033-28095-10-git-send-email-swhiteho@redhat.com \
--to=swhiteho@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).