//FIXME: use this function everywhere int pvfs_readdir(void *ctx, PVFS_credentials *credentials, PVFS_object_ref *ref, int(callback)(void *ctx, PVFS_dirent)) { int ret; PVFS_sysresp_readdir rd_response; unsigned int pvfs_dirent_incount = 256; // reasonable chank size PVFS_ds_position token = PVFS_READDIR_START; do { unsigned int i; memset(&rd_response, 0, sizeof(PVFS_sysresp_readdir)); ret = PVFS_sys_readdir(*ref, token, pvfs_dirent_incount, credentials, &rd_response, PVFS_HINT_NULL); if (ret < 0) return pvfs2errno(ret); for (i = 0; i < rd_response.pvfs_dirent_outcount; i++) { if (callback(ctx, rd_response.dirent_array[i])) break; } token = rd_response.token; if (rd_response.pvfs_dirent_outcount) { free(rd_response.dirent_array); rd_response.dirent_array = NULL; } } while (rd_response.pvfs_dirent_outcount == pvfs_dirent_incount); return 0; }
/* Preconditions: none * Parameters: testcase - the test case to be run * Postconditions: returns error code of readdir * Has 2 Test cases */ static int test_readdir(void) { int ret; PVFS_object_ref pinode_refn; PVFS_ds_position token; int pvfs_dirent_incount; PVFS_credentials credentials; PVFS_sysresp_readdir resp_readdir; int fs_id; PVFS_sysresp_lookup resp_lookup; char *name; ret = -2; name = (char *) malloc(sizeof(char) * 100); name = strcpy(name, "name"); fs_id = 9; PVFS_util_gen_credentials(&credentials); if ((ret = PVFS_sys_lookup( fs_id, name, &credentials, &resp_lookup, PVFS2_LOOKUP_LINK_NO_FOLLOW)) < 0) { fprintf(stderr, "lookup failed %d\n", ret); return -1; } pinode_refn = resp_lookup.ref; token = PVFS_READDIR_START; pvfs_dirent_incount = 1; ret = PVFS_sys_readdir(pinode_refn, token, pvfs_dirent_incount, &credentials, &resp_readdir); return ret; }
int descend(PVFS_fs_id cur_fs, struct handlelist *hl, struct handlelist *alt_hl, PVFS_object_ref dir_ref, PVFS_credentials *creds) { int i, count; PVFS_ds_position token; PVFS_sysresp_readdir readdir_resp; PVFS_sysresp_getattr getattr_resp; PVFS_object_ref entry_ref = {0, 0}; count = 64; token = 0; do { memset(&readdir_resp, 0, sizeof(PVFS_sysresp_readdir)); PVFS_sys_readdir(dir_ref, (!token ? PVFS_READDIR_START : token), count, creds, &readdir_resp, NULL); for (i = 0; i < readdir_resp.pvfs_dirent_outcount; i++) { int server_idx = 0, ret, in_main_list = 0, in_alt_list = 0; char *cur_file; PVFS_handle cur_handle; cur_handle = readdir_resp.dirent_array[i].handle; cur_file = readdir_resp.dirent_array[i].d_name; entry_ref.handle = cur_handle; entry_ref.fs_id = cur_fs; if (handlelist_find_handle(hl, cur_handle, &server_idx) == 0) { in_main_list = 1; } if (!in_main_list && alt_hl && handlelist_find_handle(alt_hl, cur_handle, &server_idx) == 0) { in_alt_list = 1; } if (!in_main_list && !in_alt_list) { ret = remove_directory_entry(dir_ref, entry_ref, cur_file, creds); assert(ret == 0); continue; } ret = PVFS_sys_getattr(entry_ref, PVFS_ATTR_SYS_ALL_NOHINT, creds, &getattr_resp, NULL); if (ret != 0) { ret = remove_directory_entry(dir_ref, entry_ref, cur_file, creds); assert(ret == 0); /* handle removed from list below */ } else { switch (getattr_resp.attr.objtype) { case PVFS_TYPE_METAFILE: if (verify_datafiles(cur_fs, hl, alt_hl, entry_ref, getattr_resp.attr.dfile_count, creds) < 0) { /* not recoverable; remove */ printf("* File %s (%llu) is not recoverable.\n", cur_file, llu(cur_handle)); /* verify_datafiles() removed the datafiles */ ret = remove_object(entry_ref, getattr_resp.attr.objtype, creds); assert(ret == 0); ret = remove_directory_entry(dir_ref, entry_ref, cur_file, creds); assert(ret == 0); } break; case PVFS_TYPE_DIRECTORY: ret = match_dirdata(hl, alt_hl, entry_ref, creds); if (ret != 0) { printf("* Directory %s (%llu) is missing DirData.\n", cur_file, llu(cur_handle)); ret = remove_object(entry_ref, getattr_resp.attr.objtype, creds); assert(ret == 0); ret = remove_directory_entry(dir_ref, entry_ref, cur_file, creds); break; } if (in_main_list) { ret = descend(cur_fs, hl, alt_hl, entry_ref, creds); assert(ret == 0); } break; case PVFS_TYPE_SYMLINK: /* nothing to do */ break; default: /* whatever this is, blow it away now. */ ret = remove_object(entry_ref, getattr_resp.attr.objtype, creds); assert(ret == 0); ret = remove_directory_entry(dir_ref, entry_ref, cur_file, creds); assert(ret == 0); break; } } /* remove from appropriate handle list */ if (in_alt_list) { handlelist_remove_handle(alt_hl, cur_handle, server_idx); } else if (in_main_list) { handlelist_remove_handle(hl, cur_handle, server_idx); } } token = readdir_resp.token; if (readdir_resp.pvfs_dirent_outcount) { free(readdir_resp.dirent_array); readdir_resp.dirent_array = NULL; } } while (readdir_resp.pvfs_dirent_outcount == count); if (readdir_resp.pvfs_dirent_outcount) { free(readdir_resp.dirent_array); readdir_resp.dirent_array = NULL; } return 0; }
void *thread_list(void *arg) { int ret; long locking = (long)arg; pthread_barrier_wait(&global_barrier); struct itimerval timer; timer.it_value.tv_sec = 1; timer.it_value.tv_usec = 0; timer.it_interval.tv_sec = 1; timer.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &timer, NULL); sleep(2); do { PVFS_sysresp_readdir rd_response; unsigned int pvfs_dirent_incount = 500; // reasonable chank size PVFS_ds_position token = 0; pvfs_fuse_handle_t dir_pfh; ret = lookup( pvfs2fuse.scratch_dir, &dir_pfh, PVFS2_LOOKUP_LINK_FOLLOW ); if (ret < 0){ printf("couldn't lookup parent directory.\n"); continue; } if (locking == 2) pthread_mutex_lock(&global_mutex); struct timeval start, end; gettimeofday(&start, NULL); do { memset(&rd_response, 0, sizeof(PVFS_sysresp_readdir)); ret = PVFS_sys_readdir(dir_pfh.ref, (!token ? PVFS_READDIR_START : token), pvfs_dirent_incount, &dir_pfh.creds, &rd_response, PVFS_HINT_NULL); if (ret < 0){ printf("couldn't list parent directory.\n"); continue; } if (!token) token = rd_response.pvfs_dirent_outcount - 1; else token += rd_response.pvfs_dirent_outcount; if (rd_response.pvfs_dirent_outcount) { free(rd_response.dirent_array); rd_response.dirent_array = NULL; } } while(rd_response.pvfs_dirent_outcount == pvfs_dirent_incount); gettimeofday(&end, NULL); if (locking == 2) pthread_mutex_unlock(&global_mutex); printf("Listed directory in %ldms.\n", (end.tv_sec-start.tv_sec)*1000 + (end.tv_usec-start.tv_usec)/1000); } while (do_list); return NULL; }