Sophie

Sophie

distrib > Mandriva > cooker > i586 > media > contrib-release-debug > by-pkgid > 29b07848f1f0d261023b5d8e39188a60 > files > 201

glame-debug-2.0.2-0.20070607.rc1.4mdv2011.0.i586.rpm

/*
 * swfs_cluster.h
 *
 * Copyright (C) 2000, 2001, 2004 Richard Guenther
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef _SWFS_CLUSTER_H
#define _SWFS_CLUSTER_H

#include "swfs_ctree.h"


struct swcluster;


/* Cluster instance, flags are
 *   SWC_DIRTY - files list is dirty
 *   SWC_CREAT - the data file needs to be created
 *   SWC_NOT_IN_CORE - files_cnt and files is uninitialized */
#define SWC_DIRTY 1
#define SWC_CREAT 2
#define SWC_NOT_IN_CORE 4
struct swcluster {
	/* Fields protected by the global CLUSTERS lock.
	 */
	struct swcluster *next_swcluster_hash;
	struct swcluster **pprev_swcluster_hash;
	struct glame_list_head lru;
	long name;
	int usage;     /* number of references to this struct cluster */

	/* All fields below are protected by the CLUSTER lock
	 * (which is nonexistent at the moment - FIXME).
	 */
	pthread_mutex_t mx;

	int flags;     /* SWC_* */

	/* The size field is always initialized. */
	s32 size;      /* size of the cluster */

	/* The fd is not always open - check for it (-1 if not).
	 * Clusters with open files are in the fdlru list. */
	struct glame_list_head fdlru;
	int fd;        /* cached fd of the on-disk _data_ */

	/* Fields created out of the cluster metadata, if
	 * SWC_NOT_IN_CORE is set, none of this fields is initialized. */
	int files_cnt; /* number of files that use this cluster */
	long *files;   /* list of files that use this cluster */

	/* Cluster shared mapping:
	 * - if map_addr is NULL, no mapping is there and other fields
	 *   need to be PROT_NONE, 0
	 * - map_prot is protection of the mapping (can be PROT_NONE)
	 * - map_cnt is the number of references to the mapping */
	/* Hash is read-protected by the CLUSTER lock, write protected
	 * by the global MAPPINGS lock. */
	struct swcluster *next_mapping_hash;
	struct swcluster **pprev_mapping_hash;
	struct glame_list_head maplru;
	char *map_addr;
	int map_prot;
	int map_cnt;
};

/* A maximum size goal we want to achieve for this inefficient
 * implementation via a native filesystem - else it would be S32_MAX. */
#define SWCLUSTER_MAXSIZE (8*1024*1024)


/* Initialize the cluster subsystem. Maxlru is the maximum number of
 * cluster descriptors cached in memory, maxfds the maximum number
 * of files kept open, maxmaps the maximum number of inactive memory
 * maps to cache and maxvm a goal for the maximum amount of virtual
 * memory used by the cluster mappings. */
static int cluster_init(int maxlru, int maxfds,
			int maxmaps, size_t maxvm);

/* Cleanup from the cluster subsystem. */
static void cluster_cleanup();


/* Gets a reference to the specified cluster, if CLUSTERGET_READFILES
 * is set, the list of files that use this cluster is read in. Returns
 * a reference or NULL on error. You may specify the size of the cluster
 * data, if you know it to speed up an eventual readin of the cluster,
 * specify -1, if you dont known the size. */
#define CLUSTERGET_READFILES 1
static struct swcluster *cluster_get(long name, int flags, s32 known_size);

/* Releases the reference, if CLUSTERPUT_SYNC is set, the list of
 * files that use this cluster is synced back to disk. */
#define CLUSTERPUT_SYNC 1
#define CLUSTERPUT_FREE 2
static void cluster_put(struct swcluster *c, int flags);


/* Allocates a new cluster with room for size bytes of data.
 * Returns a cluster reference on success, NULL on failure. */
static struct swcluster *cluster_alloc(s32 size);


/* Adds the specified file to the list of users of this cluster. */
static void cluster_addfileref(struct swcluster *c, long file);

/* Deletes the specified file from the list of users of this
 * cluster. Returns 0 if this was succesful and -1 if there
 * was no such user file. */
static int cluster_delfileref(struct swcluster *c, long file);

/* Checks, if the cluster has a reference on the file file. Returns
 * 0 if that is the case, else -1. */
static int cluster_checkfileref(struct swcluster *c, long file);


/* Creates a memory map of the cluster c possibly at address
 * start with protection and flags like mmap(2). */
static char *cluster_mmap(struct swcluster *c, int prot, int flags);

/* Unmaps a previously mmapped cluster. Returns 0 on success
 * and -1 on error (invalid supplied address) */
static int cluster_munmap(char *start);


/* Read data like read(2). Offset is cluster internal. */
static ssize_t cluster_read(struct swcluster *c, void *buf,
			    size_t count, off_t offset);

/* Write data like write(2). Offset is cluster internal. */
static ssize_t cluster_write(struct swcluster *c, const void *buf,
			     size_t count, off_t offset);


/* Splits the cluster c at position offset storing the head inside
 * ch and the tail after omitting cutcnt bytes after offset inside ct.
 * The head cluster may be identical to c afterwards, if there was only
 * one user of c, but two references are returned. This operation is
 * able to throw away (truncate) the resulting head/tail, if ch or
 * ct is NULL. */
static void cluster_split(struct swcluster *c, s32 offset, s32 cutcnt,
			  struct swcluster **ch, struct swcluster **ct);


/* Truncates the cluster to the specified size, if the cluster is not
 * shared and returns 0, else (shared cluster) -1 is returned. */
static int cluster_truncate(struct swcluster *c, s32 size);


/* Copy the cluster, if it is shared, else return the original cluster. */
static struct swcluster *cluster_unshare(struct swcluster *c);


#endif