tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: ataraid(4) and VOP_OPENing the same block device
On Thu, 11 Sep 2008 19:56:07 -0700
Bill Stouder-Studenmund <wrstuden%netbsd.org@localhost> wrote:
> But what exactly do you want to achieve? wtf is ld1 going to do with the
> disks that belong to ld0? How exactly is a disk supposed to be part of a
> RAID 0 _AND_ a RAID 1 at the same time?
>
> So far, it sounds like the code is behaving correctly.
>
> Please rephrase your question. What you're asking to do right now
> shouldn't work, so I'm not surprised it fails.
What I wanted to achieve is to use the same vnode for the RAW_PART of
the block device multiple times (if that's the correct term);
Also what I wanted was accomplished by the following code (after
looking at some sources):
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/dkio.h>
#include <sys/disk.h>
#include <sys/disklabel.h>
#include <sys/fcntl.h>
#include <sys/vnode.h>
#include <sys/kauth.h>
#include <sys/kmem.h>
#include <dev/ata/ata_raidvar.h>
struct ataraid_disk_vnode {
struct ataraid_disk_info *adv_adi;
struct vnode *adv_vnode;
SLIST_ENTRY(ataraid_disk_vnode) adv_next;
};
static SLIST_HEAD(, ataraid_disk_vnode) ataraid_disk_vnode_list =
SLIST_HEAD_INITIALIZER(ataraid_disk_vnode_list);
/*
* Finds the RAW_PART vnode of the block device associated with a component
* by looking at the singly linked list; otherwise creates, opens and
* returns the vnode to the caller.
*/
struct vnode *
ata_raid_disk_vnode_find(struct ataraid_disk_info *adi)
{
struct ataraid_disk_vnode *adv = NULL;
struct vnode *vp = NULL;
device_t devlist;
int bmajor, error = 0;
dev_t dev;
SLIST_FOREACH(adv, &ataraid_disk_vnode_list, adv_next) {
devlist = adv->adv_adi->adi_dev;
if (strcmp(device_xname(devlist),
device_xname(adi->adi_dev)) == 0)
return adv->adv_vnode;
}
adv = NULL;
adv = kmem_zalloc(sizeof(struct ataraid_disk_vnode), KM_SLEEP);
bmajor = devsw_name2blk(device_xname(adi->adi_dev), NULL, 0);
dev = MAKEDISKDEV(bmajor, device_unit(adi->adi_dev), RAW_PART);
error = bdevvp(dev, &vp);
if (error) {
kmem_free(adv, sizeof(struct ataraid_disk_vnode));
return NULL;
}
error = VOP_OPEN(vp, FREAD|FWRITE, NOCRED);
if (error) {
vput(vp);
kmem_free(adv, sizeof(struct ataraid_disk_vnode));
return NULL;
}
error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
if (error) {
vrele(vp);
kmem_free(adv, sizeof(struct ataraid_disk_vnode));
return NULL;
}
VOP_UNLOCK(vp, 0);
adv->adv_adi = adi;
adv->adv_vnode = vp;
SLIST_INSERT_HEAD(&ataraid_disk_vnode_list, adv, adv_next);
return adv->adv_vnode;
}
So in ld_ataraid_attach(), I use this routine to see if the disk
has already the vnode created and returns a pointer to it.
I'm open for suggestions if something is wrong in the code...
at least I am not having any known problems for now.
Thanks!
Home |
Main Index |
Thread Index |
Old Index