~ubuntu-branches/ubuntu/utopic/glame/utopic

« back to all changes in this revision

Viewing changes to src/swapfile/swapfile.h

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2002-04-09 17:14:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020409171412-jzpnov7mbz2w6zsr
Tags: upstream-0.6.2
ImportĀ upstreamĀ versionĀ 0.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef _SWAPFILE_H
 
2
#define _SWAPFILE_H
 
3
 
 
4
/*
 
5
 * swapfile.h
 
6
 *
 
7
 * Copyright (C) 1999, 2000 Richard Guenther
 
8
 *
 
9
 * This program is free software; you can redistribute it and/or modify
 
10
 * it under the terms of the GNU General Public License as published by
 
11
 * the Free Software Foundation; either version 2 of the License, or
 
12
 * (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software
 
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
22
 *
 
23
 */
 
24
 
 
25
/* There are some generic issues for an implementation of the
 
26
 * swapfile API to make it efficient for the desired tasks:
 
27
 * - blocks need to be able to be shared between files
 
28
 * - blocks need to be able to be split and continue to be
 
29
 *   shared between files
 
30
 * Those requirements result in the following difficulties
 
31
 * an implementation will run into:
 
32
 * - maintaining a simple bitmask of unallocated blocks is not
 
33
 *   possible, as blocks may be shared, i.e. sort of an usage
 
34
 *   count is needed, not just a true/false state
 
35
 * - mmapping a file is usually not (efficient) possible - only
 
36
 *   one block at a time can be mmapped due to block splitting
 
37
 *   block start offsets are not aligned to a minimum block size
 
38
 *   and block sizes are not multiples of a minimum block size
 
39
 * - organizing files block allocation table as a simple linear
 
40
 *   list or as extends is not efficient because of the same
 
41
 *   block alignment/size issues, so a tree-like structure needs
 
42
 *   to be used for this - and in this tree the size of the blocks
 
43
 *   or their offsets in the file need to be stored
 
44
 * - because of the splitting requirement one need information
 
45
 *   about which files use a given block - i.e. a reverse block
 
46
 *   allocation table needs to be maintained (optimize for the
 
47
 *   single file case, O(n) operations are acceptable)
 
48
 * So an efficient implementation with respect to speed _and_
 
49
 * storage requirement for metadata is quite difficult.
 
50
 */
 
51
 
 
52
#include <sys/types.h>
 
53
#include <sys/stat.h>
 
54
#include <sys/mman.h>
 
55
#include <unistd.h>
 
56
#include <fcntl.h>
 
57
 
 
58
 
 
59
 
 
60
typedef long swfd_t;                  /* open file cookie, like fd/FILE */
 
61
typedef struct { int dummy; } SWDIR;  /* cookie for open directory, like DIR */
 
62
 
 
63
struct sw_stat {
 
64
        long name;           /* file name */
 
65
        size_t size;         /* file size in bytes */
 
66
        int mode;            /* active protection */
 
67
        off_t offset;        /* current file pointer position */
 
68
        off_t cluster_start; /* start of current cluster */
 
69
        off_t cluster_end;   /* end of current cluster */
 
70
        size_t cluster_size; /* size of current cluster */
 
71
};
 
72
 
 
73
 
 
74
 
 
75
#ifdef __cplusplus
 
