blob: bc7760c2a8f2a27f4b361434b7aad2453d86d5b5 [file] [log] [blame]
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -07001/*
2 * the_nilfs.c - 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#include <linux/buffer_head.h>
25#include <linux/slab.h>
26#include <linux/blkdev.h>
27#include <linux/backing-dev.h>
Ryusuke Konishie339ad32009-04-06 19:01:59 -070028#include <linux/crc32.h>
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -070029#include "nilfs.h"
30#include "segment.h"
31#include "alloc.h"
32#include "cpfile.h"
33#include "sufile.h"
34#include "dat.h"
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -070035#include "segbuf.h"
36
Ryusuke Konishi33c8e572009-06-08 01:39:29 +090037
38static LIST_HEAD(nilfs_objects);
39static DEFINE_SPINLOCK(nilfs_lock);
40
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -070041void nilfs_set_last_segment(struct the_nilfs *nilfs,
42 sector_t start_blocknr, u64 seq, __u64 cno)
43{
44 spin_lock(&nilfs->ns_last_segment_lock);
45 nilfs->ns_last_pseg = start_blocknr;
46 nilfs->ns_last_seq = seq;
47 nilfs->ns_last_cno = cno;
48 spin_unlock(&nilfs->ns_last_segment_lock);
49}
50
51/**
52 * alloc_nilfs - allocate the_nilfs structure
53 * @bdev: block device to which the_nilfs is related
54 *
55 * alloc_nilfs() allocates memory for the_nilfs and
56 * initializes its reference count and locks.
57 *
58 * Return Value: On success, pointer to the_nilfs is returned.
59 * On error, NULL is returned.
60 */
Ryusuke Konishi33c8e572009-06-08 01:39:29 +090061static struct the_nilfs *alloc_nilfs(struct block_device *bdev)
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -070062{
63 struct the_nilfs *nilfs;
64
65 nilfs = kzalloc(sizeof(*nilfs), GFP_KERNEL);
66 if (!nilfs)
67 return NULL;
68
69 nilfs->ns_bdev = bdev;
70 atomic_set(&nilfs->ns_count, 1);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -070071 atomic_set(&nilfs->ns_ndirtyblks, 0);
72 init_rwsem(&nilfs->ns_sem);
Ryusuke Konishie59399d2009-06-08 01:39:32 +090073 init_rwsem(&nilfs->ns_super_sem);
Ryusuke Konishiaa7dfb82009-06-08 01:39:33 +090074 mutex_init(&nilfs->ns_mount_mutex);
Ryusuke Konishi027d6402009-08-02 22:45:33 +090075 init_rwsem(&nilfs->ns_writer_sem);
Ryusuke Konishi33c8e572009-06-08 01:39:29 +090076 INIT_LIST_HEAD(&nilfs->ns_list);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -070077 INIT_LIST_HEAD(&nilfs->ns_supers);
78 spin_lock_init(&nilfs->ns_last_segment_lock);
79 nilfs->ns_gc_inodes_h = NULL;
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -070080 init_rwsem(&nilfs->ns_segctor_sem);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -070081
82 return nilfs;
83}
84
85/**
Ryusuke Konishi33c8e572009-06-08 01:39:29 +090086 * find_or_create_nilfs - find or create nilfs object
87 * @bdev: block device to which the_nilfs is related
88 *
89 * find_nilfs() looks up an existent nilfs object created on the
90 * device and gets the reference count of the object. If no nilfs object
91 * is found on the device, a new nilfs object is allocated.
92 *
93 * Return Value: On success, pointer to the nilfs object is returned.
94 * On error, NULL is returned.
95 */
96struct the_nilfs *find_or_create_nilfs(struct block_device *bdev)
97{
98 struct the_nilfs *nilfs, *new = NULL;
99
100 retry:
101 spin_lock(&nilfs_lock);
102 list_for_each_entry(nilfs, &nilfs_objects, ns_list) {
103 if (nilfs->ns_bdev == bdev) {
104 get_nilfs(nilfs);
105 spin_unlock(&nilfs_lock);
106 if (new)
107 put_nilfs(new);
108 return nilfs; /* existing object */
109 }
110 }
111 if (new) {
112 list_add_tail(&new->ns_list, &nilfs_objects);
113 spin_unlock(&nilfs_lock);
114 return new; /* new object */
115 }
116 spin_unlock(&nilfs_lock);
117
118 new = alloc_nilfs(bdev);
119 if (new)
120 goto retry;
121 return NULL; /* insufficient memory */
122}
123
124/**
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700125 * put_nilfs - release a reference to the_nilfs
126 * @nilfs: the_nilfs structure to be released
127 *
128 * put_nilfs() decrements a reference counter of the_nilfs.
129 * If the reference count reaches zero, the_nilfs is freed.
130 */
131void put_nilfs(struct the_nilfs *nilfs)
132{
Ryusuke Konishi33c8e572009-06-08 01:39:29 +0900133 spin_lock(&nilfs_lock);
134 if (!atomic_dec_and_test(&nilfs->ns_count)) {
135 spin_unlock(&nilfs_lock);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700136 return;
Ryusuke Konishi33c8e572009-06-08 01:39:29 +0900137 }
138 list_del_init(&nilfs->ns_list);
139 spin_unlock(&nilfs_lock);
140
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700141 /*
Ryusuke Konishi33c8e572009-06-08 01:39:29 +0900142 * Increment of ns_count never occurs below because the caller
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700143 * of get_nilfs() holds at least one reference to the_nilfs.
144 * Thus its exclusion control is not required here.
145 */
Ryusuke Konishi33c8e572009-06-08 01:39:29 +0900146
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700147 might_sleep();
148 if (nilfs_loaded(nilfs)) {
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700149 nilfs_mdt_clear(nilfs->ns_sufile);
150 nilfs_mdt_destroy(nilfs->ns_sufile);
151 nilfs_mdt_clear(nilfs->ns_cpfile);
152 nilfs_mdt_destroy(nilfs->ns_cpfile);
153 nilfs_mdt_clear(nilfs->ns_dat);
154 nilfs_mdt_destroy(nilfs->ns_dat);
155 /* XXX: how and when to clear nilfs->ns_gc_dat? */
156 nilfs_mdt_destroy(nilfs->ns_gc_dat);
157 }
158 if (nilfs_init(nilfs)) {
159 nilfs_destroy_gccache(nilfs);
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700160 brelse(nilfs->ns_sbh[0]);
161 brelse(nilfs->ns_sbh[1]);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700162 }
163 kfree(nilfs);
164}
165
166static int nilfs_load_super_root(struct the_nilfs *nilfs,
167 struct nilfs_sb_info *sbi, sector_t sr_block)
168{
169 struct buffer_head *bh_sr;
170 struct nilfs_super_root *raw_sr;
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700171 struct nilfs_super_block **sbp = nilfs->ns_sbp;
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700172 unsigned dat_entry_size, segment_usage_size, checkpoint_size;
173 unsigned inode_size;
174 int err;
175
176 err = nilfs_read_super_root_block(sbi->s_super, sr_block, &bh_sr, 1);
177 if (unlikely(err))
178 return err;
179
180 down_read(&nilfs->ns_sem);
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700181 dat_entry_size = le16_to_cpu(sbp[0]->s_dat_entry_size);
182 checkpoint_size = le16_to_cpu(sbp[0]->s_checkpoint_size);
183 segment_usage_size = le16_to_cpu(sbp[0]->s_segment_usage_size);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700184 up_read(&nilfs->ns_sem);
185
186 inode_size = nilfs->ns_inode_size;
187
188 err = -ENOMEM;
Ryusuke Konishi79739562009-11-12 23:56:43 +0900189 nilfs->ns_dat = nilfs_dat_new(nilfs, dat_entry_size);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700190 if (unlikely(!nilfs->ns_dat))
191 goto failed;
192
Ryusuke Konishi79739562009-11-12 23:56:43 +0900193 nilfs->ns_gc_dat = nilfs_dat_new(nilfs, dat_entry_size);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700194 if (unlikely(!nilfs->ns_gc_dat))
195 goto failed_dat;
196
Ryusuke Konishi79739562009-11-12 23:56:43 +0900197 nilfs->ns_cpfile = nilfs_cpfile_new(nilfs, checkpoint_size);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700198 if (unlikely(!nilfs->ns_cpfile))
199 goto failed_gc_dat;
200
Ryusuke Konishi79739562009-11-12 23:56:43 +0900201 nilfs->ns_sufile = nilfs_sufile_new(nilfs, segment_usage_size);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700202 if (unlikely(!nilfs->ns_sufile))
203 goto failed_cpfile;
204
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700205 nilfs_mdt_set_shadow(nilfs->ns_dat, nilfs->ns_gc_dat);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700206
Ryusuke Konishi8707df32009-11-13 01:36:56 +0900207 err = nilfs_dat_read(nilfs->ns_dat, (void *)bh_sr->b_data +
208 NILFS_SR_DAT_OFFSET(inode_size));
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700209 if (unlikely(err))
210 goto failed_sufile;
211
Ryusuke Konishi8707df32009-11-13 01:36:56 +0900212 err = nilfs_cpfile_read(nilfs->ns_cpfile, (void *)bh_sr->b_data +
213 NILFS_SR_CPFILE_OFFSET(inode_size));
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700214 if (unlikely(err))
215 goto failed_sufile;
216
Ryusuke Konishi8707df32009-11-13 01:36:56 +0900217 err = nilfs_sufile_read(nilfs->ns_sufile, (void *)bh_sr->b_data +
218 NILFS_SR_SUFILE_OFFSET(inode_size));
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700219 if (unlikely(err))
220 goto failed_sufile;
221
222 raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
223 nilfs->ns_nongc_ctime = le64_to_cpu(raw_sr->sr_nongc_ctime);
224
225 failed:
226 brelse(bh_sr);
227 return err;
228
229 failed_sufile:
230 nilfs_mdt_destroy(nilfs->ns_sufile);
231
232 failed_cpfile:
233 nilfs_mdt_destroy(nilfs->ns_cpfile);
234
235 failed_gc_dat:
236 nilfs_mdt_destroy(nilfs->ns_gc_dat);
237
238 failed_dat:
239 nilfs_mdt_destroy(nilfs->ns_dat);
240 goto failed;
241}
242
243static void nilfs_init_recovery_info(struct nilfs_recovery_info *ri)
244{
245 memset(ri, 0, sizeof(*ri));
246 INIT_LIST_HEAD(&ri->ri_used_segments);
247}
248
249static void nilfs_clear_recovery_info(struct nilfs_recovery_info *ri)
250{
251 nilfs_dispose_segment_list(&ri->ri_used_segments);
252}
253
254/**
255 * load_nilfs - load and recover the nilfs
256 * @nilfs: the_nilfs structure to be released
257 * @sbi: nilfs_sb_info used to recover past segment
258 *
259 * load_nilfs() searches and load the latest super root,
260 * attaches the last segment, and does recovery if needed.
261 * The caller must call this exclusively for simultaneous mounts.
262 */
263int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
264{
265 struct nilfs_recovery_info ri;
266 unsigned int s_flags = sbi->s_super->s_flags;
267 int really_read_only = bdev_read_only(nilfs->ns_bdev);
268 unsigned valid_fs;
269 int err = 0;
270
271 nilfs_init_recovery_info(&ri);
272
273 down_write(&nilfs->ns_sem);
274 valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS);
275 up_write(&nilfs->ns_sem);
276
277 if (!valid_fs && (s_flags & MS_RDONLY)) {
278 printk(KERN_INFO "NILFS: INFO: recovery "
279 "required for readonly filesystem.\n");
280 if (really_read_only) {
281 printk(KERN_ERR "NILFS: write access "
282 "unavailable, cannot proceed.\n");
283 err = -EROFS;
284 goto failed;
285 }
286 printk(KERN_INFO "NILFS: write access will "
287 "be enabled during recovery.\n");
288 sbi->s_super->s_flags &= ~MS_RDONLY;
289 }
290
291 err = nilfs_search_super_root(nilfs, sbi, &ri);
292 if (unlikely(err)) {
293 printk(KERN_ERR "NILFS: error searching super root.\n");
294 goto failed;
295 }
296
297 err = nilfs_load_super_root(nilfs, sbi, ri.ri_super_root);
298 if (unlikely(err)) {
299 printk(KERN_ERR "NILFS: error loading super root.\n");
300 goto failed;
301 }
302
303 if (!valid_fs) {
304 err = nilfs_recover_logical_segments(nilfs, sbi, &ri);
305 if (unlikely(err)) {
306 nilfs_mdt_destroy(nilfs->ns_cpfile);
307 nilfs_mdt_destroy(nilfs->ns_sufile);
308 nilfs_mdt_destroy(nilfs->ns_dat);
309 goto failed;
310 }
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700311 if (ri.ri_need_recovery == NILFS_RECOVERY_SR_UPDATED)
312 sbi->s_super->s_dirt = 1;
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700313 }
314
315 set_nilfs_loaded(nilfs);
316
317 failed:
318 nilfs_clear_recovery_info(&ri);
319 sbi->s_super->s_flags = s_flags;
320 return err;
321}
322
323static unsigned long long nilfs_max_size(unsigned int blkbits)
324{
325 unsigned int max_bits;
326 unsigned long long res = MAX_LFS_FILESIZE; /* page cache limit */
327
328 max_bits = blkbits + NILFS_BMAP_KEY_BIT; /* bmap size limit */
329 if (max_bits < 64)
330 res = min_t(unsigned long long, res, (1ULL << max_bits) - 1);
331 return res;
332}
333
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700334static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
335 struct nilfs_super_block *sbp)
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700336{
337 if (le32_to_cpu(sbp->s_rev_level) != NILFS_CURRENT_REV) {
338 printk(KERN_ERR "NILFS: revision mismatch "
339 "(superblock rev.=%d.%d, current rev.=%d.%d). "
340 "Please check the version of mkfs.nilfs.\n",
341 le32_to_cpu(sbp->s_rev_level),
342 le16_to_cpu(sbp->s_minor_rev_level),
343 NILFS_CURRENT_REV, NILFS_MINOR_REV);
344 return -EINVAL;
345 }
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700346 nilfs->ns_sbsize = le16_to_cpu(sbp->s_bytes);
347 if (nilfs->ns_sbsize > BLOCK_SIZE)
348 return -EINVAL;
349
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700350 nilfs->ns_inode_size = le16_to_cpu(sbp->s_inode_size);
351 nilfs->ns_first_ino = le32_to_cpu(sbp->s_first_ino);
352
353 nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
354 if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) {
355 printk(KERN_ERR "NILFS: too short segment. \n");
356 return -EINVAL;
357 }
358
359 nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block);
360 nilfs->ns_nsegments = le64_to_cpu(sbp->s_nsegments);
361 nilfs->ns_r_segments_percentage =
362 le32_to_cpu(sbp->s_r_segments_percentage);
363 nilfs->ns_nrsvsegs =
364 max_t(unsigned long, NILFS_MIN_NRSVSEGS,
365 DIV_ROUND_UP(nilfs->ns_nsegments *
366 nilfs->ns_r_segments_percentage, 100));
367 nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed);
368 return 0;
369}
370
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700371static int nilfs_valid_sb(struct nilfs_super_block *sbp)
372{
373 static unsigned char sum[4];
374 const int sumoff = offsetof(struct nilfs_super_block, s_sum);
375 size_t bytes;
376 u32 crc;
377
378 if (!sbp || le16_to_cpu(sbp->s_magic) != NILFS_SUPER_MAGIC)
379 return 0;
380 bytes = le16_to_cpu(sbp->s_bytes);
381 if (bytes > BLOCK_SIZE)
382 return 0;
383 crc = crc32_le(le32_to_cpu(sbp->s_crc_seed), (unsigned char *)sbp,
384 sumoff);
385 crc = crc32_le(crc, sum, 4);
386 crc = crc32_le(crc, (unsigned char *)sbp + sumoff + 4,
387 bytes - sumoff - 4);
388 return crc == le32_to_cpu(sbp->s_sum);
389}
390
391static int nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
392{
393 return offset < ((le64_to_cpu(sbp->s_nsegments) *
394 le32_to_cpu(sbp->s_blocks_per_segment)) <<
395 (le32_to_cpu(sbp->s_log_block_size) + 10));
396}
397
398static void nilfs_release_super_block(struct the_nilfs *nilfs)
399{
400 int i;
401
402 for (i = 0; i < 2; i++) {
403 if (nilfs->ns_sbp[i]) {
404 brelse(nilfs->ns_sbh[i]);
405 nilfs->ns_sbh[i] = NULL;
406 nilfs->ns_sbp[i] = NULL;
407 }
408 }
409}
410
411void nilfs_fall_back_super_block(struct the_nilfs *nilfs)
412{
413 brelse(nilfs->ns_sbh[0]);
414 nilfs->ns_sbh[0] = nilfs->ns_sbh[1];
415 nilfs->ns_sbp[0] = nilfs->ns_sbp[1];
416 nilfs->ns_sbh[1] = NULL;
417 nilfs->ns_sbp[1] = NULL;
418}
419
420void nilfs_swap_super_block(struct the_nilfs *nilfs)
421{
422 struct buffer_head *tsbh = nilfs->ns_sbh[0];
423 struct nilfs_super_block *tsbp = nilfs->ns_sbp[0];
424
425 nilfs->ns_sbh[0] = nilfs->ns_sbh[1];
426 nilfs->ns_sbp[0] = nilfs->ns_sbp[1];
427 nilfs->ns_sbh[1] = tsbh;
428 nilfs->ns_sbp[1] = tsbp;
429}
430
431static int nilfs_load_super_block(struct the_nilfs *nilfs,
432 struct super_block *sb, int blocksize,
433 struct nilfs_super_block **sbpp)
434{
435 struct nilfs_super_block **sbp = nilfs->ns_sbp;
436 struct buffer_head **sbh = nilfs->ns_sbh;
437 u64 sb2off = NILFS_SB2_OFFSET_BYTES(nilfs->ns_bdev->bd_inode->i_size);
438 int valid[2], swp = 0;
439
440 sbp[0] = nilfs_read_super_block(sb, NILFS_SB_OFFSET_BYTES, blocksize,
441 &sbh[0]);
442 sbp[1] = nilfs_read_super_block(sb, sb2off, blocksize, &sbh[1]);
443
444 if (!sbp[0]) {
445 if (!sbp[1]) {
446 printk(KERN_ERR "NILFS: unable to read superblock\n");
447 return -EIO;
448 }
449 printk(KERN_WARNING
450 "NILFS warning: unable to read primary superblock\n");
451 } else if (!sbp[1])
452 printk(KERN_WARNING
453 "NILFS warning: unable to read secondary superblock\n");
454
455 valid[0] = nilfs_valid_sb(sbp[0]);
456 valid[1] = nilfs_valid_sb(sbp[1]);
457 swp = valid[1] &&
458 (!valid[0] ||
459 le64_to_cpu(sbp[1]->s_wtime) > le64_to_cpu(sbp[0]->s_wtime));
460
461 if (valid[swp] && nilfs_sb2_bad_offset(sbp[swp], sb2off)) {
462 brelse(sbh[1]);
463 sbh[1] = NULL;
464 sbp[1] = NULL;
465 swp = 0;
466 }
467 if (!valid[swp]) {
468 nilfs_release_super_block(nilfs);
469 printk(KERN_ERR "NILFS: Can't find nilfs on dev %s.\n",
470 sb->s_id);
471 return -EINVAL;
472 }
473
474 if (swp) {
475 printk(KERN_WARNING "NILFS warning: broken superblock. "
476 "using spare superblock.\n");
477 nilfs_swap_super_block(nilfs);
478 }
479
480 nilfs->ns_sbwtime[0] = le64_to_cpu(sbp[0]->s_wtime);
481 nilfs->ns_sbwtime[1] = valid[!swp] ? le64_to_cpu(sbp[1]->s_wtime) : 0;
482 nilfs->ns_prot_seq = le64_to_cpu(sbp[valid[1] & !swp]->s_last_seq);
483 *sbpp = sbp[0];
484 return 0;
485}
486
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700487/**
488 * init_nilfs - initialize a NILFS instance.
489 * @nilfs: the_nilfs structure
490 * @sbi: nilfs_sb_info
491 * @sb: super block
492 * @data: mount options
493 *
494 * init_nilfs() performs common initialization per block device (e.g.
495 * reading the super block, getting disk layout information, initializing
496 * shared fields in the_nilfs). It takes on some portion of the jobs
497 * typically done by a fill_super() routine. This division arises from
498 * the nature that multiple NILFS instances may be simultaneously
499 * mounted on a device.
500 * For multiple mounts on the same device, only the first mount
501 * invokes these tasks.
502 *
503 * Return Value: On success, 0 is returned. On error, a negative error
504 * code is returned.
505 */
506int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
507{
508 struct super_block *sb = sbi->s_super;
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700509 struct nilfs_super_block *sbp;
510 struct backing_dev_info *bdi;
511 int blocksize;
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700512 int err;
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700513
514 down_write(&nilfs->ns_sem);
515 if (nilfs_init(nilfs)) {
516 /* Load values from existing the_nilfs */
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700517 sbp = nilfs->ns_sbp[0];
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700518 err = nilfs_store_magic_and_option(sb, sbp, data);
519 if (err)
520 goto out;
521
522 blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
523 if (sb->s_blocksize != blocksize &&
524 !sb_set_blocksize(sb, blocksize)) {
525 printk(KERN_ERR "NILFS: blocksize %d unfit to device\n",
526 blocksize);
527 err = -EINVAL;
528 }
529 sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits);
530 goto out;
531 }
532
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700533 blocksize = sb_min_blocksize(sb, BLOCK_SIZE);
534 if (!blocksize) {
535 printk(KERN_ERR "NILFS: unable to set blocksize\n");
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700536 err = -EINVAL;
537 goto out;
538 }
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700539 err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
540 if (err)
541 goto out;
542
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700543 err = nilfs_store_magic_and_option(sb, sbp, data);
544 if (err)
545 goto failed_sbh;
546
547 blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
548 if (sb->s_blocksize != blocksize) {
Martin K. Petersene1defc42009-05-22 17:17:49 -0400549 int hw_blocksize = bdev_logical_block_size(sb->s_bdev);
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700550
551 if (blocksize < hw_blocksize) {
552 printk(KERN_ERR
553 "NILFS: blocksize %d too small for device "
554 "(sector-size = %d).\n",
555 blocksize, hw_blocksize);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700556 err = -EINVAL;
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700557 goto failed_sbh;
558 }
559 nilfs_release_super_block(nilfs);
560 sb_set_blocksize(sb, blocksize);
561
562 err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
563 if (err)
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700564 goto out;
565 /* not failed_sbh; sbh is released automatically
566 when reloading fails. */
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700567 }
568 nilfs->ns_blocksize_bits = sb->s_blocksize_bits;
569
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700570 err = nilfs_store_disk_layout(nilfs, sbp);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700571 if (err)
572 goto failed_sbh;
573
574 sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits);
575
576 nilfs->ns_mount_state = le16_to_cpu(sbp->s_state);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700577
Jens Axboe2c96ce92009-09-15 09:43:56 +0200578 bdi = nilfs->ns_bdev->bd_inode->i_mapping->backing_dev_info;
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700579 nilfs->ns_bdi = bdi ? : &default_backing_dev_info;
580
581 /* Finding last segment */
582 nilfs->ns_last_pseg = le64_to_cpu(sbp->s_last_pseg);
583 nilfs->ns_last_cno = le64_to_cpu(sbp->s_last_cno);
584 nilfs->ns_last_seq = le64_to_cpu(sbp->s_last_seq);
585
586 nilfs->ns_seg_seq = nilfs->ns_last_seq;
587 nilfs->ns_segnum =
588 nilfs_get_segnum_of_block(nilfs, nilfs->ns_last_pseg);
589 nilfs->ns_cno = nilfs->ns_last_cno + 1;
590 if (nilfs->ns_segnum >= nilfs->ns_nsegments) {
591 printk(KERN_ERR "NILFS invalid last segment number.\n");
592 err = -EINVAL;
593 goto failed_sbh;
594 }
595 /* Dummy values */
596 nilfs->ns_free_segments_count =
597 nilfs->ns_nsegments - (nilfs->ns_segnum + 1);
598
599 /* Initialize gcinode cache */
600 err = nilfs_init_gccache(nilfs);
601 if (err)
602 goto failed_sbh;
603
604 set_nilfs_init(nilfs);
605 err = 0;
606 out:
607 up_write(&nilfs->ns_sem);
608 return err;
609
610 failed_sbh:
Ryusuke Konishie339ad32009-04-06 19:01:59 -0700611 nilfs_release_super_block(nilfs);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700612 goto out;
613}
614
615int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks)
616{
617 struct inode *dat = nilfs_dat_inode(nilfs);
618 unsigned long ncleansegs;
619 int err;
620
621 down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
622 err = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile, &ncleansegs);
623 up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
624 if (likely(!err))
625 *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
626 return err;
627}
628
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700629int nilfs_near_disk_full(struct the_nilfs *nilfs)
630{
631 struct inode *sufile = nilfs->ns_sufile;
632 unsigned long ncleansegs, nincsegs;
633 int ret;
634
635 ret = nilfs_sufile_get_ncleansegs(sufile, &ncleansegs);
636 if (likely(!ret)) {
637 nincsegs = atomic_read(&nilfs->ns_ndirtyblks) /
638 nilfs->ns_blocks_per_segment + 1;
639 if (ncleansegs <= nilfs->ns_nrsvsegs + nincsegs)
640 ret++;
641 }
642 return ret;
643}
644
Ryusuke Konishi6dd47402009-06-08 01:39:31 +0900645/**
646 * nilfs_find_sbinfo - find existing nilfs_sb_info structure
647 * @nilfs: nilfs object
648 * @rw_mount: mount type (non-zero value for read/write mount)
649 * @cno: checkpoint number (zero for read-only mount)
650 *
651 * nilfs_find_sbinfo() returns the nilfs_sb_info structure which
652 * @rw_mount and @cno (in case of snapshots) matched. If no instance
653 * was found, NULL is returned. Although the super block instance can
654 * be unmounted after this function returns, the nilfs_sb_info struct
655 * is kept on memory until nilfs_put_sbinfo() is called.
656 */
657struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *nilfs,
658 int rw_mount, __u64 cno)
659{
660 struct nilfs_sb_info *sbi;
661
Ryusuke Konishie59399d2009-06-08 01:39:32 +0900662 down_read(&nilfs->ns_super_sem);
Ryusuke Konishi6dd47402009-06-08 01:39:31 +0900663 /*
664 * The SNAPSHOT flag and sb->s_flags are supposed to be
Ryusuke Konishie59399d2009-06-08 01:39:32 +0900665 * protected with nilfs->ns_super_sem.
Ryusuke Konishi6dd47402009-06-08 01:39:31 +0900666 */
667 sbi = nilfs->ns_current;
668 if (rw_mount) {
669 if (sbi && !(sbi->s_super->s_flags & MS_RDONLY))
670 goto found; /* read/write mount */
671 else
672 goto out;
673 } else if (cno == 0) {
674 if (sbi && (sbi->s_super->s_flags & MS_RDONLY))
675 goto found; /* read-only mount */
676 else
677 goto out;
678 }
679
680 list_for_each_entry(sbi, &nilfs->ns_supers, s_list) {
681 if (nilfs_test_opt(sbi, SNAPSHOT) &&
682 sbi->s_snapshot_cno == cno)
683 goto found; /* snapshot mount */
684 }
685 out:
Ryusuke Konishie59399d2009-06-08 01:39:32 +0900686 up_read(&nilfs->ns_super_sem);
Ryusuke Konishi6dd47402009-06-08 01:39:31 +0900687 return NULL;
688
689 found:
690 atomic_inc(&sbi->s_count);
Ryusuke Konishie59399d2009-06-08 01:39:32 +0900691 up_read(&nilfs->ns_super_sem);
Ryusuke Konishi6dd47402009-06-08 01:39:31 +0900692 return sbi;
693}
694
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700695int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno,
696 int snapshot_mount)
697{
698 struct nilfs_sb_info *sbi;
699 int ret = 0;
700
Ryusuke Konishie59399d2009-06-08 01:39:32 +0900701 down_read(&nilfs->ns_super_sem);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700702 if (cno == 0 || cno > nilfs->ns_cno)
703 goto out_unlock;
704
705 list_for_each_entry(sbi, &nilfs->ns_supers, s_list) {
706 if (sbi->s_snapshot_cno == cno &&
707 (!snapshot_mount || nilfs_test_opt(sbi, SNAPSHOT))) {
708 /* exclude read-only mounts */
709 ret++;
710 break;
711 }
712 }
713 /* for protecting recent checkpoints */
714 if (cno >= nilfs_last_cno(nilfs))
715 ret++;
716
717 out_unlock:
Ryusuke Konishie59399d2009-06-08 01:39:32 +0900718 up_read(&nilfs->ns_super_sem);
Ryusuke Konishi8a9d2192009-04-06 19:01:35 -0700719 return ret;
720}