4
* Copyright (C) 2000 Richard Guenther
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
#ifndef _SWFS_CLUSTER_H
23
#define _SWFS_CLUSTER_H
25
#include "swfs_ctree.h"
31
/* Cluster instance, flags are
32
* SWC_DIRTY - files list is dirty
33
* SWC_CREAT - the data file needs to be created
34
* SWC_NOT_IN_CORE - files_cnt and files is uninitialized */
37
#define SWC_NOT_IN_CORE 4
39
/* Fields protected by the global CLUSTERS lock.
41
struct swcluster *next_swcluster_hash;
42
struct swcluster **pprev_swcluster_hash;
43
struct glame_list_head lru;
45
int usage; /* number of references to this struct cluster */
47
/* All fields below are protected by the CLUSTER lock
48
* (which is nonexistent at the moment - FIXME).
52
int flags; /* SWC_* */
54
/* The size field is always initialized. */
55
s32 size; /* size of the cluster */
57
/* The fd is not always open - check for it (-1 if not).
58
* Clusters with open files are in the fdlru list. */
59
struct glame_list_head fdlru;
60
int fd; /* cached fd of the on-disk _data_ */
62
/* Fields created out of the cluster metadata, if
63
* SWC_NOT_IN_CORE is set, none of this fields is initialized. */
64
int files_cnt; /* number of files that use this cluster */
65
long *files; /* list of files that use this cluster */
67
/* Cluster shared mapping:
68
* - if map_addr is NULL, no mapping is there and other fields
69
* need to be PROT_NONE, 0
70
* - map_prot is protection of the mapping (can be PROT_NONE)
71
* - map_cnt is the number of references to the mapping */
72
/* Hash is read-protected by the CLUSTER lock, write protected
73
* by the global MAPPINGS lock. */
74
struct swcluster *next_mapping_hash;
75
struct swcluster **pprev_mapping_hash;
76
struct glame_list_head maplru;
82
/* A maximum size goal we want to achieve for this inefficient
83
* implementation via a native filesystem - else it would be S32_MAX. */
84
#define SWCLUSTER_MAXSIZE (256*1024)
87
/* Initialize the cluster subsystem. Maxlru is the maximum number of
88
* cluster descriptors cached in memory, maxfds the maximum number
89
* of files kept open, maxmaps the maximum number of inactive memory
90
* maps to cache and maxvm a goal for the maximum amount of virtual
91
* memory used by the cluster mappings. */
92
static int cluster_init(int maxlru, int maxfds,
93
int maxmaps, size_t maxvm);
95
/* Cleanup from the cluster subsystem. */
96
static void cluster_cleanup();
99
/* Gets a reference to the specified cluster, if CLUSTERGET_READFILES
100
* is set, the list of files that use this cluster is read in. Returns
101
* a reference or NULL on error. You may specify the size of the cluster
102
* data, if you know it to speed up an eventual readin of the cluster,
103
* specify -1, if you dont known the size. */
104
#define CLUSTERGET_READFILES 1
105
static struct swcluster *cluster_get(long name, int flags, s32 known_size);
107
/* Releases the reference, if CLUSTERPUT_SYNC is set, the list of
108
* files that use this cluster is synced back to disk. */
109
#define CLUSTERPUT_SYNC 1
110
#define CLUSTERPUT_FREE 2
111
static void cluster_put(struct swcluster *c, int flags);
114
/* Allocates a new cluster with room for size bytes of data.
115
* Returns a cluster reference on success, NULL on failure. */
116
static struct swcluster *cluster_alloc(s32 size);
119
/* Adds the specified file to the list of users of this cluster. */
120
static void cluster_addfileref(struct swcluster *c, long file);
122
/* Deletes the specified file from the list of users of this
123
* cluster. Returns 0 if this was succesful and -1 if there
124
* was no such user file. */
125
static int cluster_delfileref(struct swcluster *c, long file);
127
/* Checks, if the cluster has a reference on the file file. Returns
128
* 0 if that is the case, else -1. */
129
static int cluster_checkfileref(struct swcluster *c, long file);
132
/* Creates a memory map of the cluster c possibly at address
133
* start with protection and flags like mmap(2). */
134
static char *cluster_mmap(struct swcluster *c, int prot, int flags);
136
/* Unmaps a previously mmapped cluster. Returns 0 on success
137
* and -1 on error (invalid supplied address) */
138
static int cluster_munmap(char *start);
141
/* Read data like read(2). Offset is cluster internal. */
142
static ssize_t cluster_read(struct swcluster *c, void *buf,
143
size_t count, off_t offset);
145
/* Write data like write(2). Offset is cluster internal. */
146
static ssize_t cluster_write(struct swcluster *c, const void *buf,
147
size_t count, off_t offset);
150
/* Splits the cluster c at position offset storing the head inside
151
* ch and the tail after omitting cutcnt bytes after offset inside ct.
152
* The head cluster may be identical to c afterwards, if there was only
153
* one user of c, but two references are returned. This operation is
154
* able to throw away (truncate) the resulting head/tail, if ch or
156
static void cluster_split(struct swcluster *c, s32 offset, s32 cutcnt,
157
struct swcluster **ch, struct swcluster **ct);
160
/* Truncates the cluster to the specified size, if the cluster is not
161
* shared and returns 0, else (shared cluster) -1 is returned. */
162
static int cluster_truncate(struct swcluster *c, s32 size);
165
/* Copy the cluster, if it is shared, else return the original cluster. */
166
static struct swcluster *cluster_unshare(struct swcluster *c);