931
932 /*
933 * See if we have an existing shadow
934 * If none, we have to manufacture one
935 */
936 mutex_enter(&dctable_lock);
937 dp = dcfind(vp);
938 mutex_exit(&dctable_lock);
939 if (dp != NULL)
940 return (DCTOV(dp));
941
942 /*
943 * Make sure it's a valid compressed file
944 */
945 hdr = &thdr;
946 error = vn_rdwr(UIO_READ, vp, (caddr_t)hdr, sizeof (struct comphdr), 0,
947 UIO_SYSSPACE, 0, 0, cred, NULL);
948 if (error || hdr->ch_magic != CH_MAGIC_ZLIB ||
949 hdr->ch_version != CH_VERSION || hdr->ch_algorithm != CH_ALG_ZLIB ||
950 hdr->ch_fsize == 0 || hdr->ch_blksize < PAGESIZE ||
951 hdr->ch_blksize > ptob(DCCACHESIZE) ||
952 (hdr->ch_blksize & (hdr->ch_blksize - 1)) != 0)
953 return (NULL);
954
955 /* get underlying file size */
956 if (VOP_GETATTR(vp, &vattr, 0, cred, ctp) != 0)
957 return (NULL);
958
959 /*
960 * Re-read entire header
961 */
962 hdrsize = hdr->ch_blkmap[0] + sizeof (uint64_t);
963 hdr = kmem_alloc(hdrsize, KM_SLEEP);
964 error = vn_rdwr(UIO_READ, vp, (caddr_t)hdr, hdrsize, 0, UIO_SYSSPACE,
965 0, 0, cred, NULL);
966 if (error) {
967 kmem_free(hdr, hdrsize);
968 return (NULL);
969 }
970
971 /*
972 * add extra blkmap entry to make dc_getblock()'s
|
931
932 /*
933 * See if we have an existing shadow
934 * If none, we have to manufacture one
935 */
936 mutex_enter(&dctable_lock);
937 dp = dcfind(vp);
938 mutex_exit(&dctable_lock);
939 if (dp != NULL)
940 return (DCTOV(dp));
941
942 /*
943 * Make sure it's a valid compressed file
944 */
945 hdr = &thdr;
946 error = vn_rdwr(UIO_READ, vp, (caddr_t)hdr, sizeof (struct comphdr), 0,
947 UIO_SYSSPACE, 0, 0, cred, NULL);
948 if (error || hdr->ch_magic != CH_MAGIC_ZLIB ||
949 hdr->ch_version != CH_VERSION || hdr->ch_algorithm != CH_ALG_ZLIB ||
950 hdr->ch_fsize == 0 || hdr->ch_blksize < PAGESIZE ||
951 hdr->ch_blksize > ptob(DCCACHESIZE) || !ISP2(hdr->ch_blksize))
952 return (NULL);
953
954 /* get underlying file size */
955 if (VOP_GETATTR(vp, &vattr, 0, cred, ctp) != 0)
956 return (NULL);
957
958 /*
959 * Re-read entire header
960 */
961 hdrsize = hdr->ch_blkmap[0] + sizeof (uint64_t);
962 hdr = kmem_alloc(hdrsize, KM_SLEEP);
963 error = vn_rdwr(UIO_READ, vp, (caddr_t)hdr, hdrsize, 0, UIO_SYSSPACE,
964 0, 0, cred, NULL);
965 if (error) {
966 kmem_free(hdr, hdrsize);
967 return (NULL);
968 }
969
970 /*
971 * add extra blkmap entry to make dc_getblock()'s
|