Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 313463 Details for
Bug 457798
GFS2 : gfs2meta is FUBAR
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Initial patch
metafs.diff (text/plain), 14.47 KB, created by
Steve Whitehouse
on 2008-08-05 16:26:36 UTC
(
hide
)
Description:
Initial patch
Filename:
MIME Type:
Creator:
Steve Whitehouse
Created:
2008-08-05 16:26:36 UTC
Size:
14.47 KB
patch
obsolete
>diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h >index 448697a..a1777a1 100644 >--- a/fs/gfs2/incore.h >+++ b/fs/gfs2/incore.h >@@ -400,6 +400,7 @@ struct gfs2_args { > int ar_quota; /* off/account/on */ > int ar_suiddir; /* suiddir support */ > int ar_data; /* ordered/writeback */ >+ int ar_meta; /* mount metafs */ > }; > > struct gfs2_tune { >@@ -461,7 +462,6 @@ struct gfs2_sb_host { > > struct gfs2_sbd { > struct super_block *sd_vfs; >- struct super_block *sd_vfs_meta; > struct kobject sd_kobj; > unsigned long sd_flags; /* SDF_... */ > struct gfs2_sb_host sd_sb; >@@ -499,7 +499,9 @@ struct gfs2_sbd { > > /* Inode Stuff */ > >- struct inode *sd_master_dir; >+ struct dentry *sd_master_dir; >+ struct dentry *sd_root_dir; >+ > struct inode *sd_jindex; > struct inode *sd_inum_inode; > struct inode *sd_statfs_inode; >@@ -634,7 +636,6 @@ struct gfs2_sbd { > /* Debugging crud */ > > unsigned long sd_last_warning; >- struct vfsmount *sd_gfs2mnt; > struct dentry *debugfs_dir; /* debugfs directory */ > struct dentry *debugfs_dentry_glocks; /* for debugfs */ > }; >diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c >index b941f9f..df48333 100644 >--- a/fs/gfs2/mount.c >+++ b/fs/gfs2/mount.c >@@ -42,6 +42,7 @@ enum { > Opt_nosuiddir, > Opt_data_writeback, > Opt_data_ordered, >+ Opt_meta, > Opt_err, > }; > >@@ -66,6 +67,7 @@ static match_table_t tokens = { > {Opt_nosuiddir, "nosuiddir"}, > {Opt_data_writeback, "data=writeback"}, > {Opt_data_ordered, "data=ordered"}, >+ {Opt_meta, "meta"}, > {Opt_err, NULL} > }; > >@@ -239,6 +241,11 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount) > case Opt_data_ordered: > args->ar_data = GFS2_DATA_ORDERED; > break; >+ case Opt_meta: >+ if (remount && args->ar_meta != 1) >+ goto cant_remount; >+ args->ar_meta = 1; >+ break; > case Opt_err: > default: > fs_info(sdp, "unknown option: %s\n", o); >diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c >index b4d1d64..488415e 100644 >--- a/fs/gfs2/ops_fstype.c >+++ b/fs/gfs2/ops_fstype.c >@@ -224,51 +224,59 @@ fail: > return error; > } > >-static inline struct inode *gfs2_lookup_root(struct super_block *sb, >- u64 no_addr) >+static int gfs2_lookup_root(struct super_block *sb, struct dentry **dptr, >+ u64 no_addr, const char *name) > { >- return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0, 0); >+ struct gfs2_sbd *sdp = sb->s_fs_info; >+ struct dentry *dentry; >+ struct inode *inode; >+ >+ inode = gfs2_inode_lookup(sb, DT_DIR, no_addr, 0, 0); >+ if (IS_ERR(inode)) { >+ fs_err(sdp, "can't read in %s inode: %ld\n", name, PTR_ERR(inode)); >+ return PTR_ERR(inode); >+ } >+ dentry = d_alloc_root(inode); >+ if (!dentry) { >+ fs_err(sdp, "can't alloc %s dentry\n", name); >+ iput(inode); >+ return -ENOMEM; >+ } >+ dentry->d_op = &gfs2_dops; >+ *dptr = dentry; >+ return 0; > } > >-static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) >+static int init_sb(struct gfs2_sbd *sdp, int silent) > { > struct super_block *sb = sdp->sd_vfs; > struct gfs2_holder sb_gh; > u64 no_addr; >- struct inode *inode; >- int error = 0; >- >- if (undo) { >- if (sb->s_root) { >- dput(sb->s_root); >- sb->s_root = NULL; >- } >- return 0; >- } >+ int ret; > >- error = gfs2_glock_nq_num(sdp, GFS2_SB_LOCK, &gfs2_meta_glops, >- LM_ST_SHARED, 0, &sb_gh); >- if (error) { >- fs_err(sdp, "can't acquire superblock glock: %d\n", error); >- return error; >+ ret = gfs2_glock_nq_num(sdp, GFS2_SB_LOCK, &gfs2_meta_glops, >+ LM_ST_SHARED, 0, &sb_gh); >+ if (ret) { >+ fs_err(sdp, "can't acquire superblock glock: %d\n", ret); >+ return ret; > } > >- error = gfs2_read_sb(sdp, sb_gh.gh_gl, silent); >- if (error) { >- fs_err(sdp, "can't read superblock: %d\n", error); >+ ret = gfs2_read_sb(sdp, sb_gh.gh_gl, silent); >+ if (ret) { >+ fs_err(sdp, "can't read superblock: %d\n", ret); > goto out; > } > > /* Set up the buffer cache and SB for real */ > if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) { >- error = -EINVAL; >+ ret = -EINVAL; > fs_err(sdp, "FS block size (%u) is too small for device " > "block size (%u)\n", > sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev)); > goto out; > } > if (sdp->sd_sb.sb_bsize > PAGE_SIZE) { >- error = -EINVAL; >+ ret = -EINVAL; > fs_err(sdp, "FS block size (%u) is too big for machine " > "page size (%u)\n", > sdp->sd_sb.sb_bsize, (unsigned int)PAGE_SIZE); >@@ -278,26 +286,21 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) > > /* Get the root inode */ > no_addr = sdp->sd_sb.sb_root_dir.no_addr; >- if (sb->s_type == &gfs2meta_fs_type) >- no_addr = sdp->sd_sb.sb_master_dir.no_addr; >- inode = gfs2_lookup_root(sb, no_addr); >- if (IS_ERR(inode)) { >- error = PTR_ERR(inode); >- fs_err(sdp, "can't read in root inode: %d\n", error); >+ ret = gfs2_lookup_root(sb, &sdp->sd_root_dir, no_addr, "root"); >+ if (ret) > goto out; >- } > >- sb->s_root = d_alloc_root(inode); >- if (!sb->s_root) { >- fs_err(sdp, "can't get root dentry\n"); >- error = -ENOMEM; >- iput(inode); >- } else >- sb->s_root->d_op = &gfs2_dops; >- >+ /* Get the master inode */ >+ no_addr = sdp->sd_sb.sb_master_dir.no_addr; >+ ret = gfs2_lookup_root(sb, &sdp->sd_master_dir, no_addr, "master"); >+ if (ret) { >+ dput(sdp->sd_root_dir); >+ goto out; >+ } >+ sb->s_root = sdp->sd_args.ar_meta ? sdp->sd_master_dir : sdp->sd_root_dir; > out: > gfs2_glock_dq_uninit(&sb_gh); >- return error; >+ return ret; > } > > /** >@@ -372,6 +375,7 @@ static void gfs2_lm_others_may_mount(struct gfs2_sbd *sdp) > > static int init_journal(struct gfs2_sbd *sdp, int undo) > { >+ struct inode *master = sdp->sd_master_dir->d_inode; > struct gfs2_holder ji_gh; > struct task_struct *p; > struct gfs2_inode *ip; >@@ -383,7 +387,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) > goto fail_recoverd; > } > >- sdp->sd_jindex = gfs2_lookup_simple(sdp->sd_master_dir, "jindex"); >+ sdp->sd_jindex = gfs2_lookup_simple(master, "jindex"); > if (IS_ERR(sdp->sd_jindex)) { > fs_err(sdp, "can't lookup journal index: %d\n", error); > return PTR_ERR(sdp->sd_jindex); >@@ -506,25 +510,17 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo) > { > int error = 0; > struct gfs2_inode *ip; >- struct inode *inode; >+ struct inode *master = sdp->sd_master_dir->d_inode; > > if (undo) > goto fail_qinode; > >- inode = gfs2_lookup_root(sdp->sd_vfs, sdp->sd_sb.sb_master_dir.no_addr); >- if (IS_ERR(inode)) { >- error = PTR_ERR(inode); >- fs_err(sdp, "can't read in master directory: %d\n", error); >- goto fail; >- } >- sdp->sd_master_dir = inode; >- > error = init_journal(sdp, undo); > if (error) >- goto fail_master; >+ goto fail; > > /* Read in the master inode number inode */ >- sdp->sd_inum_inode = gfs2_lookup_simple(sdp->sd_master_dir, "inum"); >+ sdp->sd_inum_inode = gfs2_lookup_simple(master, "inum"); > if (IS_ERR(sdp->sd_inum_inode)) { > error = PTR_ERR(sdp->sd_inum_inode); > fs_err(sdp, "can't read in inum inode: %d\n", error); >@@ -533,7 +529,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo) > > > /* Read in the master statfs inode */ >- sdp->sd_statfs_inode = gfs2_lookup_simple(sdp->sd_master_dir, "statfs"); >+ sdp->sd_statfs_inode = gfs2_lookup_simple(master, "statfs"); > if (IS_ERR(sdp->sd_statfs_inode)) { > error = PTR_ERR(sdp->sd_statfs_inode); > fs_err(sdp, "can't read in statfs inode: %d\n", error); >@@ -541,7 +537,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo) > } > > /* Read in the resource index inode */ >- sdp->sd_rindex = gfs2_lookup_simple(sdp->sd_master_dir, "rindex"); >+ sdp->sd_rindex = gfs2_lookup_simple(master, "rindex"); > if (IS_ERR(sdp->sd_rindex)) { > error = PTR_ERR(sdp->sd_rindex); > fs_err(sdp, "can't get resource index inode: %d\n", error); >@@ -552,7 +548,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo) > sdp->sd_rindex_uptodate = 0; > > /* Read in the quota inode */ >- sdp->sd_quota_inode = gfs2_lookup_simple(sdp->sd_master_dir, "quota"); >+ sdp->sd_quota_inode = gfs2_lookup_simple(master, "quota"); > if (IS_ERR(sdp->sd_quota_inode)) { > error = PTR_ERR(sdp->sd_quota_inode); > fs_err(sdp, "can't get quota file inode: %d\n", error); >@@ -571,8 +567,6 @@ fail_inum: > iput(sdp->sd_inum_inode); > fail_journal: > init_journal(sdp, UNDO); >-fail_master: >- iput(sdp->sd_master_dir); > fail: > return error; > } >@@ -583,6 +577,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo) > char buf[30]; > int error = 0; > struct gfs2_inode *ip; >+ struct inode *master = sdp->sd_master_dir->d_inode; > > if (sdp->sd_args.ar_spectator) > return 0; >@@ -590,7 +585,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo) > if (undo) > goto fail_qc_gh; > >- pn = gfs2_lookup_simple(sdp->sd_master_dir, "per_node"); >+ pn = gfs2_lookup_simple(master, "per_node"); > if (IS_ERR(pn)) { > error = PTR_ERR(pn); > fs_err(sdp, "can't find per_node directory: %d\n", error); >@@ -828,7 +823,7 @@ static int fill_super(struct super_block *sb, void *data, int silent) > if (error) > goto fail_lm; > >- error = init_sb(sdp, silent, DO); >+ error = init_sb(sdp, silent); > if (error) > goto fail_locking; > >@@ -869,7 +864,11 @@ fail_per_node: > fail_inodes: > init_inodes(sdp, UNDO); > fail_sb: >- init_sb(sdp, 0, UNDO); >+ if (sdp->sd_root_dir) >+ dput(sdp->sd_root_dir); >+ if (sdp->sd_master_dir) >+ dput(sdp->sd_master_dir); >+ sb->s_root = NULL; > fail_locking: > init_locking(sdp, &mount_gh, UNDO); > fail_lm: >@@ -887,134 +886,47 @@ fail: > } > > static int gfs2_get_sb(struct file_system_type *fs_type, int flags, >- const char *dev_name, void *data, struct vfsmount *mnt) >-{ >- struct super_block *sb; >- struct gfs2_sbd *sdp; >- int error = get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt); >- if (error) >- goto out; >- sb = mnt->mnt_sb; >- sdp = sb->s_fs_info; >- sdp->sd_gfs2mnt = mnt; >-out: >- return error; >-} >- >-static int fill_super_meta(struct super_block *sb, struct super_block *new, >- void *data, int silent) >-{ >- struct gfs2_sbd *sdp = sb->s_fs_info; >- struct inode *inode; >- int error = 0; >- >- new->s_fs_info = sdp; >- sdp->sd_vfs_meta = sb; >- >- init_vfs(new, SDF_NOATIME); >- >- /* Get the master inode */ >- inode = igrab(sdp->sd_master_dir); >- >- new->s_root = d_alloc_root(inode); >- if (!new->s_root) { >- fs_err(sdp, "can't get root dentry\n"); >- error = -ENOMEM; >- iput(inode); >- } else >- new->s_root->d_op = &gfs2_dops; >- >- return error; >-} >- >-static int set_bdev_super(struct super_block *s, void *data) >-{ >- s->s_bdev = data; >- s->s_dev = s->s_bdev->bd_dev; >- return 0; >-} >- >-static int test_bdev_super(struct super_block *s, void *data) >+ const char *dev_name, void *data, struct vfsmount *mnt) > { >- return s->s_bdev == data; >+ return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt); > } > >-static struct super_block* get_gfs2_sb(const char *dev_name) >+static struct super_block *get_gfs2_sb(const char *dev_name) > { >- struct kstat stat; >+ struct super_block *sb; > struct nameidata nd; >- struct super_block *sb = NULL, *s; > int error; > > error = path_lookup(dev_name, LOOKUP_FOLLOW, &nd); > if (error) { >- printk(KERN_WARNING "GFS2: path_lookup on %s returned error\n", >- dev_name); >- goto out; >- } >- error = vfs_getattr(nd.path.mnt, nd.path.dentry, &stat); >- >- list_for_each_entry(s, &gfs2_fs_type.fs_supers, s_instances) { >- if ((S_ISBLK(stat.mode) && s->s_dev == stat.rdev) || >- (S_ISDIR(stat.mode) && >- s == nd.path.dentry->d_inode->i_sb)) { >- sb = s; >- goto free_nd; >- } >+ printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n", >+ dev_name, error); >+ return NULL; > } >- >- printk(KERN_WARNING "GFS2: Unrecognized block device or " >- "mount point %s\n", dev_name); >- >-free_nd: >+ sb = nd.path.dentry->d_inode->i_sb; >+ if (sb && (sb->s_type == &gfs2_fs_type)) >+ sb->s_count++; >+ else >+ sb = NULL; > path_put(&nd.path); >-out: > return sb; > } > > static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags, > const char *dev_name, void *data, struct vfsmount *mnt) > { >- int error = 0; >- struct super_block *sb = NULL, *new; >+ struct super_block *sb = NULL; > struct gfs2_sbd *sdp; > > sb = get_gfs2_sb(dev_name); > if (!sb) { > printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n"); >- error = -ENOENT; >- goto error; >+ return -ENOENT; > } > sdp = sb->s_fs_info; >- if (sdp->sd_vfs_meta) { >- printk(KERN_WARNING "GFS2: gfs2meta mount already exists\n"); >- error = -EBUSY; >- goto error; >- } >- down(&sb->s_bdev->bd_mount_sem); >- new = sget(fs_type, test_bdev_super, set_bdev_super, sb->s_bdev); >- up(&sb->s_bdev->bd_mount_sem); >- if (IS_ERR(new)) { >- error = PTR_ERR(new); >- goto error; >- } >- new->s_flags = flags; >- strlcpy(new->s_id, sb->s_id, sizeof(new->s_id)); >- sb_set_blocksize(new, sb->s_blocksize); >- error = fill_super_meta(sb, new, data, flags & MS_SILENT ? 1 : 0); >- if (error) { >- up_write(&new->s_umount); >- deactivate_super(new); >- goto error; >- } >- >- new->s_flags |= MS_ACTIVE; >- >- /* Grab a reference to the gfs2 mount point */ >- atomic_inc(&sdp->sd_gfs2mnt->mnt_count); >- return simple_set_mnt(mnt, new); >-error: >- return error; >+ mnt->mnt_sb = sb; >+ mnt->mnt_root = dget(sdp->sd_master_dir); >+ return 0; > } > > static void gfs2_kill_sb(struct super_block *sb) >@@ -1026,14 +938,6 @@ static void gfs2_kill_sb(struct super_block *sb) > kill_block_super(sb); > } > >-static void gfs2_kill_sb_meta(struct super_block *sb) >-{ >- struct gfs2_sbd *sdp = sb->s_fs_info; >- generic_shutdown_super(sb); >- sdp->sd_vfs_meta = NULL; >- atomic_dec(&sdp->sd_gfs2mnt->mnt_count); >-} >- > struct file_system_type gfs2_fs_type = { > .name = "gfs2", > .fs_flags = FS_REQUIRES_DEV, >@@ -1046,7 +950,6 @@ struct file_system_type gfs2meta_fs_type = { > .name = "gfs2meta", > .fs_flags = FS_REQUIRES_DEV, > .get_sb = gfs2_get_sb_meta, >- .kill_sb = gfs2_kill_sb_meta, > .owner = THIS_MODULE, > }; > >diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c >index f66ea0f..bf01242 100644 >--- a/fs/gfs2/ops_super.c >+++ b/fs/gfs2/ops_super.c >@@ -101,7 +101,7 @@ static void gfs2_put_super(struct super_block *sb) > > /* Release stuff */ > >- iput(sdp->sd_master_dir); >+ dput(sdp->sd_master_dir); > iput(sdp->sd_jindex); > iput(sdp->sd_inum_inode); > iput(sdp->sd_statfs_inode); >@@ -333,6 +333,16 @@ static void gfs2_clear_inode(struct inode *inode) > } > } > >+static int is_ancestor(const struct dentry *d1, const struct dentry *d2) >+{ >+ do { >+ if (d1 == d2) >+ return 1; >+ d1 = d1->d_parent; >+ } while (!IS_ROOT(d1)); >+ return 0; >+} >+ > /** > * gfs2_show_options - Show mount options for /proc/mounts > * @s: seq_file structure >@@ -346,6 +356,8 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) > struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info; > struct gfs2_args *args = &sdp->sd_args; > >+ if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir)) >+ seq_printf(s, ",meta"); > if (args->ar_lockproto[0]) > seq_printf(s, ",lockproto=%s", args->ar_lockproto); > if (args->ar_locktable[0])
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 457798
:
313463
|
313557
|
313591
|
313671
|
314898