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