예제 #1
0
파일: commit.cpp 프로젝트: cscheid/guitar
Rcpp::List Commit::parent_list()
{
    BEGIN_RCPP
    Rcpp::List v;
    unsigned int c = parent_count();
    for (int i=0; i<c; ++i) {
        v.push_back(parent(i));
    }
    return v;
    END_RCPP
}
예제 #2
0
/*****************************************************************************
 * NAME: check_link_counts
 *
 * FUNCTION:  Count links from child directories to their parents.  
 *
 *	      Verify that the link count stored in each in-use inode 
 *	      matches the number of links fsck observed for the inode.
 *
 * PARAMETERS:  none
 *
 * NOTES:
 *
 * RETURNS:
 *      success: FSCK_OK
 *      failure: something else
 */
retcode_t check_link_counts ( )
{
  retcode_t clc_rc = FSCK_OK;
  inoidx_t ino_idx;
  int num_parents;
  int invalid_count_seen = 0;
  int low_stored_count_seen = 0;
  char user_reply;
  fsck_inode_extptr this_ext;
  fsck_inode_recptr this_inorec;
  fsck_inode_recptr parent_inorec;
  int done_looking = 0;
  int aggregate_inode = 0;
  int alloc_ifnull = 0;

  struct fsck_ino_msg_info  ino_msg_info;
  fsck_msg_info_ptr msg_info_ptr;

  msg_info_ptr = &ino_msg_info;
  msg_info_ptr->msg_inopfx = fsck_fset_inode;  /* all fileset owned */

    /*
     * count links from child directories to their parents
     *
     * (These can't be counted when the parent-child relationship
     * is observed because that observation occurs while processing
     * the parent and until the child is processed we don't know
     * whether the child is a directory or not.)
     */
  clc_rc = get_inorecptr_first( aggregate_inode, &ino_idx, &this_inorec );

  while( (clc_rc == FSCK_OK) && (this_inorec != NULL) ) {
	
    if( (this_inorec->in_use) &&
        (!this_inorec->selected_to_rls) &&
        (!this_inorec->ignore_alloc_blks) &&
        (this_inorec->inode_type == directory_inode) ) {  /*
                               * inode is in use, not being released, and 
				* is type directory
                               */
      this_inorec->link_count++;  /* for the self entry */
      if( (this_inorec->parent_inonum == ROOT_I) &&
          (agg_recptr->rootdir_rebuilt)                   ) { /*
			* special case: if the parent is root and root was
			* 		rebuilt, then don't increment parent
			*/
        if( this_inorec->inonum == ROOT_I ) { /*
			* special case: if this IS the root, then it's link from itself
			* 		to itself DOES count 
			*/
          this_inorec->link_count++; 
          }
        }
      else if( this_inorec->parent_inonum != (ino_t) 0 )  {  /*
                               * not an orphan
                               */
        clc_rc = get_inorecptr( aggregate_inode, alloc_ifnull,
                                this_inorec->parent_inonum, &parent_inorec );
        if( (clc_rc != FSCK_OK) || (parent_inorec == NULL) ) {
          clc_rc = FSCK_INTERNAL_ERROR_13;
          sprintf( message_parm_0, "%ld", clc_rc );                              /* @F1 */
          msgprms[0] = message_parm_0;                                           /* @F1 */
          msgprmidx[0] = 0;                                                              /* @F1 */
          sprintf( message_parm_1, "%ld", ino_idx );                             /* @F1 */
          msgprms[1] = message_parm_1;                                            /* @F1 */
          msgprmidx[1] = 0;                                                               /* @F1 */
          sprintf( message_parm_2, "%ld", this_inorec->parent_inonum ); /* @F1 */
          msgprms[2] = message_parm_2;                                            /* @F1 */
          msgprmidx[2] = 0;                                                               /* @F1 */
          sprintf( message_parm_3, "%ld", 0 );                                     /* @F1 */
          msgprms[3] = message_parm_3;                                            /* @F1 */
          msgprmidx[3] = 0;                                                               /* @F1 */
          fsck_send_msg( fsck_INTERNALERROR, 0, 4 );                         /* @F1 */
          }
        else {
          parent_inorec->link_count++; /*
                               * handle the first (and usually the only)
                               * parent.
                               */
          }
        if( (clc_rc == FSCK_OK) && (this_inorec->ext_rec != NULL) )  {  /*
                               * there might be more parents
                               */
          num_parents = parent_count( this_inorec );
          if( num_parents > 1 ) {  /* directory with illegal links */
            this_inorec->unxpctd_prnts = 1;
            agg_recptr->corrections_needed = 1;
                /*
                 * Create an extension record for the parent inode number
                 * now stored in the child inode record.
                 * When we traverse the aggregate on-disk we'll copy the
                 * stored value into this field of the inode record for
                 * use when displaying paths to the inode.
                 */
            clc_rc = get_inode_extension( &this_ext );
            if( clc_rc == FSCK_OK )  {  /* got extension record */
              this_ext->ext_type = parent_extension;
              this_ext->inonum = this_inorec->parent_inonum;
              this_ext->next = this_inorec->ext_rec;
              this_inorec->ext_rec = this_ext;
              this_inorec->parent_inonum = 0;
              this_ext = this_ext->next;  /* already counted the first
                                   * one, back when it was in the
                                   * workspace inode record itself
                                   */
              while ( (clc_rc == FSCK_OK) &&
                      (this_ext != NULL) ) {  /* exten records to check */
                if( this_ext->ext_type == parent_extension ) {
                  clc_rc = get_inorecptr( aggregate_inode, alloc_ifnull,
                                          this_ext->inonum, &parent_inorec );
                  if( (clc_rc != FSCK_OK) || (parent_inorec == NULL) ) {
                    clc_rc = FSCK_INTERNAL_ERROR_14;
                    sprintf( message_parm_0, "%ld", clc_rc );                    /* @F1 */
                    msgprms[0] = message_parm_0;                                 /* @F1 */
                    msgprmidx[0] = 0;                                                    /* @F1 */
                    sprintf( message_parm_1, "%ld", ino_idx );                   /* @F1 */
                    msgprms[1] = message_parm_1;                                  /* @F1 */
                    msgprmidx[1] = 0;                                                     /* @F1 */
                    sprintf( message_parm_2, "%ld", this_ext->inonum );     /* @F1 */
                    msgprms[2] = message_parm_2;                                  /* @F1 */
                    msgprmidx[2] = 0;                                                     /* @F1 */
                    sprintf( message_parm_3, "%ld", 0 );                           /* @F1 */
                    msgprms[3] = message_parm_3;                                  /* @F1 */
                    msgprmidx[3] = 0;                                                     /* @F1 */
                    fsck_send_msg( fsck_INTERNALERROR, 0, 4 );                /* @F1 */
                    }
                  else {
                    parent_inorec->link_count++;
                    }
                  }
                this_ext = this_ext->next;
                }  /* end while exten records to check */
              }  /* end got extension record */
            }  /* end directory with illegal links */
          }  /* end there might be more parents */
        }  /* end not an orphan */
      }  /* end inode is in use and is type directory */
   
    if( clc_rc == FSCK_OK ) {
      clc_rc = get_inorecptr_next( aggregate_inode, &ino_idx, &this_inorec );
      }
    }  /* end while */

    /*
     * verify that stored link counts match observed link counts
     *
     * We have added each observed link and subtracted the stored
     * count.  If the stored count is correct the result is 0.
     */
  if( clc_rc == FSCK_OK ) {  /* no fatal errors */

    clc_rc = get_inorecptr_first( aggregate_inode, &ino_idx, &this_inorec );

    while( (clc_rc == FSCK_OK) && (this_inorec != NULL) && (!done_looking) ) {
	
      if( (this_inorec->in_use) &&   
        (!this_inorec->selected_to_rls) &&
        (!this_inorec->ignore_alloc_blks)  ) {  /*
				* inode is in use and not being released
				*/
        if( this_inorec->link_count != 0 ) {  /* stored
				* link count doesn't match fsck's observations
				*/
          if( this_inorec->parent_inonum == 0 ) { /* inode is an orphan */
            this_inorec->crrct_link_count = 1;
	    }
	  else {  /* not an orphan */
            this_inorec->crrct_link_count = 1;
            if( this_inorec->link_count > 0 ) {
              low_stored_count_seen = 1;
              }
            invalid_count_seen = 1;

            msgprms[0] = message_parm_0;
            msgprmidx[0] = msg_info_ptr->msg_inopfx;
            sprintf( message_parm_1, "%ld", ino_idx );
            msgprms[1] = message_parm_1;
            msgprmidx[1] = 0;
            fsck_send_msg( fsck_BADINOLKCT, 0, 2 );
            }  /* end else not an orphan */
          }  /* end stored link count doesn't match fsck's observations */
        }  /* end inode is in use and not being released */

      if( clc_rc == FSCK_OK ) {
        clc_rc = get_inorecptr_next( aggregate_inode, &ino_idx, &this_inorec );
        }
      }  /* end while */

    if( (clc_rc == FSCK_OK) && (invalid_count_seen) ) {

      if( agg_recptr->processing_readwrite ) {  /* we can fix this */
        agg_recptr->corrections_approved = 1;
        fsck_send_msg( fsck_WILLFIXLINKCTS, 0, 0 );
        }  /* end we can fix this */
      else {  /* no write access */
        if( low_stored_count_seen )  {
          agg_recptr->ag_dirty = 1;
          }  /* end if low_stored_count_seen */
            /*
             * reset all link counts (in the fsck workspace) to
             * zero so that we won't accidentally correct them
             * while doing link count adjustments.
             *
             * (Link count adjustments are side effects of approved
             * repairs.  For example, if a directory inode is
             * released, the link count of its parent directory
             * is decremented.)
             */
        clc_rc = get_inorecptr_first( aggregate_inode, &ino_idx, &this_inorec );

        while( (clc_rc == FSCK_OK) && (this_inorec != NULL) ) {
	
          if( this_inorec->in_use ) { /* inode in use  */
            this_inorec->crrct_link_count = 0;
            this_inorec->link_count = 0;
            }  /* end inode in use */

          clc_rc = get_inorecptr_next( aggregate_inode, &ino_idx, &this_inorec );
          }  /* end while */
        fsck_send_msg( fsck_BADLINKCTS, 0, 0 );
        }  /* end no write access */
      }  /* end if invalid_count_seen */
    }  /* end no fatal errors */

  return( clc_rc );
}                              /* end of check_link_counts ()  */