Blame view

fs/nilfs2/the_nilfs.h 10.8 KB
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
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
  /*
   * the_nilfs.h - the_nilfs shared structure.
   *
   * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
   *
   * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   *
   * Written by Ryusuke Konishi <ryusuke@osrg.net>
   *
   */
  
  #ifndef _THE_NILFS_H
  #define _THE_NILFS_H
  
  #include <linux/types.h>
  #include <linux/buffer_head.h>
ba65ae472   Ryusuke Konishi   nilfs2: add check...
29
  #include <linux/rbtree.h>
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
30
31
32
  #include <linux/fs.h>
  #include <linux/blkdev.h>
  #include <linux/backing-dev.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
33
  #include <linux/slab.h>
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
34

3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
35
  struct nilfs_sc_info;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
36
37
38
  /* the_nilfs struct */
  enum {
  	THE_NILFS_INIT = 0,     /* Information from super_block is set */
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
39
  	THE_NILFS_DISCONTINUED,	/* 'next' pointer chain has broken */
1cf58fa84   Jiro SEKIBA   nilfs2: shorten f...
40
  	THE_NILFS_GC_RUNNING,	/* gc process is running */
e605f0a72   Ryusuke Konishi   nilfs2: get rid o...
41
  	THE_NILFS_SB_DIRTY,	/* super block is dirty */
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
42
43
44
45
46
  };
  
  /**
   * struct the_nilfs - struct to supervise multiple nilfs mount points
   * @ns_flags: flags
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
47
   * @ns_bdev: block device
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
48
   * @ns_sem: semaphore for shared states
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
49
50
   * @ns_sbh: buffer heads of on-disk super blocks
   * @ns_sbp: pointers to super block data
b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
51
52
   * @ns_sbwtime: previous write time of super block
   * @ns_sbwcount: write count of super block
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
53
   * @ns_sbsize: size of valid data in super block
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
54
55
56
57
58
59
60
61
62
63
64
65
   * @ns_seg_seq: segment sequence counter
   * @ns_segnum: index number of the latest full segment.
   * @ns_nextnum: index number of the full segment index to be used next
   * @ns_pseg_offset: offset of next partial segment in the current full segment
   * @ns_cno: next checkpoint number
   * @ns_ctime: write time of the last segment
   * @ns_nongc_ctime: write time of the last segment not for cleaner operation
   * @ns_ndirtyblks: Number of dirty data blocks
   * @ns_last_segment_lock: lock protecting fields for the latest segment
   * @ns_last_pseg: start block number of the latest segment
   * @ns_last_seq: sequence value of the latest segment
   * @ns_last_cno: checkpoint number of the latest segment
2c2e52fc4   Ryusuke Konishi   nilfs2: extend ni...
66
   * @ns_prot_seq: least sequence number of segments which must not be reclaimed
325020477   Ryusuke Konishi   nilfs2: do not up...
67
   * @ns_prev_seq: base sequence number used to decide if advance log cursor
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
68
69
   * @ns_writer: log writer
   * @ns_segctor_sem: semaphore protecting log write
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
70
71
72
   * @ns_dat: DAT file inode
   * @ns_cpfile: checkpoint file inode
   * @ns_sufile: segusage file inode
ba65ae472   Ryusuke Konishi   nilfs2: add check...
73
74
   * @ns_cptree: rb-tree of all mounted checkpoints (nilfs_root)
   * @ns_cptree_lock: lock protecting @ns_cptree
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
75
76
   * @ns_dirty_files: list of dirty files
   * @ns_inode_lock: lock protecting @ns_dirty_files
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
77
   * @ns_gc_inodes: dummy inodes to keep live blocks
9b1fc4e49   Ryusuke Konishi   nilfs2: move next...
78
79
   * @ns_next_generation: next generation number for inodes
   * @ns_next_gen_lock: lock protecting @ns_next_generation
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
80
   * @ns_mount_opt: mount options
574e6c314   Ryusuke Konishi   nilfs2: move para...
81
82
83
84
   * @ns_resuid: uid for reserved blocks
   * @ns_resgid: gid for reserved blocks
   * @ns_interval: checkpoint creation interval
   * @ns_watermark: watermark for the number of dirty buffers
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
85
   * @ns_blocksize_bits: bit length of block size
92c60ccaf   Ryusuke Konishi   nilfs2: add block...
86
   * @ns_blocksize: block size
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
87
88
89
90
91
92
93
94
95
96
97
   * @ns_nsegments: number of segments in filesystem
   * @ns_blocks_per_segment: number of blocks per segment
   * @ns_r_segments_percentage: reserved segments percentage
   * @ns_nrsvsegs: number of reserved segments
   * @ns_first_data_block: block number of first data block
   * @ns_inode_size: size of on-disk inode
   * @ns_first_ino: first not-special inode number
   * @ns_crc_seed: seed value of CRC32 calculation
   */
  struct the_nilfs {
  	unsigned long		ns_flags;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
98
99
  
  	struct block_device    *ns_bdev;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
100
  	struct rw_semaphore	ns_sem;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
101

e59399d01   Ryusuke Konishi   nilfs2: correct e...
102
  	/*
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
103
104
105
106
107
108
  	 * used for
  	 * - loading the latest checkpoint exclusively.
  	 * - allocating a new full segment.
  	 * - protecting s_dirt in the super_block struct
  	 *   (see nilfs_write_super) and the following fields.
  	 */
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
109
110
  	struct buffer_head     *ns_sbh[2];
  	struct nilfs_super_block *ns_sbp[2];
b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
111
112
  	time_t			ns_sbwtime;
  	unsigned		ns_sbwcount;
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
113
  	unsigned		ns_sbsize;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
114
  	unsigned		ns_mount_state;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
115
116
117
118
  
  	/*
  	 * Following fields are dedicated to a writable FS-instance.
  	 * Except for the period seeking checkpoint, code outside the segment
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
119
120
  	 * constructor must lock a segment semaphore while accessing these
  	 * fields.
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
  	 * The writable FS-instance is sole during a lifetime of the_nilfs.
  	 */
  	u64			ns_seg_seq;
  	__u64			ns_segnum;
  	__u64			ns_nextnum;
  	unsigned long		ns_pseg_offset;
  	__u64			ns_cno;
  	time_t			ns_ctime;
  	time_t			ns_nongc_ctime;
  	atomic_t		ns_ndirtyblks;
  
  	/*
  	 * The following fields hold information on the latest partial segment
  	 * written to disk with a super root.  These fields are protected by
  	 * ns_last_segment_lock.
  	 */
  	spinlock_t		ns_last_segment_lock;
  	sector_t		ns_last_pseg;
  	u64			ns_last_seq;
  	__u64			ns_last_cno;
2c2e52fc4   Ryusuke Konishi   nilfs2: extend ni...
141
  	u64			ns_prot_seq;
325020477   Ryusuke Konishi   nilfs2: do not up...
142
  	u64			ns_prev_seq;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
143

3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
144
  	struct nilfs_sc_info   *ns_writer;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
145
146
147
148
149
150
151
152
153
  	struct rw_semaphore	ns_segctor_sem;
  
  	/*
  	 * Following fields are lock free except for the period before
  	 * the_nilfs is initialized.
  	 */
  	struct inode	       *ns_dat;
  	struct inode	       *ns_cpfile;
  	struct inode	       *ns_sufile;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
154

ba65ae472   Ryusuke Konishi   nilfs2: add check...
155
156
157
  	/* Checkpoint tree */
  	struct rb_root		ns_cptree;
  	spinlock_t		ns_cptree_lock;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
158
159
160
  	/* Dirty inode list */
  	struct list_head	ns_dirty_files;
  	spinlock_t		ns_inode_lock;
263d90cef   Ryusuke Konishi   nilfs2: remove ow...
161
  	/* GC inode list */
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
162
  	struct list_head	ns_gc_inodes;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
163

9b1fc4e49   Ryusuke Konishi   nilfs2: move next...
164
165
166
  	/* Inode allocator */
  	u32			ns_next_generation;
  	spinlock_t		ns_next_gen_lock;
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
167
168
  	/* Mount options */
  	unsigned long		ns_mount_opt;
574e6c314   Ryusuke Konishi   nilfs2: move para...
169
170
171
172
  	uid_t			ns_resuid;
  	gid_t			ns_resgid;
  	unsigned long		ns_interval;
  	unsigned long		ns_watermark;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
173
174
  	/* Disk layout information (static) */
  	unsigned int		ns_blocksize_bits;
92c60ccaf   Ryusuke Konishi   nilfs2: add block...
175
  	unsigned int		ns_blocksize;
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
176
177
178
179
180
181
182
183
184
  	unsigned long		ns_nsegments;
  	unsigned long		ns_blocks_per_segment;
  	unsigned long		ns_r_segments_percentage;
  	unsigned long		ns_nrsvsegs;
  	unsigned long		ns_first_data_block;
  	int			ns_inode_size;
  	int			ns_first_ino;
  	u32			ns_crc_seed;
  };
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
  #define THE_NILFS_FNS(bit, name)					\
  static inline void set_nilfs_##name(struct the_nilfs *nilfs)		\
  {									\
  	set_bit(THE_NILFS_##bit, &(nilfs)->ns_flags);			\
  }									\
  static inline void clear_nilfs_##name(struct the_nilfs *nilfs)		\
  {									\
  	clear_bit(THE_NILFS_##bit, &(nilfs)->ns_flags);			\
  }									\
  static inline int nilfs_##name(struct the_nilfs *nilfs)			\
  {									\
  	return test_bit(THE_NILFS_##bit, &(nilfs)->ns_flags);		\
  }
  
  THE_NILFS_FNS(INIT, init)
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
200
  THE_NILFS_FNS(DISCONTINUED, discontinued)
1cf58fa84   Jiro SEKIBA   nilfs2: shorten f...
201
  THE_NILFS_FNS(GC_RUNNING, gc_running)
e605f0a72   Ryusuke Konishi   nilfs2: get rid o...
202
  THE_NILFS_FNS(SB_DIRTY, sb_dirty)
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
203

3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
204
205
206
207
208
209
210
211
212
213
214
215
216
  /*
   * Mount option operations
   */
  #define nilfs_clear_opt(nilfs, opt)  \
  	do { (nilfs)->ns_mount_opt &= ~NILFS_MOUNT_##opt; } while (0)
  #define nilfs_set_opt(nilfs, opt)  \
  	do { (nilfs)->ns_mount_opt |= NILFS_MOUNT_##opt; } while (0)
  #define nilfs_test_opt(nilfs, opt) ((nilfs)->ns_mount_opt & NILFS_MOUNT_##opt)
  #define nilfs_write_opt(nilfs, mask, opt)				\
  	do { (nilfs)->ns_mount_opt =					\
  		(((nilfs)->ns_mount_opt & ~NILFS_MOUNT_##mask) |	\
  		 NILFS_MOUNT_##opt);					\
  	} while (0)
ba65ae472   Ryusuke Konishi   nilfs2: add check...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  /**
   * struct nilfs_root - nilfs root object
   * @cno: checkpoint number
   * @rb_node: red-black tree node
   * @count: refcount of this structure
   * @nilfs: nilfs object
   * @ifile: inode file
   * @root: root inode
   * @inodes_count: number of inodes
   * @blocks_count: number of blocks (Reserved)
   */
  struct nilfs_root {
  	__u64 cno;
  	struct rb_node rb_node;
  
  	atomic_t count;
  	struct the_nilfs *nilfs;
  	struct inode *ifile;
  
  	atomic_t inodes_count;
  	atomic_t blocks_count;
  };
  
  /* Special checkpoint number */
  #define NILFS_CPTREE_CURRENT_CNO	0
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
242
243
  /* Minimum interval of periodical update of superblocks (in seconds) */
  #define NILFS_SB_FREQ		10
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
244

79efdd941   Jiro SEKIBA   nilfs2: clean up ...
245
246
247
  static inline int nilfs_sb_need_update(struct the_nilfs *nilfs)
  {
  	u64 t = get_seconds();
b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
248
  	return t < nilfs->ns_sbwtime || t > nilfs->ns_sbwtime + NILFS_SB_FREQ;
79efdd941   Jiro SEKIBA   nilfs2: clean up ...
249
  }
b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
250
  static inline int nilfs_sb_will_flip(struct the_nilfs *nilfs)
79efdd941   Jiro SEKIBA   nilfs2: clean up ...
251
  {
b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
252
253
  	int flip_bits = nilfs->ns_sbwcount & 0x0FL;
  	return (flip_bits != 0x08 && flip_bits != 0x0F);
79efdd941   Jiro SEKIBA   nilfs2: clean up ...
254
  }
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
255
  void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64);
348fe8da1   Ryusuke Konishi   nilfs2: simplify ...
256
257
  struct the_nilfs *alloc_nilfs(struct block_device *bdev);
  void destroy_nilfs(struct the_nilfs *nilfs);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
258
259
  int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data);
  int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb);
4e33f9eab   Ryusuke Konishi   nilfs2: implement...
260
261
  unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs);
  void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs);
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
262
  int nilfs_discard_segments(struct the_nilfs *, __u64 *, size_t);
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
263
  int nilfs_count_free_blocks(struct the_nilfs *, sector_t *);
ba65ae472   Ryusuke Konishi   nilfs2: add check...
264
265
266
267
  struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno);
  struct nilfs_root *nilfs_find_or_create_root(struct the_nilfs *nilfs,
  					     __u64 cno);
  void nilfs_put_root(struct nilfs_root *root);
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
268
  int nilfs_near_disk_full(struct the_nilfs *);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
269
270
  void nilfs_fall_back_super_block(struct the_nilfs *);
  void nilfs_swap_super_block(struct the_nilfs *);
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
271

ba65ae472   Ryusuke Konishi   nilfs2: add check...
272
273
274
275
  static inline void nilfs_get_root(struct nilfs_root *root)
  {
  	atomic_inc(&root->count);
  }
a057d2c01   Ryusuke Konishi   nilfs2: add helpe...
276
277
278
279
280
281
282
283
284
  static inline int nilfs_valid_fs(struct the_nilfs *nilfs)
  {
  	unsigned valid_fs;
  
  	down_read(&nilfs->ns_sem);
  	valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS);
  	up_read(&nilfs->ns_sem);
  	return valid_fs;
  }
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
  static inline void
  nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum,
  			sector_t *seg_start, sector_t *seg_end)
  {
  	*seg_start = (sector_t)nilfs->ns_blocks_per_segment * segnum;
  	*seg_end = *seg_start + nilfs->ns_blocks_per_segment - 1;
  	if (segnum == 0)
  		*seg_start = nilfs->ns_first_data_block;
  }
  
  static inline sector_t
  nilfs_get_segment_start_blocknr(struct the_nilfs *nilfs, __u64 segnum)
  {
  	return (segnum == 0) ? nilfs->ns_first_data_block :
  		(sector_t)nilfs->ns_blocks_per_segment * segnum;
  }
  
  static inline __u64
  nilfs_get_segnum_of_block(struct the_nilfs *nilfs, sector_t blocknr)
  {
  	sector_t segnum = blocknr;
  
  	sector_div(segnum, nilfs->ns_blocks_per_segment);
  	return segnum;
  }
  
  static inline void
  nilfs_terminate_segment(struct the_nilfs *nilfs, sector_t seg_start,
  			sector_t seg_end)
  {
  	/* terminate the current full segment (used in case of I/O-error) */
  	nilfs->ns_pseg_offset = seg_end - seg_start + 1;
  }
  
  static inline void nilfs_shift_to_next_segment(struct the_nilfs *nilfs)
  {
  	/* move forward with a full segment */
  	nilfs->ns_segnum = nilfs->ns_nextnum;
  	nilfs->ns_pseg_offset = 0;
  	nilfs->ns_seg_seq++;
  }
  
  static inline __u64 nilfs_last_cno(struct the_nilfs *nilfs)
  {
  	__u64 cno;
  
  	spin_lock(&nilfs->ns_last_segment_lock);
  	cno = nilfs->ns_last_cno;
  	spin_unlock(&nilfs->ns_last_segment_lock);
  	return cno;
  }
cece55207   Ryusuke Konishi   nilfs2: simplify ...
336
337
338
339
  static inline int nilfs_segment_is_active(struct the_nilfs *nilfs, __u64 n)
  {
  	return n == nilfs->ns_segnum || n == nilfs->ns_nextnum;
  }
65b4643d3   Ryusuke Konishi   nilfs2: add inode...
340
  #endif /* _THE_NILFS_H */