For spe, I need to understand the database stuff in usr/src/uts/common/fs/nfs/nfs4_db.c. Note that this code is not part of the NFSv4 spec, it is a Sun implementation detail. Specifically, I need to know how to create two indexes on the same set of data. I could create two tables, but I think having a second copy is overkill. Also, it would be ugly to make sure that they stayed in sync.
The issue is that I need to keep track of mapping from data source name to guuid. Whereas the existing code only needs to be aware of the guuid.
I've gone through this code in the past, but I've forgotten most of what I learned. So I'm going to walk through it and annotate it here. I'll provide quick links which should stay relevant as the code changes.
We can see the server start to use the database code in rfs4_state_init:
1238 /* Create the overall database to hold all server state */ 1239 rfs4_server_state = rfs4_database_create(rfs4_database_debug);
It then creates some tables and indexes:
1241 /* Now create the individual tables */ 1242 rfs4_client_cache_time *= rfs4_lease_time; 1243 rfs4_client_tab = rfs4_table_create(rfs4_server_state, 1244 "Client", 1245 rfs4_client_cache_time, 1246 2, 1247 rfs4_client_create, 1248 rfs4_client_destroy, 1249 rfs4_client_expiry, 1250 sizeof (rfs4_client_t), 1251 TABSIZE, 1252 MAXTABSZ/8, 100); 1253 rfs4_nfsclnt_idx = rfs4_index_create(rfs4_client_tab, 1254 "nfs_client_id4", nfsclnt_hash, 1255 nfsclnt_compare, nfsclnt_mkkey, 1256 TRUE); 1257 rfs4_clientid_idx = rfs4_index_create(rfs4_client_tab, 1258 "client_id", clientid_hash, 1259 clientid_compare, clientid_mkkey, 1260 FALSE);
Looks like I now know I can create two different indexes on the same table.
Of interest is that there is only one index that can be used to create the table. That is given by the last parameter to rfs4_index_create. Indeed, we can see that rfs4_nfsclnt_idx is the create index for rfs4_client_tab.
BTW: Using the naming convention (see Some usr/src/uts/common/fs/nfs naming conventions)< we can easily tell that the code, table, and indexes are all for the NFSv4 server.
Going back to the code, we can see this property is enforced:
381 if (createable) {
382 table->ccnt++;
383 if (table->ccnt > 1)
384 panic("Table %s currently can have only have one "
385 "index that will allow creation of entries",
386 table->name);
387 idx->createable = TRUE;
388 } else {
389 idx->createable = FALSE;
390 }
Lines 383-384 are basically a VERIFY which spits out useful information. Note that only developers should see this panic as it should happen the first time they try to boot up a kernel. I.e., the index creation is not normally runtime dependent on executing special paths.
Hmm, that was quick. I guess when I have to dive further, I'll add more annotation. ;>