1/*
2 *   Copyright (c) International Business Machines Corp., 2001-2004
3 *
4 *   This program is free software;  you can redistribute it and/or modify
5 *   it under the terms of the GNU General Public License as published by
6 *   the Free Software Foundation; either version 2 of the License, or
7 *   (at your option) any later version.
8 *
9 *   This program is distributed in the hope that it will be useful,
10 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12 *   the GNU General Public License for more details.
13 *
14 *   You should have received a copy of the GNU General Public License
15 *   along with this program;  if not, write to the Free Software
16 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef _FILELIST_H_
19#define _FILELIST_H_
20
21#include <pthread.h>
22#include "rand.h"
23#include "rwlock.h"
24#include "cirlist.h"
25#include "rbt.h"
26
27#define SUBDIRNAME_BASE "dir"
28#define FILENAME_BASE "file"
29
30struct ffsb_file {
31	char *name;
32	uint64_t size;
33	struct rwlock lock;
34	uint32_t num;
35};
36
37struct cirlist;
38
39/* Tree of ffsb_file structs and associated state info struct must be
40 * locked during use.
41 */
42struct benchfiles {
43	/* The base directory in which all subdirs and files are
44	 * created
45	 */
46	char *basedir;
47
48	/* The name to prepend to all directory and file names */
49	char *basename;
50	uint32_t numsubdirs;
51
52	/* Files which currently exist on the filesystem */
53	struct red_black_tree *files;
54
55	/* Directories which currently exist on the filesystem */
56	struct red_black_tree *dirs;
57
58	/* Files which have been deleted, and whose numbers should be
59	 * reused
60	 */
61	struct cirlist *holes;
62	struct cirlist *dholes;
63
64	/* This lock must be held while manipulating the structure */
65	struct rwlock fileslock;
66	uint32_t listsize; /* Sum size of nodes in files and holes */
67};
68
69/* Initializes the list, user must call this before anything else it
70 * will create the basedir and subdirs on the filesystem automatically
71 * if the builddirs arg. is nonzero
72 */
73void init_filelist(struct benchfiles *, char *, char *, uint32_t, int);
74void destroy_filelist(struct benchfiles *);
75
76/* Allocates a new file, adds to list, (write) locks it, and returns
77 * it.  This function also randomly selects a filename + path to
78 * assign to the new file.
79 *
80 * It first checks the "holes" list for any available filenames.
81 * Caller must ensure file is actually created on disk
82 */
83struct ffsb_file *add_file(struct benchfiles *b, uint64_t size, randdata_t *rd);
84struct ffsb_file *add_dir(struct benchfiles *, uint64_t, randdata_t *);
85
86/* Removes file from list, decrements listsize.
87 *
88 * File should be writer-locked before calling this function.
89 *
90 * This function does not unlock file after removal from list.
91 *
92 * Caller must ensure file is actually removed on disk.
93 *
94 * Caller must NOT free file->name and file, since oldfiles are being
95 * put into holes list.
96 */
97void remove_file(struct benchfiles *, struct ffsb_file *);
98
99/* Picks a file at random, locks it for reading and returns it
100 * locked
101 */
102struct ffsb_file *choose_file_reader(struct benchfiles *, randdata_t *);
103
104/* Picks a file at random, locks it for writing and returns it
105 * locked
106 */
107struct ffsb_file *choose_file_writer(struct benchfiles *, randdata_t *);
108
109/* changes the file->name of a file, file must be write locked
110 * it does not free the old file->name, so caller must keep a ref to it
111 * and free after the call
112 */
113void rename_file(struct ffsb_file *);
114
115void unlock_file_reader(struct ffsb_file *);
116void unlock_file_writer(struct ffsb_file *);
117
118/* Uses SUBDIRNAME_BASE/FILENAME_BASE + bf->basename to validate a
119 * name returns a negative on invalid names, and the actual file
120 * number if valid
121 */
122int validate_filename(struct benchfiles *, char *);
123int validate_dirname(struct benchfiles *, char *);
124
125/* Function type which, does some validation of existing files
126 * currently only used by ffsb_fs stuff, returns 0 on success
127 */
128typedef int (*fl_validation_func_t)(struct benchfiles *, char *, void *);
129
130/* Provided for re-use of filesets.  Also runs the validation callback
131 * on each file/dir that is found, after verifying the name is
132 * conformant.  The fileset should be initialized with init_fileset()
133 * beforehand.
134 * Returns 0 on success
135 */
136int grab_old_fileset(struct benchfiles *, char *, fl_validation_func_t,
137		      void *);
138
139/* Get the number of files */
140uint32_t get_listsize(struct benchfiles *);
141
142/* Get the number of subdirectories */
143uint32_t get_numsubdirs(struct benchfiles *);
144
145#endif /* _FILELIST_H_ */
146