Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 147892
b: refs/heads/master
c: 6dd4740
h: refs/heads/master
v: v3
  • Loading branch information
Ryusuke Konishi authored and Al Viro committed Jun 12, 2009
1 parent 0f553ed commit 65dd485
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3f82ff55168e92859119bf348e9e0bd6714d2fea
refs/heads/master: 6dd4740662405a68bb229ac2b9e0aeaaf2188bf2
1 change: 1 addition & 0 deletions trunk/fs/nilfs2/sb.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct nilfs_sb_info {
struct super_block *s_super; /* reverse pointer to super_block */
struct the_nilfs *s_nilfs;
struct list_head s_list; /* list head for nilfs->ns_supers */
atomic_t s_count; /* reference count */

/* Segment constructor */
struct list_head s_dirty_files; /* dirty files list */
Expand Down
42 changes: 17 additions & 25 deletions trunk/fs/nilfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ static void nilfs_put_super(struct super_block *sb)
put_nilfs(sbi->s_nilfs);
sbi->s_super = NULL;
sb->s_fs_info = NULL;
kfree(sbi);
nilfs_put_sbinfo(sbi);

unlock_kernel();
}
Expand Down Expand Up @@ -785,6 +785,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
get_nilfs(nilfs);
sbi->s_nilfs = nilfs;
sbi->s_super = sb;
atomic_set(&sbi->s_count, 1);

err = init_nilfs(nilfs, sbi, (char *)data);
if (err)
Expand Down Expand Up @@ -902,7 +903,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
failed_sbi:
put_nilfs(nilfs);
sb->s_fs_info = NULL;
kfree(sbi);
nilfs_put_sbinfo(sbi);
return err;
}

Expand Down Expand Up @@ -1014,6 +1015,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)

struct nilfs_super_data {
struct block_device *bdev;
struct nilfs_sb_info *sbi;
__u64 cno;
int flags;
};
Expand Down Expand Up @@ -1071,27 +1073,8 @@ static int nilfs_set_bdev_super(struct super_block *s, void *data)
static int nilfs_test_bdev_super(struct super_block *s, void *data)
{
struct nilfs_super_data *sd = data;
int ret;

if (s->s_bdev != sd->bdev)
return 0;

if (!((s->s_flags | sd->flags) & MS_RDONLY))
return 1; /* Reuse an old R/W-mode super_block */

if (s->s_flags & sd->flags & MS_RDONLY) {
if (down_read_trylock(&s->s_umount)) {
ret = s->s_root &&
(sd->cno == NILFS_SB(s)->s_snapshot_cno);
up_read(&s->s_umount);
/*
* This path is locked with sb_lock by sget().
* So, drop_super() causes deadlock.
*/
return ret;
}
}
return 0;

return sd->sbi && s->s_fs_info == (void *)sd->sbi;
}

static int
Expand All @@ -1112,7 +1095,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
* much more information than normal filesystems to identify mount
* instance. For snapshot mounts, not only a mount type (ro-mount
* or rw-mount) but also a checkpoint number is required.
* The results are passed in sget() using nilfs_super_data.
*/
sd.cno = 0;
sd.flags = flags;
Expand Down Expand Up @@ -1148,13 +1130,23 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
}

/*
* Search specified snapshot or R/W mode super_block
* Find existing nilfs_sb_info struct
*/
sd.sbi = nilfs_find_sbinfo(nilfs, !(flags & MS_RDONLY), sd.cno);

if (!sd.cno)
/* trying to get the latest checkpoint. */
sd.cno = nilfs_last_cno(nilfs);

/*
* Get super block instance holding the nilfs_sb_info struct.
* A new instance is allocated if no existing mount is present or
* existing instance has been unmounted.
*/
s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, &sd);
if (sd.sbi)
nilfs_put_sbinfo(sd.sbi);

if (IS_ERR(s)) {
err = PTR_ERR(s);
goto failed_unlock;
Expand Down
50 changes: 50 additions & 0 deletions trunk/fs/nilfs2/the_nilfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,56 @@ int nilfs_near_disk_full(struct the_nilfs *nilfs)
return ret;
}

/**
* nilfs_find_sbinfo - find existing nilfs_sb_info structure
* @nilfs: nilfs object
* @rw_mount: mount type (non-zero value for read/write mount)
* @cno: checkpoint number (zero for read-only mount)
*
* nilfs_find_sbinfo() returns the nilfs_sb_info structure which
* @rw_mount and @cno (in case of snapshots) matched. If no instance
* was found, NULL is returned. Although the super block instance can
* be unmounted after this function returns, the nilfs_sb_info struct
* is kept on memory until nilfs_put_sbinfo() is called.
*/
struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *nilfs,
int rw_mount, __u64 cno)
{
struct nilfs_sb_info *sbi;

down_read(&nilfs->ns_sem);
/*
* The SNAPSHOT flag and sb->s_flags are supposed to be
* protected with nilfs->ns_sem.
*/
sbi = nilfs->ns_current;
if (rw_mount) {
if (sbi && !(sbi->s_super->s_flags & MS_RDONLY))
goto found; /* read/write mount */
else
goto out;
} else if (cno == 0) {
if (sbi && (sbi->s_super->s_flags & MS_RDONLY))
goto found; /* read-only mount */
else
goto out;
}

list_for_each_entry(sbi, &nilfs->ns_supers, s_list) {
if (nilfs_test_opt(sbi, SNAPSHOT) &&
sbi->s_snapshot_cno == cno)
goto found; /* snapshot mount */
}
out:
up_read(&nilfs->ns_sem);
return NULL;

found:
atomic_inc(&sbi->s_count);
up_read(&nilfs->ns_sem);
return sbi;
}

int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno,
int snapshot_mount)
{
Expand Down
7 changes: 7 additions & 0 deletions trunk/fs/nilfs2/the_nilfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ void put_nilfs(struct the_nilfs *);
int init_nilfs(struct the_nilfs *, struct nilfs_sb_info *, char *);
int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *);
int nilfs_count_free_blocks(struct the_nilfs *, sector_t *);
struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *, int, __u64);
int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int);
int nilfs_near_disk_full(struct the_nilfs *);
void nilfs_fall_back_super_block(struct the_nilfs *);
Expand Down Expand Up @@ -243,6 +244,12 @@ nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
mutex_unlock(&nilfs->ns_writer_mutex);
}

static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi)
{
if (!atomic_dec_and_test(&sbi->s_count))
kfree(sbi);
}

static inline void
nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum,
sector_t *seg_start, sector_t *seg_end)
Expand Down

0 comments on commit 65dd485

Please sign in to comment.