| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ufs_quota2.c,v 1.20 2012/01/29 07:04:21 dholland Exp $ */ | | 1 | /* $NetBSD: ufs_quota2.c,v 1.21 2012/01/29 07:05:12 dholland Exp $ */ |
2 | /*- | | 2 | /*- |
3 | * Copyright (c) 2010 Manuel Bouyer | | 3 | * Copyright (c) 2010 Manuel Bouyer |
4 | * All rights reserved. | | 4 | * All rights reserved. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * | | 14 | * |
| @@ -16,27 +16,27 @@ | | | @@ -16,27 +16,27 @@ |
16 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 16 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
17 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 17 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
18 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 18 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
19 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 19 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 | * POSSIBILITY OF SUCH DAMAGE. | | 25 | * POSSIBILITY OF SUCH DAMAGE. |
26 | */ | | 26 | */ |
27 | | | 27 | |
28 | #include <sys/cdefs.h> | | 28 | #include <sys/cdefs.h> |
29 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.20 2012/01/29 07:04:21 dholland Exp $"); | | 29 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.21 2012/01/29 07:05:12 dholland Exp $"); |
30 | | | 30 | |
31 | #include <sys/buf.h> | | 31 | #include <sys/buf.h> |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/kernel.h> | | 33 | #include <sys/kernel.h> |
34 | #include <sys/systm.h> | | 34 | #include <sys/systm.h> |
35 | #include <sys/malloc.h> | | 35 | #include <sys/malloc.h> |
36 | #include <sys/namei.h> | | 36 | #include <sys/namei.h> |
37 | #include <sys/file.h> | | 37 | #include <sys/file.h> |
38 | #include <sys/proc.h> | | 38 | #include <sys/proc.h> |
39 | #include <sys/vnode.h> | | 39 | #include <sys/vnode.h> |
40 | #include <sys/mount.h> | | 40 | #include <sys/mount.h> |
41 | #include <sys/fstrans.h> | | 41 | #include <sys/fstrans.h> |
42 | #include <sys/kauth.h> | | 42 | #include <sys/kauth.h> |
| @@ -819,27 +819,28 @@ quota2_handle_cmd_delete(struct ufsmount | | | @@ -819,27 +819,28 @@ quota2_handle_cmd_delete(struct ufsmount |
819 | out_dqlock: | | 819 | out_dqlock: |
820 | mutex_exit(&dqlock); | | 820 | mutex_exit(&dqlock); |
821 | out_wapbl: | | 821 | out_wapbl: |
822 | UFS_WAPBL_END(ump->um_mountp); | | 822 | UFS_WAPBL_END(ump->um_mountp); |
823 | out_il: | | 823 | out_il: |
824 | mutex_exit(&dq->dq_interlock); | | 824 | mutex_exit(&dq->dq_interlock); |
825 | out_dq: | | 825 | out_dq: |
826 | dqrele(NULLVP, dq); | | 826 | dqrele(NULLVP, dq); |
827 | return error; | | 827 | return error; |
828 | } | | 828 | } |
829 | | | 829 | |
830 | static int | | 830 | static int |
831 | quota2_result_add_q2e(struct ufsmount *ump, int idtype, | | 831 | quota2_result_add_q2e(struct ufsmount *ump, int idtype, |
832 | int id, struct quota_getall_result *result, unsigned pos) | | 832 | int id, struct quota_getall_result *result, unsigned pos, |
| | | 833 | int skipfirst, int skiplast) |
833 | { | | 834 | { |
834 | struct dquot *dq; | | 835 | struct dquot *dq; |
835 | int error; | | 836 | int error; |
836 | struct quota2_entry *q2ep, q2e; | | 837 | struct quota2_entry *q2ep, q2e; |
837 | struct buf *bp; | | 838 | struct buf *bp; |
838 | const int needswap = UFS_MPNEEDSWAP(ump); | | 839 | const int needswap = UFS_MPNEEDSWAP(ump); |
839 | | | 840 | |
840 | error = dqget(NULLVP, id, ump, idtype, &dq); | | 841 | error = dqget(NULLVP, id, ump, idtype, &dq); |
841 | if (error) | | 842 | if (error) |
842 | return error; | | 843 | return error; |
843 | | | 844 | |
844 | mutex_enter(&dq->dq_interlock); | | 845 | mutex_enter(&dq->dq_interlock); |
845 | if (dq->dq2_lblkno == 0 && dq->dq2_blkoff == 0) { | | 846 | if (dq->dq2_lblkno == 0 && dq->dq2_blkoff == 0) { |
| @@ -849,35 +850,41 @@ quota2_result_add_q2e(struct ufsmount *u | | | @@ -849,35 +850,41 @@ quota2_result_add_q2e(struct ufsmount *u |
849 | } | | 850 | } |
850 | error = getq2e(ump, idtype, dq->dq2_lblkno, dq->dq2_blkoff, | | 851 | error = getq2e(ump, idtype, dq->dq2_lblkno, dq->dq2_blkoff, |
851 | &bp, &q2ep, 0); | | 852 | &bp, &q2ep, 0); |
852 | if (error) { | | 853 | if (error) { |
853 | mutex_exit(&dq->dq_interlock); | | 854 | mutex_exit(&dq->dq_interlock); |
854 | dqrele(NULLVP, dq); | | 855 | dqrele(NULLVP, dq); |
855 | return error; | | 856 | return error; |
856 | } | | 857 | } |
857 | quota2_ufs_rwq2e(q2ep, &q2e, needswap); | | 858 | quota2_ufs_rwq2e(q2ep, &q2e, needswap); |
858 | brelse(bp, 0); | | 859 | brelse(bp, 0); |
859 | mutex_exit(&dq->dq_interlock); | | 860 | mutex_exit(&dq->dq_interlock); |
860 | dqrele(NULLVP, dq); | | 861 | dqrele(NULLVP, dq); |
861 | | | 862 | |
862 | result->qr_keys[pos].qk_idtype = idtype; | | 863 | if (skipfirst == 0) { |
863 | result->qr_keys[pos].qk_objtype = QUOTA_OBJTYPE_BLOCKS; | | 864 | result->qr_keys[pos].qk_idtype = idtype; |
864 | q2e_to_quotaval(&q2e, 0, &result->qr_keys[pos].qk_id, | | 865 | result->qr_keys[pos].qk_objtype = QUOTA_OBJTYPE_BLOCKS; |
865 | QL_BLOCK, &result->qr_vals[pos]); | | 866 | q2e_to_quotaval(&q2e, 0, &result->qr_keys[pos].qk_id, |
866 | | | 867 | QL_BLOCK, &result->qr_vals[pos]); |
867 | result->qr_keys[pos+1].qk_idtype = idtype; | | 868 | pos++; |
868 | result->qr_keys[pos+1].qk_objtype = QUOTA_OBJTYPE_FILES; | | 869 | } |
869 | q2e_to_quotaval(&q2e, 0, &result->qr_keys[pos+1].qk_id, | | 870 | |
870 | QL_FILE, &result->qr_vals[pos+1]); | | 871 | if (skiplast == 0) { |
| | | 872 | result->qr_keys[pos].qk_idtype = idtype; |
| | | 873 | result->qr_keys[pos].qk_objtype = QUOTA_OBJTYPE_FILES; |
| | | 874 | q2e_to_quotaval(&q2e, 0, &result->qr_keys[pos].qk_id, |
| | | 875 | QL_FILE, &result->qr_vals[pos]); |
| | | 876 | pos++; |
| | | 877 | } |
871 | | | 878 | |
872 | return 0; | | 879 | return 0; |
873 | } | | 880 | } |
874 | | | 881 | |
875 | static int | | 882 | static int |
876 | quota2_fetch_q2e(struct ufsmount *ump, const struct quotakey *qk, | | 883 | quota2_fetch_q2e(struct ufsmount *ump, const struct quotakey *qk, |
877 | struct quotaval *ret) | | 884 | struct quotaval *ret) |
878 | { | | 885 | { |
879 | struct dquot *dq; | | 886 | struct dquot *dq; |
880 | int error; | | 887 | int error; |
881 | struct quota2_entry *q2ep, q2e; | | 888 | struct quota2_entry *q2ep, q2e; |
882 | struct buf *bp; | | 889 | struct buf *bp; |
883 | const int needswap = UFS_MPNEEDSWAP(ump); | | 890 | const int needswap = UFS_MPNEEDSWAP(ump); |
| @@ -987,26 +994,27 @@ q2cursor_check(struct ufsq2_cursor *curs | | | @@ -987,26 +994,27 @@ q2cursor_check(struct ufsq2_cursor *curs |
987 | } | | 994 | } |
988 | if (cursor->q2c_blocks_done != 0 && cursor->q2c_blocks_done != 1) { | | 995 | if (cursor->q2c_blocks_done != 0 && cursor->q2c_blocks_done != 1) { |
989 | return EINVAL; | | 996 | return EINVAL; |
990 | } | | 997 | } |
991 | return 0; | | 998 | return 0; |
992 | } | | 999 | } |
993 | | | 1000 | |
994 | struct getuids { | | 1001 | struct getuids { |
995 | long nuids; /* number of uids in array */ | | 1002 | long nuids; /* number of uids in array */ |
996 | long size; /* size of array */ | | 1003 | long size; /* size of array */ |
997 | uid_t *uids; /* array of uids, dynamically allocated */ | | 1004 | uid_t *uids; /* array of uids, dynamically allocated */ |
998 | long skip; | | 1005 | long skip; |
999 | long seen; | | 1006 | long seen; |
| | | 1007 | long limit; |
1000 | }; | | 1008 | }; |
1001 | | | 1009 | |
1002 | static int | | 1010 | static int |
1003 | quota2_getuids_callback(struct ufsmount *ump, uint64_t *offp, | | 1011 | quota2_getuids_callback(struct ufsmount *ump, uint64_t *offp, |
1004 | struct quota2_entry *q2ep, uint64_t off, void *v) | | 1012 | struct quota2_entry *q2ep, uint64_t off, void *v) |
1005 | { | | 1013 | { |
1006 | struct getuids *gu = v; | | 1014 | struct getuids *gu = v; |
1007 | uid_t *newuids; | | 1015 | uid_t *newuids; |
1008 | #ifdef FFS_EI | | 1016 | #ifdef FFS_EI |
1009 | const int needswap = UFS_MPNEEDSWAP(ump); | | 1017 | const int needswap = UFS_MPNEEDSWAP(ump); |
1010 | #endif | | 1018 | #endif |
1011 | | | 1019 | |
1012 | if (gu->skip > 0) { | | 1020 | if (gu->skip > 0) { |
| @@ -1016,46 +1024,50 @@ quota2_getuids_callback(struct ufsmount | | | @@ -1016,46 +1024,50 @@ quota2_getuids_callback(struct ufsmount |
1016 | if (gu->nuids == gu->size) { | | 1024 | if (gu->nuids == gu->size) { |
1017 | newuids = realloc(gu->uids, gu->size + PAGE_SIZE, M_TEMP, | | 1025 | newuids = realloc(gu->uids, gu->size + PAGE_SIZE, M_TEMP, |
1018 | M_WAITOK); | | 1026 | M_WAITOK); |
1019 | if (newuids == NULL) { | | 1027 | if (newuids == NULL) { |
1020 | free(gu->uids, M_TEMP); | | 1028 | free(gu->uids, M_TEMP); |
1021 | return ENOMEM; | | 1029 | return ENOMEM; |
1022 | } | | 1030 | } |
1023 | gu->uids = newuids; | | 1031 | gu->uids = newuids; |
1024 | gu->size += (PAGE_SIZE / sizeof(uid_t)); | | 1032 | gu->size += (PAGE_SIZE / sizeof(uid_t)); |
1025 | } | | 1033 | } |
1026 | gu->uids[gu->nuids] = ufs_rw32(q2ep->q2e_uid, needswap); | | 1034 | gu->uids[gu->nuids] = ufs_rw32(q2ep->q2e_uid, needswap); |
1027 | gu->nuids++; | | 1035 | gu->nuids++; |
1028 | gu->seen++; | | 1036 | gu->seen++; |
| | | 1037 | if (gu->nuids == gu->limit) { |
| | | 1038 | return Q2WL_ABORT; |
| | | 1039 | } |
1029 | return 0; | | 1040 | return 0; |
1030 | } | | 1041 | } |
1031 | | | 1042 | |
1032 | int | | 1043 | int |
1033 | quota2_handle_cmd_getall(struct ufsmount *ump, struct quotakcursor *qkc, | | 1044 | quota2_handle_cmd_getall(struct ufsmount *ump, struct quotakcursor *qkc, |
1034 | int idtype, struct quota_getall_result *result) | | 1045 | int idtype, struct quota_getall_result *result) |
1035 | { | | 1046 | { |
1036 | int error; | | 1047 | int error; |
1037 | struct ufsq2_cursor *cursor; | | 1048 | struct ufsq2_cursor *cursor; |
1038 | struct quota2_header *q2h; | | 1049 | struct quota2_header *q2h; |
1039 | struct quota2_entry q2e; | | 1050 | struct quota2_entry q2e; |
1040 | struct buf *hbp; | | 1051 | struct buf *hbp; |
1041 | uint64_t offset; | | 1052 | uint64_t offset; |
1042 | int i, j; | | 1053 | int i, j; |
1043 | int quota2_hash_size; | | 1054 | int quota2_hash_size; |
1044 | const int needswap = UFS_MPNEEDSWAP(ump); | | 1055 | const int needswap = UFS_MPNEEDSWAP(ump); |
1045 | struct getuids gu; | | 1056 | struct getuids gu; |
1046 | id_t junkid; | | 1057 | id_t junkid; |
1047 | struct quotaval qv; | | 1058 | struct quotaval qv; |
1048 | unsigned num, maxnum; | | 1059 | unsigned num, maxnum; |
| | | 1060 | int skipfirst, skiplast; |
1049 | | | 1061 | |
1050 | cursor = Q2CURSOR(qkc); | | 1062 | cursor = Q2CURSOR(qkc); |
1051 | error = q2cursor_check(cursor); | | 1063 | error = q2cursor_check(cursor); |
1052 | if (error) { | | 1064 | if (error) { |
1053 | return error; | | 1065 | return error; |
1054 | } | | 1066 | } |
1055 | | | 1067 | |
1056 | if (ump->um_quotas[idtype] == NULLVP) { | | 1068 | if (ump->um_quotas[idtype] == NULLVP) { |
1057 | return ENODEV; | | 1069 | return ENODEV; |
1058 | } | | 1070 | } |
1059 | | | 1071 | |
1060 | mutex_enter(&dqlock); | | 1072 | mutex_enter(&dqlock); |
1061 | error = getq2h(ump, idtype, &hbp, &q2h, 0); | | 1073 | error = getq2h(ump, idtype, &hbp, &q2h, 0); |
| @@ -1088,64 +1100,87 @@ quota2_handle_cmd_getall(struct ufsmount | | | @@ -1088,64 +1100,87 @@ quota2_handle_cmd_getall(struct ufsmount |
1088 | memset(&gu, 0, sizeof(gu)); | | 1100 | memset(&gu, 0, sizeof(gu)); |
1089 | quota2_hash_size = ufs_rw16(q2h->q2h_hash_size, needswap); | | 1101 | quota2_hash_size = ufs_rw16(q2h->q2h_hash_size, needswap); |
1090 | | | 1102 | |
1091 | /* if the table size has changed, make the caller start over */ | | 1103 | /* if the table size has changed, make the caller start over */ |
1092 | if (cursor->q2c_hashsize == 0) { | | 1104 | if (cursor->q2c_hashsize == 0) { |
1093 | cursor->q2c_hashsize = quota2_hash_size; | | 1105 | cursor->q2c_hashsize = quota2_hash_size; |
1094 | } else if (cursor->q2c_hashsize != quota2_hash_size) { | | 1106 | } else if (cursor->q2c_hashsize != quota2_hash_size) { |
1095 | error = EDEADLK; | | 1107 | error = EDEADLK; |
1096 | goto fail; | | 1108 | goto fail; |
1097 | } | | 1109 | } |
1098 | | | 1110 | |
1099 | gu.skip = cursor->q2c_uidpos; | | 1111 | gu.skip = cursor->q2c_uidpos; |
1100 | gu.seen = 0; | | 1112 | gu.seen = 0; |
| | | 1113 | gu.limit = result->qr_max / 2; |
| | | 1114 | if (gu.limit == 0 && result->qr_max > 0) { |
| | | 1115 | gu.limit = 1; |
| | | 1116 | } |
1101 | for (i = cursor->q2c_hashpos; i < quota2_hash_size ; i++) { | | 1117 | for (i = cursor->q2c_hashpos; i < quota2_hash_size ; i++) { |
1102 | offset = q2h->q2h_entries[i]; | | 1118 | offset = q2h->q2h_entries[i]; |
1103 | gu.seen = 0; | | 1119 | gu.seen = 0; |
1104 | error = quota2_walk_list(ump, hbp, idtype, &offset, 0, &gu, | | 1120 | error = quota2_walk_list(ump, hbp, idtype, &offset, 0, &gu, |
1105 | quota2_getuids_callback); | | 1121 | quota2_getuids_callback); |
| | | 1122 | if (error == Q2WL_ABORT) { |
| | | 1123 | /* got enough uids for now */ |
| | | 1124 | error = 0; |
| | | 1125 | break; |
| | | 1126 | } |
1106 | if (error) { | | 1127 | if (error) { |
1107 | if (gu.uids != NULL) | | 1128 | if (gu.uids != NULL) |
1108 | free(gu.uids, M_TEMP); | | 1129 | free(gu.uids, M_TEMP); |
1109 | break; | | 1130 | break; |
1110 | } | | 1131 | } |
1111 | } | | 1132 | } |
1112 | cursor->q2c_hashpos = i; | | 1133 | cursor->q2c_hashpos = i; |
1113 | cursor->q2c_uidpos = gu.seen; | | 1134 | cursor->q2c_uidpos = gu.seen; |
1114 | | | 1135 | |
1115 | fail: | | 1136 | fail: |
1116 | mutex_exit(&dqlock); | | 1137 | mutex_exit(&dqlock); |
1117 | brelse(hbp, 0); | | 1138 | brelse(hbp, 0); |
1118 | if (error) | | 1139 | if (error) |
1119 | return error; | | 1140 | return error; |
1120 | | | 1141 | |
1121 | maxnum = gu.nuids*2; | | 1142 | maxnum = gu.nuids*2; |
1122 | result->qr_keys = malloc(maxnum * sizeof(result->qr_keys[0]), | | 1143 | result->qr_keys = malloc(maxnum * sizeof(result->qr_keys[0]), |
1123 | M_TEMP, M_WAITOK); | | 1144 | M_TEMP, M_WAITOK); |
1124 | result->qr_vals = malloc(maxnum * sizeof(result->qr_vals[0]), | | 1145 | result->qr_vals = malloc(maxnum * sizeof(result->qr_vals[0]), |
1125 | M_TEMP, M_WAITOK); | | 1146 | M_TEMP, M_WAITOK); |
1126 | | | 1147 | |
| | | 1148 | /* |
| | | 1149 | * If we've already sent back the blocks value for the first id, |
| | | 1150 | * don't send it again (skipfirst). |
| | | 1151 | * |
| | | 1152 | * If we have an odd number of available result slots and we |
| | | 1153 | * aren't going to skip the first result entry, we need to |
| | | 1154 | * leave off the last result entry (skiplast). |
| | | 1155 | */ |
| | | 1156 | skipfirst = (cursor->q2c_blocks_done != 0); |
| | | 1157 | skiplast = skipfirst == 0 && (result->qr_max < maxnum); |
1127 | num = 0; | | 1158 | num = 0; |
1128 | for (j = 0; j < gu.nuids; j++) { | | 1159 | for (j = 0; j < gu.nuids; j++) { |
1129 | error = quota2_result_add_q2e(ump, idtype, | | 1160 | error = quota2_result_add_q2e(ump, idtype, |
1130 | gu.uids[j], result, j*2); | | 1161 | gu.uids[j], result, j*2, |
| | | 1162 | j == 0 && skipfirst, |
| | | 1163 | j + 1 == gu.nuids && skiplast); |
1131 | if (error == ENOENT) | | 1164 | if (error == ENOENT) |
1132 | continue; | | 1165 | continue; |
1133 | if (error) | | 1166 | if (error) |
1134 | break; | | 1167 | break; |
1135 | num += 2; | | 1168 | num += 2; |
1136 | } | | 1169 | } |
1137 | result->qr_num = num; | | 1170 | result->qr_num = num; |
1138 | | | 1171 | |
| | | 1172 | cursor->q2c_blocks_done = skiplast; |
| | | 1173 | |
1139 | free(gu.uids, M_TEMP); | | 1174 | free(gu.uids, M_TEMP); |
1140 | return error; | | 1175 | return error; |
1141 | } | | 1176 | } |
1142 | | | 1177 | |
1143 | int | | 1178 | int |
1144 | quota2_handle_cmd_cursoropen(struct ufsmount *ump, struct quotakcursor *qkc) | | 1179 | quota2_handle_cmd_cursoropen(struct ufsmount *ump, struct quotakcursor *qkc) |
1145 | { | | 1180 | { |
1146 | struct ufsq2_cursor *cursor; | | 1181 | struct ufsq2_cursor *cursor; |
1147 | | | 1182 | |
1148 | CTASSERT(sizeof(*cursor) <= sizeof(qkc->u.qkc_space)); | | 1183 | CTASSERT(sizeof(*cursor) <= sizeof(qkc->u.qkc_space)); |
1149 | cursor = Q2CURSOR(qkc); | | 1184 | cursor = Q2CURSOR(qkc); |
1150 | | | 1185 | |
1151 | cursor->q2c_magic = Q2C_MAGIC; | | 1186 | cursor->q2c_magic = Q2C_MAGIC; |