aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-04-06 22:01:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 11:31:12 -0400
commit65b4643d3babeb203fa9571d12fd5e1bf74d27b0 (patch)
treeb9371b765ca1f52c8c7ba046f7cffea92e2bc722 /fs/nilfs2
parenteed10e39b142eb4d284c8e4c751c0eaaa0bcd707 (diff)
nilfs2: add inode and other major structures
This adds the following common structures of the NILFS2 file system. * nilfs_inode_info structure: gives on-memory inode. * nilfs_sb_info structure: keeps per-mount state and a special inode for the ifile. This structure is attached to the super_block structure. * the_nilfs structure: keeps shared state and locks among a read/write mount and snapshot mounts. This keeps special inodes for the sufile, cpfile, dat, and another dat inode used during GC (gcdat). This also has a hash table of dummy inodes to cache disk blocks during GC (gcinodes). * nilfs_transaction_info structure: keeps per task state while nilfs is writing logs or doing indivisible inode or namespace operations. This structure is used to identify context during log making and store nest level of the lock which ensures atomicity of file system operations. Signed-off-by: Koji Sato <sato.koji@lab.ntt.co.jp> Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/nilfs2')
-rw-r--r--fs/nilfs2/nilfs.h323
-rw-r--r--fs/nilfs2/sb.h102
-rw-r--r--fs/nilfs2/the_nilfs.h290
3 files changed, 715 insertions, 0 deletions
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
new file mode 100644
index 000000000000..17458ad4a809
--- /dev/null
+++ b/fs/nilfs2/nilfs.h
@@ -0,0 +1,323 @@
1/*
2 * nilfs.h - NILFS local header file.
3 *
4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
5 *
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.
10 *
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.
15 *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * Written by Koji Sato <koji@osrg.net>
21 * Ryusuke Konishi <ryusuke@osrg.net>
22 */
23
24#ifndef _NILFS_H
25#define _NILFS_H
26
27#include <linux/kernel.h>
28#include <linux/buffer_head.h>
29#include <linux/spinlock.h>
30#include <linux/blkdev.h>
31#include <linux/nilfs2_fs.h>
32#include "the_nilfs.h"
33#include "sb.h"
34#include "bmap.h"
35#include "bmap_union.h"
36
37/*
38 * NILFS filesystem version
39 */
40#define NILFS_VERSION "2.0.5"
41
42/*
43 * nilfs inode data in memory
44 */
45struct nilfs_inode_info {
46 __u32 i_flags;
47 unsigned long i_state; /* Dynamic state flags */
48 struct nilfs_bmap *i_bmap;
49 union nilfs_bmap_union i_bmap_union;
50 __u64 i_xattr; /* sector_t ??? */
51 __u32 i_dtime;
52 __u32 i_dir_start_lookup;
53 __u64 i_cno; /* check point number for GC inode */
54 struct address_space i_btnode_cache;
55 struct list_head i_dirty; /* List for connecting dirty files */
56
57#ifdef CONFIG_NILFS_XATTR
58 /*
59 * Extended attributes can be read independently of the main file
60 * data. Taking i_sem even when reading would cause contention
61 * between readers of EAs and writers of regular file data, so
62 * instead we synchronize on xattr_sem when reading or changing
63 * EAs.
64 */
65 struct rw_semaphore xattr_sem;
66#endif
67#ifdef CONFIG_NILFS_POSIX_ACL
68 struct posix_acl *i_acl;
69 struct posix_acl *i_default_acl;
70#endif
71 struct buffer_head *i_bh; /* i_bh contains a new or dirty
72 disk inode */
73 struct inode vfs_inode;
74};
75
76static inline struct nilfs_inode_info *NILFS_I(const struct inode *inode)
77{
78 return container_of(inode, struct nilfs_inode_info, vfs_inode);
79}
80
81static inline struct nilfs_inode_info *
82NILFS_BMAP_I(const struct nilfs_bmap *bmap)
83{
84 return container_of((union nilfs_bmap_union *)bmap,
85 struct nilfs_inode_info,
86 i_bmap_union);
87}
88
89static inline struct inode *NILFS_BTNC_I(struct address_space *btnc)
90{
91 struct nilfs_inode_info *ii =
92 container_of(btnc, struct nilfs_inode_info, i_btnode_cache);
93 return &ii->vfs_inode;
94}
95
96static inline struct inode *NILFS_AS_I(struct address_space *mapping)
97{
98 return (mapping->host) ? :
99 container_of(mapping, struct inode, i_data);
100}
101
102/*
103 * Dynamic state flags of NILFS on-memory inode (i_state)
104 */
105enum {
106 NILFS_I_NEW = 0, /* Inode is newly created */
107 NILFS_I_DIRTY, /* The file is dirty */
108 NILFS_I_QUEUED, /* inode is in dirty_files list */
109 NILFS_I_BUSY, /* inode is grabbed by a segment
110 constructor */
111 NILFS_I_COLLECTED, /* All dirty blocks are collected */
112 NILFS_I_UPDATED, /* The file has been written back */
113 NILFS_I_INODE_DIRTY, /* write_inode is requested */
114 NILFS_I_BMAP, /* has bmap and btnode_cache */
115 NILFS_I_GCINODE, /* inode for GC, on memory only */
116 NILFS_I_GCDAT, /* shadow DAT, on memory only */
117};
118
119/*
120 * Macros to check inode numbers
121 */
122#define NILFS_MDT_INO_BITS \
123 ((unsigned int)(1 << NILFS_DAT_INO | 1 << NILFS_CPFILE_INO | \
124 1 << NILFS_SUFILE_INO | 1 << NILFS_IFILE_INO | \
125 1 << NILFS_ATIME_INO | 1 << NILFS_SKETCH_INO))
126
127#define NILFS_SYS_INO_BITS \
128 ((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS)
129
130#define NILFS_FIRST_INO(sb) (NILFS_SB(sb)->s_nilfs->ns_first_ino)
131
132#define NILFS_MDT_INODE(sb, ino) \
133 ((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino))))
134#define NILFS_VALID_INODE(sb, ino) \
135 ((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & (1 << (ino))))
136
137/**
138 * struct nilfs_transaction_info: context information for synchronization
139 * @ti_magic: Magic number
140 * @ti_save: Backup of journal_info field of task_struct
141 * @ti_flags: Flags
142 * @ti_count: Nest level
143 * @ti_garbage: List of inode to be put when releasing semaphore
144 */
145struct nilfs_transaction_info {
146 u32 ti_magic;
147 void *ti_save;
148 /* This should never used. If this happens,
149 one of other filesystems has a bug. */
150 unsigned short ti_flags;
151 unsigned short ti_count;
152 struct list_head ti_garbage;
153};
154
155/* ti_magic */
156#define NILFS_TI_MAGIC 0xd9e392fb
157
158/* ti_flags */
159#define NILFS_TI_DYNAMIC_ALLOC 0x0001 /* Allocated from slab */
160#define NILFS_TI_SYNC 0x0002 /* Force to construct segment at the
161 end of transaction. */
162#define NILFS_TI_GC 0x0004 /* GC context */
163#define NILFS_TI_COMMIT 0x0008 /* Change happened or not */
164#define NILFS_TI_WRITER 0x0010 /* Constructor context */
165
166
167int nilfs_transaction_begin(struct super_block *,
168 struct nilfs_transaction_info *, int);
169int nilfs_transaction_end(struct super_block *, int);
170
171static inline void nilfs_set_transaction_flag(unsigned int flag)
172{
173 struct nilfs_transaction_info *ti = current->journal_info;
174
175 BUG_ON(!ti);
176 ti->ti_flags |= flag;
177}
178
179static inline int nilfs_test_transaction_flag(unsigned int flag)
180{
181 struct nilfs_transaction_info *ti = current->journal_info;
182
183 if (ti == NULL || ti->ti_magic != NILFS_TI_MAGIC)
184 return 0;
185 return !!(ti->ti_flags & flag);
186}
187
188static inline int nilfs_doing_gc(void)
189{
190 return nilfs_test_transaction_flag(NILFS_TI_GC);
191}
192
193static inline int nilfs_doing_construction(void)
194{
195 return nilfs_test_transaction_flag(NILFS_TI_WRITER);
196}
197
198static inline struct inode *nilfs_dat_inode(const struct the_nilfs *nilfs)
199{
200 return nilfs_doing_gc() ? nilfs->ns_gc_dat : nilfs->ns_dat;
201}
202
203/*
204 * function prototype
205 */
206#ifdef CONFIG_NILFS_POSIX_ACL
207#error "NILFS: not yet supported POSIX ACL"
208extern int nilfs_permission(struct inode *, int, struct nameidata *);
209extern int nilfs_acl_chmod(struct inode *);
210extern int nilfs_init_acl(struct inode *, struct inode *);
211#else
212#define nilfs_permission NULL
213
214static inline int nilfs_acl_chmod(struct inode *inode)
215{
216 return 0;
217}
218
219static inline int nilfs_init_acl(struct inode *inode, struct inode *dir)
220{
221 inode->i_mode &= ~current_umask();
222 return 0;
223}
224#endif
225
226#define NILFS_ATIME_DISABLE
227
228/* dir.c */
229extern int nilfs_add_link(struct dentry *, struct inode *);
230extern ino_t nilfs_inode_by_name(struct inode *, struct dentry *);
231extern int nilfs_make_empty(struct inode *, struct inode *);
232extern struct nilfs_dir_entry *
233nilfs_find_entry(struct inode *, struct dentry *, struct page **);
234extern int nilfs_delete_entry(struct nilfs_dir_entry *, struct page *);
235extern int nilfs_empty_dir(struct inode *);
236extern struct nilfs_dir_entry *nilfs_dotdot(struct inode *, struct page **);
237extern void nilfs_set_link(struct inode *, struct nilfs_dir_entry *,
238 struct page *, struct inode *);
239
240/* file.c */
241extern int nilfs_sync_file(struct file *, struct dentry *, int);
242
243/* ioctl.c */
244int nilfs_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
245long nilfs_compat_ioctl(struct file *, unsigned int, unsigned long);
246int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, void __user *);
247
248/* inode.c */
249extern struct inode *nilfs_new_inode(struct inode *, int);
250extern void nilfs_free_inode(struct inode *);
251extern int nilfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
252extern void nilfs_set_inode_flags(struct inode *);
253extern int nilfs_read_inode_common(struct inode *, struct nilfs_inode *);
254extern void nilfs_write_inode_common(struct inode *, struct nilfs_inode *, int);
255extern struct inode *nilfs_iget(struct super_block *, unsigned long);
256extern void nilfs_update_inode(struct inode *, struct buffer_head *);
257extern void nilfs_truncate(struct inode *);
258extern void nilfs_delete_inode(struct inode *);
259extern int nilfs_setattr(struct dentry *, struct iattr *);
260extern int nilfs_load_inode_block(struct nilfs_sb_info *, struct inode *,
261 struct buffer_head **);
262extern int nilfs_inode_dirty(struct inode *);
263extern int nilfs_set_file_dirty(struct nilfs_sb_info *, struct inode *,
264 unsigned);
265extern int nilfs_mark_inode_dirty(struct inode *);
266extern void nilfs_dirty_inode(struct inode *);
267
268/* namei.c */
269extern struct dentry *nilfs_get_parent(struct dentry *);
270
271/* super.c */
272extern struct inode *nilfs_alloc_inode(struct super_block *);
273extern void nilfs_destroy_inode(struct inode *);
274extern void nilfs_error(struct super_block *, const char *, const char *, ...)
275 __attribute__ ((format (printf, 3, 4)));
276extern void nilfs_warning(struct super_block *, const char *, const char *, ...)
277 __attribute__ ((format (printf, 3, 4)));
278extern struct nilfs_super_block *
279nilfs_load_super_block(struct super_block *, struct buffer_head **);
280extern struct nilfs_super_block *
281nilfs_reload_super_block(struct super_block *, struct buffer_head **, int);
282extern int nilfs_store_magic_and_option(struct super_block *,
283 struct nilfs_super_block *, char *);
284extern void nilfs_update_last_segment(struct nilfs_sb_info *, int);
285extern int nilfs_commit_super(struct nilfs_sb_info *);
286extern int nilfs_attach_checkpoint(struct nilfs_sb_info *, __u64);
287extern void nilfs_detach_checkpoint(struct nilfs_sb_info *);
288
289/* gcinode.c */
290int nilfs_gccache_submit_read_data(struct inode *, sector_t, sector_t, __u64,
291 struct buffer_head **);
292int nilfs_gccache_submit_read_node(struct inode *, sector_t, __u64,
293 struct buffer_head **);
294int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *);
295int nilfs_init_gccache(struct the_nilfs *);
296void nilfs_destroy_gccache(struct the_nilfs *);
297void nilfs_clear_gcinode(struct inode *);
298struct inode *nilfs_gc_iget(struct the_nilfs *, ino_t, __u64);
299void nilfs_remove_all_gcinode(struct the_nilfs *);
300
301/* gcdat.c */
302int nilfs_init_gcdat_inode(struct the_nilfs *);
303void nilfs_commit_gcdat_inode(struct the_nilfs *);
304void nilfs_clear_gcdat_inode(struct the_nilfs *);
305
306/*
307 * Inodes and files operations
308 */
309extern struct file_operations nilfs_dir_operations;
310extern struct inode_operations nilfs_file_inode_operations;
311extern struct file_operations nilfs_file_operations;
312extern struct address_space_operations nilfs_aops;
313extern struct inode_operations nilfs_dir_inode_operations;
314extern struct inode_operations nilfs_special_inode_operations;
315extern struct inode_operations nilfs_symlink_inode_operations;
316
317/*
318 * filesystem type
319 */
320extern struct file_system_type nilfs_fs_type;
321
322
323#endif /* _NILFS_H */
diff --git a/fs/nilfs2/sb.h b/fs/nilfs2/sb.h
new file mode 100644
index 000000000000..adccd4fc654e
--- /dev/null
+++ b/fs/nilfs2/sb.h
@@ -0,0 +1,102 @@
1/*
2 * sb.h - NILFS on-memory super block structure.
3 *
4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
5 *
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.
10 *
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.
15 *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * Written by Ryusuke Konishi <ryusuke@osrg.net>
21 *
22 */
23
24#ifndef _NILFS_SB
25#define _NILFS_SB
26
27#include <linux/types.h>
28#include <linux/fs.h>
29
30/*
31 * Mount options
32 */
33struct nilfs_mount_options {
34 unsigned long mount_opt;
35 __u64 snapshot_cno;
36};
37
38struct the_nilfs;
39struct nilfs_sc_info;
40
41/*
42 * NILFS super-block data in memory
43 */
44struct nilfs_sb_info {
45 /* Snapshot status */
46 __u64 s_snapshot_cno; /* Checkpoint number */
47 atomic_t s_inodes_count;
48 atomic_t s_blocks_count; /* Reserved (might be deleted) */
49
50 /* Mount options */
51 unsigned long s_mount_opt;
52 uid_t s_resuid;
53 gid_t s_resgid;
54
55 unsigned long s_interval; /* construction interval */
56 unsigned long s_watermark; /* threshold of data amount
57 for the segment construction */
58
59 /* Fundamental members */
60 struct super_block *s_super; /* reverse pointer to super_block */
61 struct the_nilfs *s_nilfs;
62 struct list_head s_list; /* list head for nilfs->ns_supers */
63
64 /* Segment constructor */
65 struct list_head s_dirty_files; /* dirty files list */
66 struct nilfs_sc_info *s_sc_info; /* segment constructor info */
67 spinlock_t s_inode_lock; /* Lock for the nilfs inode.
68 It covers s_dirty_files list */
69
70 /* Metadata files */
71 struct inode *s_ifile; /* index file inode */
72
73 /* Inode allocator */
74 spinlock_t s_next_gen_lock;
75 u32 s_next_generation;
76};
77
78static inline struct nilfs_sb_info *NILFS_SB(struct super_block *sb)
79{
80 return sb->s_fs_info;
81}
82
83static inline struct nilfs_sc_info *NILFS_SC(struct nilfs_sb_info *sbi)
84{
85 return sbi->s_sc_info;
86}
87
88/*
89 * Bit operations for the mount option
90 */
91#define nilfs_clear_opt(sbi, opt) \
92 do { (sbi)->s_mount_opt &= ~NILFS_MOUNT_##opt; } while (0)
93#define nilfs_set_opt(sbi, opt) \
94 do { (sbi)->s_mount_opt |= NILFS_MOUNT_##opt; } while (0)
95#define nilfs_test_opt(sbi, opt) ((sbi)->s_mount_opt & NILFS_MOUNT_##opt)
96#define nilfs_write_opt(sbi, mask, opt) \
97 do { (sbi)->s_mount_opt = \
98 (((sbi)->s_mount_opt & ~NILFS_MOUNT_##mask) | \
99 NILFS_MOUNT_##opt); \
100 } while (0)
101
102#endif /* _NILFS_SB */
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
new file mode 100644
index 000000000000..dee8d83e0549
--- /dev/null
+++ b/fs/nilfs2/the_nilfs.h
@@ -0,0 +1,290 @@
1/*
2 * the_nilfs.h - the_nilfs shared structure.
3 *
4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
5 *
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.
10 *
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.
15 *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * Written by Ryusuke Konishi <ryusuke@osrg.net>
21 *
22 */
23
24#ifndef _THE_NILFS_H
25#define _THE_NILFS_H
26
27#include <linux/types.h>
28#include <linux/buffer_head.h>
29#include <linux/fs.h>
30#include <linux/blkdev.h>
31#include <linux/backing-dev.h>
32#include "sb.h"
33
34/* the_nilfs struct */
35enum {
36 THE_NILFS_INIT = 0, /* Information from super_block is set */
37 THE_NILFS_LOADED, /* Roll-back/roll-forward has done and
38 the latest checkpoint was loaded */
39 THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */
40 THE_NILFS_COND_NONGC_WRITE, /* Condition to wake up cleanerd */
41};
42
43/**
44 * struct the_nilfs - struct to supervise multiple nilfs mount points
45 * @ns_flags: flags
46 * @ns_count: reference count
47 * @ns_bdev: block device
48 * @ns_bdi: backing dev info
49 * @ns_writer: back pointer to writable nilfs_sb_info
50 * @ns_sem: semaphore for shared states
51 * @ns_writer_mutex: mutex protecting ns_writer attach/detach
52 * @ns_writer_refcount: number of referrers on ns_writer
53 * @ns_sbh: buffer head of the on-disk super block
54 * @ns_sbp: pointer to the super block data
55 * @ns_used_segments: list of full segments in volatile active state
56 * @ns_supers: list of nilfs super block structs
57 * @ns_seg_seq: segment sequence counter
58 * @ns_segnum: index number of the latest full segment.
59 * @ns_nextnum: index number of the full segment index to be used next
60 * @ns_pseg_offset: offset of next partial segment in the current full segment
61 * @ns_cno: next checkpoint number
62 * @ns_ctime: write time of the last segment
63 * @ns_nongc_ctime: write time of the last segment not for cleaner operation
64 * @ns_ndirtyblks: Number of dirty data blocks
65 * @ns_last_segment_lock: lock protecting fields for the latest segment
66 * @ns_last_pseg: start block number of the latest segment
67 * @ns_last_seq: sequence value of the latest segment
68 * @ns_last_cno: checkpoint number of the latest segment
69 * @ns_free_segments_count: counter of free segments
70 * @ns_segctor_sem: segment constructor semaphore
71 * @ns_dat: DAT file inode
72 * @ns_cpfile: checkpoint file inode
73 * @ns_sufile: segusage file inode
74 * @ns_gc_dat: shadow inode of the DAT file inode for GC
75 * @ns_gc_inodes: dummy inodes to keep live blocks
76 * @ns_gc_inodes_h: hash list to keep dummy inode holding live blocks
77 * @ns_cleanerd_wq: wait queue for cleanerd
78 * @ns_blocksize_bits: bit length of block size
79 * @ns_nsegments: number of segments in filesystem
80 * @ns_blocks_per_segment: number of blocks per segment
81 * @ns_r_segments_percentage: reserved segments percentage
82 * @ns_nrsvsegs: number of reserved segments
83 * @ns_first_data_block: block number of first data block
84 * @ns_inode_size: size of on-disk inode
85 * @ns_first_ino: first not-special inode number
86 * @ns_crc_seed: seed value of CRC32 calculation
87 */
88struct the_nilfs {
89 unsigned long ns_flags;
90 atomic_t ns_count;
91
92 struct block_device *ns_bdev;
93 struct backing_dev_info *ns_bdi;
94 struct nilfs_sb_info *ns_writer;
95 struct rw_semaphore ns_sem;
96 struct mutex ns_writer_mutex;
97 atomic_t ns_writer_refcount;
98
99 /*
100 * used for
101 * - loading the latest checkpoint exclusively.
102 * - allocating a new full segment.
103 * - protecting s_dirt in the super_block struct
104 * (see nilfs_write_super) and the following fields.
105 */
106 struct buffer_head *ns_sbh;
107 struct nilfs_super_block *ns_sbp;
108 struct list_head ns_used_segments;
109 unsigned ns_mount_state;
110 struct list_head ns_supers;
111
112 /*
113 * Following fields are dedicated to a writable FS-instance.
114 * Except for the period seeking checkpoint, code outside the segment
115 * constructor must lock a segment semaphore with transaction_begin()
116 * and transaction_end(), when accessing these fields.
117 * The writable FS-instance is sole during a lifetime of the_nilfs.
118 */
119 u64 ns_seg_seq;
120 __u64 ns_segnum;
121 __u64 ns_nextnum;
122 unsigned long ns_pseg_offset;
123 __u64 ns_cno;
124 time_t ns_ctime;
125 time_t ns_nongc_ctime;
126 atomic_t ns_ndirtyblks;
127
128 /*
129 * The following fields hold information on the latest partial segment
130 * written to disk with a super root. These fields are protected by
131 * ns_last_segment_lock.
132 */
133 spinlock_t ns_last_segment_lock;
134 sector_t ns_last_pseg;
135 u64 ns_last_seq;
136 __u64 ns_last_cno;
137 unsigned long ns_free_segments_count;
138
139 struct rw_semaphore ns_segctor_sem;
140
141 /*
142 * Following fields are lock free except for the period before
143 * the_nilfs is initialized.
144 */
145 struct inode *ns_dat;
146 struct inode *ns_cpfile;
147 struct inode *ns_sufile;
148 struct inode *ns_gc_dat;
149
150 /* GC inode list and hash table head */
151 struct list_head ns_gc_inodes;
152 struct hlist_head *ns_gc_inodes_h;
153
154 /* cleanerd */
155 wait_queue_head_t ns_cleanerd_wq;
156
157 /* Disk layout information (static) */
158 unsigned int ns_blocksize_bits;
159 unsigned long ns_nsegments;
160 unsigned long ns_blocks_per_segment;
161 unsigned long ns_r_segments_percentage;
162 unsigned long ns_nrsvsegs;
163 unsigned long ns_first_data_block;
164 int ns_inode_size;
165 int ns_first_ino;
166 u32 ns_crc_seed;
167};
168
169#define NILFS_GCINODE_HASH_BITS 8
170#define NILFS_GCINODE_HASH_SIZE (1<<NILFS_GCINODE_HASH_BITS)
171
172#define THE_NILFS_FNS(bit, name) \
173static inline void set_nilfs_##name(struct the_nilfs *nilfs) \
174{ \
175 set_bit(THE_NILFS_##bit, &(nilfs)->ns_flags); \
176} \
177static inline void clear_nilfs_##name(struct the_nilfs *nilfs) \
178{ \
179 clear_bit(THE_NILFS_##bit, &(nilfs)->ns_flags); \
180} \
181static inline int nilfs_##name(struct the_nilfs *nilfs) \
182{ \
183 return test_bit(THE_NILFS_##bit, &(nilfs)->ns_flags); \
184}
185
186THE_NILFS_FNS(INIT, init)
187THE_NILFS_FNS(LOADED, loaded)
188THE_NILFS_FNS(DISCONTINUED, discontinued)
189THE_NILFS_FNS(COND_NONGC_WRITE, cond_nongc_write)
190
191void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64);
192struct the_nilfs *alloc_nilfs(struct block_device *);
193void put_nilfs(struct the_nilfs *);
194int init_nilfs(struct the_nilfs *, struct nilfs_sb_info *, char *);
195int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *);
196int nilfs_count_free_blocks(struct the_nilfs *, sector_t *);
197void nilfs_dispose_used_segments(struct the_nilfs *);
198int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int);
199int nilfs_near_disk_full(struct the_nilfs *);
200
201
202static inline void get_nilfs(struct the_nilfs *nilfs)
203{
204 /* Caller must have at least one reference of the_nilfs. */
205 atomic_inc(&nilfs->ns_count);
206}
207
208static inline struct nilfs_sb_info *nilfs_get_writer(struct the_nilfs *nilfs)
209{
210 if (atomic_inc_and_test(&nilfs->ns_writer_refcount))
211 mutex_lock(&nilfs->ns_writer_mutex);
212 return nilfs->ns_writer;
213}
214
215static inline void nilfs_put_writer(struct the_nilfs *nilfs)
216{
217 if (atomic_add_negative(-1, &nilfs->ns_writer_refcount))
218 mutex_unlock(&nilfs->ns_writer_mutex);
219}
220
221static inline void
222nilfs_attach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
223{
224 mutex_lock(&nilfs->ns_writer_mutex);
225 nilfs->ns_writer = sbi;
226 mutex_unlock(&nilfs->ns_writer_mutex);
227}
228
229static inline void
230nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
231{
232 mutex_lock(&nilfs->ns_writer_mutex);
233 if (sbi == nilfs->ns_writer)
234 nilfs->ns_writer = NULL;
235 mutex_unlock(&nilfs->ns_writer_mutex);
236}
237
238static inline void
239nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum,
240 sector_t *seg_start, sector_t *seg_end)
241{
242 *seg_start = (sector_t)nilfs->ns_blocks_per_segment * segnum;
243 *seg_end = *seg_start + nilfs->ns_blocks_per_segment - 1;
244 if (segnum == 0)
245 *seg_start = nilfs->ns_first_data_block;
246}
247
248static inline sector_t
249nilfs_get_segment_start_blocknr(struct the_nilfs *nilfs, __u64 segnum)
250{
251 return (segnum == 0) ? nilfs->ns_first_data_block :
252 (sector_t)nilfs->ns_blocks_per_segment * segnum;
253}
254
255static inline __u64
256nilfs_get_segnum_of_block(struct the_nilfs *nilfs, sector_t blocknr)
257{
258 sector_t segnum = blocknr;
259
260 sector_div(segnum, nilfs->ns_blocks_per_segment);
261 return segnum;
262}
263
264static inline void
265nilfs_terminate_segment(struct the_nilfs *nilfs, sector_t seg_start,
266 sector_t seg_end)
267{
268 /* terminate the current full segment (used in case of I/O-error) */
269 nilfs->ns_pseg_offset = seg_end - seg_start + 1;
270}
271
272static inline void nilfs_shift_to_next_segment(struct the_nilfs *nilfs)
273{
274 /* move forward with a full segment */
275 nilfs->ns_segnum = nilfs->ns_nextnum;
276 nilfs->ns_pseg_offset = 0;
277 nilfs->ns_seg_seq++;
278}
279
280static inline __u64 nilfs_last_cno(struct the_nilfs *nilfs)
281{
282 __u64 cno;
283
284 spin_lock(&nilfs->ns_last_segment_lock);
285 cno = nilfs->ns_last_cno;
286 spin_unlock(&nilfs->ns_last_segment_lock);
287 return cno;
288}
289
290#endif /* _THE_NILFS_H */