1783f6184SRyusuke Konishi /* 2783f6184SRyusuke Konishi * super.c - NILFS module and super block management. 3783f6184SRyusuke Konishi * 4783f6184SRyusuke Konishi * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. 5783f6184SRyusuke Konishi * 6783f6184SRyusuke Konishi * This program is free software; you can redistribute it and/or modify 7783f6184SRyusuke Konishi * it under the terms of the GNU General Public License as published by 8783f6184SRyusuke Konishi * the Free Software Foundation; either version 2 of the License, or 9783f6184SRyusuke Konishi * (at your option) any later version. 10783f6184SRyusuke Konishi * 11783f6184SRyusuke Konishi * This program is distributed in the hope that it will be useful, 12783f6184SRyusuke Konishi * but WITHOUT ANY WARRANTY; without even the implied warranty of 13783f6184SRyusuke Konishi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14783f6184SRyusuke Konishi * GNU General Public License for more details. 15783f6184SRyusuke Konishi * 16783f6184SRyusuke Konishi * You should have received a copy of the GNU General Public License 17783f6184SRyusuke Konishi * along with this program; if not, write to the Free Software 18783f6184SRyusuke Konishi * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19783f6184SRyusuke Konishi * 20783f6184SRyusuke Konishi * Written by Ryusuke Konishi <ryusuke@osrg.net> 21783f6184SRyusuke Konishi */ 22783f6184SRyusuke Konishi /* 23783f6184SRyusuke Konishi * linux/fs/ext2/super.c 24783f6184SRyusuke Konishi * 25783f6184SRyusuke Konishi * Copyright (C) 1992, 1993, 1994, 1995 26783f6184SRyusuke Konishi * Remy Card (card@masi.ibp.fr) 27783f6184SRyusuke Konishi * Laboratoire MASI - Institut Blaise Pascal 28783f6184SRyusuke Konishi * Universite Pierre et Marie Curie (Paris VI) 29783f6184SRyusuke Konishi * 30783f6184SRyusuke Konishi * from 31783f6184SRyusuke Konishi * 32783f6184SRyusuke Konishi * linux/fs/minix/inode.c 33783f6184SRyusuke Konishi * 34783f6184SRyusuke Konishi * Copyright (C) 1991, 1992 Linus Torvalds 35783f6184SRyusuke Konishi * 36783f6184SRyusuke Konishi * Big-endian to little-endian byte-swapping/bitmaps by 37783f6184SRyusuke Konishi * David S. Miller (davem@caip.rutgers.edu), 1995 38783f6184SRyusuke Konishi */ 39783f6184SRyusuke Konishi 40783f6184SRyusuke Konishi #include <linux/module.h> 41783f6184SRyusuke Konishi #include <linux/string.h> 42783f6184SRyusuke Konishi #include <linux/slab.h> 43783f6184SRyusuke Konishi #include <linux/init.h> 44783f6184SRyusuke Konishi #include <linux/blkdev.h> 45783f6184SRyusuke Konishi #include <linux/parser.h> 46783f6184SRyusuke Konishi #include <linux/random.h> 47783f6184SRyusuke Konishi #include <linux/crc32.h> 48783f6184SRyusuke Konishi #include <linux/vfs.h> 49783f6184SRyusuke Konishi #include <linux/writeback.h> 50b58a285bSJiro SEKIBA #include <linux/seq_file.h> 51b58a285bSJiro SEKIBA #include <linux/mount.h> 52783f6184SRyusuke Konishi #include "nilfs.h" 538e656fd5SRyusuke Konishi #include "export.h" 54783f6184SRyusuke Konishi #include "mdt.h" 55783f6184SRyusuke Konishi #include "alloc.h" 5605d0e94bSRyusuke Konishi #include "btree.h" 5705d0e94bSRyusuke Konishi #include "btnode.h" 58783f6184SRyusuke Konishi #include "page.h" 59783f6184SRyusuke Konishi #include "cpfile.h" 60783f6184SRyusuke Konishi #include "ifile.h" 61783f6184SRyusuke Konishi #include "dat.h" 62783f6184SRyusuke Konishi #include "segment.h" 63783f6184SRyusuke Konishi #include "segbuf.h" 64783f6184SRyusuke Konishi 65783f6184SRyusuke Konishi MODULE_AUTHOR("NTT Corp."); 66783f6184SRyusuke Konishi MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem " 67783f6184SRyusuke Konishi "(NILFS)"); 68783f6184SRyusuke Konishi MODULE_LICENSE("GPL"); 69783f6184SRyusuke Konishi 70abc0b50bSJiro SEKIBA static struct kmem_cache *nilfs_inode_cachep; 7141c88bd7SLi Hong struct kmem_cache *nilfs_transaction_cachep; 7241c88bd7SLi Hong struct kmem_cache *nilfs_segbuf_cachep; 7341c88bd7SLi Hong struct kmem_cache *nilfs_btree_path_cache; 7441c88bd7SLi Hong 755beb6e0bSRyusuke Konishi static int nilfs_setup_super(struct nilfs_sb_info *sbi, int is_mount); 76783f6184SRyusuke Konishi static int nilfs_remount(struct super_block *sb, int *flags, char *data); 77783f6184SRyusuke Konishi 78c8a11c8aSRyusuke Konishi static void nilfs_set_error(struct nilfs_sb_info *sbi) 79c8a11c8aSRyusuke Konishi { 80c8a11c8aSRyusuke Konishi struct the_nilfs *nilfs = sbi->s_nilfs; 81d26493b6SJiro SEKIBA struct nilfs_super_block **sbp; 82c8a11c8aSRyusuke Konishi 83c8a11c8aSRyusuke Konishi down_write(&nilfs->ns_sem); 84c8a11c8aSRyusuke Konishi if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) { 85c8a11c8aSRyusuke Konishi nilfs->ns_mount_state |= NILFS_ERROR_FS; 86b2ac86e1SJiro SEKIBA sbp = nilfs_prepare_super(sbi, 0); 87d26493b6SJiro SEKIBA if (likely(sbp)) { 88d26493b6SJiro SEKIBA sbp[0]->s_state |= cpu_to_le16(NILFS_ERROR_FS); 89b2ac86e1SJiro SEKIBA if (sbp[1]) 90b2ac86e1SJiro SEKIBA sbp[1]->s_state |= cpu_to_le16(NILFS_ERROR_FS); 91b2ac86e1SJiro SEKIBA nilfs_commit_super(sbi, NILFS_SB_COMMIT_ALL); 92c8a11c8aSRyusuke Konishi } 93d26493b6SJiro SEKIBA } 94c8a11c8aSRyusuke Konishi up_write(&nilfs->ns_sem); 95c8a11c8aSRyusuke Konishi } 96c8a11c8aSRyusuke Konishi 97783f6184SRyusuke Konishi /** 98783f6184SRyusuke Konishi * nilfs_error() - report failure condition on a filesystem 99783f6184SRyusuke Konishi * 100783f6184SRyusuke Konishi * nilfs_error() sets an ERROR_FS flag on the superblock as well as 101783f6184SRyusuke Konishi * reporting an error message. It should be called when NILFS detects 102783f6184SRyusuke Konishi * incoherences or defects of meta data on disk. As for sustainable 103783f6184SRyusuke Konishi * errors such as a single-shot I/O error, nilfs_warning() or the printk() 104783f6184SRyusuke Konishi * function should be used instead. 105783f6184SRyusuke Konishi * 106783f6184SRyusuke Konishi * The segment constructor must not call this function because it can 107783f6184SRyusuke Konishi * kill itself. 108783f6184SRyusuke Konishi */ 109783f6184SRyusuke Konishi void nilfs_error(struct super_block *sb, const char *function, 110783f6184SRyusuke Konishi const char *fmt, ...) 111783f6184SRyusuke Konishi { 1123b2ce58bSRyusuke Konishi struct the_nilfs *nilfs = sbi->s_nilfs; 113b004a5ebSJoe Perches struct va_format vaf; 114783f6184SRyusuke Konishi va_list args; 115783f6184SRyusuke Konishi 116783f6184SRyusuke Konishi va_start(args, fmt); 117b004a5ebSJoe Perches 118b004a5ebSJoe Perches vaf.fmt = fmt; 119b004a5ebSJoe Perches vaf.va = &args; 120b004a5ebSJoe Perches 121b004a5ebSJoe Perches printk(KERN_CRIT "NILFS error (device %s): %s: %pV\n", 122b004a5ebSJoe Perches sb->s_id, function, &vaf); 123b004a5ebSJoe Perches 124783f6184SRyusuke Konishi va_end(args); 125783f6184SRyusuke Konishi 126783f6184SRyusuke Konishi if (!(sb->s_flags & MS_RDONLY)) { 127c8a11c8aSRyusuke Konishi nilfs_set_error(sbi); 128783f6184SRyusuke Konishi 1293b2ce58bSRyusuke Konishi if (nilfs_test_opt(nilfs, ERRORS_RO)) { 130783f6184SRyusuke Konishi printk(KERN_CRIT "Remounting filesystem read-only\n"); 131783f6184SRyusuke Konishi sb->s_flags |= MS_RDONLY; 132783f6184SRyusuke Konishi } 133783f6184SRyusuke Konishi } 134783f6184SRyusuke Konishi 1353b2ce58bSRyusuke Konishi if (nilfs_test_opt(nilfs, ERRORS_PANIC)) 136783f6184SRyusuke Konishi panic("NILFS (device %s): panic forced after error\n", 137783f6184SRyusuke Konishi sb->s_id); 138783f6184SRyusuke Konishi } 139783f6184SRyusuke Konishi 140783f6184SRyusuke Konishi void nilfs_warning(struct super_block *sb, const char *function, 141783f6184SRyusuke Konishi const char *fmt, ...) 142783f6184SRyusuke Konishi { 143b004a5ebSJoe Perches struct va_format vaf; 144783f6184SRyusuke Konishi va_list args; 145783f6184SRyusuke Konishi 146783f6184SRyusuke Konishi va_start(args, fmt); 147b004a5ebSJoe Perches 148b004a5ebSJoe Perches vaf.fmt = fmt; 149b004a5ebSJoe Perches vaf.va = &args; 150b004a5ebSJoe Perches 151b004a5ebSJoe Perches printk(KERN_WARNING "NILFS warning (device %s): %s: %pV\n", 152b004a5ebSJoe Perches sb->s_id, function, &vaf); 153b004a5ebSJoe Perches 154783f6184SRyusuke Konishi va_end(args); 155783f6184SRyusuke Konishi } 156783f6184SRyusuke Konishi 157783f6184SRyusuke Konishi 1582879ed66SRyusuke Konishi struct inode *nilfs_alloc_inode(struct super_block *sb) 159783f6184SRyusuke Konishi { 160783f6184SRyusuke Konishi struct nilfs_inode_info *ii; 161783f6184SRyusuke Konishi 162783f6184SRyusuke Konishi ii = kmem_cache_alloc(nilfs_inode_cachep, GFP_NOFS); 163783f6184SRyusuke Konishi if (!ii) 164783f6184SRyusuke Konishi return NULL; 165783f6184SRyusuke Konishi ii->i_bh = NULL; 166783f6184SRyusuke Konishi ii->i_state = 0; 1670e14a359SRyusuke Konishi ii->i_cno = 0; 168783f6184SRyusuke Konishi ii->vfs_inode.i_version = 1; 1692879ed66SRyusuke Konishi nilfs_btnode_cache_init(&ii->i_btnode_cache, sb->s_bdi); 170783f6184SRyusuke Konishi return &ii->vfs_inode; 171783f6184SRyusuke Konishi } 172783f6184SRyusuke Konishi 173fa0d7e3dSNick Piggin static void nilfs_i_callback(struct rcu_head *head) 174783f6184SRyusuke Konishi { 175fa0d7e3dSNick Piggin struct inode *inode = container_of(head, struct inode, i_rcu); 176b91c9a97SRyusuke Konishi struct nilfs_mdt_info *mdi = NILFS_MDT(inode); 177b91c9a97SRyusuke Konishi 178fa0d7e3dSNick Piggin INIT_LIST_HEAD(&inode->i_dentry); 179fa0d7e3dSNick Piggin 180b91c9a97SRyusuke Konishi if (mdi) { 181b91c9a97SRyusuke Konishi kfree(mdi->mi_bgl); /* kfree(NULL) is safe */ 182b91c9a97SRyusuke Konishi kfree(mdi); 183b91c9a97SRyusuke Konishi } 184783f6184SRyusuke Konishi kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode)); 185783f6184SRyusuke Konishi } 186783f6184SRyusuke Konishi 187fa0d7e3dSNick Piggin void nilfs_destroy_inode(struct inode *inode) 188fa0d7e3dSNick Piggin { 189fa0d7e3dSNick Piggin call_rcu(&inode->i_rcu, nilfs_i_callback); 190fa0d7e3dSNick Piggin } 191fa0d7e3dSNick Piggin 192b2ac86e1SJiro SEKIBA static int nilfs_sync_super(struct nilfs_sb_info *sbi, int flag) 193783f6184SRyusuke Konishi { 194783f6184SRyusuke Konishi struct the_nilfs *nilfs = sbi->s_nilfs; 195783f6184SRyusuke Konishi int err; 196783f6184SRyusuke Konishi 197783f6184SRyusuke Konishi retry: 198e339ad31SRyusuke Konishi set_buffer_dirty(nilfs->ns_sbh[0]); 1993b2ce58bSRyusuke Konishi if (nilfs_test_opt(nilfs, BARRIER)) { 20087e99511SChristoph Hellwig err = __sync_dirty_buffer(nilfs->ns_sbh[0], 201f8c131f5SChristoph Hellwig WRITE_SYNC | WRITE_FLUSH_FUA); 20287e99511SChristoph Hellwig } else { 20387e99511SChristoph Hellwig err = sync_dirty_buffer(nilfs->ns_sbh[0]); 20487e99511SChristoph Hellwig } 20587e99511SChristoph Hellwig 206e339ad31SRyusuke Konishi if (unlikely(err)) { 207783f6184SRyusuke Konishi printk(KERN_ERR 208783f6184SRyusuke Konishi "NILFS: unable to write superblock (err=%d)\n", err); 209e339ad31SRyusuke Konishi if (err == -EIO && nilfs->ns_sbh[1]) { 210b2ac86e1SJiro SEKIBA /* 211b2ac86e1SJiro SEKIBA * sbp[0] points to newer log than sbp[1], 212b2ac86e1SJiro SEKIBA * so copy sbp[0] to sbp[1] to take over sbp[0]. 213b2ac86e1SJiro SEKIBA */ 214b2ac86e1SJiro SEKIBA memcpy(nilfs->ns_sbp[1], nilfs->ns_sbp[0], 215b2ac86e1SJiro SEKIBA nilfs->ns_sbsize); 216e339ad31SRyusuke Konishi nilfs_fall_back_super_block(nilfs); 217e339ad31SRyusuke Konishi goto retry; 218e339ad31SRyusuke Konishi } 219e339ad31SRyusuke Konishi } else { 220e339ad31SRyusuke Konishi struct nilfs_super_block *sbp = nilfs->ns_sbp[0]; 221e339ad31SRyusuke Konishi 222b2ac86e1SJiro SEKIBA nilfs->ns_sbwcount++; 223b2ac86e1SJiro SEKIBA 224e339ad31SRyusuke Konishi /* 225e339ad31SRyusuke Konishi * The latest segment becomes trailable from the position 226e339ad31SRyusuke Konishi * written in superblock. 227e339ad31SRyusuke Konishi */ 228783f6184SRyusuke Konishi clear_nilfs_discontinued(nilfs); 229e339ad31SRyusuke Konishi 230e339ad31SRyusuke Konishi /* update GC protection for recent segments */ 231e339ad31SRyusuke Konishi if (nilfs->ns_sbh[1]) { 232b2ac86e1SJiro SEKIBA if (flag == NILFS_SB_COMMIT_ALL) { 233e339ad31SRyusuke Konishi set_buffer_dirty(nilfs->ns_sbh[1]); 234b2ac86e1SJiro SEKIBA if (sync_dirty_buffer(nilfs->ns_sbh[1]) < 0) 235b2ac86e1SJiro SEKIBA goto out; 236b2ac86e1SJiro SEKIBA } 237b2ac86e1SJiro SEKIBA if (le64_to_cpu(nilfs->ns_sbp[1]->s_last_cno) < 238b2ac86e1SJiro SEKIBA le64_to_cpu(nilfs->ns_sbp[0]->s_last_cno)) 239e339ad31SRyusuke Konishi sbp = nilfs->ns_sbp[1]; 240e339ad31SRyusuke Konishi } 241b2ac86e1SJiro SEKIBA 2422c2e52fcSRyusuke Konishi spin_lock(&nilfs->ns_last_segment_lock); 243e339ad31SRyusuke Konishi nilfs->ns_prot_seq = le64_to_cpu(sbp->s_last_seq); 2442c2e52fcSRyusuke Konishi spin_unlock(&nilfs->ns_last_segment_lock); 245783f6184SRyusuke Konishi } 246b2ac86e1SJiro SEKIBA out: 247783f6184SRyusuke Konishi return err; 248783f6184SRyusuke Konishi } 249783f6184SRyusuke Konishi 25060f46b7eSRyusuke Konishi void nilfs_set_log_cursor(struct nilfs_super_block *sbp, 25160f46b7eSRyusuke Konishi struct the_nilfs *nilfs) 25260f46b7eSRyusuke Konishi { 25360f46b7eSRyusuke Konishi sector_t nfreeblocks; 25460f46b7eSRyusuke Konishi 25560f46b7eSRyusuke Konishi /* nilfs->ns_sem must be locked by the caller. */ 25660f46b7eSRyusuke Konishi nilfs_count_free_blocks(nilfs, &nfreeblocks); 25760f46b7eSRyusuke Konishi sbp->s_free_blocks_count = cpu_to_le64(nfreeblocks); 25860f46b7eSRyusuke Konishi 25960f46b7eSRyusuke Konishi spin_lock(&nilfs->ns_last_segment_lock); 26060f46b7eSRyusuke Konishi sbp->s_last_seq = cpu_to_le64(nilfs->ns_last_seq); 26160f46b7eSRyusuke Konishi sbp->s_last_pseg = cpu_to_le64(nilfs->ns_last_pseg); 26260f46b7eSRyusuke Konishi sbp->s_last_cno = cpu_to_le64(nilfs->ns_last_cno); 26360f46b7eSRyusuke Konishi spin_unlock(&nilfs->ns_last_segment_lock); 26460f46b7eSRyusuke Konishi } 26560f46b7eSRyusuke Konishi 266b2ac86e1SJiro SEKIBA struct nilfs_super_block **nilfs_prepare_super(struct nilfs_sb_info *sbi, 267b2ac86e1SJiro SEKIBA int flip) 268d26493b6SJiro SEKIBA { 269d26493b6SJiro SEKIBA struct the_nilfs *nilfs = sbi->s_nilfs; 270d26493b6SJiro SEKIBA struct nilfs_super_block **sbp = nilfs->ns_sbp; 271d26493b6SJiro SEKIBA 272d26493b6SJiro SEKIBA /* nilfs->ns_sem must be locked by the caller. */ 273d26493b6SJiro SEKIBA if (sbp[0]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) { 274d26493b6SJiro SEKIBA if (sbp[1] && 275d26493b6SJiro SEKIBA sbp[1]->s_magic == cpu_to_le16(NILFS_SUPER_MAGIC)) { 276b2ac86e1SJiro SEKIBA memcpy(sbp[0], sbp[1], nilfs->ns_sbsize); 277d26493b6SJiro SEKIBA } else { 278d26493b6SJiro SEKIBA printk(KERN_CRIT "NILFS: superblock broke on dev %s\n", 279d26493b6SJiro SEKIBA sbi->s_super->s_id); 280d26493b6SJiro SEKIBA return NULL; 281d26493b6SJiro SEKIBA } 282b2ac86e1SJiro SEKIBA } else if (sbp[1] && 283b2ac86e1SJiro SEKIBA sbp[1]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) { 284b2ac86e1SJiro SEKIBA memcpy(sbp[1], sbp[0], nilfs->ns_sbsize); 285d26493b6SJiro SEKIBA } 286b2ac86e1SJiro SEKIBA 287b2ac86e1SJiro SEKIBA if (flip && sbp[1]) 288b2ac86e1SJiro SEKIBA nilfs_swap_super_block(nilfs); 289b2ac86e1SJiro SEKIBA 290d26493b6SJiro SEKIBA return sbp; 291d26493b6SJiro SEKIBA } 292d26493b6SJiro SEKIBA 293b2ac86e1SJiro SEKIBA int nilfs_commit_super(struct nilfs_sb_info *sbi, int flag) 294783f6184SRyusuke Konishi { 295783f6184SRyusuke Konishi struct the_nilfs *nilfs = sbi->s_nilfs; 296e339ad31SRyusuke Konishi struct nilfs_super_block **sbp = nilfs->ns_sbp; 297e339ad31SRyusuke Konishi time_t t; 298783f6184SRyusuke Konishi 299d26493b6SJiro SEKIBA /* nilfs->ns_sem must be locked by the caller. */ 300e339ad31SRyusuke Konishi t = get_seconds(); 301b2ac86e1SJiro SEKIBA nilfs->ns_sbwtime = t; 302e339ad31SRyusuke Konishi sbp[0]->s_wtime = cpu_to_le64(t); 303e339ad31SRyusuke Konishi sbp[0]->s_sum = 0; 304e339ad31SRyusuke Konishi sbp[0]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed, 305e339ad31SRyusuke Konishi (unsigned char *)sbp[0], 306e339ad31SRyusuke Konishi nilfs->ns_sbsize)); 307b2ac86e1SJiro SEKIBA if (flag == NILFS_SB_COMMIT_ALL && sbp[1]) { 308b2ac86e1SJiro SEKIBA sbp[1]->s_wtime = sbp[0]->s_wtime; 309b2ac86e1SJiro SEKIBA sbp[1]->s_sum = 0; 310b2ac86e1SJiro SEKIBA sbp[1]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed, 311b2ac86e1SJiro SEKIBA (unsigned char *)sbp[1], 312b2ac86e1SJiro SEKIBA nilfs->ns_sbsize)); 313e339ad31SRyusuke Konishi } 314e605f0a7SRyusuke Konishi clear_nilfs_sb_dirty(nilfs); 315b2ac86e1SJiro SEKIBA return nilfs_sync_super(sbi, flag); 316783f6184SRyusuke Konishi } 317783f6184SRyusuke Konishi 3187ecaa46cSRyusuke Konishi /** 3197ecaa46cSRyusuke Konishi * nilfs_cleanup_super() - write filesystem state for cleanup 3207ecaa46cSRyusuke Konishi * @sbi: nilfs_sb_info to be unmounted or degraded to read-only 3217ecaa46cSRyusuke Konishi * 3227ecaa46cSRyusuke Konishi * This function restores state flags in the on-disk super block. 3237ecaa46cSRyusuke Konishi * This will set "clean" flag (i.e. NILFS_VALID_FS) unless the 3247ecaa46cSRyusuke Konishi * filesystem was not clean previously. 3257ecaa46cSRyusuke Konishi */ 3267ecaa46cSRyusuke Konishi int nilfs_cleanup_super(struct nilfs_sb_info *sbi) 3277ecaa46cSRyusuke Konishi { 328d26493b6SJiro SEKIBA struct nilfs_super_block **sbp; 329b2ac86e1SJiro SEKIBA int flag = NILFS_SB_COMMIT; 330d26493b6SJiro SEKIBA int ret = -EIO; 3317ecaa46cSRyusuke Konishi 332b2ac86e1SJiro SEKIBA sbp = nilfs_prepare_super(sbi, 0); 333d26493b6SJiro SEKIBA if (sbp) { 3347ecaa46cSRyusuke Konishi sbp[0]->s_state = cpu_to_le16(sbi->s_nilfs->ns_mount_state); 335b2ac86e1SJiro SEKIBA nilfs_set_log_cursor(sbp[0], sbi->s_nilfs); 336b2ac86e1SJiro SEKIBA if (sbp[1] && sbp[0]->s_last_cno == sbp[1]->s_last_cno) { 337b2ac86e1SJiro SEKIBA /* 338b2ac86e1SJiro SEKIBA * make the "clean" flag also to the opposite 339b2ac86e1SJiro SEKIBA * super block if both super blocks point to 340b2ac86e1SJiro SEKIBA * the same checkpoint. 341b2ac86e1SJiro SEKIBA */ 342b2ac86e1SJiro SEKIBA sbp[1]->s_state = sbp[0]->s_state; 343b2ac86e1SJiro SEKIBA flag = NILFS_SB_COMMIT_ALL; 344b2ac86e1SJiro SEKIBA } 345b2ac86e1SJiro SEKIBA ret = nilfs_commit_super(sbi, flag); 346d26493b6SJiro SEKIBA } 3477ecaa46cSRyusuke Konishi return ret; 3487ecaa46cSRyusuke Konishi } 3497ecaa46cSRyusuke Konishi 350783f6184SRyusuke Konishi static void nilfs_put_super(struct super_block *sb) 351783f6184SRyusuke Konishi { 352783f6184SRyusuke Konishi struct nilfs_sb_info *sbi = NILFS_SB(sb); 353783f6184SRyusuke Konishi struct the_nilfs *nilfs = sbi->s_nilfs; 354783f6184SRyusuke Konishi 355783f6184SRyusuke Konishi nilfs_detach_segment_constructor(sbi); 356783f6184SRyusuke Konishi 357783f6184SRyusuke Konishi if (!(sb->s_flags & MS_RDONLY)) { 358783f6184SRyusuke Konishi down_write(&nilfs->ns_sem); 3597ecaa46cSRyusuke Konishi nilfs_cleanup_super(sbi); 360783f6184SRyusuke Konishi up_write(&nilfs->ns_sem); 361783f6184SRyusuke Konishi } 362783f6184SRyusuke Konishi 363f1e89c86SRyusuke Konishi iput(nilfs->ns_sufile); 364f1e89c86SRyusuke Konishi iput(nilfs->ns_cpfile); 365f1e89c86SRyusuke Konishi iput(nilfs->ns_dat); 366f1e89c86SRyusuke Konishi 367348fe8daSRyusuke Konishi destroy_nilfs(nilfs); 368783f6184SRyusuke Konishi sbi->s_super = NULL; 369783f6184SRyusuke Konishi sb->s_fs_info = NULL; 370f11459adSRyusuke Konishi kfree(sbi); 371783f6184SRyusuke Konishi } 372783f6184SRyusuke Konishi 373783f6184SRyusuke Konishi static int nilfs_sync_fs(struct super_block *sb, int wait) 374783f6184SRyusuke Konishi { 3756233caa9SJiro SEKIBA struct nilfs_sb_info *sbi = NILFS_SB(sb); 3766233caa9SJiro SEKIBA struct the_nilfs *nilfs = sbi->s_nilfs; 377d26493b6SJiro SEKIBA struct nilfs_super_block **sbp; 378783f6184SRyusuke Konishi int err = 0; 379783f6184SRyusuke Konishi 380783f6184SRyusuke Konishi /* This function is called when super block should be written back */ 381783f6184SRyusuke Konishi if (wait) 382783f6184SRyusuke Konishi err = nilfs_construct_segment(sb); 3836233caa9SJiro SEKIBA 3846233caa9SJiro SEKIBA down_write(&nilfs->ns_sem); 385d26493b6SJiro SEKIBA if (nilfs_sb_dirty(nilfs)) { 386b2ac86e1SJiro SEKIBA sbp = nilfs_prepare_super(sbi, nilfs_sb_will_flip(nilfs)); 387b2ac86e1SJiro SEKIBA if (likely(sbp)) { 388b2ac86e1SJiro SEKIBA nilfs_set_log_cursor(sbp[0], nilfs); 389b2ac86e1SJiro SEKIBA nilfs_commit_super(sbi, NILFS_SB_COMMIT); 390b2ac86e1SJiro SEKIBA } 391d26493b6SJiro SEKIBA } 3926233caa9SJiro SEKIBA up_write(&nilfs->ns_sem); 3936233caa9SJiro SEKIBA 394783f6184SRyusuke Konishi return err; 395783f6184SRyusuke Konishi } 396783f6184SRyusuke Konishi 3974d8d9293SRyusuke Konishi int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, 3984d8d9293SRyusuke Konishi struct nilfs_root **rootp) 399783f6184SRyusuke Konishi { 400783f6184SRyusuke Konishi struct the_nilfs *nilfs = sbi->s_nilfs; 4014d8d9293SRyusuke Konishi struct nilfs_root *root; 402783f6184SRyusuke Konishi struct nilfs_checkpoint *raw_cp; 403783f6184SRyusuke Konishi struct buffer_head *bh_cp; 4044d8d9293SRyusuke Konishi int err = -ENOMEM; 405783f6184SRyusuke Konishi 4064d8d9293SRyusuke Konishi root = nilfs_find_or_create_root( 4074d8d9293SRyusuke Konishi nilfs, curr_mnt ? NILFS_CPTREE_CURRENT_CNO : cno); 4084d8d9293SRyusuke Konishi if (!root) 4094d8d9293SRyusuke Konishi return err; 410783f6184SRyusuke Konishi 411e912a5b6SRyusuke Konishi if (root->ifile) 412e912a5b6SRyusuke Konishi goto reuse; /* already attached checkpoint */ 413783f6184SRyusuke Konishi 4141154ecbdSZhang Qiang down_read(&nilfs->ns_segctor_sem); 415783f6184SRyusuke Konishi err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, 416783f6184SRyusuke Konishi &bh_cp); 4171154ecbdSZhang Qiang up_read(&nilfs->ns_segctor_sem); 418783f6184SRyusuke Konishi if (unlikely(err)) { 419783f6184SRyusuke Konishi if (err == -ENOENT || err == -EINVAL) { 420783f6184SRyusuke Konishi printk(KERN_ERR 421783f6184SRyusuke Konishi "NILFS: Invalid checkpoint " 422783f6184SRyusuke Konishi "(checkpoint number=%llu)\n", 423783f6184SRyusuke Konishi (unsigned long long)cno); 424783f6184SRyusuke Konishi err = -EINVAL; 425783f6184SRyusuke Konishi } 426783f6184SRyusuke Konishi goto failed; 427783f6184SRyusuke Konishi } 428f1e89c86SRyusuke Konishi 429f1e89c86SRyusuke Konishi err = nilfs_ifile_read(sbi->s_super, root, nilfs->ns_inode_size, 430f1e89c86SRyusuke Konishi &raw_cp->cp_ifile_inode, &root->ifile); 431f1e89c86SRyusuke Konishi if (err) 432783f6184SRyusuke Konishi goto failed_bh; 433b7c06342SRyusuke Konishi 434b7c06342SRyusuke Konishi atomic_set(&root->inodes_count, le64_to_cpu(raw_cp->cp_inodes_count)); 435b7c06342SRyusuke Konishi atomic_set(&root->blocks_count, le64_to_cpu(raw_cp->cp_blocks_count)); 436783f6184SRyusuke Konishi 437783f6184SRyusuke Konishi nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp); 4384d8d9293SRyusuke Konishi 439e912a5b6SRyusuke Konishi reuse: 4404d8d9293SRyusuke Konishi *rootp = root; 441783f6184SRyusuke Konishi return 0; 442783f6184SRyusuke Konishi 443783f6184SRyusuke Konishi failed_bh: 444783f6184SRyusuke Konishi nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp); 445783f6184SRyusuke Konishi failed: 4464d8d9293SRyusuke Konishi nilfs_put_root(root); 447783f6184SRyusuke Konishi 448783f6184SRyusuke Konishi return err; 449783f6184SRyusuke Konishi } 450783f6184SRyusuke Konishi 4515beb6e0bSRyusuke Konishi static int nilfs_freeze(struct super_block *sb) 452783f6184SRyusuke Konishi { 4535beb6e0bSRyusuke Konishi struct nilfs_sb_info *sbi = NILFS_SB(sb); 4545beb6e0bSRyusuke Konishi struct the_nilfs *nilfs = sbi->s_nilfs; 4555beb6e0bSRyusuke Konishi int err; 4565beb6e0bSRyusuke Konishi 4575beb6e0bSRyusuke Konishi if (sb->s_flags & MS_RDONLY) 4585beb6e0bSRyusuke Konishi return 0; 4595beb6e0bSRyusuke Konishi 4605beb6e0bSRyusuke Konishi /* Mark super block clean */ 4615beb6e0bSRyusuke Konishi down_write(&nilfs->ns_sem); 4625beb6e0bSRyusuke Konishi err = nilfs_cleanup_super(sbi); 4635beb6e0bSRyusuke Konishi up_write(&nilfs->ns_sem); 4645beb6e0bSRyusuke Konishi return err; 4655beb6e0bSRyusuke Konishi } 4665beb6e0bSRyusuke Konishi 4675beb6e0bSRyusuke Konishi static int nilfs_unfreeze(struct super_block *sb) 4685beb6e0bSRyusuke Konishi { 4695beb6e0bSRyusuke Konishi struct nilfs_sb_info *sbi = NILFS_SB(sb); 470783f6184SRyusuke Konishi struct the_nilfs *nilfs = sbi->s_nilfs; 471783f6184SRyusuke Konishi 4725beb6e0bSRyusuke Konishi if (sb->s_flags & MS_RDONLY) 4735beb6e0bSRyusuke Konishi return 0; 4745beb6e0bSRyusuke Konishi 4755beb6e0bSRyusuke Konishi down_write(&nilfs->ns_sem); 4765beb6e0bSRyusuke Konishi nilfs_setup_super(sbi, false); 4775beb6e0bSRyusuke Konishi up_write(&nilfs->ns_sem); 4785beb6e0bSRyusuke Konishi return 0; 479783f6184SRyusuke Konishi } 480783f6184SRyusuke Konishi 481783f6184SRyusuke Konishi static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf) 482783f6184SRyusuke Konishi { 483783f6184SRyusuke Konishi struct super_block *sb = dentry->d_sb; 484b7c06342SRyusuke Konishi struct nilfs_root *root = NILFS_I(dentry->d_inode)->i_root; 485b7c06342SRyusuke Konishi struct the_nilfs *nilfs = root->nilfs; 486c306af23SRyusuke Konishi u64 id = huge_encode_dev(sb->s_bdev->bd_dev); 487783f6184SRyusuke Konishi unsigned long long blocks; 488783f6184SRyusuke Konishi unsigned long overhead; 489783f6184SRyusuke Konishi unsigned long nrsvblocks; 490783f6184SRyusuke Konishi sector_t nfreeblocks; 491783f6184SRyusuke Konishi int err; 492783f6184SRyusuke Konishi 493783f6184SRyusuke Konishi /* 494783f6184SRyusuke Konishi * Compute all of the segment blocks 495783f6184SRyusuke Konishi * 496783f6184SRyusuke Konishi * The blocks before first segment and after last segment 497783f6184SRyusuke Konishi * are excluded. 498783f6184SRyusuke Konishi */ 499783f6184SRyusuke Konishi blocks = nilfs->ns_blocks_per_segment * nilfs->ns_nsegments 500783f6184SRyusuke Konishi - nilfs->ns_first_data_block; 501783f6184SRyusuke Konishi nrsvblocks = nilfs->ns_nrsvsegs * nilfs->ns_blocks_per_segment; 502783f6184SRyusuke Konishi 503783f6184SRyusuke Konishi /* 504783f6184SRyusuke Konishi * Compute the overhead 505783f6184SRyusuke Konishi * 5067a65004bSRyusuke Konishi * When distributing meta data blocks outside segment structure, 507783f6184SRyusuke Konishi * We must count them as the overhead. 508783f6184SRyusuke Konishi */ 509783f6184SRyusuke Konishi overhead = 0; 510783f6184SRyusuke Konishi 511783f6184SRyusuke Konishi err = nilfs_count_free_blocks(nilfs, &nfreeblocks); 512783f6184SRyusuke Konishi if (unlikely(err)) 513783f6184SRyusuke Konishi return err; 514783f6184SRyusuke Konishi 515783f6184SRyusuke Konishi buf->f_type = NILFS_SUPER_MAGIC; 516783f6184SRyusuke Konishi buf->f_bsize = sb->s_blocksize; 517783f6184SRyusuke Konishi buf->f_blocks = blocks - overhead; 518783f6184SRyusuke Konishi buf->f_bfree = nfreeblocks; 519783f6184SRyusuke Konishi buf->f_bavail = (buf->f_bfree >= nrsvblocks) ? 520783f6184SRyusuke Konishi (buf->f_bfree - nrsvblocks) : 0; 521b7c06342SRyusuke Konishi buf->f_files = atomic_read(&root->inodes_count); 522783f6184SRyusuke Konishi buf->f_ffree = 0; /* nilfs_count_free_inodes(sb); */ 523783f6184SRyusuke Konishi buf->f_namelen = NILFS_NAME_LEN; 524c306af23SRyusuke Konishi buf->f_fsid.val[0] = (u32)id; 525c306af23SRyusuke Konishi buf->f_fsid.val[1] = (u32)(id >> 32); 526c306af23SRyusuke Konishi 527783f6184SRyusuke Konishi return 0; 528783f6184SRyusuke Konishi } 529783f6184SRyusuke Konishi 530b58a285bSJiro SEKIBA static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs) 531b58a285bSJiro SEKIBA { 532b58a285bSJiro SEKIBA struct super_block *sb = vfs->mnt_sb; 5333b2ce58bSRyusuke Konishi struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; 534f11459adSRyusuke Konishi struct nilfs_root *root = NILFS_I(vfs->mnt_root->d_inode)->i_root; 535b58a285bSJiro SEKIBA 5363b2ce58bSRyusuke Konishi if (!nilfs_test_opt(nilfs, BARRIER)) 537c6b4d57dSRyusuke Konishi seq_puts(seq, ",nobarrier"); 538f11459adSRyusuke Konishi if (root->cno != NILFS_CPTREE_CURRENT_CNO) 539f11459adSRyusuke Konishi seq_printf(seq, ",cp=%llu", (unsigned long long)root->cno); 5403b2ce58bSRyusuke Konishi if (nilfs_test_opt(nilfs, ERRORS_PANIC)) 541c6b4d57dSRyusuke Konishi seq_puts(seq, ",errors=panic"); 5423b2ce58bSRyusuke Konishi if (nilfs_test_opt(nilfs, ERRORS_CONT)) 543c6b4d57dSRyusuke Konishi seq_puts(seq, ",errors=continue"); 5443b2ce58bSRyusuke Konishi if (nilfs_test_opt(nilfs, STRICT_ORDER)) 545c6b4d57dSRyusuke Konishi seq_puts(seq, ",order=strict"); 5463b2ce58bSRyusuke Konishi if (nilfs_test_opt(nilfs, NORECOVERY)) 547c6b4d57dSRyusuke Konishi seq_puts(seq, ",norecovery"); 5483b2ce58bSRyusuke Konishi if (nilfs_test_opt(nilfs, DISCARD)) 549c6b4d57dSRyusuke Konishi seq_puts(seq, ",discard"); 550b58a285bSJiro SEKIBA 551b58a285bSJiro SEKIBA return 0; 552b58a285bSJiro SEKIBA } 553b58a285bSJiro SEKIBA 554b87221deSAlexey Dobriyan static const struct super_operations nilfs_sops = { 555783f6184SRyusuke Konishi .alloc_inode = nilfs_alloc_inode, 556783f6184SRyusuke Konishi .destroy_inode = nilfs_destroy_inode, 557783f6184SRyusuke Konishi .dirty_inode = nilfs_dirty_inode, 558783f6184SRyusuke Konishi /* .write_inode = nilfs_write_inode, */ 559783f6184SRyusuke Konishi /* .put_inode = nilfs_put_inode, */ 560783f6184SRyusuke Konishi /* .drop_inode = nilfs_drop_inode, */ 5616fd1e5c9SAl Viro .evict_inode = nilfs_evict_inode, 562783f6184SRyusuke Konishi .put_super = nilfs_put_super, 5631dfa2710SJiro SEKIBA /* .write_super = nilfs_write_super, */ 564783f6184SRyusuke Konishi .sync_fs = nilfs_sync_fs, 5655beb6e0bSRyusuke Konishi .freeze_fs = nilfs_freeze, 5665beb6e0bSRyusuke Konishi .unfreeze_fs = nilfs_unfreeze, 567783f6184SRyusuke Konishi /* .write_super_lockfs */ 568783f6184SRyusuke Konishi /* .unlockfs */ 569783f6184SRyusuke Konishi .statfs = nilfs_statfs, 570783f6184SRyusuke Konishi .remount_fs = nilfs_remount, 571783f6184SRyusuke Konishi /* .umount_begin */ 572b58a285bSJiro SEKIBA .show_options = nilfs_show_options 573783f6184SRyusuke Konishi }; 574783f6184SRyusuke Konishi 575783f6184SRyusuke Konishi enum { 576783f6184SRyusuke Konishi Opt_err_cont, Opt_err_panic, Opt_err_ro, 577773bc4f3SRyusuke Konishi Opt_barrier, Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery, 578802d3177SRyusuke Konishi Opt_discard, Opt_nodiscard, Opt_err, 579783f6184SRyusuke Konishi }; 580783f6184SRyusuke Konishi 581783f6184SRyusuke Konishi static match_table_t tokens = { 582783f6184SRyusuke Konishi {Opt_err_cont, "errors=continue"}, 583783f6184SRyusuke Konishi {Opt_err_panic, "errors=panic"}, 584783f6184SRyusuke Konishi {Opt_err_ro, "errors=remount-ro"}, 585773bc4f3SRyusuke Konishi {Opt_barrier, "barrier"}, 58691f1953bSJiro SEKIBA {Opt_nobarrier, "nobarrier"}, 587783f6184SRyusuke Konishi {Opt_snapshot, "cp=%u"}, 588783f6184SRyusuke Konishi {Opt_order, "order=%s"}, 5890234576dSRyusuke Konishi {Opt_norecovery, "norecovery"}, 590e902ec99SJiro SEKIBA {Opt_discard, "discard"}, 591802d3177SRyusuke Konishi {Opt_nodiscard, "nodiscard"}, 592783f6184SRyusuke Konishi {Opt_err, NULL} 593783f6184SRyusuke Konishi }; 594783f6184SRyusuke Konishi 5957c017457SRyusuke Konishi static int parse_options(char *options, struct super_block *sb, int is_remount) 596783f6184SRyusuke Konishi { 5973b2ce58bSRyusuke Konishi struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; 598783f6184SRyusuke Konishi char *p; 599783f6184SRyusuke Konishi substring_t args[MAX_OPT_ARGS]; 600783f6184SRyusuke Konishi 601783f6184SRyusuke Konishi if (!options) 602783f6184SRyusuke Konishi return 1; 603783f6184SRyusuke Konishi 604783f6184SRyusuke Konishi while ((p = strsep(&options, ",")) != NULL) { 605783f6184SRyusuke Konishi int token; 606783f6184SRyusuke Konishi if (!*p) 607783f6184SRyusuke Konishi continue; 608783f6184SRyusuke Konishi 609783f6184SRyusuke Konishi token = match_token(p, tokens, args); 610783f6184SRyusuke Konishi switch (token) { 611773bc4f3SRyusuke Konishi case Opt_barrier: 6123b2ce58bSRyusuke Konishi nilfs_set_opt(nilfs, BARRIER); 613773bc4f3SRyusuke Konishi break; 61491f1953bSJiro SEKIBA case Opt_nobarrier: 6153b2ce58bSRyusuke Konishi nilfs_clear_opt(nilfs, BARRIER); 616783f6184SRyusuke Konishi break; 617783f6184SRyusuke Konishi case Opt_order: 618783f6184SRyusuke Konishi if (strcmp(args[0].from, "relaxed") == 0) 619783f6184SRyusuke Konishi /* Ordered data semantics */ 6203b2ce58bSRyusuke Konishi nilfs_clear_opt(nilfs, STRICT_ORDER); 621783f6184SRyusuke Konishi else if (strcmp(args[0].from, "strict") == 0) 622783f6184SRyusuke Konishi /* Strict in-order semantics */ 6233b2ce58bSRyusuke Konishi nilfs_set_opt(nilfs, STRICT_ORDER); 624783f6184SRyusuke Konishi else 625783f6184SRyusuke Konishi return 0; 626783f6184SRyusuke Konishi break; 627783f6184SRyusuke Konishi case Opt_err_panic: 6283b2ce58bSRyusuke Konishi nilfs_write_opt(nilfs, ERROR_MODE, ERRORS_PANIC); 629783f6184SRyusuke Konishi break; 630783f6184SRyusuke Konishi case Opt_err_ro: 6313b2ce58bSRyusuke Konishi nilfs_write_opt(nilfs, ERROR_MODE, ERRORS_RO); 632783f6184SRyusuke Konishi break; 633783f6184SRyusuke Konishi case Opt_err_cont: 6343b2ce58bSRyusuke Konishi nilfs_write_opt(nilfs, ERROR_MODE, ERRORS_CONT); 635783f6184SRyusuke Konishi break; 636783f6184SRyusuke Konishi case Opt_snapshot: 6377c017457SRyusuke Konishi if (is_remount) { 6387c017457SRyusuke Konishi printk(KERN_ERR 639f11459adSRyusuke Konishi "NILFS: \"%s\" option is invalid " 640f11459adSRyusuke Konishi "for remount.\n", p); 6417c017457SRyusuke Konishi return 0; 6427c017457SRyusuke Konishi } 6437c017457SRyusuke Konishi break; 6440234576dSRyusuke Konishi case Opt_norecovery: 6453b2ce58bSRyusuke Konishi nilfs_set_opt(nilfs, NORECOVERY); 6460234576dSRyusuke Konishi break; 647e902ec99SJiro SEKIBA case Opt_discard: 6483b2ce58bSRyusuke Konishi nilfs_set_opt(nilfs, DISCARD); 649e902ec99SJiro SEKIBA break; 650802d3177SRyusuke Konishi case Opt_nodiscard: 6513b2ce58bSRyusuke Konishi nilfs_clear_opt(nilfs, DISCARD); 652802d3177SRyusuke Konishi break; 653783f6184SRyusuke Konishi default: 654783f6184SRyusuke Konishi printk(KERN_ERR 655783f6184SRyusuke Konishi "NILFS: Unrecognized mount option \"%s\"\n", p); 656783f6184SRyusuke Konishi return 0; 657783f6184SRyusuke Konishi } 658783f6184SRyusuke Konishi } 659783f6184SRyusuke Konishi return 1; 660783f6184SRyusuke Konishi } 661783f6184SRyusuke Konishi 662783f6184SRyusuke Konishi static inline void 6633b2ce58bSRyusuke Konishi nilfs_set_default_options(struct super_block *sb, 664783f6184SRyusuke Konishi struct nilfs_super_block *sbp) 665783f6184SRyusuke Konishi { 6663b2ce58bSRyusuke Konishi struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; 6673b2ce58bSRyusuke Konishi 6683b2ce58bSRyusuke Konishi nilfs->ns_mount_opt = 669277a6a34SRyusuke Konishi NILFS_MOUNT_ERRORS_RO | NILFS_MOUNT_BARRIER; 670783f6184SRyusuke Konishi } 671783f6184SRyusuke Konishi 6725beb6e0bSRyusuke Konishi static int nilfs_setup_super(struct nilfs_sb_info *sbi, int is_mount) 673783f6184SRyusuke Konishi { 674783f6184SRyusuke Konishi struct the_nilfs *nilfs = sbi->s_nilfs; 675d26493b6SJiro SEKIBA struct nilfs_super_block **sbp; 676d26493b6SJiro SEKIBA int max_mnt_count; 677d26493b6SJiro SEKIBA int mnt_count; 678783f6184SRyusuke Konishi 679d26493b6SJiro SEKIBA /* nilfs->ns_sem must be locked by the caller. */ 680b2ac86e1SJiro SEKIBA sbp = nilfs_prepare_super(sbi, 0); 681d26493b6SJiro SEKIBA if (!sbp) 682d26493b6SJiro SEKIBA return -EIO; 683d26493b6SJiro SEKIBA 6845beb6e0bSRyusuke Konishi if (!is_mount) 6855beb6e0bSRyusuke Konishi goto skip_mount_setup; 6865beb6e0bSRyusuke Konishi 687d26493b6SJiro SEKIBA max_mnt_count = le16_to_cpu(sbp[0]->s_max_mnt_count); 688d26493b6SJiro SEKIBA mnt_count = le16_to_cpu(sbp[0]->s_mnt_count); 689d26493b6SJiro SEKIBA 690f50a4c81SRyusuke Konishi if (nilfs->ns_mount_state & NILFS_ERROR_FS) { 691783f6184SRyusuke Konishi printk(KERN_WARNING 692783f6184SRyusuke Konishi "NILFS warning: mounting fs with errors\n"); 693783f6184SRyusuke Konishi #if 0 694783f6184SRyusuke Konishi } else if (max_mnt_count >= 0 && mnt_count >= max_mnt_count) { 695783f6184SRyusuke Konishi printk(KERN_WARNING 696783f6184SRyusuke Konishi "NILFS warning: maximal mount count reached\n"); 697783f6184SRyusuke Konishi #endif 698783f6184SRyusuke Konishi } 699783f6184SRyusuke Konishi if (!max_mnt_count) 700d26493b6SJiro SEKIBA sbp[0]->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT); 701783f6184SRyusuke Konishi 702d26493b6SJiro SEKIBA sbp[0]->s_mnt_count = cpu_to_le16(mnt_count + 1); 7035beb6e0bSRyusuke Konishi sbp[0]->s_mtime = cpu_to_le64(get_seconds()); 7045beb6e0bSRyusuke Konishi 7055beb6e0bSRyusuke Konishi skip_mount_setup: 706d26493b6SJiro SEKIBA sbp[0]->s_state = 707d26493b6SJiro SEKIBA cpu_to_le16(le16_to_cpu(sbp[0]->s_state) & ~NILFS_VALID_FS); 708b2ac86e1SJiro SEKIBA /* synchronize sbp[1] with sbp[0] */ 7090ca7a5b9SRyusuke Konishi if (sbp[1]) 710b2ac86e1SJiro SEKIBA memcpy(sbp[1], sbp[0], nilfs->ns_sbsize); 711b2ac86e1SJiro SEKIBA return nilfs_commit_super(sbi, NILFS_SB_COMMIT_ALL); 712783f6184SRyusuke Konishi } 713783f6184SRyusuke Konishi 714e339ad31SRyusuke Konishi struct nilfs_super_block *nilfs_read_super_block(struct super_block *sb, 715e339ad31SRyusuke Konishi u64 pos, int blocksize, 716e339ad31SRyusuke Konishi struct buffer_head **pbh) 717783f6184SRyusuke Konishi { 718e339ad31SRyusuke Konishi unsigned long long sb_index = pos; 719e339ad31SRyusuke Konishi unsigned long offset; 720783f6184SRyusuke Konishi 721e339ad31SRyusuke Konishi offset = do_div(sb_index, blocksize); 722783f6184SRyusuke Konishi *pbh = sb_bread(sb, sb_index); 723e339ad31SRyusuke Konishi if (!*pbh) 724783f6184SRyusuke Konishi return NULL; 725783f6184SRyusuke Konishi return (struct nilfs_super_block *)((char *)(*pbh)->b_data + offset); 726783f6184SRyusuke Konishi } 727783f6184SRyusuke Konishi 728783f6184SRyusuke Konishi int nilfs_store_magic_and_option(struct super_block *sb, 729783f6184SRyusuke Konishi struct nilfs_super_block *sbp, 730783f6184SRyusuke Konishi char *data) 731783f6184SRyusuke Konishi { 732*574e6c31SRyusuke Konishi struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; 733783f6184SRyusuke Konishi 734783f6184SRyusuke Konishi sb->s_magic = le16_to_cpu(sbp->s_magic); 735783f6184SRyusuke Konishi 736783f6184SRyusuke Konishi /* FS independent flags */ 737783f6184SRyusuke Konishi #ifdef NILFS_ATIME_DISABLE 738783f6184SRyusuke Konishi sb->s_flags |= MS_NOATIME; 739783f6184SRyusuke Konishi #endif 740783f6184SRyusuke Konishi 7413b2ce58bSRyusuke Konishi nilfs_set_default_options(sb, sbp); 742783f6184SRyusuke Konishi 743*574e6c31SRyusuke Konishi nilfs->ns_resuid = le16_to_cpu(sbp->s_def_resuid); 744*574e6c31SRyusuke Konishi nilfs->ns_resgid = le16_to_cpu(sbp->s_def_resgid); 745*574e6c31SRyusuke Konishi nilfs->ns_interval = le32_to_cpu(sbp->s_c_interval); 746*574e6c31SRyusuke Konishi nilfs->ns_watermark = le32_to_cpu(sbp->s_c_block_max); 747783f6184SRyusuke Konishi 7487c017457SRyusuke Konishi return !parse_options(data, sb, 0) ? -EINVAL : 0 ; 749783f6184SRyusuke Konishi } 750783f6184SRyusuke Konishi 751c5ca48aaSRyusuke Konishi int nilfs_check_feature_compatibility(struct super_block *sb, 752c5ca48aaSRyusuke Konishi struct nilfs_super_block *sbp) 753c5ca48aaSRyusuke Konishi { 754c5ca48aaSRyusuke Konishi __u64 features; 755c5ca48aaSRyusuke Konishi 756c5ca48aaSRyusuke Konishi features = le64_to_cpu(sbp->s_feature_incompat) & 757c5ca48aaSRyusuke Konishi ~NILFS_FEATURE_INCOMPAT_SUPP; 758c5ca48aaSRyusuke Konishi if (features) { 759c5ca48aaSRyusuke Konishi printk(KERN_ERR "NILFS: couldn't mount because of unsupported " 760c5ca48aaSRyusuke Konishi "optional features (%llx)\n", 761c5ca48aaSRyusuke Konishi (unsigned long long)features); 762c5ca48aaSRyusuke Konishi return -EINVAL; 763c5ca48aaSRyusuke Konishi } 764c5ca48aaSRyusuke Konishi features = le64_to_cpu(sbp->s_feature_compat_ro) & 765c5ca48aaSRyusuke Konishi ~NILFS_FEATURE_COMPAT_RO_SUPP; 766c5ca48aaSRyusuke Konishi if (!(sb->s_flags & MS_RDONLY) && features) { 767c5ca48aaSRyusuke Konishi printk(KERN_ERR "NILFS: couldn't mount RDWR because of " 768c5ca48aaSRyusuke Konishi "unsupported optional features (%llx)\n", 769c5ca48aaSRyusuke Konishi (unsigned long long)features); 770c5ca48aaSRyusuke Konishi return -EINVAL; 771c5ca48aaSRyusuke Konishi } 772c5ca48aaSRyusuke Konishi return 0; 773c5ca48aaSRyusuke Konishi } 774c5ca48aaSRyusuke Konishi 775367ea334SRyusuke Konishi static int nilfs_get_root_dentry(struct super_block *sb, 776367ea334SRyusuke Konishi struct nilfs_root *root, 777367ea334SRyusuke Konishi struct dentry **root_dentry) 778367ea334SRyusuke Konishi { 779367ea334SRyusuke Konishi struct inode *inode; 780367ea334SRyusuke Konishi struct dentry *dentry; 781367ea334SRyusuke Konishi int ret = 0; 782367ea334SRyusuke Konishi 783367ea334SRyusuke Konishi inode = nilfs_iget(sb, root, NILFS_ROOT_INO); 784367ea334SRyusuke Konishi if (IS_ERR(inode)) { 785367ea334SRyusuke Konishi printk(KERN_ERR "NILFS: get root inode failed\n"); 786367ea334SRyusuke Konishi ret = PTR_ERR(inode); 787367ea334SRyusuke Konishi goto out; 788367ea334SRyusuke Konishi } 789367ea334SRyusuke Konishi if (!S_ISDIR(inode->i_mode) || !inode->i_blocks || !inode->i_size) { 790367ea334SRyusuke Konishi iput(inode); 791367ea334SRyusuke Konishi printk(KERN_ERR "NILFS: corrupt root inode.\n"); 792367ea334SRyusuke Konishi ret = -EINVAL; 793367ea334SRyusuke Konishi goto out; 794367ea334SRyusuke Konishi } 795367ea334SRyusuke Konishi 796f11459adSRyusuke Konishi if (root->cno == NILFS_CPTREE_CURRENT_CNO) { 797f11459adSRyusuke Konishi dentry = d_find_alias(inode); 798f11459adSRyusuke Konishi if (!dentry) { 799367ea334SRyusuke Konishi dentry = d_alloc_root(inode); 800367ea334SRyusuke Konishi if (!dentry) { 801367ea334SRyusuke Konishi iput(inode); 802367ea334SRyusuke Konishi ret = -ENOMEM; 803f11459adSRyusuke Konishi goto failed_dentry; 804f11459adSRyusuke Konishi } 805f11459adSRyusuke Konishi } else { 806f11459adSRyusuke Konishi iput(inode); 807f11459adSRyusuke Konishi } 808f11459adSRyusuke Konishi } else { 809f11459adSRyusuke Konishi dentry = d_obtain_alias(inode); 810f11459adSRyusuke Konishi if (IS_ERR(dentry)) { 811f11459adSRyusuke Konishi ret = PTR_ERR(dentry); 812f11459adSRyusuke Konishi goto failed_dentry; 813f11459adSRyusuke Konishi } 814367ea334SRyusuke Konishi } 815367ea334SRyusuke Konishi *root_dentry = dentry; 816367ea334SRyusuke Konishi out: 817367ea334SRyusuke Konishi return ret; 818f11459adSRyusuke Konishi 819f11459adSRyusuke Konishi failed_dentry: 820f11459adSRyusuke Konishi printk(KERN_ERR "NILFS: get root dentry failed\n"); 821f11459adSRyusuke Konishi goto out; 822367ea334SRyusuke Konishi } 823367ea334SRyusuke Konishi 824ab4d8f7eSRyusuke Konishi static int nilfs_attach_snapshot(struct super_block *s, __u64 cno, 825ab4d8f7eSRyusuke Konishi struct dentry **root_dentry) 826ab4d8f7eSRyusuke Konishi { 827ab4d8f7eSRyusuke Konishi struct the_nilfs *nilfs = NILFS_SB(s)->s_nilfs; 828ab4d8f7eSRyusuke Konishi struct nilfs_root *root; 829ab4d8f7eSRyusuke Konishi int ret; 830ab4d8f7eSRyusuke Konishi 831ab4d8f7eSRyusuke Konishi down_read(&nilfs->ns_segctor_sem); 832ab4d8f7eSRyusuke Konishi ret = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile, cno); 833ab4d8f7eSRyusuke Konishi up_read(&nilfs->ns_segctor_sem); 834ab4d8f7eSRyusuke Konishi if (ret < 0) { 835ab4d8f7eSRyusuke Konishi ret = (ret == -ENOENT) ? -EINVAL : ret; 836ab4d8f7eSRyusuke Konishi goto out; 837ab4d8f7eSRyusuke Konishi } else if (!ret) { 838ab4d8f7eSRyusuke Konishi printk(KERN_ERR "NILFS: The specified checkpoint is " 839ab4d8f7eSRyusuke Konishi "not a snapshot (checkpoint number=%llu).\n", 840ab4d8f7eSRyusuke Konishi (unsigned long long)cno); 841ab4d8f7eSRyusuke Konishi ret = -EINVAL; 842ab4d8f7eSRyusuke Konishi goto out; 843ab4d8f7eSRyusuke Konishi } 844ab4d8f7eSRyusuke Konishi 845ab4d8f7eSRyusuke Konishi ret = nilfs_attach_checkpoint(NILFS_SB(s), cno, false, &root); 846ab4d8f7eSRyusuke Konishi if (ret) { 847ab4d8f7eSRyusuke Konishi printk(KERN_ERR "NILFS: error loading snapshot " 848ab4d8f7eSRyusuke Konishi "(checkpoint number=%llu).\n", 849ab4d8f7eSRyusuke Konishi (unsigned long long)cno); 850ab4d8f7eSRyusuke Konishi goto out; 851ab4d8f7eSRyusuke Konishi } 852ab4d8f7eSRyusuke Konishi ret = nilfs_get_root_dentry(s, root, root_dentry); 853ab4d8f7eSRyusuke Konishi nilfs_put_root(root); 854ab4d8f7eSRyusuke Konishi out: 855ab4d8f7eSRyusuke Konishi return ret; 856ab4d8f7eSRyusuke Konishi } 857ab4d8f7eSRyusuke Konishi 858f11459adSRyusuke Konishi static int nilfs_tree_was_touched(struct dentry *root_dentry) 859f11459adSRyusuke Konishi { 860b7ab39f6SNick Piggin return root_dentry->d_count > 1; 861f11459adSRyusuke Konishi } 862f11459adSRyusuke Konishi 863f11459adSRyusuke Konishi /** 864f11459adSRyusuke Konishi * nilfs_try_to_shrink_tree() - try to shrink dentries of a checkpoint 865f11459adSRyusuke Konishi * @root_dentry: root dentry of the tree to be shrunk 866f11459adSRyusuke Konishi * 867f11459adSRyusuke Konishi * This function returns true if the tree was in-use. 868f11459adSRyusuke Konishi */ 869f11459adSRyusuke Konishi static int nilfs_try_to_shrink_tree(struct dentry *root_dentry) 870f11459adSRyusuke Konishi { 871f11459adSRyusuke Konishi if (have_submounts(root_dentry)) 872f11459adSRyusuke Konishi return true; 873f11459adSRyusuke Konishi shrink_dcache_parent(root_dentry); 874f11459adSRyusuke Konishi return nilfs_tree_was_touched(root_dentry); 875f11459adSRyusuke Konishi } 876f11459adSRyusuke Konishi 877032dbb3bSRyusuke Konishi int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno) 878032dbb3bSRyusuke Konishi { 879032dbb3bSRyusuke Konishi struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; 880032dbb3bSRyusuke Konishi struct nilfs_root *root; 881032dbb3bSRyusuke Konishi struct inode *inode; 882032dbb3bSRyusuke Konishi struct dentry *dentry; 883032dbb3bSRyusuke Konishi int ret; 884032dbb3bSRyusuke Konishi 885032dbb3bSRyusuke Konishi if (cno < 0 || cno > nilfs->ns_cno) 886032dbb3bSRyusuke Konishi return false; 887032dbb3bSRyusuke Konishi 888032dbb3bSRyusuke Konishi if (cno >= nilfs_last_cno(nilfs)) 889032dbb3bSRyusuke Konishi return true; /* protect recent checkpoints */ 890032dbb3bSRyusuke Konishi 891032dbb3bSRyusuke Konishi ret = false; 892032dbb3bSRyusuke Konishi root = nilfs_lookup_root(NILFS_SB(sb)->s_nilfs, cno); 893032dbb3bSRyusuke Konishi if (root) { 894032dbb3bSRyusuke Konishi inode = nilfs_ilookup(sb, root, NILFS_ROOT_INO); 895032dbb3bSRyusuke Konishi if (inode) { 896032dbb3bSRyusuke Konishi dentry = d_find_alias(inode); 897032dbb3bSRyusuke Konishi if (dentry) { 898032dbb3bSRyusuke Konishi if (nilfs_tree_was_touched(dentry)) 899032dbb3bSRyusuke Konishi ret = nilfs_try_to_shrink_tree(dentry); 900032dbb3bSRyusuke Konishi dput(dentry); 901032dbb3bSRyusuke Konishi } 902032dbb3bSRyusuke Konishi iput(inode); 903032dbb3bSRyusuke Konishi } 904032dbb3bSRyusuke Konishi nilfs_put_root(root); 905032dbb3bSRyusuke Konishi } 906032dbb3bSRyusuke Konishi return ret; 907032dbb3bSRyusuke Konishi } 908032dbb3bSRyusuke Konishi 909783f6184SRyusuke Konishi /** 910783f6184SRyusuke Konishi * nilfs_fill_super() - initialize a super block instance 911783f6184SRyusuke Konishi * @sb: super_block 912783f6184SRyusuke Konishi * @data: mount options 913783f6184SRyusuke Konishi * @silent: silent mode flag 914783f6184SRyusuke Konishi * 915aa7dfb89SRyusuke Konishi * This function is called exclusively by nilfs->ns_mount_mutex. 916783f6184SRyusuke Konishi * So, the recovery process is protected from other simultaneous mounts. 917783f6184SRyusuke Konishi */ 918783f6184SRyusuke Konishi static int 919348fe8daSRyusuke Konishi nilfs_fill_super(struct super_block *sb, void *data, int silent) 920783f6184SRyusuke Konishi { 921348fe8daSRyusuke Konishi struct the_nilfs *nilfs; 922783f6184SRyusuke Konishi struct nilfs_sb_info *sbi; 9234d8d9293SRyusuke Konishi struct nilfs_root *fsroot; 924026a7d63SRyusuke Konishi struct backing_dev_info *bdi; 925783f6184SRyusuke Konishi __u64 cno; 926783f6184SRyusuke Konishi int err; 927783f6184SRyusuke Konishi 928783f6184SRyusuke Konishi sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); 929783f6184SRyusuke Konishi if (!sbi) 930783f6184SRyusuke Konishi return -ENOMEM; 931783f6184SRyusuke Konishi 932783f6184SRyusuke Konishi sb->s_fs_info = sbi; 933783f6184SRyusuke Konishi sbi->s_super = sb; 934783f6184SRyusuke Konishi 935348fe8daSRyusuke Konishi nilfs = alloc_nilfs(sb->s_bdev); 936348fe8daSRyusuke Konishi if (!nilfs) { 937348fe8daSRyusuke Konishi err = -ENOMEM; 938348fe8daSRyusuke Konishi goto failed_sbi; 939348fe8daSRyusuke Konishi } 940348fe8daSRyusuke Konishi sbi->s_nilfs = nilfs; 941783f6184SRyusuke Konishi 942783f6184SRyusuke Konishi err = init_nilfs(nilfs, sbi, (char *)data); 943783f6184SRyusuke Konishi if (err) 944348fe8daSRyusuke Konishi goto failed_nilfs; 945783f6184SRyusuke Konishi 946783f6184SRyusuke Konishi spin_lock_init(&sbi->s_inode_lock); 947783f6184SRyusuke Konishi INIT_LIST_HEAD(&sbi->s_dirty_files); 948783f6184SRyusuke Konishi 949783f6184SRyusuke Konishi /* 950783f6184SRyusuke Konishi * Following initialization is overlapped because 951783f6184SRyusuke Konishi * nilfs_sb_info structure has been cleared at the beginning. 952783f6184SRyusuke Konishi * But we reserve them to keep our interest and make ready 953783f6184SRyusuke Konishi * for the future change. 954783f6184SRyusuke Konishi */ 955783f6184SRyusuke Konishi get_random_bytes(&sbi->s_next_generation, 956783f6184SRyusuke Konishi sizeof(sbi->s_next_generation)); 957783f6184SRyusuke Konishi spin_lock_init(&sbi->s_next_gen_lock); 958783f6184SRyusuke Konishi 959783f6184SRyusuke Konishi sb->s_op = &nilfs_sops; 960783f6184SRyusuke Konishi sb->s_export_op = &nilfs_export_ops; 961783f6184SRyusuke Konishi sb->s_root = NULL; 96261239230SRyusuke Konishi sb->s_time_gran = 1; 963026a7d63SRyusuke Konishi 964026a7d63SRyusuke Konishi bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info; 965026a7d63SRyusuke Konishi sb->s_bdi = bdi ? : &default_backing_dev_info; 966783f6184SRyusuke Konishi 967783f6184SRyusuke Konishi err = load_nilfs(nilfs, sbi); 968783f6184SRyusuke Konishi if (err) 969348fe8daSRyusuke Konishi goto failed_nilfs; 970f50a4c81SRyusuke Konishi 971783f6184SRyusuke Konishi cno = nilfs_last_cno(nilfs); 972ab4d8f7eSRyusuke Konishi err = nilfs_attach_checkpoint(sbi, cno, true, &fsroot); 973783f6184SRyusuke Konishi if (err) { 974f11459adSRyusuke Konishi printk(KERN_ERR "NILFS: error loading last checkpoint " 975783f6184SRyusuke Konishi "(checkpoint number=%llu).\n", (unsigned long long)cno); 976f1e89c86SRyusuke Konishi goto failed_unload; 977783f6184SRyusuke Konishi } 978783f6184SRyusuke Konishi 979783f6184SRyusuke Konishi if (!(sb->s_flags & MS_RDONLY)) { 980e912a5b6SRyusuke Konishi err = nilfs_attach_segment_constructor(sbi, fsroot); 981783f6184SRyusuke Konishi if (err) 982783f6184SRyusuke Konishi goto failed_checkpoint; 983783f6184SRyusuke Konishi } 984783f6184SRyusuke Konishi 985367ea334SRyusuke Konishi err = nilfs_get_root_dentry(sb, fsroot, &sb->s_root); 986367ea334SRyusuke Konishi if (err) 987783f6184SRyusuke Konishi goto failed_segctor; 988783f6184SRyusuke Konishi 9894d8d9293SRyusuke Konishi nilfs_put_root(fsroot); 990783f6184SRyusuke Konishi 991783f6184SRyusuke Konishi if (!(sb->s_flags & MS_RDONLY)) { 992783f6184SRyusuke Konishi down_write(&nilfs->ns_sem); 9935beb6e0bSRyusuke Konishi nilfs_setup_super(sbi, true); 994783f6184SRyusuke Konishi up_write(&nilfs->ns_sem); 995783f6184SRyusuke Konishi } 996783f6184SRyusuke Konishi 997783f6184SRyusuke Konishi return 0; 998783f6184SRyusuke Konishi 999783f6184SRyusuke Konishi failed_segctor: 1000783f6184SRyusuke Konishi nilfs_detach_segment_constructor(sbi); 1001783f6184SRyusuke Konishi 1002783f6184SRyusuke Konishi failed_checkpoint: 10034d8d9293SRyusuke Konishi nilfs_put_root(fsroot); 1004783f6184SRyusuke Konishi 1005f1e89c86SRyusuke Konishi failed_unload: 1006f1e89c86SRyusuke Konishi iput(nilfs->ns_sufile); 1007f1e89c86SRyusuke Konishi iput(nilfs->ns_cpfile); 1008f1e89c86SRyusuke Konishi iput(nilfs->ns_dat); 1009f1e89c86SRyusuke Konishi 1010348fe8daSRyusuke Konishi failed_nilfs: 1011348fe8daSRyusuke Konishi destroy_nilfs(nilfs); 1012783f6184SRyusuke Konishi 1013783f6184SRyusuke Konishi failed_sbi: 1014783f6184SRyusuke Konishi sb->s_fs_info = NULL; 1015f11459adSRyusuke Konishi kfree(sbi); 1016783f6184SRyusuke Konishi return err; 1017783f6184SRyusuke Konishi } 1018783f6184SRyusuke Konishi 1019783f6184SRyusuke Konishi static int nilfs_remount(struct super_block *sb, int *flags, char *data) 1020783f6184SRyusuke Konishi { 1021783f6184SRyusuke Konishi struct nilfs_sb_info *sbi = NILFS_SB(sb); 1022783f6184SRyusuke Konishi struct the_nilfs *nilfs = sbi->s_nilfs; 1023783f6184SRyusuke Konishi unsigned long old_sb_flags; 102406df0f99SRyusuke Konishi unsigned long old_mount_opt; 1025f11459adSRyusuke Konishi int err; 1026783f6184SRyusuke Konishi 1027783f6184SRyusuke Konishi old_sb_flags = sb->s_flags; 10283b2ce58bSRyusuke Konishi old_mount_opt = nilfs->ns_mount_opt; 1029783f6184SRyusuke Konishi 10307c017457SRyusuke Konishi if (!parse_options(data, sb, 1)) { 1031783f6184SRyusuke Konishi err = -EINVAL; 1032783f6184SRyusuke Konishi goto restore_opts; 1033783f6184SRyusuke Konishi } 1034783f6184SRyusuke Konishi sb->s_flags = (sb->s_flags & ~MS_POSIXACL); 1035783f6184SRyusuke Konishi 1036d240e067SRyusuke Konishi err = -EINVAL; 1037783f6184SRyusuke Konishi 10380234576dSRyusuke Konishi if (!nilfs_valid_fs(nilfs)) { 10390234576dSRyusuke Konishi printk(KERN_WARNING "NILFS (device %s): couldn't " 10400234576dSRyusuke Konishi "remount because the filesystem is in an " 10410234576dSRyusuke Konishi "incomplete recovery state.\n", sb->s_id); 10420234576dSRyusuke Konishi goto restore_opts; 10430234576dSRyusuke Konishi } 10440234576dSRyusuke Konishi 1045783f6184SRyusuke Konishi if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 1046783f6184SRyusuke Konishi goto out; 1047783f6184SRyusuke Konishi if (*flags & MS_RDONLY) { 1048783f6184SRyusuke Konishi /* Shutting down the segment constructor */ 1049783f6184SRyusuke Konishi nilfs_detach_segment_constructor(sbi); 1050783f6184SRyusuke Konishi sb->s_flags |= MS_RDONLY; 1051783f6184SRyusuke Konishi 1052783f6184SRyusuke Konishi /* 1053783f6184SRyusuke Konishi * Remounting a valid RW partition RDONLY, so set 1054783f6184SRyusuke Konishi * the RDONLY flag and then mark the partition as valid again. 1055783f6184SRyusuke Konishi */ 1056783f6184SRyusuke Konishi down_write(&nilfs->ns_sem); 10577ecaa46cSRyusuke Konishi nilfs_cleanup_super(sbi); 1058783f6184SRyusuke Konishi up_write(&nilfs->ns_sem); 1059783f6184SRyusuke Konishi } else { 1060c5ca48aaSRyusuke Konishi __u64 features; 1061e912a5b6SRyusuke Konishi struct nilfs_root *root; 1062c5ca48aaSRyusuke Konishi 1063783f6184SRyusuke Konishi /* 1064783f6184SRyusuke Konishi * Mounting a RDONLY partition read-write, so reread and 1065783f6184SRyusuke Konishi * store the current valid flag. (It may have been changed 1066783f6184SRyusuke Konishi * by fsck since we originally mounted the partition.) 1067783f6184SRyusuke Konishi */ 1068c5ca48aaSRyusuke Konishi down_read(&nilfs->ns_sem); 1069c5ca48aaSRyusuke Konishi features = le64_to_cpu(nilfs->ns_sbp[0]->s_feature_compat_ro) & 1070c5ca48aaSRyusuke Konishi ~NILFS_FEATURE_COMPAT_RO_SUPP; 1071c5ca48aaSRyusuke Konishi up_read(&nilfs->ns_sem); 1072c5ca48aaSRyusuke Konishi if (features) { 1073c5ca48aaSRyusuke Konishi printk(KERN_WARNING "NILFS (device %s): couldn't " 1074c5ca48aaSRyusuke Konishi "remount RDWR because of unsupported optional " 1075c5ca48aaSRyusuke Konishi "features (%llx)\n", 1076c5ca48aaSRyusuke Konishi sb->s_id, (unsigned long long)features); 1077c5ca48aaSRyusuke Konishi err = -EROFS; 1078c5ca48aaSRyusuke Konishi goto restore_opts; 1079c5ca48aaSRyusuke Konishi } 1080c5ca48aaSRyusuke Konishi 1081783f6184SRyusuke Konishi sb->s_flags &= ~MS_RDONLY; 1082783f6184SRyusuke Konishi 1083e912a5b6SRyusuke Konishi root = NILFS_I(sb->s_root->d_inode)->i_root; 1084e912a5b6SRyusuke Konishi err = nilfs_attach_segment_constructor(sbi, root); 1085783f6184SRyusuke Konishi if (err) 1086e59399d0SRyusuke Konishi goto restore_opts; 1087783f6184SRyusuke Konishi 1088783f6184SRyusuke Konishi down_write(&nilfs->ns_sem); 10895beb6e0bSRyusuke Konishi nilfs_setup_super(sbi, true); 1090783f6184SRyusuke Konishi up_write(&nilfs->ns_sem); 1091783f6184SRyusuke Konishi } 1092783f6184SRyusuke Konishi out: 1093783f6184SRyusuke Konishi return 0; 1094783f6184SRyusuke Konishi 1095783f6184SRyusuke Konishi restore_opts: 1096783f6184SRyusuke Konishi sb->s_flags = old_sb_flags; 10973b2ce58bSRyusuke Konishi nilfs->ns_mount_opt = old_mount_opt; 1098783f6184SRyusuke Konishi return err; 1099783f6184SRyusuke Konishi } 1100783f6184SRyusuke Konishi 1101783f6184SRyusuke Konishi struct nilfs_super_data { 1102783f6184SRyusuke Konishi struct block_device *bdev; 11036dd47406SRyusuke Konishi struct nilfs_sb_info *sbi; 1104783f6184SRyusuke Konishi __u64 cno; 1105783f6184SRyusuke Konishi int flags; 1106783f6184SRyusuke Konishi }; 1107783f6184SRyusuke Konishi 1108783f6184SRyusuke Konishi /** 1109783f6184SRyusuke Konishi * nilfs_identify - pre-read mount options needed to identify mount instance 1110783f6184SRyusuke Konishi * @data: mount options 1111783f6184SRyusuke Konishi * @sd: nilfs_super_data 1112783f6184SRyusuke Konishi */ 1113783f6184SRyusuke Konishi static int nilfs_identify(char *data, struct nilfs_super_data *sd) 1114783f6184SRyusuke Konishi { 1115783f6184SRyusuke Konishi char *p, *options = data; 1116783f6184SRyusuke Konishi substring_t args[MAX_OPT_ARGS]; 1117c05dbfc2SRyusuke Konishi int token; 1118783f6184SRyusuke Konishi int ret = 0; 1119783f6184SRyusuke Konishi 1120783f6184SRyusuke Konishi do { 1121783f6184SRyusuke Konishi p = strsep(&options, ","); 1122783f6184SRyusuke Konishi if (p != NULL && *p) { 1123783f6184SRyusuke Konishi token = match_token(p, tokens, args); 1124783f6184SRyusuke Konishi if (token == Opt_snapshot) { 1125c05dbfc2SRyusuke Konishi if (!(sd->flags & MS_RDONLY)) { 1126783f6184SRyusuke Konishi ret++; 1127c05dbfc2SRyusuke Konishi } else { 1128c05dbfc2SRyusuke Konishi sd->cno = simple_strtoull(args[0].from, 1129c05dbfc2SRyusuke Konishi NULL, 0); 1130c05dbfc2SRyusuke Konishi /* 1131c05dbfc2SRyusuke Konishi * No need to see the end pointer; 1132c05dbfc2SRyusuke Konishi * match_token() has done syntax 1133c05dbfc2SRyusuke Konishi * checking. 1134c05dbfc2SRyusuke Konishi */ 1135c05dbfc2SRyusuke Konishi if (sd->cno == 0) 1136783f6184SRyusuke Konishi ret++; 1137783f6184SRyusuke Konishi } 1138783f6184SRyusuke Konishi } 1139783f6184SRyusuke Konishi if (ret) 1140783f6184SRyusuke Konishi printk(KERN_ERR 1141783f6184SRyusuke Konishi "NILFS: invalid mount option: %s\n", p); 1142783f6184SRyusuke Konishi } 1143783f6184SRyusuke Konishi if (!options) 1144783f6184SRyusuke Konishi break; 1145783f6184SRyusuke Konishi BUG_ON(options == data); 1146783f6184SRyusuke Konishi *(options - 1) = ','; 1147783f6184SRyusuke Konishi } while (!ret); 1148783f6184SRyusuke Konishi return ret; 1149783f6184SRyusuke Konishi } 1150783f6184SRyusuke Konishi 1151783f6184SRyusuke Konishi static int nilfs_set_bdev_super(struct super_block *s, void *data) 1152783f6184SRyusuke Konishi { 1153f11459adSRyusuke Konishi s->s_bdev = data; 1154783f6184SRyusuke Konishi s->s_dev = s->s_bdev->bd_dev; 1155783f6184SRyusuke Konishi return 0; 1156783f6184SRyusuke Konishi } 1157783f6184SRyusuke Konishi 1158783f6184SRyusuke Konishi static int nilfs_test_bdev_super(struct super_block *s, void *data) 1159783f6184SRyusuke Konishi { 1160f11459adSRyusuke Konishi return (void *)s->s_bdev == data; 1161783f6184SRyusuke Konishi } 1162783f6184SRyusuke Konishi 1163e4c59d61SAl Viro static struct dentry * 1164e4c59d61SAl Viro nilfs_mount(struct file_system_type *fs_type, int flags, 1165e4c59d61SAl Viro const char *dev_name, void *data) 1166783f6184SRyusuke Konishi { 1167783f6184SRyusuke Konishi struct nilfs_super_data sd; 116833c8e57cSRyusuke Konishi struct super_block *s; 1169d4d77629STejun Heo fmode_t mode = FMODE_READ | FMODE_EXCL; 1170f11459adSRyusuke Konishi struct dentry *root_dentry; 1171f11459adSRyusuke Konishi int err, s_new = false; 1172783f6184SRyusuke Konishi 117313e90559SRyusuke Konishi if (!(flags & MS_RDONLY)) 117413e90559SRyusuke Konishi mode |= FMODE_WRITE; 117513e90559SRyusuke Konishi 1176d4d77629STejun Heo sd.bdev = blkdev_get_by_path(dev_name, mode, fs_type); 1177d6d4c19cSJan Blunck if (IS_ERR(sd.bdev)) 1178e4c59d61SAl Viro return ERR_CAST(sd.bdev); 1179783f6184SRyusuke Konishi 1180783f6184SRyusuke Konishi sd.cno = 0; 1181783f6184SRyusuke Konishi sd.flags = flags; 1182783f6184SRyusuke Konishi if (nilfs_identify((char *)data, &sd)) { 1183783f6184SRyusuke Konishi err = -EINVAL; 1184783f6184SRyusuke Konishi goto failed; 1185783f6184SRyusuke Konishi } 1186783f6184SRyusuke Konishi 11875beb6e0bSRyusuke Konishi /* 11885beb6e0bSRyusuke Konishi * once the super is inserted into the list by sget, s_umount 11895beb6e0bSRyusuke Konishi * will protect the lockfs code from trying to start a snapshot 11905beb6e0bSRyusuke Konishi * while we are mounting 11915beb6e0bSRyusuke Konishi */ 11925beb6e0bSRyusuke Konishi mutex_lock(&sd.bdev->bd_fsfreeze_mutex); 11935beb6e0bSRyusuke Konishi if (sd.bdev->bd_fsfreeze_count > 0) { 11945beb6e0bSRyusuke Konishi mutex_unlock(&sd.bdev->bd_fsfreeze_mutex); 11955beb6e0bSRyusuke Konishi err = -EBUSY; 119633c8e57cSRyusuke Konishi goto failed; 119733c8e57cSRyusuke Konishi } 1198f11459adSRyusuke Konishi s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, sd.bdev); 11995beb6e0bSRyusuke Konishi mutex_unlock(&sd.bdev->bd_fsfreeze_mutex); 120033c8e57cSRyusuke Konishi if (IS_ERR(s)) { 120133c8e57cSRyusuke Konishi err = PTR_ERR(s); 1202348fe8daSRyusuke Konishi goto failed; 1203783f6184SRyusuke Konishi } 1204783f6184SRyusuke Konishi 1205783f6184SRyusuke Konishi if (!s->s_root) { 1206783f6184SRyusuke Konishi char b[BDEVNAME_SIZE]; 1207783f6184SRyusuke Konishi 1208f11459adSRyusuke Konishi s_new = true; 1209f11459adSRyusuke Konishi 121033c8e57cSRyusuke Konishi /* New superblock instance created */ 1211783f6184SRyusuke Konishi s->s_flags = flags; 12124571b82cSRyusuke Konishi s->s_mode = mode; 1213783f6184SRyusuke Konishi strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id)); 1214783f6184SRyusuke Konishi sb_set_blocksize(s, block_size(sd.bdev)); 1215783f6184SRyusuke Konishi 1216348fe8daSRyusuke Konishi err = nilfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0); 1217783f6184SRyusuke Konishi if (err) 1218348fe8daSRyusuke Konishi goto failed_super; 1219783f6184SRyusuke Konishi 1220783f6184SRyusuke Konishi s->s_flags |= MS_ACTIVE; 1221f11459adSRyusuke Konishi } else if (!sd.cno) { 1222f11459adSRyusuke Konishi int busy = false; 1223f11459adSRyusuke Konishi 1224f11459adSRyusuke Konishi if (nilfs_tree_was_touched(s->s_root)) { 1225f11459adSRyusuke Konishi busy = nilfs_try_to_shrink_tree(s->s_root); 1226f11459adSRyusuke Konishi if (busy && (flags ^ s->s_flags) & MS_RDONLY) { 1227f11459adSRyusuke Konishi printk(KERN_ERR "NILFS: the device already " 1228f11459adSRyusuke Konishi "has a %s mount.\n", 1229f11459adSRyusuke Konishi (s->s_flags & MS_RDONLY) ? 1230f11459adSRyusuke Konishi "read-only" : "read/write"); 1231f11459adSRyusuke Konishi err = -EBUSY; 1232f11459adSRyusuke Konishi goto failed_super; 1233f11459adSRyusuke Konishi } 1234f11459adSRyusuke Konishi } 1235f11459adSRyusuke Konishi if (!busy) { 1236f11459adSRyusuke Konishi /* 1237f11459adSRyusuke Konishi * Try remount to setup mount states if the current 1238f11459adSRyusuke Konishi * tree is not mounted and only snapshots use this sb. 1239f11459adSRyusuke Konishi */ 1240f11459adSRyusuke Konishi err = nilfs_remount(s, &flags, data); 1241f11459adSRyusuke Konishi if (err) 1242f11459adSRyusuke Konishi goto failed_super; 1243f11459adSRyusuke Konishi } 1244783f6184SRyusuke Konishi } 1245783f6184SRyusuke Konishi 1246f11459adSRyusuke Konishi if (sd.cno) { 1247f11459adSRyusuke Konishi err = nilfs_attach_snapshot(s, sd.cno, &root_dentry); 1248348fe8daSRyusuke Konishi if (err) 1249f11459adSRyusuke Konishi goto failed_super; 1250f11459adSRyusuke Konishi } else { 1251f11459adSRyusuke Konishi root_dentry = dget(s->s_root); 1252783f6184SRyusuke Konishi } 1253783f6184SRyusuke Konishi 1254f11459adSRyusuke Konishi if (!s_new) 1255d4d77629STejun Heo blkdev_put(sd.bdev, mode); 1256f11459adSRyusuke Konishi 1257e4c59d61SAl Viro return root_dentry; 1258783f6184SRyusuke Konishi 1259f11459adSRyusuke Konishi failed_super: 1260a95161aaSAl Viro deactivate_locked_super(s); 1261783f6184SRyusuke Konishi 1262348fe8daSRyusuke Konishi failed: 1263348fe8daSRyusuke Konishi if (!s_new) 1264d4d77629STejun Heo blkdev_put(sd.bdev, mode); 1265e4c59d61SAl Viro return ERR_PTR(err); 1266783f6184SRyusuke Konishi } 1267783f6184SRyusuke Konishi 1268783f6184SRyusuke Konishi struct file_system_type nilfs_fs_type = { 1269783f6184SRyusuke Konishi .owner = THIS_MODULE, 1270783f6184SRyusuke Konishi .name = "nilfs2", 1271e4c59d61SAl Viro .mount = nilfs_mount, 1272783f6184SRyusuke Konishi .kill_sb = kill_block_super, 1273783f6184SRyusuke Konishi .fs_flags = FS_REQUIRES_DEV, 1274783f6184SRyusuke Konishi }; 1275783f6184SRyusuke Konishi 127641c88bd7SLi Hong static void nilfs_inode_init_once(void *obj) 127741c88bd7SLi Hong { 127841c88bd7SLi Hong struct nilfs_inode_info *ii = obj; 127941c88bd7SLi Hong 128041c88bd7SLi Hong INIT_LIST_HEAD(&ii->i_dirty); 128141c88bd7SLi Hong #ifdef CONFIG_NILFS_XATTR 128241c88bd7SLi Hong init_rwsem(&ii->xattr_sem); 128341c88bd7SLi Hong #endif 12842aa15890SMiklos Szeredi address_space_init_once(&ii->i_btnode_cache); 128505d0e94bSRyusuke Konishi ii->i_bmap = &ii->i_bmap_data; 128641c88bd7SLi Hong inode_init_once(&ii->vfs_inode); 128741c88bd7SLi Hong } 128841c88bd7SLi Hong 128941c88bd7SLi Hong static void nilfs_segbuf_init_once(void *obj) 129041c88bd7SLi Hong { 129141c88bd7SLi Hong memset(obj, 0, sizeof(struct nilfs_segment_buffer)); 129241c88bd7SLi Hong } 129341c88bd7SLi Hong 129441c88bd7SLi Hong static void nilfs_destroy_cachep(void) 129541c88bd7SLi Hong { 129641c88bd7SLi Hong if (nilfs_inode_cachep) 129741c88bd7SLi Hong kmem_cache_destroy(nilfs_inode_cachep); 129841c88bd7SLi Hong if (nilfs_transaction_cachep) 129941c88bd7SLi Hong kmem_cache_destroy(nilfs_transaction_cachep); 130041c88bd7SLi Hong if (nilfs_segbuf_cachep) 130141c88bd7SLi Hong kmem_cache_destroy(nilfs_segbuf_cachep); 130241c88bd7SLi Hong if (nilfs_btree_path_cache) 130341c88bd7SLi Hong kmem_cache_destroy(nilfs_btree_path_cache); 130441c88bd7SLi Hong } 130541c88bd7SLi Hong 130641c88bd7SLi Hong static int __init nilfs_init_cachep(void) 130741c88bd7SLi Hong { 130841c88bd7SLi Hong nilfs_inode_cachep = kmem_cache_create("nilfs2_inode_cache", 130941c88bd7SLi Hong sizeof(struct nilfs_inode_info), 0, 131041c88bd7SLi Hong SLAB_RECLAIM_ACCOUNT, nilfs_inode_init_once); 131141c88bd7SLi Hong if (!nilfs_inode_cachep) 131241c88bd7SLi Hong goto fail; 131341c88bd7SLi Hong 131441c88bd7SLi Hong nilfs_transaction_cachep = kmem_cache_create("nilfs2_transaction_cache", 131541c88bd7SLi Hong sizeof(struct nilfs_transaction_info), 0, 131641c88bd7SLi Hong SLAB_RECLAIM_ACCOUNT, NULL); 131741c88bd7SLi Hong if (!nilfs_transaction_cachep) 131841c88bd7SLi Hong goto fail; 131941c88bd7SLi Hong 132041c88bd7SLi Hong nilfs_segbuf_cachep = kmem_cache_create("nilfs2_segbuf_cache", 132141c88bd7SLi Hong sizeof(struct nilfs_segment_buffer), 0, 132241c88bd7SLi Hong SLAB_RECLAIM_ACCOUNT, nilfs_segbuf_init_once); 132341c88bd7SLi Hong if (!nilfs_segbuf_cachep) 132441c88bd7SLi Hong goto fail; 132541c88bd7SLi Hong 132641c88bd7SLi Hong nilfs_btree_path_cache = kmem_cache_create("nilfs2_btree_path_cache", 132741c88bd7SLi Hong sizeof(struct nilfs_btree_path) * NILFS_BTREE_LEVEL_MAX, 132841c88bd7SLi Hong 0, 0, NULL); 132941c88bd7SLi Hong if (!nilfs_btree_path_cache) 133041c88bd7SLi Hong goto fail; 133141c88bd7SLi Hong 133241c88bd7SLi Hong return 0; 133341c88bd7SLi Hong 133441c88bd7SLi Hong fail: 133541c88bd7SLi Hong nilfs_destroy_cachep(); 133641c88bd7SLi Hong return -ENOMEM; 133741c88bd7SLi Hong } 133841c88bd7SLi Hong 1339783f6184SRyusuke Konishi static int __init init_nilfs_fs(void) 1340783f6184SRyusuke Konishi { 1341783f6184SRyusuke Konishi int err; 1342783f6184SRyusuke Konishi 134341c88bd7SLi Hong err = nilfs_init_cachep(); 1344783f6184SRyusuke Konishi if (err) 134541c88bd7SLi Hong goto fail; 1346783f6184SRyusuke Konishi 1347783f6184SRyusuke Konishi err = register_filesystem(&nilfs_fs_type); 1348783f6184SRyusuke Konishi if (err) 134941c88bd7SLi Hong goto free_cachep; 1350783f6184SRyusuke Konishi 13519f130263SLi Hong printk(KERN_INFO "NILFS version 2 loaded\n"); 1352783f6184SRyusuke Konishi return 0; 1353783f6184SRyusuke Konishi 135441c88bd7SLi Hong free_cachep: 135541c88bd7SLi Hong nilfs_destroy_cachep(); 135641c88bd7SLi Hong fail: 1357783f6184SRyusuke Konishi return err; 1358783f6184SRyusuke Konishi } 1359783f6184SRyusuke Konishi 1360783f6184SRyusuke Konishi static void __exit exit_nilfs_fs(void) 1361783f6184SRyusuke Konishi { 136241c88bd7SLi Hong nilfs_destroy_cachep(); 1363783f6184SRyusuke Konishi unregister_filesystem(&nilfs_fs_type); 1364783f6184SRyusuke Konishi } 1365783f6184SRyusuke Konishi 1366783f6184SRyusuke Konishi module_init(init_nilfs_fs) 1367783f6184SRyusuke Konishi module_exit(exit_nilfs_fs) 1368