linux/fs/nilfs2/the_nilfs.h
<<
>>
Prefs
   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/rbtree.h>
  30#include <linux/fs.h>
  31#include <linux/blkdev.h>
  32#include <linux/backing-dev.h>
  33#include <linux/slab.h>
  34
  35struct nilfs_sc_info;
  36struct nilfs_sysfs_dev_subgroups;
  37
  38/* the_nilfs struct */
  39enum {
  40        THE_NILFS_INIT = 0,     /* Information from super_block is set */
  41        THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */
  42        THE_NILFS_GC_RUNNING,   /* gc process is running */
  43        THE_NILFS_SB_DIRTY,     /* super block is dirty */
  44};
  45
  46/**
  47 * struct the_nilfs - struct to supervise multiple nilfs mount points
  48 * @ns_flags: flags
  49 * @ns_flushed_device: flag indicating if all volatile data was flushed
  50 * @ns_bdev: block device
  51 * @ns_sem: semaphore for shared states
  52 * @ns_snapshot_mount_mutex: mutex to protect snapshot mounts
  53 * @ns_sbh: buffer heads of on-disk super blocks
  54 * @ns_sbp: pointers to super block data
  55 * @ns_sbwtime: previous write time of super block
  56 * @ns_sbwcount: write count of super block
  57 * @ns_sbsize: size of valid data in super block
  58 * @ns_mount_state: file system state
  59 * @ns_sb_update_freq: interval of periodical update of superblocks (in seconds)
  60 * @ns_seg_seq: segment sequence counter
  61 * @ns_segnum: index number of the latest full segment.
  62 * @ns_nextnum: index number of the full segment index to be used next
  63 * @ns_pseg_offset: offset of next partial segment in the current full segment
  64 * @ns_cno: next checkpoint number
  65 * @ns_ctime: write time of the last segment
  66 * @ns_nongc_ctime: write time of the last segment not for cleaner operation
  67 * @ns_ndirtyblks: Number of dirty data blocks
  68 * @ns_last_segment_lock: lock protecting fields for the latest segment
  69 * @ns_last_pseg: start block number of the latest segment
  70 * @ns_last_seq: sequence value of the latest segment
  71 * @ns_last_cno: checkpoint number of the latest segment
  72 * @ns_prot_seq: least sequence number of segments which must not be reclaimed
  73 * @ns_prev_seq: base sequence number used to decide if advance log cursor
  74 * @ns_writer: log writer
  75 * @ns_segctor_sem: semaphore protecting log write
  76 * @ns_dat: DAT file inode
  77 * @ns_cpfile: checkpoint file inode
  78 * @ns_sufile: segusage file inode
  79 * @ns_cptree: rb-tree of all mounted checkpoints (nilfs_root)
  80 * @ns_cptree_lock: lock protecting @ns_cptree
  81 * @ns_dirty_files: list of dirty files
  82 * @ns_inode_lock: lock protecting @ns_dirty_files
  83 * @ns_gc_inodes: dummy inodes to keep live blocks
  84 * @ns_next_generation: next generation number for inodes
  85 * @ns_next_gen_lock: lock protecting @ns_next_generation
  86 * @ns_mount_opt: mount options
  87 * @ns_resuid: uid for reserved blocks
  88 * @ns_resgid: gid for reserved blocks
  89 * @ns_interval: checkpoint creation interval
  90 * @ns_watermark: watermark for the number of dirty buffers
  91 * @ns_blocksize_bits: bit length of block size
  92 * @ns_blocksize: block size
  93 * @ns_nsegments: number of segments in filesystem
  94 * @ns_blocks_per_segment: number of blocks per segment
  95 * @ns_r_segments_percentage: reserved segments percentage
  96 * @ns_nrsvsegs: number of reserved segments
  97 * @ns_first_data_block: block number of first data block
  98 * @ns_inode_size: size of on-disk inode
  99 * @ns_first_ino: first not-special inode number
 100 * @ns_crc_seed: seed value of CRC32 calculation
 101 * @ns_dev_kobj: /sys/fs/<nilfs>/<device>
 102 * @ns_dev_kobj_unregister: completion state
 103 * @ns_dev_subgroups: <device> subgroups pointer
 104 */
 105struct the_nilfs {
 106        unsigned long           ns_flags;
 107        int                     ns_flushed_device;
 108
 109        struct block_device    *ns_bdev;
 110        struct rw_semaphore     ns_sem;
 111        struct mutex            ns_snapshot_mount_mutex;
 112
 113        /*
 114         * used for
 115         * - loading the latest checkpoint exclusively.
 116         * - allocating a new full segment.
 117         */
 118        struct buffer_head     *ns_sbh[2];
 119        struct nilfs_super_block *ns_sbp[2];
 120        time_t                  ns_sbwtime;
 121        unsigned                ns_sbwcount;
 122        unsigned                ns_sbsize;
 123        unsigned                ns_mount_state;
 124        unsigned                ns_sb_update_freq;
 125
 126        /*
 127         * Following fields are dedicated to a writable FS-instance.
 128         * Except for the period seeking checkpoint, code outside the segment
 129         * constructor must lock a segment semaphore while accessing these
 130         * fields.
 131         * The writable FS-instance is sole during a lifetime of the_nilfs.
 132         */
 133        u64                     ns_seg_seq;
 134        __u64                   ns_segnum;
 135        __u64                   ns_nextnum;
 136        unsigned long           ns_pseg_offset;
 137        __u64                   ns_cno;
 138        time_t                  ns_ctime;
 139        time_t                  ns_nongc_ctime;
 140        atomic_t                ns_ndirtyblks;
 141
 142        /*
 143         * The following fields hold information on the latest partial segment
 144         * written to disk with a super root.  These fields are protected by
 145         * ns_last_segment_lock.
 146         */
 147        spinlock_t              ns_last_segment_lock;
 148        sector_t                ns_last_pseg;
 149        u64                     ns_last_seq;
 150        __u64                   ns_last_cno;
 151        u64                     ns_prot_seq;
 152        u64                     ns_prev_seq;
 153
 154        struct nilfs_sc_info   *ns_writer;
 155        struct rw_semaphore     ns_segctor_sem;
 156
 157        /*
 158         * Following fields are lock free except for the period before
 159         * the_nilfs is initialized.
 160         */
 161        struct inode           *ns_dat;
 162        struct inode           *ns_cpfile;
 163        struct inode           *ns_sufile;
 164
 165        /* Checkpoint tree */
 166        struct rb_root          ns_cptree;
 167        spinlock_t              ns_cptree_lock;
 168
 169        /* Dirty inode list */
 170        struct list_head        ns_dirty_files;
 171        spinlock_t              ns_inode_lock;
 172
 173        /* GC inode list */
 174        struct list_head        ns_gc_inodes;
 175
 176        /* Inode allocator */
 177        u32                     ns_next_generation;
 178        spinlock_t              ns_next_gen_lock;
 179
 180        /* Mount options */
 181        unsigned long           ns_mount_opt;
 182
 183        uid_t                   ns_resuid;
 184        gid_t                   ns_resgid;
 185        unsigned long           ns_interval;
 186        unsigned long           ns_watermark;
 187
 188        /* Disk layout information (static) */
 189        unsigned int            ns_blocksize_bits;
 190        unsigned int            ns_blocksize;
 191        unsigned long           ns_nsegments;
 192        unsigned long           ns_blocks_per_segment;
 193        unsigned long           ns_r_segments_percentage;
 194        unsigned long           ns_nrsvsegs;
 195        unsigned long           ns_first_data_block;
 196        int                     ns_inode_size;
 197        int                     ns_first_ino;
 198        u32                     ns_crc_seed;
 199
 200        /* /sys/fs/<nilfs>/<device> */
 201        struct kobject ns_dev_kobj;
 202        struct completion ns_dev_kobj_unregister;
 203        struct nilfs_sysfs_dev_subgroups *ns_dev_subgroups;
 204};
 205
 206#define THE_NILFS_FNS(bit, name)                                        \
 207static inline void set_nilfs_##name(struct the_nilfs *nilfs)            \
 208{                                                                       \
 209        set_bit(THE_NILFS_##bit, &(nilfs)->ns_flags);                   \
 210}                                                                       \
 211static inline void clear_nilfs_##name(struct the_nilfs *nilfs)          \
 212{                                                                       \
 213        clear_bit(THE_NILFS_##bit, &(nilfs)->ns_flags);                 \
 214}                                                                       \
 215static inline int nilfs_##name(struct the_nilfs *nilfs)                 \
 216{                                                                       \
 217        return test_bit(THE_NILFS_##bit, &(nilfs)->ns_flags);           \
 218}
 219
 220THE_NILFS_FNS(INIT, init)
 221THE_NILFS_FNS(DISCONTINUED, discontinued)
 222THE_NILFS_FNS(GC_RUNNING, gc_running)
 223THE_NILFS_FNS(SB_DIRTY, sb_dirty)
 224
 225/*
 226 * Mount option operations
 227 */
 228#define nilfs_clear_opt(nilfs, opt)  \
 229        do { (nilfs)->ns_mount_opt &= ~NILFS_MOUNT_##opt; } while (0)
 230#define nilfs_set_opt(nilfs, opt)  \
 231        do { (nilfs)->ns_mount_opt |= NILFS_MOUNT_##opt; } while (0)
 232#define nilfs_test_opt(nilfs, opt) ((nilfs)->ns_mount_opt & NILFS_MOUNT_##opt)
 233#define nilfs_write_opt(nilfs, mask, opt)                               \
 234        do { (nilfs)->ns_mount_opt =                                    \
 235                (((nilfs)->ns_mount_opt & ~NILFS_MOUNT_##mask) |        \
 236                 NILFS_MOUNT_##opt);                                    \
 237        } while (0)
 238
 239/**
 240 * struct nilfs_root - nilfs root object
 241 * @cno: checkpoint number
 242 * @rb_node: red-black tree node
 243 * @count: refcount of this structure
 244 * @nilfs: nilfs object
 245 * @ifile: inode file
 246 * @inodes_count: number of inodes
 247 * @blocks_count: number of blocks
 248 * @snapshot_kobj: /sys/fs/<nilfs>/<device>/mounted_snapshots/<snapshot>
 249 * @snapshot_kobj_unregister: completion state for kernel object
 250 */
 251struct nilfs_root {
 252        __u64 cno;
 253        struct rb_node rb_node;
 254
 255        atomic_t count;
 256        struct the_nilfs *nilfs;
 257        struct inode *ifile;
 258
 259        atomic64_t inodes_count;
 260        atomic64_t blocks_count;
 261
 262        /* /sys/fs/<nilfs>/<device>/mounted_snapshots/<snapshot> */
 263        struct kobject snapshot_kobj;
 264        struct completion snapshot_kobj_unregister;
 265};
 266
 267/* Special checkpoint number */
 268#define NILFS_CPTREE_CURRENT_CNO        0
 269
 270/* Minimum interval of periodical update of superblocks (in seconds) */
 271#define NILFS_SB_FREQ           10
 272
 273static inline int nilfs_sb_need_update(struct the_nilfs *nilfs)
 274{
 275        u64 t = get_seconds();
 276        return t < nilfs->ns_sbwtime ||
 277                t > nilfs->ns_sbwtime + nilfs->ns_sb_update_freq;
 278}
 279
 280static inline int nilfs_sb_will_flip(struct the_nilfs *nilfs)
 281{
 282        int flip_bits = nilfs->ns_sbwcount & 0x0FL;
 283        return (flip_bits != 0x08 && flip_bits != 0x0F);
 284}
 285
 286void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64);
 287struct the_nilfs *alloc_nilfs(struct block_device *bdev);
 288void destroy_nilfs(struct the_nilfs *nilfs);
 289int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data);
 290int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb);
 291unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs);
 292void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs);
 293int nilfs_discard_segments(struct the_nilfs *, __u64 *, size_t);
 294int nilfs_count_free_blocks(struct the_nilfs *, sector_t *);
 295struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno);
 296struct nilfs_root *nilfs_find_or_create_root(struct the_nilfs *nilfs,
 297                                             __u64 cno);
 298void nilfs_put_root(struct nilfs_root *root);
 299int nilfs_near_disk_full(struct the_nilfs *);
 300void nilfs_fall_back_super_block(struct the_nilfs *);
 301void nilfs_swap_super_block(struct the_nilfs *);
 302
 303
 304static inline void nilfs_get_root(struct nilfs_root *root)
 305{
 306        atomic_inc(&root->count);
 307}
 308
 309static inline int nilfs_valid_fs(struct the_nilfs *nilfs)
 310{
 311        unsigned valid_fs;
 312
 313        down_read(&nilfs->ns_sem);
 314        valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS);
 315        up_read(&nilfs->ns_sem);
 316        return valid_fs;
 317}
 318
 319static inline void
 320nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum,
 321                        sector_t *seg_start, sector_t *seg_end)
 322{
 323        *seg_start = (sector_t)nilfs->ns_blocks_per_segment * segnum;
 324        *seg_end = *seg_start + nilfs->ns_blocks_per_segment - 1;
 325        if (segnum == 0)
 326                *seg_start = nilfs->ns_first_data_block;
 327}
 328
 329static inline sector_t
 330nilfs_get_segment_start_blocknr(struct the_nilfs *nilfs, __u64 segnum)
 331{
 332        return (segnum == 0) ? nilfs->ns_first_data_block :
 333                (sector_t)nilfs->ns_blocks_per_segment * segnum;
 334}
 335
 336static inline __u64
 337nilfs_get_segnum_of_block(struct the_nilfs *nilfs, sector_t blocknr)
 338{
 339        sector_t segnum = blocknr;
 340
 341        sector_div(segnum, nilfs->ns_blocks_per_segment);
 342        return segnum;
 343}
 344
 345static inline void
 346nilfs_terminate_segment(struct the_nilfs *nilfs, sector_t seg_start,
 347                        sector_t seg_end)
 348{
 349        /* terminate the current full segment (used in case of I/O-error) */
 350        nilfs->ns_pseg_offset = seg_end - seg_start + 1;
 351}
 352
 353static inline void nilfs_shift_to_next_segment(struct the_nilfs *nilfs)
 354{
 355        /* move forward with a full segment */
 356        nilfs->ns_segnum = nilfs->ns_nextnum;
 357        nilfs->ns_pseg_offset = 0;
 358        nilfs->ns_seg_seq++;
 359}
 360
 361static inline __u64 nilfs_last_cno(struct the_nilfs *nilfs)
 362{
 363        __u64 cno;
 364
 365        spin_lock(&nilfs->ns_last_segment_lock);
 366        cno = nilfs->ns_last_cno;
 367        spin_unlock(&nilfs->ns_last_segment_lock);
 368        return cno;
 369}
 370
 371static inline int nilfs_segment_is_active(struct the_nilfs *nilfs, __u64 n)
 372{
 373        return n == nilfs->ns_segnum || n == nilfs->ns_nextnum;
 374}
 375
 376static inline int nilfs_flush_device(struct the_nilfs *nilfs)
 377{
 378        int err;
 379
 380        if (!nilfs_test_opt(nilfs, BARRIER) || nilfs->ns_flushed_device)
 381                return 0;
 382
 383        nilfs->ns_flushed_device = 1;
 384        /*
 385         * the store to ns_flushed_device must not be reordered after
 386         * blkdev_issue_flush().
 387         */
 388        smp_wmb();
 389
 390        err = blkdev_issue_flush(nilfs->ns_bdev, GFP_KERNEL, NULL);
 391        if (err != -EIO)
 392                err = 0;
 393        return err;
 394}
 395
 396#endif /* _THE_NILFS_H */
 397