[DRBD-cvs] r1755 - in trunk/drbd: . linux
svn at svn.drbd.org
svn at svn.drbd.org
Wed Feb 2 22:19:47 CET 2005
Author: phil
Date: 2005-02-02 22:19:44 +0100 (Wed, 02 Feb 2005)
New Revision: 1755
Modified:
trunk/drbd/drbd_compat_wrappers.h
trunk/drbd/drbd_fs.c
trunk/drbd/drbd_int.h
trunk/drbd/drbd_main.c
trunk/drbd/drbd_receiver.c
trunk/drbd/drbd_req.c
trunk/drbd/linux/drbd.h
Log:
- Fixed random problems with the tl_hash
- Added the ee_hash
...everything ufinished currently...
Modified: trunk/drbd/drbd_compat_wrappers.h
===================================================================
--- trunk/drbd/drbd_compat_wrappers.h 2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_compat_wrappers.h 2005-02-02 21:19:44 UTC (rev 1755)
@@ -84,7 +84,7 @@
return req->master_bio->bi_size;
}
-static inline drbd_bio_t* drbd_req_private_bio(struct drbd_request *req)
+static inline struct bio* drbd_req_private_bio(struct drbd_request *req)
{
return req->private_bio;
}
Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c 2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_fs.c 2005-02-02 21:19:44 UTC (rev 1755)
@@ -522,6 +522,8 @@
enum ret_codes retcode;
struct net_config new_conf;
struct crypto_tfm* tfm = NULL;
+ struct hlist_head *new_tl_hash = NULL;
+ struct hlist_head *new_ee_hash = NULL;
minor=(int)(mdev-drbd_conf);
@@ -566,6 +568,25 @@
mdev->cram_hmac_tfm = tfm;
+
+ if (mdev->tl_hash_s != new_conf.max_epoch_size/8 ) {
+ new_tl_hash = kmalloc(mdev->tl_hash_s * sizeof(void*),
+ GFP_KERNEL);
+ if(!new_tl_hash) {
+ retcode=KMallocFailed;
+ goto fail_ioctl;
+ }
+ }
+
+ if (mdev->ee_hash_s != new_conf.max_buffers/8 ) {
+ new_ee_hash = kmalloc(mdev->ee_hash_s * sizeof(void*),
+ GFP_KERNEL);
+ if(!new_ee_hash) {
+ retcode=KMallocFailed;
+ goto fail_ioctl;
+ }
+ }
+
/* IMPROVE:
We should warn the user if the LL_DEV is
used already. E.g. some FS mounted on it.
@@ -607,19 +628,20 @@
mdev->send_cnt = 0;
mdev->recv_cnt = 0;
- if (mdev->tl_hash_s != mdev->conf.max_epoch_size/8 ) {
+ if(new_tl_hash) {
if (mdev->tl_hash) kfree(mdev->tl_hash);
mdev->tl_hash_s = mdev->conf.max_epoch_size/8;
- mdev->tl_hash = kmalloc(mdev->tl_hash_s * sizeof(void*),
- GFP_KERNEL);
- if(!mdev->tl_hash) {
- mdev->tl_hash_s = 0;
- return -ENOMEM;
- }
-
+ mdev->tl_hash = new_tl_hash;
memset(mdev->tl_hash, 0, mdev->tl_hash_s * sizeof(void*));
}
+ if(new_ee_hash) {
+ if (mdev->ee_hash) kfree(mdev->ee_hash);
+ mdev->ee_hash_s = mdev->conf.max_buffers/8;
+ mdev->ee_hash = new_ee_hash;
+ memset(mdev->ee_hash, 0, mdev->ee_hash_s * sizeof(void*));
+ }
+
drbd_thread_start(&mdev->worker);
if( drbd_request_state(mdev,NS(conn,Unconnected)) > 0) {
drbd_thread_start(&mdev->receiver);
@@ -628,6 +650,8 @@
return 0;
fail_ioctl:
+ if (new_tl_hash) kfree(new_tl_hash);
+ if (new_ee_hash) kfree(new_ee_hash);
if (put_user(retcode, &arg->ret_code)) return -EFAULT;
return -EINVAL;
}
Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h 2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_int.h 2005-02-02 21:19:44 UTC (rev 1755)
@@ -606,6 +606,7 @@
long magic;
unsigned int ee_size;
sector_t ee_sector;
+ struct hlist_node colision;
// THINK: maybe we rather want bio_alloc(GFP_*,1)
struct bio_vec ee_bvec;
};
@@ -741,6 +742,8 @@
struct list_head done_ee; // send ack
struct list_head read_ee; // IO in progress
struct list_head net_ee; // zero-copy network send in progress
+ struct hlist_head * ee_hash; // is proteced by tl_lock!
+ unsigned int ee_hash_s;
spinlock_t pr_lock;
struct list_head app_reads;
struct list_head resync_reads;
@@ -789,7 +792,7 @@
extern int tl_verify(drbd_dev *mdev, drbd_request_t * item, sector_t sector);
#define TLHW_FLAG_SENT 0x10000000
#define TLHW_FLAG_RECVW 0x20000000
-extern int req_have_write(drbd_dev *mdev, sector_t sector, int size_n_flags);
+extern int req_have_write(drbd_dev *mdev, struct Tl_epoch_entry *e, int flags);
extern void drbd_free_sock(drbd_dev *mdev);
extern int drbd_send(drbd_dev *mdev, struct socket *sock,
void* buf, size_t size, unsigned msg_flags);
Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c 2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_main.c 2005-02-02 21:19:44 UTC (rev 1755)
@@ -201,6 +201,7 @@
b->n_req--;
list_del(&item->w.list);
+ hlist_del(&item->colision);
item->rq_status &= ~RQ_DRBD_IN_TL;
spin_unlock_irq(&mdev->tl_lock);
@@ -300,6 +301,7 @@
r = ( item->barrier == mdev->newest_barrier );
list_del(&item->w.list);
+ hlist_del(&item->colision);
if( item->rq_status & RQ_DRBD_RECVW ) wake_up(&mdev->cstate_wait);
@@ -360,6 +362,11 @@
}
}
+STATIC unsigned int ee_hash_fn(drbd_dev *mdev, sector_t sector)
+{
+ return (sector>>HT_SHIFT) % mdev->ee_hash_s;
+}
+
STATIC int overlaps(sector_t s1, int l1, sector_t s2, int l2)
{
return !( ( s1 + (l1>>9) <= s2 ) || ( s1 >= s2 + (l2>>9) ) );
@@ -371,12 +378,13 @@
* 1 ... a conflicting write, have not got ack by now.
* 2 ... a conflicting write, have got also got ack.
*/
-int req_have_write(drbd_dev *mdev, sector_t sector, int size_n_flags)
+int req_have_write(drbd_dev *mdev, struct Tl_epoch_entry *e, int flags)
{
struct hlist_head *slot;
struct hlist_node *n;
drbd_request_t * req;
- int size = size_n_flags & ~(TLHW_FLAG_SENT|TLHW_FLAG_RECVW);
+ sector_t sector = drbd_ee_get_sector(e);
+ int size = drbd_ee_get_size(e);
int i, rv=0;
D_ASSERT(size <= 1<<(HT_SHIFT+9) );
@@ -393,10 +401,10 @@
size) ) {
rv=1;
if( req->rq_status & RQ_DRBD_SENT ) rv++;
- if( size_n_flags & TLHW_FLAG_SENT ) {
+ if( flags & TLHW_FLAG_SENT ) {
req->rq_status |= RQ_DRBD_SENT;
}
- if( size_n_flags & TLHW_FLAG_RECVW ) {
+ if( flags & TLHW_FLAG_RECVW ) {
req->rq_status |= RQ_DRBD_RECVW;
}
goto out;
@@ -404,7 +412,10 @@
} // hlist_for_each_entry()
}
- // PRE TODO: insert ee onto ee_hash_table here...
+ // Good, no conflict found
+ INIT_HLIST_NODE(&e->colision);
+ hlist_add_head( &e->colision, mdev->ee_hash +
+ ee_hash_fn(mdev, sector) );
out:
spin_unlock_irq(&mdev->tl_lock);
@@ -1858,6 +1869,11 @@
__free_page(mdev->md_io_tmpp);
if (mdev->act_log) lc_free(mdev->act_log);
+
+ if(mdev->ee_hash) {
+ kfree(mdev->ee_hash);
+ mdev->ee_hash_s = 0;
+ }
}
drbd_destroy_mempools();
}
Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c 2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_receiver.c 2005-02-02 21:19:44 UTC (rev 1755)
@@ -1072,6 +1072,16 @@
e = read_in_block(mdev,data_size);
if (!e) return FALSE;
+ if(!inc_local(mdev)) {
+ if (DRBD_ratelimit(5*HZ,5))
+ ERR("Can not write mirrored data block to local disk.\n");
+ drbd_send_ack(mdev,NegAck,e);
+ spin_lock_irq(&mdev->ee_lock);
+ drbd_put_ee(mdev,e);
+ spin_unlock_irq(&mdev->ee_lock);
+ return TRUE;
+ }
+
if(discard) {
spin_lock_irq(&mdev->ee_lock);
drbd_put_ee(mdev,e);
@@ -1081,13 +1091,13 @@
return TRUE;
}
- switch( req_have_write(mdev, sector, data_size) ) {
+ switch( req_have_write(mdev, e, 0) ) {
case 2: /* Conflicting write, got ACK */
/* write afterwards ...*/
WARN("Concurrent write! [W AFTERWARDS] sec=%lu\n",
(unsigned long)sector);
if( wait_event_interruptible(mdev->cstate_wait,
- !req_have_write(mdev,sector,data_size|TLHW_FLAG_RECVW))) {
+ !req_have_write(mdev,e,TLHW_FLAG_RECVW))) {
spin_lock_irq(&mdev->ee_lock);
drbd_put_ee(mdev,e);
spin_unlock_irq(&mdev->ee_lock);
@@ -1106,7 +1116,7 @@
WARN("Concurrent write! [W AFTERWARDS] sec=%lu\n",
(unsigned long)sector);
if( wait_event_interruptible(mdev->cstate_wait,
- !req_have_write(mdev,sector,data_size|
+ !req_have_write(mdev,e,
TLHW_FLAG_RECVW|TLHW_FLAG_SENT))) {
spin_lock_irq(&mdev->ee_lock);
drbd_put_ee(mdev,e);
@@ -1120,16 +1130,6 @@
e->block_id = p->block_id; // no meaning on this side, e* on partner
- if(!inc_local(mdev)) {
- if (DRBD_ratelimit(5*HZ,5))
- ERR("Can not write mirrored data block to local disk.\n");
- drbd_send_ack(mdev,NegAck,e);
- spin_lock_irq(&mdev->ee_lock);
- drbd_put_ee(mdev,e);
- spin_unlock_irq(&mdev->ee_lock);
- return TRUE;
- }
-
drbd_ee_prepare_write(mdev, e, sector, data_size);
e->w.cb = e_end_block;
Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c 2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_req.c 2005-02-02 21:19:44 UTC (rev 1755)
@@ -57,7 +57,6 @@
req->rq_status |= nextstate;
req->rq_status &= er_flags | ~0x0001;
if( (req->rq_status & RQ_DRBD_DONE) == RQ_DRBD_DONE ) {
- hlist_del(&req->colision);
goto end_it;
}
@@ -81,6 +80,7 @@
set_bit(ISSUE_BARRIER,&mdev->flags);
} else {
list_del(&req->w.list); // we have the tl_lock...
+ hlist_del(&req->colision);
}
}
@@ -324,6 +324,9 @@
}
}
+ /* NOTE: drbd_send_dlobck() must happen before start of local IO,
+ to get he concurrent write detection right. */
+
if (local) {
if (rw == WRITE) {
if (!remote) drbd_set_out_of_sync(mdev,sector,size);
Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h 2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/linux/drbd.h 2005-02-02 21:19:44 UTC (rev 1755)
@@ -136,6 +136,7 @@
MDIOError,
MDInvalid,
CRAMAlgNotAvail,
+ KMallocFailed,
};
struct ioctl_disk_config {
More information about the drbd-cvs
mailing list