Commit 5bab188a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2:
  nilfs2: move NILFS_SUPER_MAGIC to linux/magic.h
  nilfs2: get rid of nilfs_sb_info structure
  nilfs2: use sb instance instead of nilfs_sb_info struct
  nilfs2: get rid of sc_sbi back pointer
  nilfs2: move log writer onto nilfs object
  nilfs2: move next generation counter into nilfs object
  nilfs2: move s_inode_lock and s_dirty_files into nilfs object
  nilfs2: move parameters on nilfs_sb_info into nilfs object
  nilfs2: move mount options to nilfs object
  nilfs2: record used amount of each checkpoint in checkpoint list
  nilfs2: optimize rec_len functions
  nilfs2: append blocksize info to warnings during loading super blocks
  nilfs2: add compat ioctl
  nilfs2: implement FS_IOC_GETFLAGS/SETFLAGS/GETVERSION
  nilfs2: tighten restrictions on inode flags
  nilfs2: mark S_NOATIME on inodes only if NOATIME attribute is set
  nilfs2: use common file attribute macros
  nilfs2: add free entries count only if clear bit operation succeeded
  nilfs2: decrement inodes count only if raw inode was successfully deleted
parents a8c91da5 4d3cf1bc
...@@ -521,8 +521,8 @@ void nilfs_palloc_commit_free_entry(struct inode *inode, ...@@ -521,8 +521,8 @@ void nilfs_palloc_commit_free_entry(struct inode *inode,
group_offset, bitmap)) group_offset, bitmap))
printk(KERN_WARNING "%s: entry number %llu already freed\n", printk(KERN_WARNING "%s: entry number %llu already freed\n",
__func__, (unsigned long long)req->pr_entry_nr); __func__, (unsigned long long)req->pr_entry_nr);
else
nilfs_palloc_group_desc_add_entries(inode, group, desc, 1); nilfs_palloc_group_desc_add_entries(inode, group, desc, 1);
kunmap(req->pr_bitmap_bh->b_page); kunmap(req->pr_bitmap_bh->b_page);
kunmap(req->pr_desc_bh->b_page); kunmap(req->pr_desc_bh->b_page);
...@@ -558,8 +558,8 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode, ...@@ -558,8 +558,8 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
group_offset, bitmap)) group_offset, bitmap))
printk(KERN_WARNING "%s: entry number %llu already freed\n", printk(KERN_WARNING "%s: entry number %llu already freed\n",
__func__, (unsigned long long)req->pr_entry_nr); __func__, (unsigned long long)req->pr_entry_nr);
else
nilfs_palloc_group_desc_add_entries(inode, group, desc, 1); nilfs_palloc_group_desc_add_entries(inode, group, desc, 1);
kunmap(req->pr_bitmap_bh->b_page); kunmap(req->pr_bitmap_bh->b_page);
kunmap(req->pr_desc_bh->b_page); kunmap(req->pr_desc_bh->b_page);
...@@ -665,7 +665,7 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems) ...@@ -665,7 +665,7 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
for (j = i, n = 0; for (j = i, n = 0;
(j < nitems) && nilfs_palloc_group_is_in(inode, group, (j < nitems) && nilfs_palloc_group_is_in(inode, group,
entry_nrs[j]); entry_nrs[j]);
j++, n++) { j++) {
nilfs_palloc_group(inode, entry_nrs[j], &group_offset); nilfs_palloc_group(inode, entry_nrs[j], &group_offset);
if (!nilfs_clear_bit_atomic( if (!nilfs_clear_bit_atomic(
nilfs_mdt_bgl_lock(inode, group), nilfs_mdt_bgl_lock(inode, group),
...@@ -674,6 +674,8 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems) ...@@ -674,6 +674,8 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
"%s: entry number %llu already freed\n", "%s: entry number %llu already freed\n",
__func__, __func__,
(unsigned long long)entry_nrs[j]); (unsigned long long)entry_nrs[j]);
} else {
n++;
} }
} }
nilfs_palloc_group_desc_add_entries(inode, group, desc, n); nilfs_palloc_group_desc_add_entries(inode, group, desc, n);
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include "nilfs.h" #include "nilfs.h"
#include "bmap.h" #include "bmap.h"
#include "sb.h"
#include "btree.h" #include "btree.h"
#include "direct.h" #include "direct.h"
#include "btnode.h" #include "btnode.h"
...@@ -425,17 +424,6 @@ int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *bmap) ...@@ -425,17 +424,6 @@ int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *bmap)
/* /*
* Internal use only * Internal use only
*/ */
void nilfs_bmap_add_blocks(const struct nilfs_bmap *bmap, int n)
{
inode_add_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n);
}
void nilfs_bmap_sub_blocks(const struct nilfs_bmap *bmap, int n)
{
inode_sub_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n);
}
__u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap, __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap,
const struct buffer_head *bh) const struct buffer_head *bh)
{ {
......
...@@ -240,9 +240,6 @@ __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *, ...@@ -240,9 +240,6 @@ __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *,
__u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64); __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64);
__u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *); __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *);
void nilfs_bmap_add_blocks(const struct nilfs_bmap *, int);
void nilfs_bmap_sub_blocks(const struct nilfs_bmap *, int);
/* Assume that bmap semaphore is locked. */ /* Assume that bmap semaphore is locked. */
static inline int nilfs_bmap_dirty(const struct nilfs_bmap *bmap) static inline int nilfs_bmap_dirty(const struct nilfs_bmap *bmap)
......
...@@ -1174,7 +1174,7 @@ static int nilfs_btree_insert(struct nilfs_bmap *btree, __u64 key, __u64 ptr) ...@@ -1174,7 +1174,7 @@ static int nilfs_btree_insert(struct nilfs_bmap *btree, __u64 key, __u64 ptr)
if (ret < 0) if (ret < 0)
goto out; goto out;
nilfs_btree_commit_insert(btree, path, level, key, ptr); nilfs_btree_commit_insert(btree, path, level, key, ptr);
nilfs_bmap_add_blocks(btree, stats.bs_nblocks); nilfs_inode_add_blocks(btree->b_inode, stats.bs_nblocks);
out: out:
nilfs_btree_free_path(path); nilfs_btree_free_path(path);
...@@ -1511,7 +1511,7 @@ static int nilfs_btree_delete(struct nilfs_bmap *btree, __u64 key) ...@@ -1511,7 +1511,7 @@ static int nilfs_btree_delete(struct nilfs_bmap *btree, __u64 key)
if (ret < 0) if (ret < 0)
goto out; goto out;
nilfs_btree_commit_delete(btree, path, level, dat); nilfs_btree_commit_delete(btree, path, level, dat);
nilfs_bmap_sub_blocks(btree, stats.bs_nblocks); nilfs_inode_sub_blocks(btree->b_inode, stats.bs_nblocks);
out: out:
nilfs_btree_free_path(path); nilfs_btree_free_path(path);
...@@ -1776,7 +1776,7 @@ int nilfs_btree_convert_and_insert(struct nilfs_bmap *btree, ...@@ -1776,7 +1776,7 @@ int nilfs_btree_convert_and_insert(struct nilfs_bmap *btree,
return ret; return ret;
nilfs_btree_commit_convert_and_insert(btree, key, ptr, keys, ptrs, n, nilfs_btree_commit_convert_and_insert(btree, key, ptr, keys, ptrs, n,
di, ni, bh); di, ni, bh);
nilfs_bmap_add_blocks(btree, stats.bs_nblocks); nilfs_inode_add_blocks(btree->b_inode, stats.bs_nblocks);
return 0; return 0;
} }
......
...@@ -440,7 +440,6 @@ void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, ...@@ -440,7 +440,6 @@ void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
nilfs_commit_chunk(page, mapping, from, to); nilfs_commit_chunk(page, mapping, from, to);
nilfs_put_page(page); nilfs_put_page(page);
dir->i_mtime = dir->i_ctime = CURRENT_TIME; dir->i_mtime = dir->i_ctime = CURRENT_TIME;
/* NILFS_I(dir)->i_flags &= ~NILFS_BTREE_FL; */
} }
/* /*
...@@ -531,7 +530,6 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode) ...@@ -531,7 +530,6 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
nilfs_set_de_type(de, inode); nilfs_set_de_type(de, inode);
nilfs_commit_chunk(page, page->mapping, from, to); nilfs_commit_chunk(page, page->mapping, from, to);
dir->i_mtime = dir->i_ctime = CURRENT_TIME; dir->i_mtime = dir->i_ctime = CURRENT_TIME;
/* NILFS_I(dir)->i_flags &= ~NILFS_BTREE_FL; */
nilfs_mark_inode_dirty(dir); nilfs_mark_inode_dirty(dir);
/* OFFSET_CACHE */ /* OFFSET_CACHE */
out_put: out_put:
...@@ -579,7 +577,6 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page) ...@@ -579,7 +577,6 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page)
dir->inode = 0; dir->inode = 0;
nilfs_commit_chunk(page, mapping, from, to); nilfs_commit_chunk(page, mapping, from, to);
inode->i_ctime = inode->i_mtime = CURRENT_TIME; inode->i_ctime = inode->i_mtime = CURRENT_TIME;
/* NILFS_I(inode)->i_flags &= ~NILFS_BTREE_FL; */
out: out:
nilfs_put_page(page); nilfs_put_page(page);
return err; return err;
...@@ -684,7 +681,7 @@ const struct file_operations nilfs_dir_operations = { ...@@ -684,7 +681,7 @@ const struct file_operations nilfs_dir_operations = {
.readdir = nilfs_readdir, .readdir = nilfs_readdir,
.unlocked_ioctl = nilfs_ioctl, .unlocked_ioctl = nilfs_ioctl,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_ioctl = nilfs_ioctl, .compat_ioctl = nilfs_compat_ioctl,
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */
.fsync = nilfs_sync_file, .fsync = nilfs_sync_file,
......
...@@ -146,7 +146,7 @@ static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) ...@@ -146,7 +146,7 @@ static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
if (NILFS_BMAP_USE_VBN(bmap)) if (NILFS_BMAP_USE_VBN(bmap))
nilfs_bmap_set_target_v(bmap, key, req.bpr_ptr); nilfs_bmap_set_target_v(bmap, key, req.bpr_ptr);
nilfs_bmap_add_blocks(bmap, 1); nilfs_inode_add_blocks(bmap->b_inode, 1);
} }
return ret; return ret;
} }
...@@ -168,7 +168,7 @@ static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key) ...@@ -168,7 +168,7 @@ static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key)
if (!ret) { if (!ret) {
nilfs_bmap_commit_end_ptr(bmap, &req, dat); nilfs_bmap_commit_end_ptr(bmap, &req, dat);
nilfs_direct_set_ptr(bmap, key, NILFS_BMAP_INVALID_PTR); nilfs_direct_set_ptr(bmap, key, NILFS_BMAP_INVALID_PTR);
nilfs_bmap_sub_blocks(bmap, 1); nilfs_inode_sub_blocks(bmap->b_inode, 1);
} }
return ret; return ret;
} }
......
...@@ -59,7 +59,7 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -59,7 +59,7 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
struct nilfs_transaction_info ti; struct nilfs_transaction_info ti;
int ret; int ret;
if (unlikely(nilfs_near_disk_full(NILFS_SB(inode->i_sb)->s_nilfs))) if (unlikely(nilfs_near_disk_full(inode->i_sb->s_fs_info)))
return VM_FAULT_SIGBUS; /* -ENOSPC */ return VM_FAULT_SIGBUS; /* -ENOSPC */
lock_page(page); lock_page(page);
...@@ -142,7 +142,7 @@ const struct file_operations nilfs_file_operations = { ...@@ -142,7 +142,7 @@ const struct file_operations nilfs_file_operations = {
.aio_write = generic_file_aio_write, .aio_write = generic_file_aio_write,
.unlocked_ioctl = nilfs_ioctl, .unlocked_ioctl = nilfs_ioctl,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_ioctl = nilfs_ioctl, .compat_ioctl = nilfs_compat_ioctl,
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */
.mmap = nilfs_file_mmap, .mmap = nilfs_file_mmap,
.open = generic_file_open, .open = generic_file_open,
......
...@@ -41,6 +41,24 @@ struct nilfs_iget_args { ...@@ -41,6 +41,24 @@ struct nilfs_iget_args {
int for_gc; int for_gc;
}; };
void nilfs_inode_add_blocks(struct inode *inode, int n)
{
struct nilfs_root *root = NILFS_I(inode)->i_root;
inode_add_bytes(inode, (1 << inode->i_blkbits) * n);
if (root)
atomic_add(n, &root->blocks_count);
}
void nilfs_inode_sub_blocks(struct inode *inode, int n)
{
struct nilfs_root *root = NILFS_I(inode)->i_root;
inode_sub_bytes(inode, (1 << inode->i_blkbits) * n);
if (root)
atomic_sub(n, &root->blocks_count);
}
/** /**
* nilfs_get_block() - get a file block on the filesystem (callback function) * nilfs_get_block() - get a file block on the filesystem (callback function)
* @inode - inode struct of the target file * @inode - inode struct of the target file
...@@ -277,7 +295,7 @@ const struct address_space_operations nilfs_aops = { ...@@ -277,7 +295,7 @@ const struct address_space_operations nilfs_aops = {
struct inode *nilfs_new_inode(struct inode *dir, int mode) struct inode *nilfs_new_inode(struct inode *dir, int mode)
{ {
struct super_block *sb = dir->i_sb; struct super_block *sb = dir->i_sb;
struct nilfs_sb_info *sbi = NILFS_SB(sb); struct the_nilfs *nilfs = sb->s_fs_info;
struct inode *inode; struct inode *inode;
struct nilfs_inode_info *ii; struct nilfs_inode_info *ii;
struct nilfs_root *root; struct nilfs_root *root;
...@@ -315,19 +333,16 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) ...@@ -315,19 +333,16 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode)
/* No lock is needed; iget() ensures it. */ /* No lock is needed; iget() ensures it. */
} }
ii->i_flags = NILFS_I(dir)->i_flags; ii->i_flags = nilfs_mask_flags(
if (S_ISLNK(mode)) mode, NILFS_I(dir)->i_flags & NILFS_FL_INHERITED);
ii->i_flags &= ~(NILFS_IMMUTABLE_FL | NILFS_APPEND_FL);
if (!S_ISDIR(mode))
ii->i_flags &= ~NILFS_DIRSYNC_FL;
/* ii->i_file_acl = 0; */ /* ii->i_file_acl = 0; */
/* ii->i_dir_acl = 0; */ /* ii->i_dir_acl = 0; */
ii->i_dir_start_lookup = 0; ii->i_dir_start_lookup = 0;
nilfs_set_inode_flags(inode); nilfs_set_inode_flags(inode);
spin_lock(&sbi->s_next_gen_lock); spin_lock(&nilfs->ns_next_gen_lock);
inode->i_generation = sbi->s_next_generation++; inode->i_generation = nilfs->ns_next_generation++;
spin_unlock(&sbi->s_next_gen_lock); spin_unlock(&nilfs->ns_next_gen_lock);
insert_inode_hash(inode); insert_inode_hash(inode);
err = nilfs_init_acl(inode, dir); err = nilfs_init_acl(inode, dir);
...@@ -359,17 +374,15 @@ void nilfs_set_inode_flags(struct inode *inode) ...@@ -359,17 +374,15 @@ void nilfs_set_inode_flags(struct inode *inode)
inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME |
S_DIRSYNC); S_DIRSYNC);
if (flags & NILFS_SYNC_FL) if (flags & FS_SYNC_FL)
inode->i_flags |= S_SYNC; inode->i_flags |= S_SYNC;
if (flags & NILFS_APPEND_FL) if (flags & FS_APPEND_FL)
inode->i_flags |= S_APPEND; inode->i_flags |= S_APPEND;
if (flags & NILFS_IMMUTABLE_FL) if (flags & FS_IMMUTABLE_FL)
inode->i_flags |= S_IMMUTABLE; inode->i_flags |= S_IMMUTABLE;
#ifndef NILFS_ATIME_DISABLE if (flags & FS_NOATIME_FL)
if (flags & NILFS_NOATIME_FL)
#endif
inode->i_flags |= S_NOATIME; inode->i_flags |= S_NOATIME;
if (flags & NILFS_DIRSYNC_FL) if (flags & FS_DIRSYNC_FL)
inode->i_flags |= S_DIRSYNC; inode->i_flags |= S_DIRSYNC;
mapping_set_gfp_mask(inode->i_mapping, mapping_set_gfp_mask(inode->i_mapping,
mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
...@@ -420,7 +433,7 @@ static int __nilfs_read_inode(struct super_block *sb, ...@@ -420,7 +433,7 @@ static int __nilfs_read_inode(struct super_block *sb,
struct nilfs_root *root, unsigned long ino, struct nilfs_root *root, unsigned long ino,
struct inode *inode) struct inode *inode)
{ {
struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; struct the_nilfs *nilfs = sb->s_fs_info;
struct buffer_head *bh; struct buffer_head *bh;
struct nilfs_inode *raw_inode; struct nilfs_inode *raw_inode;
int err; int err;
...@@ -707,6 +720,7 @@ void nilfs_evict_inode(struct inode *inode) ...@@ -707,6 +720,7 @@ void nilfs_evict_inode(struct inode *inode)
struct nilfs_transaction_info ti; struct nilfs_transaction_info ti;
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
struct nilfs_inode_info *ii = NILFS_I(inode); struct nilfs_inode_info *ii = NILFS_I(inode);
int ret;
if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) { if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) {
if (inode->i_data.nrpages) if (inode->i_data.nrpages)
...@@ -725,8 +739,9 @@ void nilfs_evict_inode(struct inode *inode) ...@@ -725,8 +739,9 @@ void nilfs_evict_inode(struct inode *inode)
nilfs_mark_inode_dirty(inode); nilfs_mark_inode_dirty(inode);
end_writeback(inode); end_writeback(inode);
nilfs_ifile_delete_inode(ii->i_root->ifile, inode->i_ino); ret = nilfs_ifile_delete_inode(ii->i_root->ifile, inode->i_ino);
atomic_dec(&ii->i_root->inodes_count); if (!ret)
atomic_dec(&ii->i_root->inodes_count);
nilfs_clear_inode(inode); nilfs_clear_inode(inode);
...@@ -792,18 +807,18 @@ int nilfs_permission(struct inode *inode, int mask, unsigned int flags) ...@@ -792,18 +807,18 @@ int nilfs_permission(struct inode *inode, int mask, unsigned int flags)
int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh) int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh)
{ {
struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb); struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
struct nilfs_inode_info *ii = NILFS_I(inode); struct nilfs_inode_info *ii = NILFS_I(inode);
int err; int err;
spin_lock(&sbi->s_inode_lock); spin_lock(&nilfs->ns_inode_lock);
if (ii->i_bh == NULL) { if (ii->i_bh == NULL) {
spin_unlock(&sbi->s_inode_lock); spin_unlock(&nilfs->ns_inode_lock);
err = nilfs_ifile_get_inode_block(ii->i_root->ifile, err = nilfs_ifile_get_inode_block(ii->i_root->ifile,
inode->i_ino, pbh); inode->i_ino, pbh);
if (unlikely(err)) if (unlikely(err))
return err; return err;
spin_lock(&sbi->s_inode_lock); spin_lock(&nilfs->ns_inode_lock);
if (ii->i_bh == NULL) if (ii->i_bh == NULL)
ii->i_bh = *pbh; ii->i_bh = *pbh;
else { else {
...@@ -814,36 +829,36 @@ int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh) ...@@ -814,36 +829,36 @@ int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh)
*pbh = ii->i_bh; *pbh = ii->i_bh;
get_bh(*pbh); get_bh(*pbh);
spin_unlock(&sbi->s_inode_lock); spin_unlock(&nilfs->ns_inode_lock);
return 0; return 0;
} }
int nilfs_inode_dirty(struct inode *inode) int nilfs_inode_dirty(struct inode *inode)
{ {
struct nilfs_inode_info *ii = NILFS_I(inode); struct nilfs_inode_info *ii = NILFS_I(inode);
struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb); struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
int ret = 0; int ret = 0;
if (!list_empty(&ii->i_dirty)) { if (!list_empty(&ii->i_dirty)) {
spin_lock(&sbi->s_inode_lock); spin_lock(&nilfs->ns_inode_lock);
ret = test_bit(NILFS_I_DIRTY, &ii->i_state) || ret = test_bit(NILFS_I_DIRTY, &ii->i_state) ||
test_bit(NILFS_I_BUSY, &ii->i_state); test_bit(NILFS_I_BUSY, &ii->i_state);
spin_unlock(&sbi->s_inode_lock); spin_unlock(&nilfs->ns_inode_lock);
} }
return ret; return ret;
} }
int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty) int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty)
{ {
struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb);
struct nilfs_inode_info *ii = NILFS_I(inode); struct nilfs_inode_info *ii = NILFS_I(inode);
struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
atomic_add(nr_dirty, &sbi->s_nilfs->ns_ndirtyblks); atomic_add(nr_dirty, &nilfs->ns_ndirtyblks);
if (test_and_set_bit(NILFS_I_DIRTY, &ii->i_state)) if (test_and_set_bit(NILFS_I_DIRTY, &ii->i_state))
return 0; return 0;
spin_lock(&sbi->s_inode_lock); spin_lock(&nilfs->ns_inode_lock);
if (!test_bit(NILFS_I_QUEUED, &ii->i_state) && if (!test_bit(NILFS_I_QUEUED, &ii->i_state) &&
!test_bit(NILFS_I_BUSY, &ii->i_state)) { !test_bit(NILFS_I_BUSY, &ii->i_state)) {
/* Because this routine may race with nilfs_dispose_list(), /* Because this routine may race with nilfs_dispose_list(),
...@@ -851,18 +866,18 @@ int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty) ...@@ -851,18 +866,18 @@ int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty)
if (list_empty(&ii->i_dirty) && igrab(inode) == NULL) { if (list_empty(&ii->i_dirty) && igrab(inode) == NULL) {
/* This will happen when somebody is freeing /* This will happen when somebody is freeing
this inode. */ this inode. */
nilfs_warning(sbi->s_super, __func__, nilfs_warning(inode->i_sb, __func__,
"cannot get inode (ino=%lu)\n", "cannot get inode (ino=%lu)\n",
inode->i_ino); inode->i_ino);
spin_unlock(&sbi->s_inode_lock); spin_unlock(&nilfs->ns_inode_lock);
return -EINVAL; /* NILFS_I_DIRTY may remain for return -EINVAL; /* NILFS_I_DIRTY may remain for
freeing inode */ freeing inode */
} }
list_del(&ii->i_dirty); list_del(&ii->i_dirty);
list_add_tail(&ii->i_dirty, &sbi->s_dirty_files); list_add_tail(&ii->i_dirty, &nilfs->ns_dirty_files);
set_bit(NILFS_I_QUEUED, &ii->i_state); set_bit(NILFS_I_QUEUED, &ii->i_state);
} }
spin_unlock(&sbi->s_inode_lock); spin_unlock(&nilfs->ns_inode_lock);
return 0; return 0;
} }
......
...@@ -26,7 +26,9 @@ ...@@ -26,7 +26,9 @@
#include <linux/capability.h> /* capable() */ #include <linux/capability.h> /* capable() */
#include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */ #include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/compat.h> /* compat_ptr() */
#include <linux/mount.h> /* mnt_want_write(), mnt_drop_write() */ #include <linux/mount.h> /* mnt_want_write(), mnt_drop_write() */
#include <linux/buffer_head.h>
#include <linux/nilfs2_fs.h> #include <linux/nilfs2_fs.h>
#include "nilfs.h" #include "nilfs.h"
#include "segment.h" #include "segment.h"
...@@ -97,11 +99,74 @@ static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs, ...@@ -97,11 +99,74 @@ static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
return ret; return ret;
} }
static int nilfs_ioctl_getflags(struct inode *inode, void __user *argp)
{
unsigned int flags = NILFS_I(inode)->i_flags & FS_FL_USER_VISIBLE;
return put_user(flags, (int __user *)argp);
}
static int nilfs_ioctl_setflags(struct inode *inode, struct file *filp,
void __user *argp)
{
struct nilfs_transaction_info ti;
unsigned int flags, oldflags;
int ret;
if (!is_owner_or_cap(inode))
return -EACCES;
if (get_user(flags, (int __user *)argp))
return -EFAULT;
ret = mnt_want_write(filp->f_path.mnt);
if (ret)
return ret;
flags = nilfs_mask_flags(inode->i_mode, flags);
mutex_lock(&inode->i_mutex);
oldflags = NILFS_I(inode)->i_flags;
/*
* The IMMUTABLE and APPEND_ONLY flags can only be changed by the
* relevant capability.
*/
ret = -EPERM;
if (((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) &&
!capable(CAP_LINUX_IMMUTABLE))
goto out;
ret = nilfs_transaction_begin(inode->i_sb, &ti, 0);
if (ret)
goto out;
NILFS_I(inode)->i_flags = (oldflags & ~FS_FL_USER_MODIFIABLE) |
(flags & FS_FL_USER_MODIFIABLE);
nilfs_set_inode_flags(inode);
inode->i_ctime = CURRENT_TIME;
if (IS_SYNC(inode))
nilfs_set_transaction_flag(NILFS_TI_SYNC);
nilfs_mark_inode_dirty(inode);
ret = nilfs_transaction_commit(inode->i_sb);
out:
mutex_unlock(&inode->i_mutex);
mnt_drop_write(filp->f_path.mnt);
return ret;
}
static int nilfs_ioctl_getversion(struct inode *inode, void __user *argp)
{
return put_user(inode->i_generation, (int __user *)argp);
}
static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp, static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
unsigned int cmd, void __user *argp) unsigned int cmd, void __user *argp)
{ {
struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
struct inode *cpfile = nilfs->ns_cpfile;
struct nilfs_transaction_info ti; struct nilfs_transaction_info ti;
struct nilfs_cpmode cpmode; struct nilfs_cpmode cpmode;
int ret; int ret;
...@@ -121,7 +186,7 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp, ...@@ -121,7 +186,7 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
nilfs_transaction_begin(inode->i_sb, &ti, 0); nilfs_transaction_begin(inode->i_sb, &ti, 0);
ret = nilfs_cpfile_change_cpmode( ret = nilfs_cpfile_change_cpmode(
cpfile, cpmode.cm_cno, cpmode.cm_mode); nilfs->ns_cpfile, cpmode.cm_cno, cpmode.cm_mode);
if (unlikely(ret < 0)) if (unlikely(ret < 0))
nilfs_transaction_abort(inode->i_sb); nilfs_transaction_abort(inode->i_sb);
else else
...@@ -137,7 +202,7 @@ static int ...@@ -137,7 +202,7 @@ static int
nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp, nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp,
unsigned int cmd, void __user *argp) unsigned int cmd, void __user *argp)
{ {
struct inode *cpfile = NILFS_SB(inode->i_sb)->s_nilfs->ns_cpfile; struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
struct nilfs_transaction_info ti; struct nilfs_transaction_info ti;
__u64 cno; __u64 cno;
int ret; int ret;
...@@ -154,7 +219,7 @@ nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp, ...@@ -154,7 +219,7 @@ nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp,
goto out; goto out;
nilfs_transaction_begin(inode->i_sb, &ti, 0); nilfs_transaction_begin(inode->i_sb, &ti, 0);
ret = nilfs_cpfile_delete_checkpoint(cpfile, cno); ret = nilfs_cpfile_delete_checkpoint(nilfs->ns_cpfile, cno);
if (unlikely(ret < 0)) if (unlikely(ret < 0))
nilfs_transaction_abort(inode->i_sb); nilfs_transaction_abort(inode->i_sb);
else else
...@@ -180,7 +245,7 @@ nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, ...@@ -180,7 +245,7 @@ nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp, static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp,
unsigned int cmd, void __user *argp) unsigned int cmd, void __user *argp)
{ {
struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
struct nilfs_cpstat cpstat; struct nilfs_cpstat cpstat;
int ret; int ret;
...@@ -211,7 +276,7 @@ nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, ...@@ -211,7 +276,7 @@ nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp, static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp,
unsigned int cmd, void __user *argp) unsigned int cmd, void __user *argp)
{ {
struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
struct nilfs_sustat sustat; struct nilfs_sustat sustat;
int ret; int ret;
...@@ -267,7 +332,7 @@ nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags, ...@@ -267,7 +332,7 @@ nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags,
static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp, static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp,
unsigned int cmd, void __user *argp) unsigned int cmd, void __user *argp)
{ {
struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
struct nilfs_argv argv; struct nilfs_argv argv;
int ret; int ret;
...@@ -336,7 +401,7 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb, ...@@ -336,7 +401,7 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb,
struct nilfs_argv *argv, void *buf) struct nilfs_argv *argv, void *buf)
{ {
size_t nmembs = argv->v_nmembs; size_t nmembs = argv->v_nmembs;
struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; struct the_nilfs *nilfs = sb->s_fs_info;
struct inode *inode; struct inode *inode;
struct nilfs_vdesc *vdesc; struct nilfs_vdesc *vdesc;
struct buffer_head *bh, *n; struct buffer_head *bh, *n;
...@@ -550,7 +615,7 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, ...@@ -550,7 +615,7 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
ret = PTR_ERR(kbufs[4]); ret = PTR_ERR(kbufs[4]);
goto out; goto out;
} }
nilfs = NILFS_SB(inode->i_sb)->s_nilfs; nilfs = inode->i_sb->s_fs_info;
for (n = 0; n < 4; n++) { for (n = 0; n < 4; n++) {
ret = -EINVAL; ret = -EINVAL;
...@@ -623,7 +688,7 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp, ...@@ -623,7 +688,7 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
return ret; return ret;
if (argp != NULL) { if (argp != NULL) {
nilfs = NILFS_SB(inode->i_sb)->s_nilfs; nilfs = inode->i_sb->s_fs_info;
down_read(&nilfs->ns_segctor_sem); down_read(&nilfs->ns_segctor_sem);
cno = nilfs->ns_cno - 1; cno = nilfs->ns_cno - 1;
up_read(&nilfs->ns_segctor_sem); up_read(&nilfs->ns_segctor_sem);
...@@ -641,7 +706,7 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp, ...@@ -641,7 +706,7 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
void *, size_t, size_t)) void *, size_t, size_t))
{ {
struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
struct nilfs_argv argv; struct nilfs_argv argv;
int ret; int ret;
...@@ -666,6 +731,12 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -666,6 +731,12 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
switch (cmd) { switch (cmd) {
case FS_IOC_GETFLAGS:
return nilfs_ioctl_getflags(inode, argp);
case FS_IOC_SETFLAGS:
return nilfs_ioctl_setflags(inode, filp, argp);
case FS_IOC_GETVERSION:
return nilfs_ioctl_getversion(inode, argp);
case NILFS_IOCTL_CHANGE_CPMODE: case NILFS_IOCTL_CHANGE_CPMODE:
return nilfs_ioctl_change_cpmode(inode, filp, cmd, argp); return nilfs_ioctl_change_cpmode(inode, filp, cmd, argp);
case NILFS_IOCTL_DELETE_CHECKPOINT: case NILFS_IOCTL_DELETE_CHECKPOINT:
...@@ -696,3 +767,23 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -696,3 +767,23 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return -ENOTTY; return -ENOTTY;
} }
} }
#ifdef CONFIG_COMPAT
long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
switch (cmd) {
case FS_IOC32_GETFLAGS:
cmd = FS_IOC_GETFLAGS;
break;
case FS_IOC32_SETFLAGS:
cmd = FS_IOC_SETFLAGS;
break;
case FS_IOC32_GETVERSION:
cmd = FS_IOC_GETVERSION;
break;
default:
return -ENOIOCTLCMD;
}
return nilfs_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
}
#endif
...@@ -66,7 +66,7 @@ static inline struct nilfs_mdt_info *NILFS_MDT(const struct inode *inode) ...@@ -66,7 +66,7 @@ static inline struct nilfs_mdt_info *NILFS_MDT(const struct inode *inode)
static inline struct the_nilfs *NILFS_I_NILFS(struct inode *inode) static inline struct the_nilfs *NILFS_I_NILFS(struct inode *inode)
{ {
return NILFS_SB(inode->i_sb)->s_nilfs; return inode->i_sb->s_fs_info;
} }
/* Default GFP flags using highmem */ /* Default GFP flags using highmem */
......
...@@ -482,7 +482,7 @@ static struct dentry *nilfs_get_dentry(struct super_block *sb, u64 cno, ...@@ -482,7 +482,7 @@ static struct dentry *nilfs_get_dentry(struct super_block *sb, u64 cno,
if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO) if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO)
return ERR_PTR(-ESTALE); return ERR_PTR(-ESTALE);
root = nilfs_lookup_root(NILFS_SB(sb)->s_nilfs, cno); root = nilfs_lookup_root(sb->s_fs_info, cno);
if (!root) if (!root)
return ERR_PTR(-ESTALE); return ERR_PTR(-ESTALE);
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/nilfs2_fs.h> #include <linux/nilfs2_fs.h>
#include "the_nilfs.h" #include "the_nilfs.h"
#include "sb.h"
#include "bmap.h" #include "bmap.h"
/* /*
...@@ -122,7 +121,7 @@ enum { ...@@ -122,7 +121,7 @@ enum {
#define NILFS_SYS_INO_BITS \ #define NILFS_SYS_INO_BITS \
((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS) ((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS)
#define NILFS_FIRST_INO(sb) (NILFS_SB(sb)->s_nilfs->ns_first_ino) #define NILFS_FIRST_INO(sb) (((struct the_nilfs *)sb->s_fs_info)->ns_first_ino)
#define NILFS_MDT_INODE(sb, ino) \ #define NILFS_MDT_INODE(sb, ino) \
((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino)))) ((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino))))
...@@ -212,6 +211,23 @@ static inline int nilfs_init_acl(struct inode *inode, struct inode *dir) ...@@ -212,6 +211,23 @@ static inline int nilfs_init_acl(struct inode *inode, struct inode *dir)
#define NILFS_ATIME_DISABLE #define NILFS_ATIME_DISABLE
/* Flags that should be inherited by new inodes from their parent. */
#define NILFS_FL_INHERITED \
(FS_SECRM_FL | FS_UNRM_FL | FS_COMPR_FL | FS_SYNC_FL | \
FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NODUMP_FL | FS_NOATIME_FL |\
FS_COMPRBLK_FL | FS_NOCOMP_FL | FS_NOTAIL_FL | FS_DIRSYNC_FL)
/* Mask out flags that are inappropriate for the given type of inode. */
static inline __u32 nilfs_mask_flags(umode_t mode, __u32 flags)
{
if (S_ISDIR(mode))
return flags;
else if (S_ISREG(mode))
return flags & ~(FS_DIRSYNC_FL | FS_TOPDIR_FL);
else
return flags & (FS_NODUMP_FL | FS_NOATIME_FL);
}
/* dir.c */ /* dir.c */
extern int nilfs_add_link(struct dentry *, struct inode *); extern int nilfs_add_link(struct dentry *, struct inode *);
extern ino_t nilfs_inode_by_name(struct inode *, const struct qstr *); extern ino_t nilfs_inode_by_name(struct inode *, const struct qstr *);
...@@ -229,10 +245,13 @@ extern int nilfs_sync_file(struct file *, int); ...@@ -229,10 +245,13 @@ extern int nilfs_sync_file(struct file *, int);
/* ioctl.c */ /* ioctl.c */
long nilfs_ioctl(struct file *, unsigned int, unsigned long); long nilfs_ioctl(struct file *, unsigned int, unsigned long);
long nilfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, struct nilfs_argv *, int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, struct nilfs_argv *,
void **); void **);
/* inode.c */ /* inode.c */
void nilfs_inode_add_blocks(struct inode *inode, int n);
void nilfs_inode_sub_blocks(struct inode *inode, int n);
extern struct inode *nilfs_new_inode(struct inode *, int); extern struct inode *nilfs_new_inode(struct inode *, int);
extern void nilfs_free_inode(struct inode *); extern void nilfs_free_inode(struct inode *);
extern int nilfs_get_block(struct inode *, sector_t, struct buffer_head *, int); extern int nilfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
...@@ -275,11 +294,11 @@ extern int nilfs_check_feature_compatibility(struct super_block *, ...@@ -275,11 +294,11 @@ extern int nilfs_check_feature_compatibility(struct super_block *,
struct nilfs_super_block *); struct nilfs_super_block *);
extern void nilfs_set_log_cursor(struct nilfs_super_block *, extern void nilfs_set_log_cursor(struct nilfs_super_block *,
struct the_nilfs *); struct the_nilfs *);
extern struct nilfs_super_block **nilfs_prepare_super(struct nilfs_sb_info *, struct nilfs_super_block **nilfs_prepare_super(struct super_block *sb,
int flip); int flip);
extern int nilfs_commit_super(struct nilfs_sb_info *, int); int nilfs_commit_super(struct super_block *sb, int flag);
extern int nilfs_cleanup_super(struct nilfs_sb_info *); int nilfs_cleanup_super(struct super_block *sb);
int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, int nilfs_attach_checkpoint(struct super_block *sb, __u64 cno, int curr_mnt,
struct nilfs_root **root); struct nilfs_root **root);
int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno); int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno);
......
...@@ -425,7 +425,7 @@ void nilfs_dispose_segment_list(struct list_head *head) ...@@ -425,7 +425,7 @@ void nilfs_dispose_segment_list(struct list_head *head)
} }
static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
struct nilfs_sb_info *sbi, struct super_block *sb,
struct nilfs_recovery_info *ri) struct nilfs_recovery_info *ri)
{ {
struct list_head *head = &ri->ri_used_segments; struct list_head *head = &ri->ri_used_segments;
...@@ -501,7 +501,7 @@ static int nilfs_recovery_copy_block(struct the_nilfs *nilfs, ...@@ -501,7 +501,7 @@ static int nilfs_recovery_copy_block(struct the_nilfs *nilfs,
} }
static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs,
struct nilfs_sb_info *sbi, struct super_block *sb,
struct nilfs_root *root, struct nilfs_root *root,
struct list_head *head, struct list_head *head,
unsigned long *nr_salvaged_blocks) unsigned long *nr_salvaged_blocks)
...@@ -514,7 +514,7 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, ...@@ -514,7 +514,7 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs,
int err = 0, err2 = 0; int err = 0, err2 = 0;
list_for_each_entry_safe(rb, n, head, list) { list_for_each_entry_safe(rb, n, head, list) {
inode = nilfs_iget(sbi->s_super, root, rb->ino); inode = nilfs_iget(sb, root, rb->ino);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
err = PTR_ERR(inode); err = PTR_ERR(inode);
inode = NULL; inode = NULL;
...@@ -572,11 +572,11 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, ...@@ -572,11 +572,11 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs,
* nilfs_do_roll_forward - salvage logical segments newer than the latest * nilfs_do_roll_forward - salvage logical segments newer than the latest
* checkpoint * checkpoint
* @nilfs: nilfs object * @nilfs: nilfs object
* @sbi: nilfs_sb_info * @sb: super block instance
* @ri: pointer to a nilfs_recovery_info * @ri: pointer to a nilfs_recovery_info
*/ */
static int nilfs_do_roll_forward(struct the_nilfs *nilfs, static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
struct nilfs_sb_info *sbi, struct super_block *sb,
struct nilfs_root *root, struct nilfs_root *root,
struct nilfs_recovery_info *ri) struct nilfs_recovery_info *ri)
{ {
...@@ -648,7 +648,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs, ...@@ -648,7 +648,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
goto failed; goto failed;
if (flags & NILFS_SS_LOGEND) { if (flags & NILFS_SS_LOGEND) {
err = nilfs_recover_dsync_blocks( err = nilfs_recover_dsync_blocks(
nilfs, sbi, root, &dsync_blocks, nilfs, sb, root, &dsync_blocks,
&nsalvaged_blocks); &nsalvaged_blocks);
if (unlikely(err)) if (unlikely(err))
goto failed; goto failed;
...@@ -681,7 +681,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs, ...@@ -681,7 +681,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
if (nsalvaged_blocks) { if (nsalvaged_blocks) {
printk(KERN_INFO "NILFS (device %s): salvaged %lu blocks\n", printk(KERN_INFO "NILFS (device %s): salvaged %lu blocks\n",
sbi->s_super->s_id, nsalvaged_blocks); sb->s_id, nsalvaged_blocks);
ri->ri_need_recovery = NILFS_RECOVERY_ROLLFORWARD_DONE; ri->ri_need_recovery = NILFS_RECOVERY_ROLLFORWARD_DONE;
} }
out: out:
...@@ -695,7 +695,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs, ...@@ -695,7 +695,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
printk(KERN_ERR printk(KERN_ERR
"NILFS (device %s): Error roll-forwarding " "NILFS (device %s): Error roll-forwarding "
"(err=%d, pseg block=%llu). ", "(err=%d, pseg block=%llu). ",
sbi->s_super->s_id, err, (unsigned long long)pseg_start); sb->s_id, err, (unsigned long long)pseg_start);
goto out; goto out;
} }
...@@ -724,7 +724,7 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs, ...@@ -724,7 +724,7 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs,
/** /**
* nilfs_salvage_orphan_logs - salvage logs written after the latest checkpoint * nilfs_salvage_orphan_logs - salvage logs written after the latest checkpoint
* @nilfs: nilfs object * @nilfs: nilfs object
* @sbi: nilfs_sb_info * @sb: super block instance
* @ri: pointer to a nilfs_recovery_info struct to store search results. * @ri: pointer to a nilfs_recovery_info struct to store search results.
* *
* Return Value: On success, 0 is returned. On error, one of the following * Return Value: On success, 0 is returned. On error, one of the following
...@@ -741,7 +741,7 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs, ...@@ -741,7 +741,7 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs,
* %-ENOMEM - Insufficient memory available. * %-ENOMEM - Insufficient memory available.
*/ */
int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs, int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
struct nilfs_sb_info *sbi, struct super_block *sb,
struct nilfs_recovery_info *ri) struct nilfs_recovery_info *ri)
{ {
struct nilfs_root *root; struct nilfs_root *root;
...@@ -750,32 +750,32 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs, ...@@ -750,32 +750,32 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
if (ri->ri_lsegs_start == 0 || ri->ri_lsegs_end == 0) if (ri->ri_lsegs_start == 0 || ri->ri_lsegs_end == 0)
return 0; return 0;
err = nilfs_attach_checkpoint(sbi, ri->ri_cno, true, &root); err = nilfs_attach_checkpoint(sb, ri->ri_cno, true, &root);
if (unlikely(err)) { if (unlikely(err)) {
printk(KERN_ERR printk(KERN_ERR
"NILFS: error loading the latest checkpoint.\n"); "NILFS: error loading the latest checkpoint.\n");
return err; return err;
} }
err = nilfs_do_roll_forward(nilfs, sbi, root, ri); err = nilfs_do_roll_forward(nilfs, sb, root, ri);
if (unlikely(err)) if (unlikely(err))
goto failed; goto failed;
if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) { if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) {
err = nilfs_prepare_segment_for_recovery(nilfs, sbi, ri); err = nilfs_prepare_segment_for_recovery(nilfs, sb, ri);
if (unlikely(err)) { if (unlikely(err)) {
printk(KERN_ERR "NILFS: Error preparing segments for " printk(KERN_ERR "NILFS: Error preparing segments for "
"recovery.\n"); "recovery.\n");
goto failed; goto failed;
} }
err = nilfs_attach_segment_constructor(sbi, root); err = nilfs_attach_log_writer(sb, root);
if (unlikely(err)) if (unlikely(err))
goto failed; goto failed;
set_nilfs_discontinued(nilfs); set_nilfs_discontinued(nilfs);
err = nilfs_construct_segment(sbi->s_super); err = nilfs_construct_segment(sb);
nilfs_detach_segment_constructor(sbi); nilfs_detach_log_writer(sb);
if (unlikely(err)) { if (unlikely(err)) {
printk(KERN_ERR "NILFS: Oops! recovery failed. " printk(KERN_ERR "NILFS: Oops! recovery failed. "
......
/*
* sb.h - NILFS on-memory super block structure.
*
* Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Written by Ryusuke Konishi <ryusuke@osrg.net>
*
*/
#ifndef _NILFS_SB
#define _NILFS_SB
#include <linux/types.h>
#include <linux/fs.h>
struct the_nilfs;
struct nilfs_sc_info;
/*
* NILFS super-block data in memory
*/
struct nilfs_sb_info {
/* Mount options */
unsigned long s_mount_opt;
uid_t s_resuid;
gid_t s_resgid;
unsigned long s_interval; /* construction interval */
unsigned long s_watermark; /* threshold of data amount
for the segment construction */
/* Fundamental members */
struct super_block *s_super; /* reverse pointer to super_block */
struct the_nilfs *s_nilfs;
/* Segment constructor */
struct list_head s_dirty_files; /* dirty files list */
struct nilfs_sc_info *s_sc_info; /* segment constructor info */
spinlock_t s_inode_lock; /* Lock for the nilfs inode.
It covers s_dirty_files list */
/* Inode allocator */
spinlock_t s_next_gen_lock;
u32 s_next_generation;
};
static inline struct nilfs_sb_info *NILFS_SB(struct super_block *sb)
{
return sb->s_fs_info;
}
static inline struct nilfs_sc_info *NILFS_SC(struct nilfs_sb_info *sbi)
{
return sbi->s_sc_info;
}
/*
* Bit operations for the mount option
*/
#define nilfs_clear_opt(sbi, opt) \
do { (sbi)->s_mount_opt &= ~NILFS_MOUNT_##opt; } while (0)
#define nilfs_set_opt(sbi, opt) \
do { (sbi)->s_mount_opt |= NILFS_MOUNT_##opt; } while (0)
#define nilfs_test_opt(sbi, opt) ((sbi)->s_mount_opt & NILFS_MOUNT_##opt)
#define nilfs_write_opt(sbi, mask, opt) \
do { (sbi)->s_mount_opt = \
(((sbi)->s_mount_opt & ~NILFS_MOUNT_##mask) | \
NILFS_MOUNT_##opt); \
} while (0)
#endif /* _NILFS_SB */
This diff is collapsed.
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/nilfs2_fs.h> #include <linux/nilfs2_fs.h>
#include "sb.h" #include "nilfs.h"
struct nilfs_root; struct nilfs_root;
...@@ -88,7 +88,6 @@ struct nilfs_segsum_pointer { ...@@ -88,7 +88,6 @@ struct nilfs_segsum_pointer {
/** /**
* struct nilfs_sc_info - Segment constructor information * struct nilfs_sc_info - Segment constructor information
* @sc_super: Back pointer to super_block struct * @sc_super: Back pointer to super_block struct
* @sc_sbi: Back pointer to nilfs_sb_info struct
* @sc_root: root object of the current filesystem tree * @sc_root: root object of the current filesystem tree
* @sc_nblk_inc: Block count of current generation * @sc_nblk_inc: Block count of current generation
* @sc_dirty_files: List of files to be written * @sc_dirty_files: List of files to be written
...@@ -131,7 +130,6 @@ struct nilfs_segsum_pointer { ...@@ -131,7 +130,6 @@ struct nilfs_segsum_pointer {
*/ */
struct nilfs_sc_info { struct nilfs_sc_info {
struct super_block *sc_super; struct super_block *sc_super;
struct nilfs_sb_info *sc_sbi;
struct nilfs_root *sc_root; struct nilfs_root *sc_root;
unsigned long sc_nblk_inc; unsigned long sc_nblk_inc;
...@@ -235,18 +233,16 @@ extern void nilfs_flush_segment(struct super_block *, ino_t); ...@@ -235,18 +233,16 @@ extern void nilfs_flush_segment(struct super_block *, ino_t);
extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *, extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *,
void **); void **);
int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi, int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root);
struct nilfs_root *root); void nilfs_detach_log_writer(struct super_block *sb);
extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *);
/* recovery.c */ /* recovery.c */
extern int nilfs_read_super_root_block(struct the_nilfs *, sector_t, extern int nilfs_read_super_root_block(struct the_nilfs *, sector_t,
struct buffer_head **, int); struct buffer_head **, int);
extern int nilfs_search_super_root(struct the_nilfs *, extern int nilfs_search_super_root(struct the_nilfs *,
struct nilfs_recovery_info *); struct nilfs_recovery_info *);
extern int nilfs_salvage_orphan_logs(struct the_nilfs *, int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs, struct super_block *sb,
struct nilfs_sb_info *, struct nilfs_recovery_info *ri);
struct nilfs_recovery_info *);
extern void nilfs_dispose_segment_list(struct list_head *); extern void nilfs_dispose_segment_list(struct list_head *);
#endif /* _NILFS_SEGMENT_H */ #endif /* _NILFS_SEGMENT_H */
This diff is collapsed.
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/random.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include "nilfs.h" #include "nilfs.h"
#include "segment.h" #include "segment.h"
...@@ -75,7 +76,10 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev) ...@@ -75,7 +76,10 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev)
nilfs->ns_bdev = bdev; nilfs->ns_bdev = bdev;
atomic_set(&nilfs->ns_ndirtyblks, 0); atomic_set(&nilfs->ns_ndirtyblks, 0);
init_rwsem(&nilfs->ns_sem); init_rwsem(&nilfs->ns_sem);
INIT_LIST_HEAD(&nilfs->ns_dirty_files);
INIT_LIST_HEAD(&nilfs->ns_gc_inodes); INIT_LIST_HEAD(&nilfs->ns_gc_inodes);
spin_lock_init(&nilfs->ns_inode_lock);
spin_lock_init(&nilfs->ns_next_gen_lock);
spin_lock_init(&nilfs->ns_last_segment_lock); spin_lock_init(&nilfs->ns_last_segment_lock);
nilfs->ns_cptree = RB_ROOT; nilfs->ns_cptree = RB_ROOT;
spin_lock_init(&nilfs->ns_cptree_lock); spin_lock_init(&nilfs->ns_cptree_lock);
...@@ -197,16 +201,16 @@ static int nilfs_store_log_cursor(struct the_nilfs *nilfs, ...@@ -197,16 +201,16 @@ static int nilfs_store_log_cursor(struct the_nilfs *nilfs,
/** /**
* load_nilfs - load and recover the nilfs * load_nilfs - load and recover the nilfs
* @nilfs: the_nilfs structure to be released * @nilfs: the_nilfs structure to be released
* @sbi: nilfs_sb_info used to recover past segment * @sb: super block isntance used to recover past segment
* *
* load_nilfs() searches and load the latest super root, * load_nilfs() searches and load the latest super root,
* attaches the last segment, and does recovery if needed. * attaches the last segment, and does recovery if needed.
* The caller must call this exclusively for simultaneous mounts. * The caller must call this exclusively for simultaneous mounts.
*/ */
int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
{ {
struct nilfs_recovery_info ri; struct nilfs_recovery_info ri;
unsigned int s_flags = sbi->s_super->s_flags; unsigned int s_flags = sb->s_flags;
int really_read_only = bdev_read_only(nilfs->ns_bdev); int really_read_only = bdev_read_only(nilfs->ns_bdev);
int valid_fs = nilfs_valid_fs(nilfs); int valid_fs = nilfs_valid_fs(nilfs);
int err; int err;
...@@ -271,7 +275,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) ...@@ -271,7 +275,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
goto scan_error; goto scan_error;
} }
err = nilfs_load_super_root(nilfs, sbi->s_super, ri.ri_super_root); err = nilfs_load_super_root(nilfs, sb, ri.ri_super_root);
if (unlikely(err)) { if (unlikely(err)) {
printk(KERN_ERR "NILFS: error loading super root.\n"); printk(KERN_ERR "NILFS: error loading super root.\n");
goto failed; goto failed;
...@@ -283,7 +287,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) ...@@ -283,7 +287,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
if (s_flags & MS_RDONLY) { if (s_flags & MS_RDONLY) {
__u64 features; __u64 features;
if (nilfs_test_opt(sbi, NORECOVERY)) { if (nilfs_test_opt(nilfs, NORECOVERY)) {
printk(KERN_INFO "NILFS: norecovery option specified. " printk(KERN_INFO "NILFS: norecovery option specified. "
"skipping roll-forward recovery\n"); "skipping roll-forward recovery\n");
goto skip_recovery; goto skip_recovery;
...@@ -304,21 +308,21 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) ...@@ -304,21 +308,21 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
err = -EROFS; err = -EROFS;
goto failed_unload; goto failed_unload;
} }
sbi->s_super->s_flags &= ~MS_RDONLY; sb->s_flags &= ~MS_RDONLY;
} else if (nilfs_test_opt(sbi, NORECOVERY)) { } else if (nilfs_test_opt(nilfs, NORECOVERY)) {
printk(KERN_ERR "NILFS: recovery cancelled because norecovery " printk(KERN_ERR "NILFS: recovery cancelled because norecovery "
"option was specified for a read/write mount\n"); "option was specified for a read/write mount\n");
err = -EINVAL; err = -EINVAL;
goto failed_unload; goto failed_unload;
} }
err = nilfs_salvage_orphan_logs(nilfs, sbi, &ri); err = nilfs_salvage_orphan_logs(nilfs, sb, &ri);
if (err) if (err)
goto failed_unload; goto failed_unload;
down_write(&nilfs->ns_sem); down_write(&nilfs->ns_sem);
nilfs->ns_mount_state |= NILFS_VALID_FS; /* set "clean" flag */ nilfs->ns_mount_state |= NILFS_VALID_FS; /* set "clean" flag */
err = nilfs_cleanup_super(sbi); err = nilfs_cleanup_super(sb);
up_write(&nilfs->ns_sem); up_write(&nilfs->ns_sem);
if (err) { if (err) {
...@@ -330,7 +334,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) ...@@ -330,7 +334,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
skip_recovery: skip_recovery:
nilfs_clear_recovery_info(&ri); nilfs_clear_recovery_info(&ri);
sbi->s_super->s_flags = s_flags; sb->s_flags = s_flags;
return 0; return 0;
scan_error: scan_error:
...@@ -344,7 +348,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) ...@@ -344,7 +348,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
failed: failed:
nilfs_clear_recovery_info(&ri); nilfs_clear_recovery_info(&ri);
sbi->s_super->s_flags = s_flags; sb->s_flags = s_flags;
return err; return err;
} }
...@@ -475,10 +479,13 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, ...@@ -475,10 +479,13 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs,
return -EIO; return -EIO;
} }
printk(KERN_WARNING printk(KERN_WARNING
"NILFS warning: unable to read primary superblock\n"); "NILFS warning: unable to read primary superblock "
} else if (!sbp[1]) "(blocksize = %d)\n", blocksize);
} else if (!sbp[1]) {
printk(KERN_WARNING printk(KERN_WARNING
"NILFS warning: unable to read secondary superblock\n"); "NILFS warning: unable to read secondary superblock "
"(blocksize = %d)\n", blocksize);
}
/* /*
* Compare two super blocks and set 1 in swp if the secondary * Compare two super blocks and set 1 in swp if the secondary
...@@ -505,7 +512,7 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, ...@@ -505,7 +512,7 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs,
if (!valid[!swp]) if (!valid[!swp])
printk(KERN_WARNING "NILFS warning: broken superblock. " printk(KERN_WARNING "NILFS warning: broken superblock. "
"using spare superblock.\n"); "using spare superblock (blocksize = %d).\n", blocksize);
if (swp) if (swp)
nilfs_swap_super_block(nilfs); nilfs_swap_super_block(nilfs);
...@@ -519,7 +526,6 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, ...@@ -519,7 +526,6 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs,
/** /**
* init_nilfs - initialize a NILFS instance. * init_nilfs - initialize a NILFS instance.
* @nilfs: the_nilfs structure * @nilfs: the_nilfs structure
* @sbi: nilfs_sb_info
* @sb: super block * @sb: super block
* @data: mount options * @data: mount options
* *
...@@ -530,9 +536,8 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, ...@@ -530,9 +536,8 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs,
* Return Value: On success, 0 is returned. On error, a negative error * Return Value: On success, 0 is returned. On error, a negative error
* code is returned. * code is returned.
*/ */
int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data) int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
{ {
struct super_block *sb = sbi->s_super;
struct nilfs_super_block *sbp; struct nilfs_super_block *sbp;
int blocksize; int blocksize;
int err; int err;
...@@ -588,6 +593,9 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data) ...@@ -588,6 +593,9 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
nilfs->ns_blocksize_bits = sb->s_blocksize_bits; nilfs->ns_blocksize_bits = sb->s_blocksize_bits;
nilfs->ns_blocksize = blocksize; nilfs->ns_blocksize = blocksize;
get_random_bytes(&nilfs->ns_next_generation,
sizeof(nilfs->ns_next_generation));
err = nilfs_store_disk_layout(nilfs, sbp); err = nilfs_store_disk_layout(nilfs, sbp);
if (err) if (err)
goto failed_sbh; goto failed_sbh;
......
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "sb.h"
struct nilfs_sc_info;
/* the_nilfs struct */ /* the_nilfs struct */
enum { enum {
...@@ -65,13 +66,23 @@ enum { ...@@ -65,13 +66,23 @@ enum {
* @ns_last_cno: checkpoint number of the latest segment * @ns_last_cno: checkpoint number of the latest segment
* @ns_prot_seq: least sequence number of segments which must not be reclaimed * @ns_prot_seq: least sequence number of segments which must not be reclaimed
* @ns_prev_seq: base sequence number used to decide if advance log cursor * @ns_prev_seq: base sequence number used to decide if advance log cursor
* @ns_segctor_sem: segment constructor semaphore * @ns_writer: log writer
* @ns_segctor_sem: semaphore protecting log write
* @ns_dat: DAT file inode * @ns_dat: DAT file inode
* @ns_cpfile: checkpoint file inode * @ns_cpfile: checkpoint file inode
* @ns_sufile: segusage file inode * @ns_sufile: segusage file inode
* @ns_cptree: rb-tree of all mounted checkpoints (nilfs_root) * @ns_cptree: rb-tree of all mounted checkpoints (nilfs_root)
* @ns_cptree_lock: lock protecting @ns_cptree * @ns_cptree_lock: lock protecting @ns_cptree
* @ns_dirty_files: list of dirty files
* @ns_inode_lock: lock protecting @ns_dirty_files
* @ns_gc_inodes: dummy inodes to keep live blocks * @ns_gc_inodes: dummy inodes to keep live blocks
* @ns_next_generation: next generation number for inodes
* @ns_next_gen_lock: lock protecting @ns_next_generation
* @ns_mount_opt: mount options
* @ns_resuid: uid for reserved blocks
* @ns_resgid: gid for reserved blocks
* @ns_interval: checkpoint creation interval
* @ns_watermark: watermark for the number of dirty buffers
* @ns_blocksize_bits: bit length of block size * @ns_blocksize_bits: bit length of block size
* @ns_blocksize: block size * @ns_blocksize: block size
* @ns_nsegments: number of segments in filesystem * @ns_nsegments: number of segments in filesystem
...@@ -131,6 +142,7 @@ struct the_nilfs { ...@@ -131,6 +142,7 @@ struct the_nilfs {
u64 ns_prot_seq; u64 ns_prot_seq;
u64 ns_prev_seq; u64 ns_prev_seq;
struct nilfs_sc_info *ns_writer;
struct rw_semaphore ns_segctor_sem; struct rw_semaphore ns_segctor_sem;
/* /*
...@@ -145,9 +157,25 @@ struct the_nilfs { ...@@ -145,9 +157,25 @@ struct the_nilfs {
struct rb_root ns_cptree; struct rb_root ns_cptree;
spinlock_t ns_cptree_lock; spinlock_t ns_cptree_lock;
/* Dirty inode list */
struct list_head ns_dirty_files;
spinlock_t ns_inode_lock;
/* GC inode list */ /* GC inode list */
struct list_head ns_gc_inodes; struct list_head ns_gc_inodes;
/* Inode allocator */
u32 ns_next_generation;
spinlock_t ns_next_gen_lock;
/* Mount options */
unsigned long ns_mount_opt;
uid_t ns_resuid;
gid_t ns_resgid;
unsigned long ns_interval;
unsigned long ns_watermark;
/* Disk layout information (static) */ /* Disk layout information (static) */
unsigned int ns_blocksize_bits; unsigned int ns_blocksize_bits;
unsigned int ns_blocksize; unsigned int ns_blocksize;
...@@ -180,6 +208,20 @@ THE_NILFS_FNS(DISCONTINUED, discontinued) ...@@ -180,6 +208,20 @@ THE_NILFS_FNS(DISCONTINUED, discontinued)
THE_NILFS_FNS(GC_RUNNING, gc_running) THE_NILFS_FNS(GC_RUNNING, gc_running)
THE_NILFS_FNS(SB_DIRTY, sb_dirty) THE_NILFS_FNS(SB_DIRTY, sb_dirty)
/*
* Mount option operations
*/
#define nilfs_clear_opt(nilfs, opt) \
do { (nilfs)->ns_mount_opt &= ~NILFS_MOUNT_##opt; } while (0)
#define nilfs_set_opt(nilfs, opt) \
do { (nilfs)->ns_mount_opt |= NILFS_MOUNT_##opt; } while (0)
#define nilfs_test_opt(nilfs, opt) ((nilfs)->ns_mount_opt & NILFS_MOUNT_##opt)
#define nilfs_write_opt(nilfs, mask, opt) \
do { (nilfs)->ns_mount_opt = \
(((nilfs)->ns_mount_opt & ~NILFS_MOUNT_##mask) | \
NILFS_MOUNT_##opt); \
} while (0)
/** /**
* struct nilfs_root - nilfs root object * struct nilfs_root - nilfs root object
* @cno: checkpoint number * @cno: checkpoint number
...@@ -224,15 +266,14 @@ static inline int nilfs_sb_will_flip(struct the_nilfs *nilfs) ...@@ -224,15 +266,14 @@ static inline int nilfs_sb_will_flip(struct the_nilfs *nilfs)
void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64); void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64);
struct the_nilfs *alloc_nilfs(struct block_device *bdev); struct the_nilfs *alloc_nilfs(struct block_device *bdev);
void destroy_nilfs(struct the_nilfs *nilfs); void destroy_nilfs(struct the_nilfs *nilfs);
int init_nilfs(struct the_nilfs *, struct nilfs_sb_info *, char *); int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data);
int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *); int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb);
int nilfs_discard_segments(struct the_nilfs *, __u64 *, size_t); int nilfs_discard_segments(struct the_nilfs *, __u64 *, size_t);
int nilfs_count_free_blocks(struct the_nilfs *, sector_t *); int nilfs_count_free_blocks(struct the_nilfs *, sector_t *);
struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno); struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno);
struct nilfs_root *nilfs_find_or_create_root(struct the_nilfs *nilfs, struct nilfs_root *nilfs_find_or_create_root(struct the_nilfs *nilfs,
__u64 cno); __u64 cno);
void nilfs_put_root(struct nilfs_root *root); void nilfs_put_root(struct nilfs_root *root);
struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *, int, __u64);
int nilfs_near_disk_full(struct the_nilfs *); int nilfs_near_disk_full(struct the_nilfs *);
void nilfs_fall_back_super_block(struct the_nilfs *); void nilfs_fall_back_super_block(struct the_nilfs *);
void nilfs_swap_super_block(struct the_nilfs *); void nilfs_swap_super_block(struct the_nilfs *);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#define XENFS_SUPER_MAGIC 0xabba1974 #define XENFS_SUPER_MAGIC 0xabba1974
#define EXT4_SUPER_MAGIC 0xEF53 #define EXT4_SUPER_MAGIC 0xEF53
#define BTRFS_SUPER_MAGIC 0x9123683E #define BTRFS_SUPER_MAGIC 0x9123683E
#define NILFS_SUPER_MAGIC 0x3434
#define HPFS_SUPER_MAGIC 0xf995e849 #define HPFS_SUPER_MAGIC 0xf995e849
#define ISOFS_SUPER_MAGIC 0x9660 #define ISOFS_SUPER_MAGIC 0x9660
#define JFFS2_SUPER_MAGIC 0x72b6 #define JFFS2_SUPER_MAGIC 0x72b6
......
...@@ -40,26 +40,7 @@ ...@@ -40,26 +40,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/magic.h>
/*
* Inode flags stored in nilfs_inode and on-memory nilfs inode
*
* We define these flags based on ext2-fs because of the
* compatibility reason; to avoid problems in chattr(1)
*/
#define NILFS_SECRM_FL 0x00000001 /* Secure deletion */
#define NILFS_UNRM_FL 0x00000002 /* Undelete */
#define NILFS_SYNC_FL 0x00000008 /* Synchronous updates */
#define NILFS_IMMUTABLE_FL 0x00000010 /* Immutable file */
#define NILFS_APPEND_FL 0x00000020 /* writes to file may only append */
#define NILFS_NODUMP_FL 0x00000040 /* do not dump file */
#define NILFS_NOATIME_FL 0x00000080 /* do not update atime */
/* Reserved for compression usage... */
#define NILFS_NOTAIL_FL 0x00008000 /* file tail should not be merged */
#define NILFS_DIRSYNC_FL 0x00010000 /* dirsync behaviour */
#define NILFS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
#define NILFS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
#define NILFS_INODE_BMAP_SIZE 7 #define NILFS_INODE_BMAP_SIZE 7
...@@ -236,8 +217,10 @@ struct nilfs_super_block { ...@@ -236,8 +217,10 @@ struct nilfs_super_block {
* If there is a bit set in the incompatible feature set that the kernel * If there is a bit set in the incompatible feature set that the kernel
* doesn't know about, it should refuse to mount the filesystem. * doesn't know about, it should refuse to mount the filesystem.
*/ */
#define NILFS_FEATURE_COMPAT_RO_BLOCK_COUNT 0x00000001ULL
#define NILFS_FEATURE_COMPAT_SUPP 0ULL #define NILFS_FEATURE_COMPAT_SUPP 0ULL
#define NILFS_FEATURE_COMPAT_RO_SUPP 0ULL #define NILFS_FEATURE_COMPAT_RO_SUPP NILFS_FEATURE_COMPAT_RO_BLOCK_COUNT
#define NILFS_FEATURE_INCOMPAT_SUPP 0ULL #define NILFS_FEATURE_INCOMPAT_SUPP 0ULL
/* /*
...@@ -260,7 +243,6 @@ struct nilfs_super_block { ...@@ -260,7 +243,6 @@ struct nilfs_super_block {
#define NILFS_USER_INO 11 /* Fisrt user's file inode number */ #define NILFS_USER_INO 11 /* Fisrt user's file inode number */
#define NILFS_SB_OFFSET_BYTES 1024 /* byte offset of nilfs superblock */ #define NILFS_SB_OFFSET_BYTES 1024 /* byte offset of nilfs superblock */
#define NILFS_SUPER_MAGIC 0x3434 /* NILFS filesystem magic number */
#define NILFS_SEG_MIN_BLOCKS 16 /* Minimum number of blocks in #define NILFS_SEG_MIN_BLOCKS 16 /* Minimum number of blocks in
a full segment */ a full segment */
...@@ -346,17 +328,21 @@ static inline unsigned nilfs_rec_len_from_disk(__le16 dlen) ...@@ -346,17 +328,21 @@ static inline unsigned nilfs_rec_len_from_disk(__le16 dlen)
{ {
unsigned len = le16_to_cpu(dlen); unsigned len = le16_to_cpu(dlen);
#if !defined(__KERNEL__) || (PAGE_CACHE_SIZE >= 65536)
if (len == NILFS_MAX_REC_LEN) if (len == NILFS_MAX_REC_LEN)
return 1 << 16; return 1 << 16;
#endif
return len; return len;
} }
static inline __le16 nilfs_rec_len_to_disk(unsigned len) static inline __le16 nilfs_rec_len_to_disk(unsigned len)
{ {
#if !defined(__KERNEL__) || (PAGE_CACHE_SIZE >= 65536)
if (len == (1 << 16)) if (len == (1 << 16))
return cpu_to_le16(NILFS_MAX_REC_LEN); return cpu_to_le16(NILFS_MAX_REC_LEN);
else if (len > (1 << 16)) else if (len > (1 << 16))
BUG(); BUG();
#endif
return cpu_to_le16(len); return cpu_to_le16(len);
} }
...@@ -525,7 +511,7 @@ struct nilfs_checkpoint { ...@@ -525,7 +511,7 @@ struct nilfs_checkpoint {
__le64 cp_create; __le64 cp_create;
__le64 cp_nblk_inc; __le64 cp_nblk_inc;
__le64 cp_inodes_count; __le64 cp_inodes_count;
__le64 cp_blocks_count; /* Reserved (might be deleted) */ __le64 cp_blocks_count;
/* Do not change the byte offset of ifile inode. /* Do not change the byte offset of ifile inode.
To keep the compatibility of the disk format, To keep the compatibility of the disk format,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment