From owner-p4-projects@FreeBSD.ORG Sun Jun 21 14:08:44 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4A6211065674; Sun, 21 Jun 2009 14:08:43 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0A2911065672 for ; Sun, 21 Jun 2009 14:08:43 +0000 (UTC) (envelope-from gk@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id EACDD8FC08 for ; Sun, 21 Jun 2009 14:08:42 +0000 (UTC) (envelope-from gk@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5LE8gJF010764 for ; Sun, 21 Jun 2009 14:08:42 GMT (envelope-from gk@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5LE8ggF010762 for perforce@freebsd.org; Sun, 21 Jun 2009 14:08:42 GMT (envelope-from gk@FreeBSD.org) Date: Sun, 21 Jun 2009 14:08:42 GMT Message-Id: <200906211408.n5LE8ggF010762@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gk@FreeBSD.org using -f From: Gleb Kurtsou To: Perforce Change Reviews Cc: Subject: PERFORCE change 164811 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 14:08:44 -0000 http://perforce.freebsd.org/chv.cgi?CH=164811 Change 164811 by gk@gk_h1 on 2009/06/21 14:07:54 add rest of vops. support not block aligned read/write. handle file resize. rename to be more consistens, cleanup Affected files ... .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs.h#3 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_subr.c#3 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vfsops.c#2 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#3 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_xbase64.c#2 edit .. //depot/projects/soc2009/gk_pefs/sys/modules/pefs/Makefile#3 edit Differences ... ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs.h#3 (text+ko) ==== @@ -39,62 +39,81 @@ #include -struct pe_mount { - struct mount *pem_vfs; - struct vnode *pem_rootvp; /* Reference to root pe_node */ +struct pefs_mount { + struct mount *pm_vfs; + struct vnode *pm_rootvp; /* Reference to root pefs_node */ }; #ifdef _KERNEL + +#define PEFS_BLOCK 16 + /* * A cache of vnode references */ -struct pe_node { - LIST_ENTRY(pe_node) pe_hash; /* Hash list */ - struct vnode *pe_lowervp; /* VREFed once */ - struct vnode *pe_vnode; /* Back pointer */ +struct pefs_node { + LIST_ENTRY(pefs_node) pn_hash; /* Hash list */ + struct vnode *pn_lowervp; /* VREFed once */ + struct vnode *pn_vnode; /* Back pointer */ }; -struct pe_xuio { - struct uio xuio_uio; - void **xuio_bases; +struct pefs_chunk { + int pc_iovcnt; + int pc_basescnt; + struct iovec *pc_iov; + int pc_size; + void **pc_bases; + struct uio pc_uio; }; -typedef void (*pe_tr)(void *mem, size_t size, void *arg); +typedef void (*pefs_tr)(void *mem, size_t size, void *arg); -#define MOUNTTOPEMOUNT(mp) ((struct pe_mount *)((mp)->mnt_data)) -#define VTOPE(vp) ((struct pe_node *)(vp)->v_data) -#define PETOV(xp) ((xp)->pe_vnode) +#define MOUNTTOPEMOUNT(mp) ((struct pefs_mount *)((mp)->mnt_data)) +#define VTOPE(vp) ((struct pefs_node *)(vp)->v_data) +#define PETOV(xp) ((xp)->pn_vnode) struct vfsconf; struct vop_generic_args; int pefs_init(struct vfsconf *vfsp); int pefs_uninit(struct vfsconf *vfsp); -int pe_nodeget(struct mount *mp, struct vnode *target, struct vnode **vpp); -void pe_hashrem(struct pe_node *xp); -int pe_bypass(struct vop_generic_args *ap); -struct pe_xuio* pe_xuio_create(struct uio* uio); -void pe_xuio_finish(struct pe_xuio* xuio, struct uio *src); -void pe_xuio_transfrom(struct pe_xuio *xuio, struct uio *src, pe_tr tr, void *arg); -int pe_name_encrypt(const char *plain, size_t plain_len, char *enc, size_t enc_size); -int pe_name_decrypt(const char *enc, size_t enc_len, char *plain, size_t plain_size); +int pefs_nodeget(struct mount *mp, struct vnode *target, struct vnode **vpp); +void pefs_hashrem(struct pefs_node *xp); +int pefs_bypass(struct vop_generic_args *ap); +int pefs_name_encrypt(const char *plain, size_t plain_len, char *enc, size_t enc_size); +int pefs_name_decrypt(const char *enc, size_t enc_len, char *plain, size_t plain_size); + +void pefs_xor(void *mem, size_t size); + +#define PEFS_NAME_NTOP_SIZE(a) (((a) * 4 + 2)/3) +#define PEFS_NAME_PTON_SIZE(a) (((a) * 3)/4) +int pefs_name_ntop(u_char const *src, size_t srclength, char *target, size_t targsize); +int pefs_name_pton(char const *src, size_t srclen, u_char *target, size_t targsize); -void pe_xor(void *mem, size_t size, void *arg); +void pefs_xor_chunk(struct pefs_chunk *pc); -int pe_b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize); -int pe_b64_pton(char const *src, size_t srclen, u_char *target, size_t targsize); +struct pefs_chunk* pefs_chunk_create(size_t size); +void pefs_chunk_free(struct pefs_chunk* pc); +struct uio* pefs_chunk_uio(struct pefs_chunk *pc, off_t uio_offset, enum uio_rw uio_rw); +struct uio* pefs_chunk_uio_range(struct pefs_chunk *pc, size_t skip, size_t size, off_t uio_offset, enum uio_rw uio_rw); +void* pefs_chunk_get(struct pefs_chunk *pc, size_t *size, long *_state); +void pefs_chunk_zero(struct pefs_chunk *pc); +int pefs_chunk_copy(struct pefs_chunk *pc, size_t skip, struct uio *uio); +void pefs_chunk_crop(struct pefs_chunk *pc, size_t skip_begin, size_t skip_end); +void pefs_chunk_shrink(struct pefs_chunk *pc, size_t size); #ifdef DIAGNOSTIC -struct vnode *pe_checkvp(struct vnode *vp, char *fil, int lno); -#define PEVPTOLOWERVP(vp) pe_checkvp((vp), __FILE__, __LINE__) +struct vnode *pefs_checkvp(struct vnode *vp, char *fil, int lno); +#define PEVPTOLOWERVP(vp) pefs_checkvp((vp), __FILE__, __LINE__) #else -#define PEVPTOLOWERVP(vp) (VTOPE(vp)->pe_lowervp) +#define PEVPTOLOWERVP(vp) (VTOPE(vp)->pn_lowervp) #endif -extern struct vop_vector pe_vnodeops; +extern struct vop_vector pefs_vnodeops; #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_PEFSNODE); +MALLOC_DECLARE(M_PEFSBUF); #endif #ifdef PEFS_DEBUG ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_subr.c#3 (text+ko) ==== @@ -61,31 +61,27 @@ * alias is removed the lower vnode is vrele'd. */ -#define PE_NHASH(vp) \ - (&pe_node_hashtbl[(((uintptr_t)vp)>>LOG2_SIZEVNODE) & pe_node_hash]) +#define PEFS_NHASH(vp) \ + (&pefs_node_hashtbl[(((uintptr_t)vp)>>LOG2_SIZEVNODE) & pefs_node_hash]) -static LIST_HEAD(pe_node_hashhead, pe_node) *pe_node_hashtbl; -static u_long pe_node_hash; -struct mtx pe_hashmtx; +static LIST_HEAD(pefs_node_hashhead, pefs_node) *pefs_node_hashtbl; +static u_long pefs_node_hash; +struct mtx pefs_hashmtx; static MALLOC_DEFINE(M_PEFSHASH, "pefs_hash", "PEFS hash table"); MALLOC_DEFINE(M_PEFSNODE, "pefs_node", "PEFS vnode private part"); -static MALLOC_DEFINE(M_PEFSBUF, "pefs_buf", "PEFS buffers"); +MALLOC_DEFINE(M_PEFSBUF, "pefs_buf", "PEFS buffers"); -static struct vnode * pe_hashget(struct mount *, struct vnode *); -static struct vnode * pe_hashins(struct mount *, struct pe_node *); - /* * Initialise cache headers */ int -pefs_init(vfsp) - struct vfsconf *vfsp; +pefs_init(struct vfsconf *vfsp) { PEFSDEBUG("pefs_init\n"); /* printed during system boot */ - pe_node_hashtbl = hashinit(NPENODECACHE, M_PEFSHASH, &pe_node_hash); - mtx_init(&pe_hashmtx, "pehs", NULL, MTX_DEF); + pefs_node_hashtbl = hashinit(NPENODECACHE, M_PEFSHASH, &pefs_node_hash); + mtx_init(&pefs_hashmtx, "pehs", NULL, MTX_DEF); return (0); } @@ -94,8 +90,8 @@ struct vfsconf *vfsp; { - mtx_destroy(&pe_hashmtx); - free(pe_node_hashtbl, M_PEFSHASH); + mtx_destroy(&pefs_hashmtx); + free(pefs_node_hashtbl, M_PEFSHASH); return (0); } @@ -104,26 +100,24 @@ * Lower vnode should be locked on entry and will be left locked on exit. */ static struct vnode * -pe_hashget(mp, lowervp) - struct mount *mp; - struct vnode *lowervp; +pefs_hashget(struct mount *mp, struct vnode *lowervp) { - struct pe_node_hashhead *hd; - struct pe_node *a; + struct pefs_node_hashhead *hd; + struct pefs_node *a; struct vnode *vp; - ASSERT_VOP_LOCKED(lowervp, "pe_hashget"); + ASSERT_VOP_LOCKED(lowervp, "pefs_hashget"); /* * Find hash base, and then search the (two-way) linked - * list looking for a pe_node structure which is referencing - * the lower vnode. If found, the increment the pe_node + * list looking for a pefs_node structure which is referencing + * the lower vnode. If found, the increment the pefs_node * reference count (but NOT the lower vnode's VREF counter). */ - hd = PE_NHASH(lowervp); - mtx_lock(&pe_hashmtx); - LIST_FOREACH(a, hd, pe_hash) { - if (a->pe_lowervp == lowervp && PETOV(a)->v_mount == mp) { + hd = PEFS_NHASH(lowervp); + mtx_lock(&pefs_hashmtx); + LIST_FOREACH(a, hd, pn_hash) { + if (a->pn_lowervp == lowervp && PETOV(a)->v_mount == mp) { /* * Since we have the lower node locked the pefs * node can not be in the process of recycling. If @@ -132,49 +126,47 @@ */ vp = PETOV(a); vref(vp); - mtx_unlock(&pe_hashmtx); + mtx_unlock(&pefs_hashmtx); return (vp); } } - mtx_unlock(&pe_hashmtx); + mtx_unlock(&pefs_hashmtx); return (NULLVP); } /* - * Act like pe_hashget, but add passed pe_node to hash if no existing + * Act like pefs_hashget, but add passed pefs_node to hash if no existing * node found. */ static struct vnode * -pe_hashins(mp, xp) - struct mount *mp; - struct pe_node *xp; +pefs_hashins(struct mount *mp, struct pefs_node *xp) { - struct pe_node_hashhead *hd; - struct pe_node *oxp; + struct pefs_node_hashhead *hd; + struct pefs_node *oxp; struct vnode *ovp; - hd = PE_NHASH(xp->pe_lowervp); - mtx_lock(&pe_hashmtx); - LIST_FOREACH(oxp, hd, pe_hash) { - if (oxp->pe_lowervp == xp->pe_lowervp && + hd = PEFS_NHASH(xp->pn_lowervp); + mtx_lock(&pefs_hashmtx); + LIST_FOREACH(oxp, hd, pn_hash) { + if (oxp->pn_lowervp == xp->pn_lowervp && PETOV(oxp)->v_mount == mp) { /* - * See pe_hashget for a description of this + * See pefs_hashget for a description of this * operation. */ ovp = PETOV(oxp); vref(ovp); - mtx_unlock(&pe_hashmtx); + mtx_unlock(&pefs_hashmtx); return (ovp); } } - LIST_INSERT_HEAD(hd, xp, pe_hash); - mtx_unlock(&pe_hashmtx); + LIST_INSERT_HEAD(hd, xp, pn_hash); + mtx_unlock(&pefs_hashmtx); return (NULLVP); } static void -pe_insmntque_dtr(struct vnode *vp, void *xp) +pefs_insmntque_dtr(struct vnode *vp, void *xp) { vp->v_data = NULL; vp->v_vnlock = &vp->v_lock; @@ -194,17 +186,14 @@ * the caller's "spare" reference to created pefs vnode. */ int -pe_nodeget(mp, lowervp, vpp) - struct mount *mp; - struct vnode *lowervp; - struct vnode **vpp; +pefs_nodeget(struct mount *mp, struct vnode *lowervp, struct vnode **vpp) { - struct pe_node *xp; + struct pefs_node *xp; struct vnode *vp; int error; /* Lookup the hash firstly */ - *vpp = pe_hashget(mp, lowervp); + *vpp = pefs_hashget(mp, lowervp); if (*vpp != NULL) { vrele(lowervp); return (0); @@ -223,34 +212,34 @@ * might cause a bogus v_data pointer to get dereferenced * elsewhere if MALLOC should block. */ - xp = malloc(sizeof(struct pe_node), + xp = malloc(sizeof(struct pefs_node), M_PEFSNODE, M_WAITOK); - error = getnewvnode("null", mp, &pe_vnodeops, &vp); + error = getnewvnode("pefs", mp, &pefs_vnodeops, &vp); if (error) { free(xp, M_PEFSNODE); return (error); } - xp->pe_vnode = vp; - xp->pe_lowervp = lowervp; + xp->pn_vnode = vp; + xp->pn_lowervp = lowervp; vp->v_type = lowervp->v_type; vp->v_data = xp; vp->v_vnlock = lowervp->v_vnlock; if (vp->v_vnlock == NULL) - panic("pe_nodeget: Passed a NULL vnlock.\n"); - error = insmntque1(vp, mp, pe_insmntque_dtr, xp); + panic("pefs_nodeget: Passed a NULL vnlock.\n"); + error = insmntque1(vp, mp, pefs_insmntque_dtr, xp); if (error != 0) return (error); /* * Atomically insert our new node into the hash or vget existing * if someone else has beaten us to it. */ - *vpp = pe_hashins(mp, xp); + *vpp = pefs_hashins(mp, xp); if (*vpp != NULL) { vrele(lowervp); vp->v_vnlock = &vp->v_lock; - xp->pe_lowervp = NULL; + xp->pn_lowervp = NULL; vrele(vp); return (0); } @@ -263,17 +252,16 @@ * Remove node from hash. */ void -pe_hashrem(xp) - struct pe_node *xp; +pefs_hashrem(struct pefs_node *xp) { - mtx_lock(&pe_hashmtx); - LIST_REMOVE(xp, pe_hash); - mtx_unlock(&pe_hashmtx); + mtx_lock(&pefs_hashmtx); + LIST_REMOVE(xp, pn_hash); + mtx_unlock(&pefs_hashmtx); } void -pe_xor(void *mem, size_t size, void *arg) +pefs_xor(void *mem, size_t size) { char *b = (char *)mem; char *e = b + size; @@ -283,8 +271,23 @@ } } +void +pefs_xor_chunk(struct pefs_chunk *pc) +{ + long arg = 0; + char *mem; + size_t size; + + while (1) { + mem = pefs_chunk_get(pc, &size, &arg); + if (mem == NULL) + break; + pefs_xor(mem, size); + } +} + int -pe_name_encrypt(const char *plain, size_t plain_len, char *enc, size_t enc_size) +pefs_name_encrypt(const char *plain, size_t plain_len, char *enc, size_t enc_size) { char b_static[64]; char *b; @@ -298,123 +301,236 @@ // FIXME for (int i = 0; i < plain_len; i++) b[i] ^= 0xAA; - r = pe_b64_ntop(b, plain_len, enc, enc_size); - printf("pe_name_encrypt: %d; %.*s => %.*s\n", r, plain_len, plain, r, enc); + r = pefs_name_ntop(b, plain_len, enc, enc_size); + // printf("pefs_name_encrypt: %d; %.*s => %.*s\n", r, plain_len, plain, r, enc); if (b != b_static) free(b, M_PEFSBUF); return r; } int -pe_name_decrypt(const char *enc, size_t enc_len, char *plain, size_t plain_size) +pefs_name_decrypt(const char *enc, size_t enc_len, char *plain, size_t plain_size) { int r; - r = pe_b64_pton(enc, enc_len, plain, plain_size); + r = pefs_name_pton(enc, enc_len, plain, plain_size); if (r > 0) { // FIXME for (int i = 0; i < r; i++) plain[i] ^= 0xAA; } - printf("pe_name_decrypt: %d; %.*s => %.*s\n", r, enc_len, enc, r < 0 ? 0 : r, plain); + if (r < plain_size) + plain[r] = '\0'; + // printf("pefs_name_decrypt: %d; %.*s => %.*s\n", r, enc_len, enc, r < 0 ? 0 : r, plain); return r; } -struct pe_xuio* -pe_xuio_create(struct uio* uio) +struct pefs_chunk* +pefs_chunk_create(size_t size) +{ + struct pefs_chunk *pc; + int iovcnt; + + iovcnt = (size + PAGE_SIZE - 1) / PAGE_SIZE; + PEFSDEBUG("%s: length=%u; iovcnt=%d\n", __func__, size, iovcnt); + pc = malloc(sizeof(struct pefs_chunk) + (sizeof(void*) + sizeof(struct iovec) * 2) * iovcnt, + M_PEFSBUF, M_WAITOK | M_ZERO); + + pc->pc_size = size; + pc->pc_iovcnt = iovcnt; + pc->pc_basescnt = iovcnt; + pc->pc_bases = (void **)(pc + 1); + pc->pc_iov = (struct iovec *)(pc->pc_bases + iovcnt); + pc->pc_uio.uio_iov = (struct iovec *)(pc->pc_iov + iovcnt); + + for (int i = 0; i < iovcnt && size > 0; i++) { + int len = imin(PAGE_SIZE, size); + pc->pc_iov[i].iov_len = len; + pc->pc_bases[i] = malloc(len, M_PEFSBUF, M_WAITOK | M_ZERO); + pc->pc_iov[i].iov_base = pc->pc_bases[i]; + size -= len; + } + if (size != 0) + panic("pefs_chunk initialization error\n"); + + return (pc); +} + +void +pefs_chunk_free(struct pefs_chunk* pc) +{ + for (int i = 0; i < pc->pc_basescnt; i++) { + free(pc->pc_bases[i], M_PEFSBUF); + } + free(pc, M_PEFSBUF); +} + +struct uio* +pefs_chunk_uio(struct pefs_chunk *pc, off_t uio_offset, enum uio_rw uio_rw) +{ + return pefs_chunk_uio_range(pc, 0, pc->pc_size, uio_offset, uio_rw); +} + +struct uio* +pefs_chunk_uio_range(struct pefs_chunk *pc, size_t skip, size_t size, off_t uio_offset, enum uio_rw uio_rw) { - struct pe_xuio *xuio; - size_t len; - int iov_cnt; + int skip_iov, i; - len = 0; - for (int i = 0; i < uio->uio_iovcnt; i++) { - len += uio->uio_iov[i].iov_len; + KASSERT(pc->pc_size >= size + skip, ("invalid range value")); + /* skip */ + for (skip_iov = 0; skip_iov < pc->pc_iovcnt && skip; skip_iov++) { + if (skip < pc->pc_iov[skip_iov].iov_len) + break; + else + skip -= pc->pc_iov[skip_iov].iov_len; } - iov_cnt = (len + PAGE_SIZE - 1) / PAGE_SIZE; - xuio = malloc(sizeof(struct pe_xuio) + (sizeof(void*) + sizeof(struct iovec)) * iov_cnt, - M_PEFSBUF, M_WAITOK); - xuio->xuio_uio = *uio; - xuio->xuio_uio.uio_segflg = UIO_SYSSPACE; - xuio->xuio_uio.uio_iov = (struct iovec *)(xuio + 1); - xuio->xuio_bases = (void **)(xuio->xuio_uio.uio_iov + iov_cnt); - for (int i = 0; i < iov_cnt; i++) { - xuio->xuio_uio.uio_iov[i].iov_len = imin(PAGE_SIZE, len); - len -= PAGE_SIZE; - xuio->xuio_bases[i] = xuio->xuio_uio.uio_iov[i].iov_base = - malloc(xuio->xuio_uio.uio_iov[i].iov_len, M_PEFSBUF, M_WAITOK); + pc->pc_uio.uio_offset = uio_offset; + pc->pc_uio.uio_resid = size; + pc->pc_uio.uio_rw = uio_rw; + pc->pc_uio.uio_segflg = UIO_SYSSPACE; + pc->pc_uio.uio_td = curthread; + + for (i = 0; skip_iov + i < pc->pc_iovcnt && size; i++) { + pc->pc_uio.uio_iov[i].iov_base = (char *)pc->pc_iov[skip_iov + i].iov_base + skip; + pc->pc_uio.uio_iov[i].iov_len = min(size, pc->pc_iov[skip_iov + i].iov_len - skip); + size -= pc->pc_uio.uio_iov[i].iov_len; + skip = 0; + printf("%s: creating iov: i=%d; len=%d; base=%p\n", __func__, i, + pc->pc_uio.uio_iov[i].iov_len, pc->pc_uio.uio_iov[i].iov_base); } + pc->pc_uio.uio_iovcnt = i; + + return (&pc->pc_uio); +} - return (xuio); +void* +pefs_chunk_get(struct pefs_chunk *pc, size_t *size, long *state) +{ + void *mem; + + if (!size || !state || *state < 0) + panic("invalid args"); + if (*state >= pc->pc_iovcnt) { + *size = 0; + return (NULL); + } + mem = pc->pc_iov[*state].iov_base; + *size = pc->pc_iov[*state].iov_len; + (*state)++; + return (mem); } void -pe_xuio_finish(struct pe_xuio* xuio, struct uio *src) +pefs_chunk_zero(struct pefs_chunk *pc) +{ + int i; + + for (i = 0; i < pc->pc_iovcnt; i++) { + bzero(pc->pc_iov[i].iov_base, pc->pc_iov[i].iov_len); + } +} + +int +pefs_chunk_copy(struct pefs_chunk *pc, size_t skip, struct uio *uio) { - src->uio_offset = xuio->xuio_uio.uio_offset; - src->uio_resid = xuio->xuio_uio.uio_resid; - for (int i = 0; i < xuio->xuio_uio.uio_iovcnt; i++) { - free(xuio->xuio_bases[i], M_PEFSBUF); + int i; + int error; + + KASSERT(pc->pc_size >= skip, ("invalid range value")); + /* skip */ + for (i = 0; i < pc->pc_iovcnt && skip; i++) { + if (skip < pc->pc_iov[i].iov_len) + break; + else + skip -= pc->pc_iov[i].iov_len; + } + + for (; i < pc->pc_iovcnt && uio->uio_resid; i++) { + error = uiomove((char *)pc->pc_iov[i].iov_base + skip, pc->pc_iov[i].iov_len - skip, uio); + if (error) + return (error); + skip = 0; } - free(xuio, M_PEFSBUF); + return (0); } void -pe_xuio_transfrom(struct pe_xuio *_xuio, struct uio *src, pe_tr tr, void *arg) +pefs_chunk_crop(struct pefs_chunk *pc, size_t skip_begin, size_t skip_end) { - struct uio *xuio = &_xuio->xuio_uio; + + KASSERT(pc->pc_size >= skip_begin + skip_end, ("invalid range value")); + + if (skip_begin + skip_end == 0) + return; + + PEFSDEBUG("%s: skip_begin=%d; skip_end=%d; size=%d\n", __func__, + skip_begin, skip_end, pc->pc_size); + + for (int i = 0; i < pc->pc_iovcnt && skip_begin; i++) { + struct iovec *iov = &pc->pc_iov[i]; - KASSERT(xuio->uio_segflg == UIO_SYSSPACE && xuio->uio_rw == src->uio_rw, - ("pe_uio_transfrom")); - for (int i = 0; i < xuio->uio_iovcnt; i++) { - int n; - void *base = xuio->uio_iov[i].iov_base; + if (skip_begin < iov->iov_len) { + pc->pc_size -= skip_begin; + iov->iov_base = (char *)iov->iov_base + skip_begin; + iov->iov_len -= skip_begin; + skip_begin = 0; + break; + } else { + pc->pc_size -= iov->iov_len; + skip_begin -= iov->iov_len; + pc->pc_iovcnt--; + i--; + pc->pc_iov++; + } + } + for (int i = pc->pc_iovcnt - 1; i >= 0 && skip_end; i--) { + struct iovec *iov = &pc->pc_iov[i]; - if (xuio->uio_rw == UIO_READ) { - n = src->uio_iov[i].iov_len - xuio->uio_iov[i].iov_len; - base = ((caddr_t) base) - n; + if (skip_end < iov->iov_len) { + pc->pc_size -= skip_end; + iov->iov_len -= skip_end; + skip_end = 0; + break; } else { - n = src->uio_iov[i].iov_len; + pc->pc_size -= iov->iov_len; + skip_end -= iov->iov_len; + pc->pc_iovcnt--; } - if (xuio->uio_rw == UIO_WRITE) - uiomove(base, n, src); - if (tr) - tr(base, n, arg); - if (xuio->uio_rw == UIO_READ) - uiomove(base, n, src); } } +void +pefs_chunk_shrink(struct pefs_chunk *pc, size_t size) +{ + pefs_chunk_crop(pc, 0, pc->pc_size - size); +} #ifdef DIAGNOSTIC #ifdef KDB -#define pe_checkvp_barrier 1 +#define pefs_checkvp_barrier 1 #else -#define pe_checkvp_barrier 0 +#define pefs_checkvp_barrier 0 #endif struct vnode * -pe_checkvp(vp, fil, lno) - struct vnode *vp; - char *fil; - int lno; +pefs_checkvp(struct vnode *vp, char *fil, int lno) { int interlock = 0; - struct pe_node *a = VTOPE(vp); + struct pefs_node *a = VTOPE(vp); #ifdef notyet /* * Can't do this check because vop_reclaim runs * with a funny vop vector. */ - if (vp->v_op != pe_vnodeop_p) { - printf ("pe_checkvp: on non-null-node\n"); - while (pe_checkvp_barrier) /*WAIT*/ ; - panic("pe_checkvp"); + if (vp->v_op != pefs_vnodeop_p) { + printf ("pefs_checkvp: on non-null-node\n"); + while (pefs_checkvp_barrier) /*WAIT*/ ; + panic("pefs_checkvp"); }; #endif - if (a->pe_lowervp == NULLVP) { + if (a->pefs_lowervp == NULLVP) { /* Should never happen */ int i; u_long *p; printf("vp = %p, ZERO ptr\n", (void *)vp); @@ -422,21 +538,21 @@ printf(" %lx", p[i]); printf("\n"); /* wait for debugger */ - while (pe_checkvp_barrier) /*WAIT*/ ; - panic("pe_checkvp"); + while (pefs_checkvp_barrier) /*WAIT*/ ; + panic("pefs_checkvp"); } if (mtx_owned(VI_MTX(vp)) != 0) { VI_UNLOCK(vp); interlock = 1; } - if (vrefcnt(a->pe_lowervp) < 1) { + if (vrefcnt(a->pefs_lowervp) < 1) { int i; u_long *p; printf("vp = %p, unref'ed lowervp\n", (void *)vp); for (p = (u_long *) a, i = 0; i < 8; i++) printf(" %lx", p[i]); printf("\n"); /* wait for debugger */ - while (pe_checkvp_barrier) /*WAIT*/ ; + while (pefs_checkvp_barrier) /*WAIT*/ ; panic ("null with unref'ed lowervp"); }; if (interlock != 0) @@ -444,9 +560,9 @@ #ifdef notyet printf("null %x/%d -> %x/%d [%s, %d]\n", PETOV(a), vrefcnt(PETOV(a)), - a->pe_lowervp, vrefcnt(a->pe_lowervp), + a->pn_lowervp, vrefcnt(a->pn_lowervp), fil, lno); #endif - return a->pe_lowervp; + return a->pn_lowervp; } #endif ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vfsops.c#2 (text+ko) ==== @@ -38,11 +38,6 @@ * $FreeBSD$ */ -/* - * Null Layer - * (See pe_vnops.c for a description of what this does.) - */ - #include #include #include @@ -58,16 +53,6 @@ static MALLOC_DEFINE(M_PEFSMNT, "pefs_mount", "PEFS mount structure"); -static vfs_fhtovp_t pefs_fhtovp; -static vfs_mount_t pefs_mount; -static vfs_quotactl_t pefs_quotactl; -static vfs_root_t pefs_root; -static vfs_sync_t pefs_sync; -static vfs_statfs_t pefs_statfs; -static vfs_unmount_t pefs_unmount; -static vfs_vget_t pefs_vget; -static vfs_extattrctl_t pefs_extattrctl; - /* * Mount null layer */ @@ -76,8 +61,8 @@ { int error = 0; struct vnode *lowerrootvp, *vp; - struct vnode *pem_rootvp; - struct pe_mount *xmp; + struct vnode *pm_rootvp; + struct pefs_mount *xmp; char *target; int isvnunlocked = 0, len; struct nameidata nd, *ndp = &nd; @@ -110,7 +95,7 @@ * Unlock lower node to avoid deadlock. * (XXX) VOP_ISLOCKED is needed? */ - if ((mp->mnt_vnodecovered->v_op == &pe_vnodeops) && + if ((mp->mnt_vnodecovered->v_op == &pefs_vnodeops) && VOP_ISLOCKED(mp->mnt_vnodecovered)) { VOP_UNLOCK(mp->mnt_vnodecovered, 0); isvnunlocked = 1; @@ -138,25 +123,25 @@ /* * Check multi null mount to avoid `lock against myself' panic. */ - if (lowerrootvp == VTOPE(mp->mnt_vnodecovered)->pe_lowervp) { + if (lowerrootvp == VTOPE(mp->mnt_vnodecovered)->pn_lowervp) { PEFSDEBUG("pefs_mount: multi null mount?\n"); vput(lowerrootvp); return (EDEADLK); } - xmp = (struct pe_mount *) malloc(sizeof(struct pe_mount), + xmp = (struct pefs_mount *) malloc(sizeof(struct pefs_mount), M_PEFSMNT, M_WAITOK); /* XXX */ /* * Save reference to underlying FS */ - xmp->pem_vfs = lowerrootvp->v_mount; + xmp->pm_vfs = lowerrootvp->v_mount; /* * Save reference. Each mount also holds * a reference on the root vnode. */ - error = pe_nodeget(mp, lowerrootvp, &vp); + error = pefs_nodeget(mp, lowerrootvp, &vp); /* * Make sure the node alias worked */ @@ -171,16 +156,16 @@ * Keep a held reference to the root vnode. * It is vrele'd in pefs_unmount. */ - pem_rootvp = vp; - pem_rootvp->v_vflag |= VV_ROOT; - xmp->pem_rootvp = pem_rootvp; + pm_rootvp = vp; + pm_rootvp->v_vflag |= VV_ROOT; + xmp->pm_rootvp = pm_rootvp; /* * Unlock the node (either the lower or the alias) */ VOP_UNLOCK(vp, 0); - if (PEVPTOLOWERVP(pem_rootvp)->v_mount->mnt_flag & MNT_LOCAL) { + if (PEVPTOLOWERVP(pm_rootvp)->v_mount->mnt_flag & MNT_LOCAL) { MNT_ILOCK(mp); mp->mnt_flag |= MNT_LOCAL; MNT_IUNLOCK(mp); @@ -202,9 +187,7 @@ * Free reference to null layer */ static int -pefs_unmount(mp, mntflags) - struct mount *mp; - int mntflags; +pefs_unmount(struct mount *mp, int mntflags) { void *mntdata; int error; @@ -215,13 +198,13 @@ if (mntflags & MNT_FORCE) flags |= FORCECLOSE; - /* There is 1 extra root vnode reference (pem_rootvp). */ + /* There is 1 extra root vnode reference (pm_rootvp). */ error = vflush(mp, 1, flags, curthread); if (error) return (error); /* - * Finally, throw away the pe_mount structure + * Finally, throw away the pefs_mount structure */ mntdata = mp->mnt_data; mp->mnt_data = 0; @@ -230,24 +213,21 @@ } static int -pefs_root(mp, flags, vpp) - struct mount *mp; - int flags; - struct vnode **vpp; +pefs_root(struct mount *mp, int flags, struct vnode **vpp) { struct vnode *vp; PEFSDEBUG("pefs_root(mp = %p, vp = %p->%p)\n", (void *)mp, - (void *)MOUNTTOPEMOUNT(mp)->pem_rootvp, - (void *)PEVPTOLOWERVP(MOUNTTOPEMOUNT(mp)->pem_rootvp)); + (void *)MOUNTTOPEMOUNT(mp)->pm_rootvp, + (void *)PEVPTOLOWERVP(MOUNTTOPEMOUNT(mp)->pm_rootvp)); /* * Return locked reference to root. */ - vp = MOUNTTOPEMOUNT(mp)->pem_rootvp; + vp = MOUNTTOPEMOUNT(mp)->pm_rootvp; VREF(vp); -#ifdef PEFS_DEBUG +#ifdef PEFSXXX_DEBUG if (VOP_ISLOCKED(vp)) panic("root vnode is locked.\n"); #endif @@ -257,30 +237,24 @@ } static int -pefs_quotactl(mp, cmd, uid, arg) - struct mount *mp; - int cmd; - uid_t uid; - void *arg; +pefs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg) { - return VFS_QUOTACTL(MOUNTTOPEMOUNT(mp)->pem_vfs, cmd, uid, arg); + return VFS_QUOTACTL(MOUNTTOPEMOUNT(mp)->pm_vfs, cmd, uid, arg); } static int -pefs_statfs(mp, sbp) - struct mount *mp; - struct statfs *sbp; +pefs_statfs(struct mount *mp, struct statfs *sbp) { int error; struct statfs mstat; PEFSDEBUG("pefs_statfs(mp = %p, vp = %p->%p)\n", (void *)mp, - (void *)MOUNTTOPEMOUNT(mp)->pem_rootvp, - (void *)PEVPTOLOWERVP(MOUNTTOPEMOUNT(mp)->pem_rootvp)); + (void *)MOUNTTOPEMOUNT(mp)->pm_rootvp, + (void *)PEVPTOLOWERVP(MOUNTTOPEMOUNT(mp)->pm_rootvp)); bzero(&mstat, sizeof(mstat)); - error = VFS_STATFS(MOUNTTOPEMOUNT(mp)->pem_vfs, &mstat); + error = VFS_STATFS(MOUNTTOPEMOUNT(mp)->pm_vfs, &mstat); if (error) return (error); @@ -298,9 +272,7 @@ } static int -pefs_sync(mp, waitfor) - struct mount *mp; - int waitfor; +pefs_sync(struct mount *mp, int waitfor) { /* * XXX - Assumes no data cached at null layer. @@ -309,48 +281,43 @@ } static int -pefs_vget(mp, ino, flags, vpp) - struct mount *mp; - ino_t ino; - int flags; - struct vnode **vpp; +pefs_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) { int error; - error = VFS_VGET(MOUNTTOPEMOUNT(mp)->pem_vfs, ino, flags, vpp); + error = VFS_VGET(MOUNTTOPEMOUNT(mp)->pm_vfs, ino, flags, vpp); if (error) return (error); - return (pe_nodeget(mp, *vpp, vpp)); + return (pefs_nodeget(mp, *vpp, vpp)); } static int -pefs_fhtovp(mp, fidp, vpp) - struct mount *mp; - struct fid *fidp; - struct vnode **vpp; +pefs_fhtovp(struct mount *mp, struct fid *fidp, struct vnode **vpp) { int error; - error = VFS_FHTOVP(MOUNTTOPEMOUNT(mp)->pem_vfs, fidp, vpp); + + error = VFS_FHTOVP(MOUNTTOPEMOUNT(mp)->pm_vfs, fidp, vpp); if (error) return (error); - return (pe_nodeget(mp, *vpp, vpp)); + error = pefs_nodeget(mp, *vpp, vpp); + printf("pefs_fhtovp: error=%d; vp=%p; v_object=%p\n", error, + !error ? *vpp : NULL, !error ? (*vpp)->v_object : NULL); + if (error) + return (error); + vnode_create_vobject(*vpp, 0, curthread); + return (error); } -static int -pefs_extattrctl(mp, cmd, filename_vp, namespace, attrname) - struct mount *mp; - int cmd; - struct vnode *filename_vp; - int namespace; - const char *attrname; +static int +pefs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp, int namespace, const char *attrname) { - return VFS_EXTATTRCTL(MOUNTTOPEMOUNT(mp)->pem_vfs, cmd, filename_vp, + return VFS_EXTATTRCTL(MOUNTTOPEMOUNT(mp)->pm_vfs, cmd, filename_vp, namespace, attrname); >>> TRUNCATED FOR MAIL (1000 lines) <<<