📄 log_work.c
字号:
last_slot->next = sidx; dtrt->header.freecnt += 1; last_slot = &(dtrt->slot[sidx]); } /* end if */ } /* end for */ last_slot->next = -1; /* terminate the chain */ } /* end found a free one */ return (0);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME: findCommit(tid) * * FUNCTION: Search in the commit array for a commit record with * transaction id (tid) matching the given tid. * Return the commit array index where found, or 0 * if not found. */int findCommit(int32_t tid){ /* transaction id */ int32_t k, hash; hash = tid & comhmask; /* hash class */ for (k = comhash[hash]; k != 0; k = com[k].next) if (com[k].tid == tid) return (k); return (0); /* not found */}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME: findPageRedo() * * FUNCTION: Search in the RedoPage hash table for a record * containing the block address in the given pxd. * If no match is found, such a record is created and * inserted into the table. * * The address of the found (or created) doblk is * returned. * */int findPageRedo(int32_t aggregate, /* file system aggregate/lv number */ pxd_t pxd, /* on-disk page pxd */ struct doblk **doptr){ int rc = 0; int32_t hash; struct doblk *dp; int32_t allocated_from_bmap = 0; /* * Search for a record with matching aggregate, and block offset. */ hash = (aggregate + addressPXD(&pxd)) & blkhmask; for (dp = blkhash[hash]; dp != NULL; dp = dp->next) if (dp->aggregate == aggregate && addressPXD(&dp->pxd) == addressPXD(&pxd)) { /* * match found. return its address to caller */ *doptr = dp; return (0); } /* * No match was found. */ /* * if there are no available doblk records, * allocate some storage */ if (Freedoblk == 0) { fsck_send_msg(lrdo_ALLOC4DOBLK, PSIZE); rc = alloc_storage((uint32_t) PSIZE, (void **) &Blkpage, &allocated_from_bmap); if ((rc != 0) || (Blkpage == NULL)) { fsck_send_msg(lrdo_ALLOC4DOBLKFAIL, PSIZE); return (ENOMEM4); } if (allocated_from_bmap) { fsck_send_msg(lrdo_USINGBMAPALLOC4DOBLK); } Freedoblk = PSIZE / sizeof (struct doblk); } dp = Blkpage; /* * Allocate a doblk record and initialize it * with the given aggregate and block * offset. Insert the record into the RedoPage * hash table. */ numdoblk++; Blkpage++; Freedoblk--; dp->next = blkhash[hash]; blkhash[hash] = dp; dp->aggregate = aggregate; dp->pxd = pxd; dp->type = 0; memset(&dp->summary, 0, sizeof (dp->summary)); /* * return the address of the created doblk to caller */ *doptr = dp; return (0);}int open_device(dev_t device){ char dev_name[100]; char dev_path[110]; char line[110]; FILE *pp; int maj, min, size, fd; pp = fopen("/proc/partitions", "r"); if (!pp) { printf("Could not open /proc/partitions\n"); return -ENODEV; } while (fgets(line, sizeof (line), pp)) { if (sscanf(line, "%d %d %d %[^\n ]", &maj, &min, &size, dev_name) != 4) continue; if ((maj == major(device)) && (min == minor(device))) { fclose(pp); sprintf(dev_path, "/dev/%s", dev_name); fd = open(dev_path, O_RDWR); return fd; } } fclose(pp); return -ENODEV;}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME: logredoInit() * * FUNCTION: allocate/initialize runtime data structures and * initialize for file systems sharing the log. */int logredoInit(){ int rc = 0; int k; int allocated_from_bmap = 0; /* * init free list for com. index 0 is not used. */ comfree = 1; for (k = 1; k < COMSIZE; k++) com[k].next = k + 1; /* * init comhash chains */ for (k = 0; k < 64; k++) comhash[k] = 0; /* * init block hash chains */ numdoblk = 0; for (k = 0; k < BHASHSIZE; k++) blkhash[k] = NULL; /* * allocate one page space for redo page hash table */ fsck_send_msg(lrdo_ALLOC4REDOPG, PSIZE); rc = alloc_storage((uint32_t) PSIZE, (void **) &Blkpage, &allocated_from_bmap); if ((rc != 0) || (Blkpage == NULL)) { /* RedoPage record allocation failed */ fsck_send_msg(lrdo_ALLOC4REDOPGFAIL, PSIZE); return (ENOMEM5); } if (allocated_from_bmap) { fsck_send_msg(lrdo_USINGBMAPALLOC4RDPG); } Freedoblk = PSIZE / sizeof (struct doblk); /* * init nodofile hash chains , and counts */ numnodofile = 0; for (k = 0; k < NODOFILEHASHSIZE; k++) nodofilehash[k] = NULL; /* * allocate one page space for nodo file hash table */ fsck_send_msg(lrdo_ALLOC4NODOFL, PSIZE); rc = alloc_storage((uint32_t) PSIZE, (void **) &Nodofilep, &allocated_from_bmap); if ((rc != 0) || (Nodofilep == NULL)) { /* RedoPage record allocation failed */ fsck_send_msg(lrdo_ALLOC4NODOFLFAIL, PSIZE); return (ENOMEM6); } if (allocated_from_bmap) { fsck_send_msg(lrdo_USINGBMAPALLOC4NDFL); } Freenodofile = PSIZE / sizeof (struct nodofile); /* init buffer pool */ for (k = 0; k < NBUFPOOL; k++) { bufhdr[k].next = k + 1; bufhdr[k].prev = k - 1; } bufhdr[0].prev = NBUFPOOL - 1; bufhdr[NBUFPOOL - 1].next = 0; /* * initialize file systems * For outlinelog, * open all file system lvs which were in the log active list; * validate superblock and allocation map of file systems; * For inlinelog, only one file system to be processed at one time, * so open just this file system. logmajor and logminor is the file * system's major and minor numbers. */ if (log.location & INLINELOG) { if (openVol(0) != 0) return (CANTOPEN_INLINELOG); } else { int success = 0; for (k = 0; k < MAX_ACTIVE; k++) { if (!uuid_is_null(logsup.active[k])) { uuid_copy(vopen[k].uuid, logsup.active[k]); if (openVol(k)) vopen[k].status = FM_LOGREDO; else success = 1; } } if (!success) return CANTOPEN_OUTLINELOG; } return (0);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME: markBmap() * * FUNCTION: This routine updates the Aggregate Block Map * for each block described by the given pxd unless * it has already been done. That is, on a block-by-block * basis, if the Aggregate Block Map has not been updated * for the block in the current session, then it is * updated now. * * Specifically, if the Block Map persistent map (pmap) * bit representing the block has not already been * updated by this routine, that bit is updated as * requested by the caller * * NOTES: This routine uses the Block Map page working map (wmap) * to keep track of which IAG pmap bits have already been * updated by this routine. */int markBmap(struct dmap *dmappg, /* the beginning of bmap file */ pxd_t pxd, /* descriptor for the blocks of interest */ int val, /* 1 to allocate, 0 to free */ int vol){ int rc = 0; int64_t blkno, dmap_pg; struct dmap_bitmaps *dp; uint32_t rem, nblocks, word, dbitno, nblks, rbits, nwords; uint16_t wbitno, nbits, n, j; int32_t dmap_number; if (Insuff_memory_for_maps) return 0; nblocks = lengthPXD(&pxd); /* number of blocks described */ blkno = addressPXD(&pxd); /* the first block number */ if ((blkno + nblocks) > vopen[vol].fssize) { fsck_send_msg(lrdo_MBMPBLKOUTRANGE, (long long) blkno, nblocks); fsError(DBTYPE, vol, blkno); return (BLOCK_OUTOFRANGE); } /* * nblocks may be large enough to span several struct dmap pages. * Update the block state one struct dmap page at a time. */ for (rem = nblocks; rem > 0; rem -= nblks, blkno += nblks) { dmap_pg = BLKTODMAPN(blkno); dp = vopen[vol].bmap_wsp[dmap_pg].dmap_bitmaps; if (dp == NULL) { /* first touch to this dmap */ dmap_number = blkno >> L2BPERDMAP; rc = dMapGet(vol, dmap_number); if (rc != 0) { return (rc); } dp = vopen[vol].bmap_wsp[dmap_pg].dmap_bitmaps; } /* the bit position, within the current dmap page, * representing the current aggregate block. */ dbitno = blkno & (BPERDMAP - 1); /* the word, within the current dmap page, which contains * the bit for the block. */ word = dbitno >> L2DBWORD; /* number of blocks which are in the extent and are * described by the current dmap. */ nblks = MIN(rem, BPERDMAP - dbitno); /* * Mark the dmap bitmap. */ for (rbits = nblks; rbits > 0; rbits -= nbits, dbitno += nbits) { wbitno = dbitno & (DBWORD - 1); nbits = MIN(rbits, DBWORD - wbitno); /* * only part of the word is implicated */ if (nbits < DBWORD) { for (n = 0; n < nbits; n++, wbitno++) { /* * If bit already updated in this * logredo session, nothing to do. */ if (dp->wmap[word] & (UZBIT_32 >> wbitno)) continue; /* update pmap according to val. * set wmap to indicate state is * determined. */ dp->wmap[word] |= (UZBIT_32 >> wbitno); if (val) /* request to turn on */ dp->pmap[word] |= (UZBIT_32 >> wbitno); else /* request to turn off */ dp->pmap[word] &= ~(UZBIT_32 >> wbitno); } word += 1; } else { /* nbits == DBWORD. One or more words * are to have all their bits updated. */ nwords = rbits >> L2DBWORD; nbits = nwords << L2DBWORD; for (n = 0; n < nwords; n++, word++) for (j = 0; j < DBWORD; j++) { /* * If bit already updated in * this logredo session, * nothing to do. */ if (dp->wmap[word] & (UZBIT_32 >> j)) continue; /* note (in the wmap) that the * bits have been updated in * this session. */ dp->wmap[word] |= (UZBIT_32 >> j); if (val) /* turn on request */ dp->pmap[word] |= (UZBIT_32 >> j); else /* turn off request */ dp->pmap[word] &= ~(UZBIT_32 >> j); } /* end for j */ } } } return (0);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME: markImap() * * FUNCTION: This routine updates the inode allocation map * for the specified inode unless it has already * been done. * * Specifically, if the IAG persistent map (pmap) * bit representing the inode has not already been * updated by this routine, * * - that bit is updated as requested by the caller * * - If the bit is being set to '1', the descriptor * for the extent containing the inode is refreshed. * * NOTES: This routine uses the IAG working map (wmap) to keep * track of which IAG pmap bits have already been updated * by this routine. */int markImap(struct fsimap_lst fsimap, /* data for the inode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -