Example #1
0
/**
 * add an entry to the volume group cache.
 *
 * @param[in] dp       disk partition object
 * @param[in] parent   parent volume id
 * @param[in] child    child volume id
 * @param[out] newvg   if non-NULL, *newvg is 1 if adding this added a
 *                     new VG, 0 if we added to an existing VG
 *
 * @return operation status
 *    @retval 0 success
 */
int
VVGCache_entry_add(struct DiskPartition64 * dp,
		   VolumeId parent,
		   VolumeId child,
		   afs_int32 *newvg)
{
    int code = 0;

    VOL_LOCK;
    VVGCache_entry_add_r(dp, parent, child, newvg);
    VOL_UNLOCK;

    return code;
}
Example #2
0
/**
 * flush thread-local scan table to the global VG cache.
 *
 * @param[in] tbl     scan table
 * @param[in] dp      disk partition object
 *
 * @pre VOL_LOCK is NOT held
 *
 * @return operation status
 *    @retval 0 success
 *    @retval nonzero a VVGCache_entry_add_r operation failed during a
 *                    flush of the thread-local table
 *
 * @internal
 */
static int
_VVGC_scan_table_flush(VVGCache_scan_table_t * tbl,
		       struct DiskPartition64 * dp)
{
    int code = 0, res, i;
    afs_int32 newvg = 0;
    unsigned long newvols, newvgs;

    newvols = tbl->newvols;
    newvgs = tbl->newvgs;

    VOL_LOCK;

    for (i = 0; i < tbl->idx; i++) {
	/*
	 * We need to check the 'to-delete' list and prevent adding any entries
	 * that are on it. The volser could potentially create a volume in one
	 * VG, then delete it and put it on another VG. If we are doing a scan
	 * when that happens, tbl->entries could have the entries for trying to
	 * put the vol on both VGs, though at least one of them will also be on
	 * the dlist.  If we put everything in tbl->entries on the VGC then try
	 * to delete afterwards, putting one entry on the VGC cause an error,
	 * and we'll fail to add it. So instead, avoid adding any new VGC
	 * entries if it is on the dlist.
	 */
	if (_VVGC_dlist_lookup_r(dp, tbl->entries[i].parent,
			         tbl->entries[i].volid)) {
	    continue;
	}
	res = VVGCache_entry_add_r(dp,
				   tbl->entries[i].parent,
				   tbl->entries[i].volid,
				   &newvg);
	if (res) {
	    code = res;
	} else {
	    newvols++;
	    newvgs += newvg;
	}
    }

    /* flush the to-delete list while we're here. We don't need to preserve
     * the list across the entire scan, and flushing it each time we flush
     * a scan table will keep the size of the dlist down */
    _VVGC_flush_dlist(dp);

    VOL_UNLOCK;

    ViceLog(125, ("VVGC_scan_table_flush: flushed %d entries from "
                  "scan table to global VG cache\n", tbl->idx));
    ViceLog(125, ("VVGC_scan_table_flush: %s total: %lu vols, %lu groups\n",
                  VPartitionPath(dp), newvols, newvgs));

    res = _VVGC_scan_table_init(tbl);
    if (res) {
	code = res;
    }

    tbl->newvols = newvols;
    tbl->newvgs = newvgs;

    return code;
}