/* Private version of above function used only for reusing a * fileset. */ static struct ffsb_file *add_file_named(struct benchfiles *b, uint64_t size, char *name) { struct ffsb_file *newfile = NULL; newfile = ffsb_malloc(sizeof(struct ffsb_file)); memset(newfile, 0, sizeof(struct ffsb_file)); newfile->name = ffsb_strdup(name); newfile->size = size; init_rwlock(&newfile->lock); /* Write lock the filelist, begin critical section */ rw_lock_write(&b->fileslock); newfile->num = b->listsize; b->listsize++; /* Add a new file to the rbtree */ rbtree_insert(b->files, newfile); rw_lock_write(&newfile->lock); /* Unlock filelist */ rw_unlock_write(&b->fileslock); return newfile; }
void ffsb_deletefile(ffsb_thread_t *ft, ffsb_fs_t *fs, unsigned opnum) { struct benchfiles *bf = (struct benchfiles *)fs_get_opdata(fs, opnum); struct ffsb_file *curfile = NULL; randdata_t *rd = ft_get_randdata(ft); struct timeval start, end; int need_stats = ft_needs_stats(ft, SYS_UNLINK) || fs_needs_stats(fs, SYS_UNLINK); curfile = choose_file_writer(bf, rd); remove_file(bf, curfile); if (need_stats) gettimeofday(&start, NULL); if (unlink(curfile->name) == -1) { printf("error deleting %s in deletefile\n", curfile->name); perror("deletefile"); exit(0); } if (need_stats) { gettimeofday(&end, NULL); do_stats(&start, &end, ft, fs, SYS_UNLINK); } rw_unlock_write(&curfile->lock); ft_incr_op(ft, opnum, 1, 0); }
struct ffsb_file *add_file(struct benchfiles *b, uint64_t size, randdata_t *rd) { struct ffsb_file *newfile, *oldfile = NULL; int filenum = 0; /* We pre-allocate here, because I don't want to spend time * malloc'ing while the list is locked we free it later if * necessary */ newfile = ffsb_malloc(sizeof(struct ffsb_file)); newfile->size = size; init_rwlock(&(newfile->lock)); /* Write lock the filelist, begin critical section */ rw_lock_write(&b->fileslock); /* First check "holes" for a file */ if (!cl_empty(b->holes)) { oldfile = cl_remove_head(b->holes); rbtree_insert(b->files, oldfile); rw_lock_write(&oldfile->lock); } else { filenum = b->listsize; b->listsize++; newfile->num = filenum; rbtree_insert(b->files, newfile); rw_lock_write(&newfile->lock); } /* unlock filelist */ rw_unlock_write(&b->fileslock); if (oldfile == NULL) { char buf[FILENAME_MAX]; int randdir = getrandom(rd, b->numsubdirs+1); int namesize = 0; if (randdir == 0) namesize = snprintf(buf, FILENAME_MAX, "%s/%s%s%d", b->basedir, b->basename, FILENAME_BASE, filenum); else namesize = snprintf(buf, FILENAME_MAX, "%s/%s%s%d/%s%s%d", b->basedir, b->basename, SUBDIRNAME_BASE, randdir - 1, b->basename, FILENAME_BASE, filenum); if (namesize >= FILENAME_MAX) /* !!! do something about this ? */ printf("warning: filename \"%s\" too long\n", buf); newfile->name = ffsb_strdup(buf); return newfile; } else { free(newfile); return oldfile; } }
void remove_file(struct benchfiles *b, struct ffsb_file *entry) { rw_lock_write(&b->fileslock); rbtree_remove(b->files, entry, NULL); /* add node to the cir. list of "holes" */ cl_insert_tail(b->holes, entry); rw_unlock_write(&b->fileslock); }
struct ffsb_file *add_dir(struct benchfiles *b, uint64_t size, randdata_t *rd) { struct ffsb_file *newdir, *olddir = NULL; int dirnum = 0; newdir = ffsb_malloc(sizeof(struct ffsb_file)); init_rwlock(&newdir->lock); /* write lock the filelist, beging critical section */ rw_lock_write(&b->fileslock); /* First check "holes" for a file */ if (!cl_empty(b->dholes)) { olddir = cl_remove_head(b->dholes); rbtree_insert(b->files, olddir); rw_lock_write(&olddir->lock); } else { dirnum = b->numsubdirs; b->numsubdirs++; printf("dirnum: %d\n", dirnum); newdir->num = dirnum; rbtree_insert(b->dirs, newdir); rw_lock_write(&newdir->lock); } /* unlock filelist */ rw_unlock_write(&b->fileslock); if (olddir == NULL) { char buf[FILENAME_MAX]; int namesize = 0; namesize = snprintf(buf, FILENAME_MAX, "%s/%s%s%d", b->basedir, b->basename, SUBDIRNAME_BASE, dirnum); if (namesize >= FILENAME_MAX) printf("warning: filename \"%s\" too long\n", buf); /* TODO: take action here... */ newdir->name = ffsb_strdup(buf); return newdir; } else { free(newdir); return olddir; } }
void unlock_file_writer(struct ffsb_file *file) { rw_unlock_write(&file->lock) ; }