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: fix possible mismatch of sufile counters on recovery nilfs2: segment usage file cleanups nilfs2: fix wrong accounting and duplicate brelse in nilfs_sufile_set_error nilfs2: simplify handling of active state of segments fix nilfs2: remove module version nilfs2: fix lockdep recursive locking warning on meta data files nilfs2: fix lockdep recursive locking warning on bmap nilfs2: return f_fsid for statfs2
This commit is contained in:
Коммит
9fc0178caa
|
@ -688,6 +688,8 @@ static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_gc = {
|
|||
.bpop_translate = NULL,
|
||||
};
|
||||
|
||||
static struct lock_class_key nilfs_bmap_dat_lock_key;
|
||||
|
||||
/**
|
||||
* nilfs_bmap_read - read a bmap from an inode
|
||||
* @bmap: bmap
|
||||
|
@ -715,6 +717,7 @@ int nilfs_bmap_read(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode)
|
|||
bmap->b_pops = &nilfs_bmap_ptr_ops_p;
|
||||
bmap->b_last_allocated_key = 0; /* XXX: use macro */
|
||||
bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT;
|
||||
lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
|
||||
break;
|
||||
case NILFS_CPFILE_INO:
|
||||
case NILFS_SUFILE_INO:
|
||||
|
@ -772,6 +775,7 @@ void nilfs_bmap_init_gcdat(struct nilfs_bmap *gcbmap, struct nilfs_bmap *bmap)
|
|||
{
|
||||
memcpy(gcbmap, bmap, sizeof(union nilfs_bmap_union));
|
||||
init_rwsem(&gcbmap->b_sem);
|
||||
lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
|
||||
gcbmap->b_inode = &NILFS_BMAP_I(gcbmap)->vfs_inode;
|
||||
}
|
||||
|
||||
|
@ -779,5 +783,6 @@ void nilfs_bmap_commit_gcdat(struct nilfs_bmap *gcbmap, struct nilfs_bmap *bmap)
|
|||
{
|
||||
memcpy(bmap, gcbmap, sizeof(union nilfs_bmap_union));
|
||||
init_rwsem(&bmap->b_sem);
|
||||
lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
|
||||
bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
|
||||
}
|
||||
|
|
|
@ -34,11 +34,6 @@
|
|||
#include "bmap.h"
|
||||
#include "bmap_union.h"
|
||||
|
||||
/*
|
||||
* NILFS filesystem version
|
||||
*/
|
||||
#define NILFS_VERSION "2.0.5"
|
||||
|
||||
/*
|
||||
* nilfs inode data in memory
|
||||
*/
|
||||
|
|
|
@ -413,7 +413,6 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
|
|||
struct nilfs_segment_entry *ent, *n;
|
||||
struct inode *sufile = nilfs->ns_sufile;
|
||||
__u64 segnum[4];
|
||||
time_t mtime;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
|
@ -442,24 +441,13 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
|
|||
* Collecting segments written after the latest super root.
|
||||
* These are marked dirty to avoid being reallocated in the next write.
|
||||
*/
|
||||
mtime = get_seconds();
|
||||
list_for_each_entry_safe(ent, n, head, list) {
|
||||
if (ent->segnum == segnum[0]) {
|
||||
list_del(&ent->list);
|
||||
nilfs_free_segment_entry(ent);
|
||||
continue;
|
||||
}
|
||||
err = nilfs_open_segment_entry(ent, sufile);
|
||||
if (unlikely(err))
|
||||
goto failed;
|
||||
if (!nilfs_segment_usage_dirty(ent->raw_su)) {
|
||||
/* make the segment garbage */
|
||||
ent->raw_su->su_nblocks = cpu_to_le32(0);
|
||||
ent->raw_su->su_lastmod = cpu_to_le32(mtime);
|
||||
nilfs_segment_usage_set_dirty(ent->raw_su);
|
||||
if (ent->segnum != segnum[0]) {
|
||||
err = nilfs_sufile_scrap(sufile, ent->segnum);
|
||||
if (unlikely(err))
|
||||
goto failed;
|
||||
}
|
||||
list_del(&ent->list);
|
||||
nilfs_close_segment_entry(ent, sufile);
|
||||
nilfs_free_segment_entry(ent);
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,52 @@ nilfs_sufile_get_segment_usage_block(struct inode *sufile, __u64 segnum,
|
|||
create, NULL, bhp);
|
||||
}
|
||||
|
||||
static void nilfs_sufile_mod_counter(struct buffer_head *header_bh,
|
||||
u64 ncleanadd, u64 ndirtyadd)
|
||||
{
|
||||
struct nilfs_sufile_header *header;
|
||||
void *kaddr;
|
||||
|
||||
kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
|
||||
header = kaddr + bh_offset(header_bh);
|
||||
le64_add_cpu(&header->sh_ncleansegs, ncleanadd);
|
||||
le64_add_cpu(&header->sh_ndirtysegs, ndirtyadd);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(header_bh);
|
||||
}
|
||||
|
||||
int nilfs_sufile_update(struct inode *sufile, __u64 segnum, int create,
|
||||
void (*dofunc)(struct inode *, __u64,
|
||||
struct buffer_head *,
|
||||
struct buffer_head *))
|
||||
{
|
||||
struct buffer_head *header_bh, *bh;
|
||||
int ret;
|
||||
|
||||
if (unlikely(segnum >= nilfs_sufile_get_nsegments(sufile))) {
|
||||
printk(KERN_WARNING "%s: invalid segment number: %llu\n",
|
||||
__func__, (unsigned long long)segnum);
|
||||
return -EINVAL;
|
||||
}
|
||||
down_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
|
||||
ret = nilfs_sufile_get_header_block(sufile, &header_bh);
|
||||
if (ret < 0)
|
||||
goto out_sem;
|
||||
|
||||
ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, create, &bh);
|
||||
if (!ret) {
|
||||
dofunc(sufile, segnum, header_bh, bh);
|
||||
brelse(bh);
|
||||
}
|
||||
brelse(header_bh);
|
||||
|
||||
out_sem:
|
||||
up_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_alloc - allocate a segment
|
||||
* @sufile: inode of segment usage file
|
||||
|
@ -113,7 +159,6 @@ nilfs_sufile_get_segment_usage_block(struct inode *sufile, __u64 segnum,
|
|||
int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
|
||||
{
|
||||
struct buffer_head *header_bh, *su_bh;
|
||||
struct the_nilfs *nilfs;
|
||||
struct nilfs_sufile_header *header;
|
||||
struct nilfs_segment_usage *su;
|
||||
size_t susz = NILFS_MDT(sufile)->mi_entry_size;
|
||||
|
@ -124,8 +169,6 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
|
|||
|
||||
down_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
|
||||
nilfs = NILFS_MDT(sufile)->mi_nilfs;
|
||||
|
||||
ret = nilfs_sufile_get_header_block(sufile, &header_bh);
|
||||
if (ret < 0)
|
||||
goto out_sem;
|
||||
|
@ -192,165 +235,84 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_cancel_free -
|
||||
* @sufile: inode of segment usage file
|
||||
* @segnum: segment number
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Return Value: On success, 0 is returned. On error, one of the following
|
||||
* negative error codes is returned.
|
||||
*
|
||||
* %-EIO - I/O error.
|
||||
*
|
||||
* %-ENOMEM - Insufficient amount of memory available.
|
||||
*/
|
||||
int nilfs_sufile_cancel_free(struct inode *sufile, __u64 segnum)
|
||||
void nilfs_sufile_do_cancel_free(struct inode *sufile, __u64 segnum,
|
||||
struct buffer_head *header_bh,
|
||||
struct buffer_head *su_bh)
|
||||
{
|
||||
struct buffer_head *header_bh, *su_bh;
|
||||
struct the_nilfs *nilfs;
|
||||
struct nilfs_sufile_header *header;
|
||||
struct nilfs_segment_usage *su;
|
||||
void *kaddr;
|
||||
int ret;
|
||||
|
||||
down_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
|
||||
nilfs = NILFS_MDT(sufile)->mi_nilfs;
|
||||
|
||||
ret = nilfs_sufile_get_header_block(sufile, &header_bh);
|
||||
if (ret < 0)
|
||||
goto out_sem;
|
||||
|
||||
ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &su_bh);
|
||||
if (ret < 0)
|
||||
goto out_header;
|
||||
|
||||
kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
|
||||
su = nilfs_sufile_block_get_segment_usage(
|
||||
sufile, segnum, su_bh, kaddr);
|
||||
su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
|
||||
if (unlikely(!nilfs_segment_usage_clean(su))) {
|
||||
printk(KERN_WARNING "%s: segment %llu must be clean\n",
|
||||
__func__, (unsigned long long)segnum);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
goto out_su_bh;
|
||||
return;
|
||||
}
|
||||
nilfs_segment_usage_set_dirty(su);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
|
||||
header = nilfs_sufile_block_get_header(sufile, header_bh, kaddr);
|
||||
le64_add_cpu(&header->sh_ncleansegs, -1);
|
||||
le64_add_cpu(&header->sh_ndirtysegs, 1);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(header_bh);
|
||||
nilfs_sufile_mod_counter(header_bh, -1, 1);
|
||||
nilfs_mdt_mark_buffer_dirty(su_bh);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
|
||||
out_su_bh:
|
||||
brelse(su_bh);
|
||||
out_header:
|
||||
brelse(header_bh);
|
||||
out_sem:
|
||||
up_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_freev - free segments
|
||||
* @sufile: inode of segment usage file
|
||||
* @segnum: array of segment numbers
|
||||
* @nsegs: number of segments
|
||||
*
|
||||
* Description: nilfs_sufile_freev() frees segments specified by @segnum and
|
||||
* @nsegs, which must have been returned by a previous call to
|
||||
* nilfs_sufile_alloc().
|
||||
*
|
||||
* Return Value: On success, 0 is returned. On error, one of the following
|
||||
* negative error codes is returned.
|
||||
*
|
||||
* %-EIO - I/O error.
|
||||
*
|
||||
* %-ENOMEM - Insufficient amount of memory available.
|
||||
*/
|
||||
#define NILFS_SUFILE_FREEV_PREALLOC 16
|
||||
int nilfs_sufile_freev(struct inode *sufile, __u64 *segnum, size_t nsegs)
|
||||
void nilfs_sufile_do_scrap(struct inode *sufile, __u64 segnum,
|
||||
struct buffer_head *header_bh,
|
||||
struct buffer_head *su_bh)
|
||||
{
|
||||
struct buffer_head *header_bh, **su_bh,
|
||||
*su_bh_prealloc[NILFS_SUFILE_FREEV_PREALLOC];
|
||||
struct the_nilfs *nilfs;
|
||||
struct nilfs_sufile_header *header;
|
||||
struct nilfs_segment_usage *su;
|
||||
void *kaddr;
|
||||
int ret, i;
|
||||
int clean, dirty;
|
||||
|
||||
down_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
|
||||
nilfs = NILFS_MDT(sufile)->mi_nilfs;
|
||||
|
||||
/* prepare resources */
|
||||
if (nsegs <= NILFS_SUFILE_FREEV_PREALLOC)
|
||||
su_bh = su_bh_prealloc;
|
||||
else {
|
||||
su_bh = kmalloc(sizeof(*su_bh) * nsegs, GFP_NOFS);
|
||||
if (su_bh == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto out_sem;
|
||||
}
|
||||
}
|
||||
|
||||
ret = nilfs_sufile_get_header_block(sufile, &header_bh);
|
||||
if (ret < 0)
|
||||
goto out_su_bh;
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
ret = nilfs_sufile_get_segment_usage_block(sufile, segnum[i],
|
||||
0, &su_bh[i]);
|
||||
if (ret < 0)
|
||||
goto out_bh;
|
||||
}
|
||||
|
||||
/* free segments */
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
kaddr = kmap_atomic(su_bh[i]->b_page, KM_USER0);
|
||||
su = nilfs_sufile_block_get_segment_usage(
|
||||
sufile, segnum[i], su_bh[i], kaddr);
|
||||
WARN_ON(nilfs_segment_usage_error(su));
|
||||
nilfs_segment_usage_set_clean(su);
|
||||
kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
|
||||
su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
|
||||
if (su->su_flags == cpu_to_le32(1UL << NILFS_SEGMENT_USAGE_DIRTY) &&
|
||||
su->su_nblocks == cpu_to_le32(0)) {
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
nilfs_mdt_mark_buffer_dirty(su_bh[i]);
|
||||
return;
|
||||
}
|
||||
kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
|
||||
header = nilfs_sufile_block_get_header(sufile, header_bh, kaddr);
|
||||
le64_add_cpu(&header->sh_ncleansegs, nsegs);
|
||||
le64_add_cpu(&header->sh_ndirtysegs, -(u64)nsegs);
|
||||
clean = nilfs_segment_usage_clean(su);
|
||||
dirty = nilfs_segment_usage_dirty(su);
|
||||
|
||||
/* make the segment garbage */
|
||||
su->su_lastmod = cpu_to_le64(0);
|
||||
su->su_nblocks = cpu_to_le32(0);
|
||||
su->su_flags = cpu_to_le32(1UL << NILFS_SEGMENT_USAGE_DIRTY);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
nilfs_mdt_mark_buffer_dirty(header_bh);
|
||||
|
||||
nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1);
|
||||
nilfs_mdt_mark_buffer_dirty(su_bh);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
|
||||
out_bh:
|
||||
for (i--; i >= 0; i--)
|
||||
brelse(su_bh[i]);
|
||||
brelse(header_bh);
|
||||
|
||||
out_su_bh:
|
||||
if (su_bh != su_bh_prealloc)
|
||||
kfree(su_bh);
|
||||
|
||||
out_sem:
|
||||
up_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_free -
|
||||
* @sufile:
|
||||
* @segnum:
|
||||
*/
|
||||
int nilfs_sufile_free(struct inode *sufile, __u64 segnum)
|
||||
void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum,
|
||||
struct buffer_head *header_bh,
|
||||
struct buffer_head *su_bh)
|
||||
{
|
||||
return nilfs_sufile_freev(sufile, &segnum, 1);
|
||||
struct nilfs_segment_usage *su;
|
||||
void *kaddr;
|
||||
int sudirty;
|
||||
|
||||
kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
|
||||
su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
|
||||
if (nilfs_segment_usage_clean(su)) {
|
||||
printk(KERN_WARNING "%s: segment %llu is already clean\n",
|
||||
__func__, (unsigned long long)segnum);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
return;
|
||||
}
|
||||
WARN_ON(nilfs_segment_usage_error(su));
|
||||
WARN_ON(!nilfs_segment_usage_dirty(su));
|
||||
|
||||
sudirty = nilfs_segment_usage_dirty(su);
|
||||
nilfs_segment_usage_set_clean(su);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
nilfs_mdt_mark_buffer_dirty(su_bh);
|
||||
|
||||
nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -500,72 +462,28 @@ int nilfs_sufile_get_ncleansegs(struct inode *sufile, unsigned long *nsegsp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_set_error - mark a segment as erroneous
|
||||
* @sufile: inode of segment usage file
|
||||
* @segnum: segment number
|
||||
*
|
||||
* Description: nilfs_sufile_set_error() marks the segment specified by
|
||||
* @segnum as erroneous. The error segment will never be used again.
|
||||
*
|
||||
* Return Value: On success, 0 is returned. On error, one of the following
|
||||
* negative error codes is returned.
|
||||
*
|
||||
* %-EIO - I/O error.
|
||||
*
|
||||
* %-ENOMEM - Insufficient amount of memory available.
|
||||
*
|
||||
* %-EINVAL - Invalid segment usage number.
|
||||
*/
|
||||
int nilfs_sufile_set_error(struct inode *sufile, __u64 segnum)
|
||||
void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum,
|
||||
struct buffer_head *header_bh,
|
||||
struct buffer_head *su_bh)
|
||||
{
|
||||
struct buffer_head *header_bh, *su_bh;
|
||||
struct nilfs_segment_usage *su;
|
||||
struct nilfs_sufile_header *header;
|
||||
void *kaddr;
|
||||
int ret;
|
||||
|
||||
if (unlikely(segnum >= nilfs_sufile_get_nsegments(sufile))) {
|
||||
printk(KERN_WARNING "%s: invalid segment number: %llu\n",
|
||||
__func__, (unsigned long long)segnum);
|
||||
return -EINVAL;
|
||||
}
|
||||
down_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
|
||||
ret = nilfs_sufile_get_header_block(sufile, &header_bh);
|
||||
if (ret < 0)
|
||||
goto out_sem;
|
||||
ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &su_bh);
|
||||
if (ret < 0)
|
||||
goto out_header;
|
||||
int suclean;
|
||||
|
||||
kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
|
||||
su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
|
||||
if (nilfs_segment_usage_error(su)) {
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
brelse(su_bh);
|
||||
goto out_header;
|
||||
return;
|
||||
}
|
||||
|
||||
suclean = nilfs_segment_usage_clean(su);
|
||||
nilfs_segment_usage_set_error(su);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
brelse(su_bh);
|
||||
|
||||
kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
|
||||
header = nilfs_sufile_block_get_header(sufile, header_bh, kaddr);
|
||||
le64_add_cpu(&header->sh_ndirtysegs, -1);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
nilfs_mdt_mark_buffer_dirty(header_bh);
|
||||
if (suclean)
|
||||
nilfs_sufile_mod_counter(header_bh, -1, 0);
|
||||
nilfs_mdt_mark_buffer_dirty(su_bh);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
brelse(su_bh);
|
||||
|
||||
out_header:
|
||||
brelse(header_bh);
|
||||
|
||||
out_sem:
|
||||
up_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -625,7 +543,7 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum,
|
|||
si[i + j].sui_nblocks = le32_to_cpu(su->su_nblocks);
|
||||
si[i + j].sui_flags = le32_to_cpu(su->su_flags) &
|
||||
~(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
|
||||
if (nilfs_segment_is_active(nilfs, segnum + i + j))
|
||||
if (nilfs_segment_is_active(nilfs, segnum + j))
|
||||
si[i + j].sui_flags |=
|
||||
(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
|
||||
}
|
||||
|
|
|
@ -36,9 +36,6 @@ static inline unsigned long nilfs_sufile_get_nsegments(struct inode *sufile)
|
|||
}
|
||||
|
||||
int nilfs_sufile_alloc(struct inode *, __u64 *);
|
||||
int nilfs_sufile_cancel_free(struct inode *, __u64);
|
||||
int nilfs_sufile_freev(struct inode *, __u64 *, size_t);
|
||||
int nilfs_sufile_free(struct inode *, __u64);
|
||||
int nilfs_sufile_get_segment_usage(struct inode *, __u64,
|
||||
struct nilfs_segment_usage **,
|
||||
struct buffer_head **);
|
||||
|
@ -46,9 +43,83 @@ void nilfs_sufile_put_segment_usage(struct inode *, __u64,
|
|||
struct buffer_head *);
|
||||
int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
|
||||
int nilfs_sufile_get_ncleansegs(struct inode *, unsigned long *);
|
||||
int nilfs_sufile_set_error(struct inode *, __u64);
|
||||
ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, struct nilfs_suinfo *,
|
||||
size_t);
|
||||
|
||||
int nilfs_sufile_update(struct inode *, __u64, int,
|
||||
void (*dofunc)(struct inode *, __u64,
|
||||
struct buffer_head *,
|
||||
struct buffer_head *));
|
||||
void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *,
|
||||
struct buffer_head *);
|
||||
void nilfs_sufile_do_scrap(struct inode *, __u64, struct buffer_head *,
|
||||
struct buffer_head *);
|
||||
void nilfs_sufile_do_free(struct inode *, __u64, struct buffer_head *,
|
||||
struct buffer_head *);
|
||||
void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *,
|
||||
struct buffer_head *);
|
||||
|
||||
/**
|
||||
* nilfs_sufile_cancel_free -
|
||||
* @sufile: inode of segment usage file
|
||||
* @segnum: segment number
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Return Value: On success, 0 is returned. On error, one of the following
|
||||
* negative error codes is returned.
|
||||
*
|
||||
* %-EIO - I/O error.
|
||||
*
|
||||
* %-ENOMEM - Insufficient amount of memory available.
|
||||
*/
|
||||
static inline int nilfs_sufile_cancel_free(struct inode *sufile, __u64 segnum)
|
||||
{
|
||||
return nilfs_sufile_update(sufile, segnum, 0,
|
||||
nilfs_sufile_do_cancel_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_scrap - make a segment garbage
|
||||
* @sufile: inode of segment usage file
|
||||
* @segnum: segment number to be freed
|
||||
*/
|
||||
static inline int nilfs_sufile_scrap(struct inode *sufile, __u64 segnum)
|
||||
{
|
||||
return nilfs_sufile_update(sufile, segnum, 1, nilfs_sufile_do_scrap);
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_free - free segment
|
||||
* @sufile: inode of segment usage file
|
||||
* @segnum: segment number to be freed
|
||||
*/
|
||||
static inline int nilfs_sufile_free(struct inode *sufile, __u64 segnum)
|
||||
{
|
||||
return nilfs_sufile_update(sufile, segnum, 0, nilfs_sufile_do_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_set_error - mark a segment as erroneous
|
||||
* @sufile: inode of segment usage file
|
||||
* @segnum: segment number
|
||||
*
|
||||
* Description: nilfs_sufile_set_error() marks the segment specified by
|
||||
* @segnum as erroneous. The error segment will never be used again.
|
||||
*
|
||||
* Return Value: On success, 0 is returned. On error, one of the following
|
||||
* negative error codes is returned.
|
||||
*
|
||||
* %-EIO - I/O error.
|
||||
*
|
||||
* %-ENOMEM - Insufficient amount of memory available.
|
||||
*
|
||||
* %-EINVAL - Invalid segment usage number.
|
||||
*/
|
||||
static inline int nilfs_sufile_set_error(struct inode *sufile, __u64 segnum)
|
||||
{
|
||||
return nilfs_sufile_update(sufile, segnum, 0,
|
||||
nilfs_sufile_do_set_error);
|
||||
}
|
||||
|
||||
#endif /* _NILFS_SUFILE_H */
|
||||
|
|
|
@ -63,7 +63,6 @@
|
|||
MODULE_AUTHOR("NTT Corp.");
|
||||
MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem "
|
||||
"(NILFS)");
|
||||
MODULE_VERSION(NILFS_VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int nilfs_remount(struct super_block *sb, int *flags, char *data);
|
||||
|
@ -476,11 +475,12 @@ static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|||
{
|
||||
struct super_block *sb = dentry->d_sb;
|
||||
struct nilfs_sb_info *sbi = NILFS_SB(sb);
|
||||
struct the_nilfs *nilfs = sbi->s_nilfs;
|
||||
u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
|
||||
unsigned long long blocks;
|
||||
unsigned long overhead;
|
||||
unsigned long nrsvblocks;
|
||||
sector_t nfreeblocks;
|
||||
struct the_nilfs *nilfs = sbi->s_nilfs;
|
||||
int err;
|
||||
|
||||
/*
|
||||
|
@ -514,6 +514,9 @@ static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|||
buf->f_files = atomic_read(&sbi->s_inodes_count);
|
||||
buf->f_ffree = 0; /* nilfs_count_free_inodes(sb); */
|
||||
buf->f_namelen = NILFS_NAME_LEN;
|
||||
buf->f_fsid.val[0] = (u32)id;
|
||||
buf->f_fsid.val[1] = (u32)(id >> 32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ void put_nilfs(struct the_nilfs *nilfs)
|
|||
static int nilfs_load_super_root(struct the_nilfs *nilfs,
|
||||
struct nilfs_sb_info *sbi, sector_t sr_block)
|
||||
{
|
||||
static struct lock_class_key dat_lock_key;
|
||||
struct buffer_head *bh_sr;
|
||||
struct nilfs_super_root *raw_sr;
|
||||
struct nilfs_super_block **sbp = nilfs->ns_sbp;
|
||||
|
@ -163,6 +164,9 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs,
|
|||
if (unlikely(err))
|
||||
goto failed_sufile;
|
||||
|
||||
lockdep_set_class(&NILFS_MDT(nilfs->ns_dat)->mi_sem, &dat_lock_key);
|
||||
lockdep_set_class(&NILFS_MDT(nilfs->ns_gc_dat)->mi_sem, &dat_lock_key);
|
||||
|
||||
nilfs_mdt_set_shadow(nilfs->ns_dat, nilfs->ns_gc_dat);
|
||||
nilfs_mdt_set_entry_size(nilfs->ns_cpfile, checkpoint_size,
|
||||
sizeof(struct nilfs_cpfile_header));
|
||||
|
|
Загрузка…
Ссылка в новой задаче