76
extern "C" {
 
77
#endif
 
78
 
 
79
 
 
80
/**********************************************************************
 
81
 * Initialization/cleanup
 
82
 */
 
83
 
 
84
/* Registers a handler that gets executed if the swapfile subsystem
 
85
 * is about to commit suicide. The message may be a hint to the user. */
 
86
void swapfile_register_panic_handler(void (*handler)(const char *));
 
87
 
 
88
/* Tries to open an existing swap file/partition.
 
89
 * Returns 0 on success, -1 on failure.
 
90
 * Failures can be
 
91
 *  - missing swap file/parition
 
92
 *  - in use swap
 
93
 *  - unclean swap */
 
94
int swapfile_open(const char *name, int flags);
 
95
 
 
96
/* Syncs the in memory caches and metadata to disk. Does not sync
 
97
 * exisiting memory mappings. */
 
98
void swapfile_sync();
 
99
 
 
100
/* Closes and updates a previously opened swap file/partition
 
101
 * and marks it clean. */
 
102
void swapfile_close();
 
103
 
 
104
/* Tries to create an empty swapfile on name of size size. */
 
105
int swapfile_creat(const char *name, size_t size);
 
106
 
 
107
/* Tries to recover from unclean shutdown. Returns -1, if fsck
 
108
 * cannot be performed or failed, 0 if swapfile is clean, 1 if
 
109
 * swapfile was modified. Provide force == 1 to force a complete
 
110
 * fsck, even if swapfile is clean. */
 
111
int swapfile_fsck(const char *name, int force);
 
112
 
 
113
 
 
114
 
 
115
/**********************************************************************
 
116
 * Operations on the swapfile namespace. Unlike a unix filesystem
 
117
 * the swapfile filesystem has names composed out of a single "long".
 
118
 * Also the swapfile name hierarchy is flat - i.e. no directories.
 
119
 * Names are >=0, negative values are reserved.
 
120
 * All namespace operations are atomic (i.e. thread safe) and not
 
121
 * undoable (well - just sw_unlink is not undoable).
 
122
 */
 
123
 
 
124
/* Deletes a name from the filesystem. Like unlink(2). */
 
125
int sw_unlink(long name);
 
126
 
 
127
/* Open the (flat) swapfile directory for reading. The stream
 
128
 * is positioned at the first file. Like opendir(3), but w/o
 
129
 * directory specification for obvious reason. */
 
130
SWDIR *sw_opendir();
 
131
 
 
132
/* As the namespace is rather simple the equivalent to readdir(3) is
 
133
 * just returning the names, no directory entry. Anything else
 
134
 * is like readdir(3). If no further entries are available, -1 is returned. */
 
135
long sw_readdir(SWDIR *dir);
 
136
 
 
137
/* Like closedir(3). */
 
138
int sw_closedir(SWDIR *d);
 
139
 
 
140
 
 
141
/**********************************************************************
 
142
 * Operations on a single file. Files are organized in variable sized
 
143
 * clusters. Access to the file is limited to mapping those clusters.
 
144
 */
 
145
 
 
146
/* Open a file like open(2) - flags can be O_CREAT, O_EXCL,
 
147
 * O_RDWR, O_RDONLY, O_WRONLY with same semantics as open(2).
 
148
 * Returns a file descriptor on success, -1 on error. */
 
149
swfd_t sw_open(long name, int flags);
 
150
 
 
151
/* Closes a file descriptor. Like close(2). */
 
152
int sw_close(swfd_t fd);
 
153
 
 
154
/* Changes the size of the file fd like ftruncate(2). */
 
155
int sw_ftruncate(swfd_t fd, off_t length);
 
156
 
 
157
/* Tries to copy count bytes from the current position of in_fd
 
158
 * to the current position of out_fd (updating both file pointer
 
159
 * positions). The actual number of copied bytes is returned, or
 
160
 * -1 on an error.
 
161
 * Two different modes are supported (may be or'ed together):
 
162
 * - SWSENDFILE_INSERT inserts into, rather than overwrites/extends
 
163
 *   the destination file
 
164
 * - SWSENDFILE_CUT removes copied data from the source file
 
165
 * The destination file descriptor may be SW_NOFILE, in that case
 
166
 * no data is actually written (useful with SWSENDFILE_CUT). */
 
167
#define SW_NOFILE ((swfd_t)-1)
 
168
#define SWSENDFILE_INSERT 1
 
169
#define SWSENDFILE_CUT 2
 
170
ssize_t sw_sendfile(swfd_t out_fd, swfd_t in_fd, size_t count, int mode);
 
171
 
 
172
/* Update the file pointer position like lseek(2). */
 
173
off_t sw_lseek(swfd_t fd, off_t offset, int whence);
 
174
 
 
175
/* Like read(2), read count bytes from the current filepointer
 
176
 * position to the array pointed to by buf. */
 
177
ssize_t sw_read(swfd_t fd, void *buf, size_t count);
 
178
 
 
179
/* Like write(2), write count bytes from buf starting at the current
 
180
 * filepointer position. */
 
181
ssize_t sw_write(swfd_t fd, const void *buf, size_t count);
 
182
 
 
183
/* Obtain information about the file - works like fstat(2), but
 
184
 * with different struct stat. Also included is information about
 
185
 * the actual (file pointer position, see sw_lseek) cluster which
 
186
 * can be mapped using sw_mmap. */
 
187
int sw_fstat(swfd_t fd, struct sw_stat *buf);
 
188
 
 
189
/* Maps the actual (file pointer position, see sw_lseek and sw_fstat)
 
190
 * cluster into memory with parameters like mmap(2) - no size/offset
 
191
 * as they are determined by the actual cluster offset/size. */
 
192
void *sw_mmap(void *start, int prot, int flags, swfd_t fd);
 
193
 
 
194
/* Unmaps a previously mapped part of a file. Like munmap(2). */
 
195
int sw_munmap(void *start);
 
196
 
 
197
 
 
198
#ifdef __cplusplus
 
199
}
 
200
#endif
 
201
 
 
202
#endif