int common_check() { int pcount=1; int error; int try=0; struct stat stbuf; char *dirstr; if ( chkoptions.optimizetc == 1 ){ printf( "Phase %i : Running optimize on the databases. ",pcount); tc_defrag(); pcount++; } error=dbstat("/lost+found",&stbuf); if ( error == -ENOENT ) { lost_mkdir("/lost+found"); error=dbstat("/lost+found",&stbuf); } while ( !S_ISDIR(stbuf.st_mode)) { show_progress(); printf("Someone silly (YOU) created lost+found as a regular file.\n"); dirstr=as_sprintf("/lost+found_%i",try); error=dbstat(dirstr,&stbuf); if ( -ENOENT == error ) { lost_mkdir(dirstr); error=dbstat(dirstr,&stbuf); free(dirstr); break; } free(dirstr); try++; if ( try > 3 ) { printf("Stupidity count overflow.\n"); exit(EXIT_USAGE); } } lafinode=stbuf.st_ino; printf( "%c \nPhase %u : Check directory structure.\n",BACKSPACE,pcount); check_directory_structure(); pcount++; printf( "%cPhase %u : Check for orphaned inodes.\n",BACKSPACE, pcount); check_inodes(); pcount++; return(pcount); } void lessfsck_tc() { int pcount=common_check(); printf("%cPhase %u : Check for orphaned data blocks.\n",BACKSPACE,pcount); check_orphaned_data_blocks(); pcount++; }
static void dbstatCallFunc(const iocshArgBuf *args) { dbstat();}
int file_unlink_file(const char *path) { int res = 0; int haslinks = 0; int dir_links = 0; struct stat st; struct stat dirst; char *dname; char *bname; unsigned char *stiger; unsigned long long inode; unsigned long long counter = 0; INUSE *inuse; unsigned long long done = 0; time_t thetime; void *vdirnode; DBT *bdata; DBT *ddbuf; DBT *dataptr; DDSTAT *ddstat; DINOINO dinoino; INOBNO inobno; char *filename; FUNC; LDEBUG("unlink_file %s", path); res = dbstat(path, &st); if (res == -ENOENT) return (res); inode = st.st_ino; //release_global_lock(); //wait_io_pending(inode); //sync_flush_dtaq(); haslinks = st.st_nlink; thetime = time(NULL); dname = s_dirname((char *) path); /* Change ctime and mtime of the parentdir Posix std posix behavior */ res = update_parent_time(dname,0); bname = s_basename((char *) path); res = dbstat(dname, &dirst); if (S_ISLNK(st.st_mode) && haslinks == 1) { LDEBUG("unlink symlink %s inode %llu", path, inode); delete_key(dbs, &inode, sizeof(unsigned long long)); LDEBUG("unlink symlink done %s", path); } inobno.inode = inode; inobno.blocknr = counter; while (done < st.st_size) { get_dbb_lock(); bdata = search_memhash(dbbm, &inobno, sizeof(INOBNO)); if ( NULL == bdata ) { bdata = search_dbdata(dbb, &inobno, sizeof(INOBNO)); } release_dbb_lock(); if (bdata == NULL) { LDEBUG("%llu is sparse", counter); done = done + BLKSIZE; counter++; inobno.blocknr = counter; continue; } stiger = s_malloc(bdata->size); memcpy(stiger, bdata->data, bdata->size); loghash("search inuse for ", stiger); inuse = file_get_inuse(stiger); if (NULL != inuse) { if (haslinks == 1) { if (inuse->inuse == 1) { loghash("unlink_file delete dbu,dbdta for ", stiger); delete_inuse(stiger); put_on_freelist(inuse); } else { if (inuse->inuse > 1) inuse->inuse--; loghash("updateInUse dbu,dbdta for ", stiger); file_update_inuse(stiger, inuse); } } free(inuse); } else log_fatal_hash("unlink_file inuse not found",stiger); free(stiger); DBTfree(bdata); if (haslinks == 1) { LDEBUG("unlink_file : delete inode %llu - %llu", inobno.inode, inobno.blocknr); delete_dbb(&inobno); } counter++; inobno.blocknr = counter; done = done + BLKSIZE; } if (haslinks == 1) { if (0 != (res = btdelete_curkey(dbdirent, &dirst.st_ino, sizeof(unsigned long long), &inode, sizeof(unsigned long long)))) { free(bname); free(dname); return (res); } delete_key(dbp, (unsigned char *) &inode, sizeof(unsigned long long)); } else { dataptr = search_dbdata(dbp, (unsigned char *) &inode, sizeof(unsigned long long)); if (dataptr == NULL) { die_dataerr("Failed to find file %llu", inode); } ddstat = value_to_ddstat(dataptr); ddstat->stbuf.st_nlink--; ddstat->stbuf.st_ctim.tv_sec = thetime; ddstat->stbuf.st_ctim.tv_nsec=0; ddstat->stbuf.st_mtim.tv_sec = thetime; ddstat->stbuf.st_mtim.tv_nsec=0; dinoino.dirnode = dirst.st_ino; dinoino.inode = ddstat->stbuf.st_ino; dir_links = count_dirlinks(&dinoino, sizeof(DINOINO)); res = btdelete_curkey(dbl, &dinoino, sizeof(DINOINO), bname, strlen(bname)); btdelete_curkey(dbl, &ddstat->stbuf.st_ino, sizeof(unsigned long long), &dinoino, sizeof(DINOINO)); // Restore to regular file settings and clean up. if (ddstat->stbuf.st_nlink == 1) { vdirnode = btsearch_keyval(dbl, &ddstat->stbuf.st_ino, sizeof(unsigned long long), NULL, 0); memcpy(&dinoino, vdirnode, sizeof(DINOINO)); free(vdirnode); filename = (char *) btsearch_keyval(dbl, &dinoino, sizeof(DINOINO), NULL, 0); memcpy(&ddstat->filename, filename, strlen(filename) + 1); free(filename); LDEBUG ("unlink_file : Restore %s to regular file settings and clean up.", ddstat->filename); btdelete_curkey(dbl, &dinoino, sizeof(DINOINO), ddstat->filename, strlen(ddstat->filename)); btdelete_curkey(dbl, &ddstat->stbuf.st_ino, sizeof(unsigned long long), &dinoino, sizeof(DINOINO)); btdelete_curkey(dbl, &inode, sizeof(unsigned long long), &dinoino, sizeof(DINOINO)); res = 0; } if (dir_links == 1) { if (0 != (res = btdelete_curkey(dbdirent, &dirst.st_ino, sizeof(unsigned long long), &inode, sizeof(unsigned long long)))) { die_dataerr("unlink_file : Failed to delete record."); } } ddbuf = create_ddbuf(ddstat->stbuf, ddstat->filename); bin_write_dbdata(dbp, &inode, sizeof(unsigned long long), (void *) ddbuf->data, ddbuf->size); DBTfree(dataptr); DBTfree(ddbuf); ddstatfree(ddstat); } free(bname); free(dname); EFUNC; return (res); }