aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/reservations.h
blob: 42c2b804f3fdd1be89aa37cc0ba967fefe98eca6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* -*- mode: c; c-basic-offset: 8; -*-
 * vim: noexpandtab sw=8 ts=8 sts=0:
 *
 * reservations.h
 *
 * Allocation reservations function prototypes and structures.
 *
 * Copyright (C) 2010 Novell.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#ifndef	OCFS2_RESERVATIONS_H
#define	OCFS2_RESERVATIONS_H

#include <linux/rbtree.h>

#define OCFS2_DEFAULT_RESV_LEVEL	2
#define OCFS2_MAX_RESV_LEVEL	9
#define OCFS2_MIN_RESV_LEVEL	0

struct ocfs2_alloc_reservation {
	struct rb_node	r_node;

	unsigned int	r_start;	/* Beginning of current window */
	unsigned int	r_len;		/* Length of the window */

	unsigned int	r_last_len;	/* Length of most recent alloc */
	unsigned int	r_last_start;	/* Start of most recent alloc */
	struct list_head	r_lru;	/* LRU list head */

	unsigned int	r_flags;
};

#define	OCFS2_RESV_FLAG_INUSE	0x01	/* Set when r_node is part of a btree */
#define	OCFS2_RESV_FLAG_TMP	0x02	/* Temporary reservation, will be
					 * destroyed immedately after use */
#define	OCFS2_RESV_FLAG_DIR	0x04	/* Reservation is for an unindexed
					 * directory btree */

struct ocfs2_reservation_map {
	struct rb_root		m_reservations;
	char			*m_disk_bitmap;

	struct ocfs2_super	*m_osb;

	/* The following are not initialized to meaningful values until a disk
	 * bitmap is provided. */
	u32			m_bitmap_len;	/* Number of valid
						 * bits available */

	struct list_head	m_lru;		/* LRU of reservations
						 * structures. */

};

void ocfs2_resv_init_once(struct ocfs2_alloc_reservation *resv);

#define OCFS2_RESV_TYPES	(OCFS2_RESV_FLAG_TMP|OCFS2_RESV_FLAG_DIR)
void ocfs2_resv_set_type(struct ocfs2_alloc_reservation *resv,
			 unsigned int flags);

int ocfs2_dir_resv_allowed(struct ocfs2_super *osb);

/**
 * ocfs2_resv_discard() - truncate a reservation
 * @resmap:
 * @resv: the reservation to truncate.
 *
 * After this function is called, the reservation will be empty, and
 * unlinked from the rbtree.
 */
void ocfs2_resv_discard(struct ocfs2_reservation_map *resmap,
			struct ocfs2_alloc_reservation *resv);


/**
 * ocfs2_resmap_init() - Initialize fields of a reservations bitmap
 * @resmap: struct ocfs2_reservation_map to initialize
 * @obj: unused for now
 * @ops: unused for now
 * @max_bitmap_bytes: Maximum size of the bitmap (typically blocksize)
 *
 * Only possible return value other than '0' is -ENOMEM for failure to
 * allocation mirror bitmap.
 */
int ocfs2_resmap_init(struct ocfs2_super *osb,
		      struct ocfs2_reservation_map *resmap);

/**
 * ocfs2_resmap_restart() - "restart" a reservation bitmap
 * @resmap: reservations bitmap
 * @clen: Number of valid bits in the bitmap
 * @disk_bitmap: the disk bitmap this resmap should refer to.
 *
 * Re-initialize the parameters of a reservation bitmap. This is
 * useful for local alloc window slides.
 *
 * This function will call ocfs2_trunc_resv against all existing
 * reservations. A future version will recalculate existing
 * reservations based on the new bitmap.
 */
void ocfs2_resmap_restart(struct ocfs2_reservation_map *resmap,
			  unsigned int clen, char *disk_bitmap);

/**
 * ocfs2_resmap_uninit() - uninitialize a reservation bitmap structure
 * @resmap: the struct ocfs2_reservation_map to uninitialize
 */
void ocfs2_resmap_uninit(struct ocfs2_reservation_map *resmap);

/**
 * ocfs2_resmap_resv_bits() - Return still-valid reservation bits
 * @resmap: reservations bitmap
 * @resv: reservation to base search from
 * @cstart: start of proposed allocation
 * @clen: length (in clusters) of proposed allocation
 *
 * Using the reservation data from resv, this function will compare
 * resmap and resmap->m_disk_bitmap to determine what part (if any) of
 * the reservation window is still clear to use. If resv is empty,
 * this function will try to allocate a window for it.
 *
 * On success, zero is returned and the valid allocation area is set in cstart
 * and clen.
 *
 * Returns -ENOSPC if reservations are disabled.
 */
int ocfs2_resmap_resv_bits(struct ocfs2_reservation_map *resmap,
			   struct ocfs2_alloc_reservation *resv,
			   int *cstart, int *clen);

/**
 * ocfs2_resmap_claimed_bits() - Tell the reservation code that bits were used.
 * @resmap: reservations bitmap
 * @resv: optional reservation to recalulate based on new bitmap
 * @cstart: start of allocation in clusters
 * @clen: end of allocation in clusters.
 *
 * Tell the reservation code that bits were used to fulfill allocation in
 * resmap. The bits don't have to have been part of any existing
 * reservation. But we must always call this function when bits are claimed.
 * Internally, the reservations code will use this information to mark the
 * reservations bitmap. If resv is passed, it's next allocation window will be
 * calculated. It also expects that 'cstart' is the same as we passed back
 * from ocfs2_resmap_resv_bits().
 */
void ocfs2_resmap_claimed_bits(struct ocfs2_reservation_map *resmap,
			       struct ocfs2_alloc_reservation *resv,
			       u32 cstart, u32 clen);

#endif	/* OCFS2_RESERVATIONS_H */