From 0d5839ad05acd0fe2a84a39f33ac5efdf634a5a5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 16 Mar 2011 05:27:27 -0400 Subject: nfs: propagate devname to nfs{,4}_get_root() step 1 of ->mnt_devname fixes: make sure we have the value of devname available in ..._get_root(). Signed-off-by: Al Viro --- fs/nfs/super.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'fs/nfs/super.c') diff --git a/fs/nfs/super.c b/fs/nfs/super.c index b68c8607770f..1d81032b226a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2336,7 +2336,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, s, data ? data->fscache_uniq : NULL, NULL); } - mntroot = nfs_get_root(s, mntfh); + mntroot = nfs_get_root(s, mntfh, dev_name); if (IS_ERR(mntroot)) { error = PTR_ERR(mntroot); goto error_splat_super; @@ -2450,7 +2450,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags, nfs_fscache_get_super_cookie(s, NULL, data); } - mntroot = nfs_get_root(s, data->fh); + mntroot = nfs_get_root(s, data->fh, dev_name); if (IS_ERR(mntroot)) { error = PTR_ERR(mntroot); goto error_splat_super; @@ -2718,7 +2718,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags, s, data ? data->fscache_uniq : NULL, NULL); } - mntroot = nfs4_get_root(s, mntfh); + mntroot = nfs4_get_root(s, mntfh, dev_name); if (IS_ERR(mntroot)) { error = PTR_ERR(mntroot); goto error_splat_super; @@ -3033,7 +3033,7 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags, nfs_fscache_get_super_cookie(s, NULL, data); } - mntroot = nfs4_get_root(s, data->fh); + mntroot = nfs4_get_root(s, data->fh, dev_name); if (IS_ERR(mntroot)) { error = PTR_ERR(mntroot); goto error_splat_super; @@ -3120,7 +3120,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, nfs_fscache_get_super_cookie(s, NULL, data); } - mntroot = nfs4_get_root(s, mntfh); + mntroot = nfs4_get_root(s, mntfh, dev_name); if (IS_ERR(mntroot)) { error = PTR_ERR(mntroot); goto error_splat_super; -- cgit v1.2.3 From b514f872f86d4b0c13fed74a1fe1f7ab500c4fd0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 16 Mar 2011 06:26:11 -0400 Subject: nfs: make nfs_path() work without vfsmount part 3: now we have everything to get nfs_path() just by dentry - just follow to (disconnected) root and pick the rest of the thing there. Start killing propagation of struct vfsmount * on the paths that used to bring it to nfs_path(). Signed-off-by: Al Viro --- fs/nfs/internal.h | 15 +++++------ fs/nfs/namespace.c | 69 ++++++++++++++++++++++++++++++++------------------ fs/nfs/nfs4namespace.c | 43 ++++++++++++++----------------- fs/nfs/super.c | 9 +++---- 4 files changed, 74 insertions(+), 62 deletions(-) (limited to 'fs/nfs/super.c') diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 9e5a003ccc53..f0234118d044 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -163,10 +163,10 @@ static inline void nfs_fs_proc_exit(void) /* nfs4namespace.c */ #ifdef CONFIG_NFS_V4 -extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry); +extern struct vfsmount *nfs_do_refmount(struct super_block *sb, struct dentry *dentry); #else static inline -struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry) +struct vfsmount *nfs_do_refmount(struct super_block *sb, struct dentry *dentry) { return ERR_PTR(-ENOENT); } @@ -247,9 +247,7 @@ extern void nfs_sb_active(struct super_block *sb); extern void nfs_sb_deactive(struct super_block *sb); /* namespace.c */ -extern char *nfs_path(const char *base, - const struct dentry *droot, - const struct dentry *dentry, +extern char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen); extern struct vfsmount *nfs_d_automount(struct path *path); @@ -290,12 +288,11 @@ extern int _nfs4_call_sync_session(struct nfs_server *server, /* * Determine the device name as a string */ -static inline char *nfs_devname(const struct vfsmount *mnt_parent, - const struct dentry *dentry, +static inline char *nfs_devname(struct dentry *dentry, char *buffer, ssize_t buflen) { - return nfs_path(mnt_parent->mnt_devname, mnt_parent->mnt_root, - dentry, buffer, buflen); + char *dummy; + return nfs_path(&dummy, dentry, buffer, buflen); } /* diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index f32b8603dca8..859cdaba4c1c 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -25,33 +25,31 @@ static LIST_HEAD(nfs_automount_list); static DECLARE_DELAYED_WORK(nfs_automount_task, nfs_expire_automounts); int nfs_mountpoint_expiry_timeout = 500 * HZ; -static struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, - const struct dentry *dentry, +static struct vfsmount *nfs_do_submount(struct super_block *sb, + struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr); /* * nfs_path - reconstruct the path given an arbitrary dentry - * @base - arbitrary string to prepend to the path - * @droot - pointer to root dentry for mountpoint + * @base - used to return pointer to the end of devname part of path * @dentry - pointer to dentry * @buffer - result buffer * @buflen - length of buffer * - * Helper function for constructing the path from the - * root dentry to an arbitrary hashed dentry. + * Helper function for constructing the server pathname + * by arbitrary hashed dentry. * * This is mainly for use in figuring out the path on the - * server side when automounting on top of an existing partition. + * server side when automounting on top of an existing partition + * and in generating /proc/mounts and friends. */ -char *nfs_path(const char *base, - const struct dentry *droot, - const struct dentry *dentry, - char *buffer, ssize_t buflen) +char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen) { char *end; int namelen; unsigned seq; + const char *base; rename_retry: end = buffer+buflen; @@ -60,7 +58,10 @@ rename_retry: seq = read_seqbegin(&rename_lock); rcu_read_lock(); - while (!IS_ROOT(dentry) && dentry != droot) { + while (1) { + spin_lock(&dentry->d_lock); + if (IS_ROOT(dentry)) + break; namelen = dentry->d_name.len; buflen -= namelen + 1; if (buflen < 0) @@ -68,27 +69,47 @@ rename_retry: end -= namelen; memcpy(end, dentry->d_name.name, namelen); *--end = '/'; + spin_unlock(&dentry->d_lock); dentry = dentry->d_parent; } - rcu_read_unlock(); - if (read_seqretry(&rename_lock, seq)) + if (read_seqretry(&rename_lock, seq)) { + spin_unlock(&dentry->d_lock); + rcu_read_unlock(); goto rename_retry; + } if (*end != '/') { - if (--buflen < 0) + if (--buflen < 0) { + spin_unlock(&dentry->d_lock); + rcu_read_unlock(); goto Elong; + } *--end = '/'; } + *p = end; + base = dentry->d_fsdata; + if (!base) { + spin_unlock(&dentry->d_lock); + rcu_read_unlock(); + WARN_ON(1); + return end; + } namelen = strlen(base); /* Strip off excess slashes in base string */ while (namelen > 0 && base[namelen - 1] == '/') namelen--; buflen -= namelen; - if (buflen < 0) + if (buflen < 0) { + spin_lock(&dentry->d_lock); + rcu_read_unlock(); goto Elong; + } end -= namelen; memcpy(end, base, namelen); + spin_unlock(&dentry->d_lock); + rcu_read_unlock(); return end; Elong_unlock: + spin_lock(&dentry->d_lock); rcu_read_unlock(); if (read_seqretry(&rename_lock, seq)) goto rename_retry; @@ -143,9 +164,9 @@ struct vfsmount *nfs_d_automount(struct path *path) } if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) - mnt = nfs_do_refmount(path->mnt, path->dentry); + mnt = nfs_do_refmount(path->mnt->mnt_sb, path->dentry); else - mnt = nfs_do_submount(path->mnt, path->dentry, fh, fattr); + mnt = nfs_do_submount(path->mnt->mnt_sb, path->dentry, fh, fattr); if (IS_ERR(mnt)) goto out; @@ -209,19 +230,19 @@ static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, /** * nfs_do_submount - set up mountpoint when crossing a filesystem boundary - * @mnt_parent - mountpoint of parent directory + * @sb - superblock of parent directory * @dentry - parent directory * @fh - filehandle for new root dentry * @fattr - attributes for new root inode * */ -static struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, - const struct dentry *dentry, +static struct vfsmount *nfs_do_submount(struct super_block *sb, + struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr) { struct nfs_clone_mount mountdata = { - .sb = mnt_parent->mnt_sb, + .sb = sb, .dentry = dentry, .fh = fh, .fattr = fattr, @@ -237,11 +258,11 @@ static struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, dentry->d_name.name); if (page == NULL) goto out; - devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE); + devname = nfs_devname(dentry, page, PAGE_SIZE); mnt = (struct vfsmount *)devname; if (IS_ERR(devname)) goto free_page; - mnt = nfs_do_clone_mount(NFS_SB(mnt_parent->mnt_sb), devname, &mountdata); + mnt = nfs_do_clone_mount(NFS_SB(sb), devname, &mountdata); free_page: free_page((unsigned long)page); out: diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 3c2a1724fbd2..46942e2680a0 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c @@ -54,33 +54,29 @@ Elong: /* * Determine the mount path as a string */ -static char *nfs4_path(const struct vfsmount *mnt_parent, - const struct dentry *dentry, - char *buffer, ssize_t buflen) +static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) { - const char *srvpath; - - srvpath = strchr(mnt_parent->mnt_devname, ':'); - if (srvpath) - srvpath++; - else - srvpath = mnt_parent->mnt_devname; - - return nfs_path(srvpath, mnt_parent->mnt_root, dentry, buffer, buflen); + char *limit; + char *path = nfs_path(&limit, dentry, buffer, buflen); + if (!IS_ERR(path)) { + char *colon = strchr(path, ':'); + if (colon && colon < limit) + path = colon + 1; + } + return path; } /* * Check that fs_locations::fs_root [RFC3530 6.3] is a prefix for what we * believe to be the server path to this dentry */ -static int nfs4_validate_fspath(const struct vfsmount *mnt_parent, - const struct dentry *dentry, +static int nfs4_validate_fspath(struct dentry *dentry, const struct nfs4_fs_locations *locations, char *page, char *page2) { const char *path, *fs_path; - path = nfs4_path(mnt_parent, dentry, page, PAGE_SIZE); + path = nfs4_path(dentry, page, PAGE_SIZE); if (IS_ERR(path)) return PTR_ERR(path); @@ -165,20 +161,20 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, /** * nfs_follow_referral - set up mountpoint when hitting a referral on moved error - * @mnt_parent - mountpoint of parent directory + * @sb - superblock of parent directory * @dentry - parent directory * @locations - array of NFSv4 server location information * */ -static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, - const struct dentry *dentry, +static struct vfsmount *nfs_follow_referral(struct super_block *sb, + struct dentry *dentry, const struct nfs4_fs_locations *locations) { struct vfsmount *mnt = ERR_PTR(-ENOENT); struct nfs_clone_mount mountdata = { - .sb = mnt_parent->mnt_sb, + .sb = sb, .dentry = dentry, - .authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor, + .authflavor = NFS_SB(sb)->client->cl_auth->au_flavor, }; char *page = NULL, *page2 = NULL; int loc, error; @@ -198,7 +194,7 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, goto out; /* Ensure fs path is a prefix of current dentry path */ - error = nfs4_validate_fspath(mnt_parent, dentry, locations, page, page2); + error = nfs4_validate_fspath(dentry, locations, page, page2); if (error < 0) { mnt = ERR_PTR(error); goto out; @@ -225,11 +221,10 @@ out: /* * nfs_do_refmount - handle crossing a referral on server - * @mnt_parent - mountpoint of referral * @dentry - dentry of referral * */ -struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry) +struct vfsmount *nfs_do_refmount(struct super_block *sb, struct dentry *dentry) { struct vfsmount *mnt = ERR_PTR(-ENOMEM); struct dentry *parent; @@ -262,7 +257,7 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr fs_locations->fs_path.ncomponents <= 0) goto out_free; - mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations); + mnt = nfs_follow_referral(sb, dentry, fs_locations); out_free: __free_page(page); kfree(fs_locations); diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 1d81032b226a..a6ab483c9ad0 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2771,16 +2771,15 @@ static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, return root_mnt; } -static void nfs_fix_devname(const struct path *path, struct vfsmount *mnt) +static void nfs_fix_devname(struct dentry *dentry, struct vfsmount *mnt) { char *page = (char *) __get_free_page(GFP_KERNEL); char *devname, *tmp; + char *dummy; if (page == NULL) return; - devname = nfs_path(path->mnt->mnt_devname, - path->mnt->mnt_root, path->dentry, - page, PAGE_SIZE); + devname = nfs_path(&dummy, dentry, page, PAGE_SIZE); if (IS_ERR(devname)) goto out_freepage; tmp = kstrdup(devname, GFP_KERNEL); @@ -2894,7 +2893,7 @@ static int nfs_follow_remote_path(struct vfsmount *root_mnt, mnt_target->mnt_root = dget(nd->path.dentry); /* Correct the device pathname */ - nfs_fix_devname(&nd->path, mnt_target); + nfs_fix_devname(nd->path.dentry, mnt_target); path_put(&nd->path); kfree(nd); -- cgit v1.2.3 From c7f404b40a3665d9f4e9a927cc5c1ee0479ed8f9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 16 Mar 2011 06:59:40 -0400 Subject: vfs: new superblock methods to override /proc/*/mount{s,info} a) ->show_devname(m, mnt) - what to put into devname columns in mounts, mountinfo and mountstats b) ->show_path(m, mnt) - what to put into relative path column in mountinfo Leaving those NULL gives old behaviour. NFS switched to using those. Signed-off-by: Al Viro --- fs/namespace.c | 39 ++++++++++++++++++++++++++++++--------- fs/nfs/super.c | 28 ++++++++++++++++++++++++++++ include/linux/fs.h | 2 ++ 3 files changed, 60 insertions(+), 9 deletions(-) (limited to 'fs/nfs/super.c') diff --git a/fs/namespace.c b/fs/namespace.c index dffe6f49ab93..75d843ae46d2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -978,7 +978,13 @@ static int show_vfsmnt(struct seq_file *m, void *v) int err = 0; struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; - mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); + if (mnt->mnt_sb->s_op->show_devname) { + err = mnt->mnt_sb->s_op->show_devname(m, mnt); + if (err) + goto out; + } else { + mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); + } seq_putc(m, ' '); seq_path(m, &mnt_path, " \t\n\\"); seq_putc(m, ' '); @@ -1025,7 +1031,12 @@ static int show_mountinfo(struct seq_file *m, void *v) seq_printf(m, "%i %i %u:%u ", mnt->mnt_id, mnt->mnt_parent->mnt_id, MAJOR(sb->s_dev), MINOR(sb->s_dev)); - seq_dentry(m, mnt->mnt_root, " \t\n\\"); + if (sb->s_op->show_path) + err = sb->s_op->show_path(m, mnt); + else + seq_dentry(m, mnt->mnt_root, " \t\n\\"); + if (err) + goto out; seq_putc(m, ' '); seq_path_root(m, &mnt_path, &root, " \t\n\\"); if (root.mnt != p->root.mnt || root.dentry != p->root.dentry) { @@ -1060,7 +1071,12 @@ static int show_mountinfo(struct seq_file *m, void *v) seq_puts(m, " - "); show_type(m, sb); seq_putc(m, ' '); - mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); + if (sb->s_op->show_devname) + err = sb->s_op->show_devname(m, mnt); + else + mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); + if (err) + goto out; seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw"); err = show_sb_opts(m, sb); if (err) @@ -1086,11 +1102,15 @@ static int show_vfsstat(struct seq_file *m, void *v) int err = 0; /* device */ - if (mnt->mnt_devname) { - seq_puts(m, "device "); - mangle(m, mnt->mnt_devname); - } else - seq_puts(m, "no device"); + if (mnt->mnt_sb->s_op->show_devname) { + err = mnt->mnt_sb->s_op->show_devname(m, mnt); + } else { + if (mnt->mnt_devname) { + seq_puts(m, "device "); + mangle(m, mnt->mnt_devname); + } else + seq_puts(m, "no device"); + } /* mount point */ seq_puts(m, " mounted on "); @@ -1104,7 +1124,8 @@ static int show_vfsstat(struct seq_file *m, void *v) /* optional statistics */ if (mnt->mnt_sb->s_op->show_stats) { seq_putc(m, ' '); - err = mnt->mnt_sb->s_op->show_stats(m, mnt); + if (!err) + err = mnt->mnt_sb->s_op->show_stats(m, mnt); } seq_putc(m, '\n'); diff --git a/fs/nfs/super.c b/fs/nfs/super.c index a6ab483c9ad0..79bc61fe2868 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -263,6 +263,8 @@ static match_table_t nfs_local_lock_tokens = { static void nfs_umount_begin(struct super_block *); static int nfs_statfs(struct dentry *, struct kstatfs *); static int nfs_show_options(struct seq_file *, struct vfsmount *); +static int nfs_show_devname(struct seq_file *, struct vfsmount *); +static int nfs_show_path(struct seq_file *, struct vfsmount *); static int nfs_show_stats(struct seq_file *, struct vfsmount *); static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type, @@ -296,6 +298,8 @@ static const struct super_operations nfs_sops = { .evict_inode = nfs_evict_inode, .umount_begin = nfs_umount_begin, .show_options = nfs_show_options, + .show_devname = nfs_show_devname, + .show_path = nfs_show_path, .show_stats = nfs_show_stats, .remount_fs = nfs_remount, }; @@ -366,6 +370,8 @@ static const struct super_operations nfs4_sops = { .evict_inode = nfs4_evict_inode, .umount_begin = nfs_umount_begin, .show_options = nfs_show_options, + .show_devname = nfs_show_devname, + .show_path = nfs_show_path, .show_stats = nfs_show_stats, .remount_fs = nfs_remount, }; @@ -726,6 +732,28 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt) return 0; } +static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt) +{ + char *page = (char *) __get_free_page(GFP_KERNEL); + char *devname, *dummy; + int err = 0; + if (!page) + return -ENOMEM; + devname = nfs_path(&dummy, mnt->mnt_root, page, PAGE_SIZE); + if (IS_ERR(devname)) + err = PTR_ERR(devname); + else + seq_escape(m, devname, " \t\n\\"); + free_page((unsigned long)page); + return err; +} + +static int nfs_show_path(struct seq_file *m, struct vfsmount *mnt) +{ + seq_puts(m, "/"); + return 0; +} + /* * Present statistical information for this VFS mountpoint */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 13df14e2c42e..e6d3fe45981b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1632,6 +1632,8 @@ struct super_operations { void (*umount_begin) (struct super_block *); int (*show_options)(struct seq_file *, struct vfsmount *); + int (*show_devname)(struct seq_file *, struct vfsmount *); + int (*show_path)(struct seq_file *, struct vfsmount *); int (*show_stats)(struct seq_file *, struct vfsmount *); #ifdef CONFIG_QUOTA ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); -- cgit v1.2.3 From fd462fb51db46c84bea0fc377c11b9a7e16bc1a0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 16 Mar 2011 07:05:45 -0400 Subject: nfs: stop mangling ->mnt_devname on NFS now we can do that - nobody cares about its value anymore. Signed-off-by: Al Viro --- fs/nfs/super.c | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'fs/nfs/super.c') diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 79bc61fe2868..3f967cee4072 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2799,26 +2799,6 @@ static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, return root_mnt; } -static void nfs_fix_devname(struct dentry *dentry, struct vfsmount *mnt) -{ - char *page = (char *) __get_free_page(GFP_KERNEL); - char *devname, *tmp; - char *dummy; - - if (page == NULL) - return; - devname = nfs_path(&dummy, dentry, page, PAGE_SIZE); - if (IS_ERR(devname)) - goto out_freepage; - tmp = kstrdup(devname, GFP_KERNEL); - if (tmp == NULL) - goto out_freepage; - kfree(mnt->mnt_devname); - mnt->mnt_devname = tmp; -out_freepage: - free_page((unsigned long)page); -} - struct nfs_referral_count { struct list_head list; const struct task_struct *task; @@ -2920,9 +2900,6 @@ static int nfs_follow_remote_path(struct vfsmount *root_mnt, mnt_target->mnt_sb = s; mnt_target->mnt_root = dget(nd->path.dentry); - /* Correct the device pathname */ - nfs_fix_devname(nd->path.dentry, mnt_target); - path_put(&nd->path); kfree(nd); down_write(&s->s_umount); -- cgit v1.2.3 From 011949811b946bd3b72fca71200f197c6168a5f8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 16 Mar 2011 07:25:36 -0400 Subject: nfs: switch NFS from ->get_sb() to ->mount() The last remaining instances of ->get_sb() can be converted ->mount() now - nothing in them uses new vfsmount anymore. Signed-off-by: Al Viro --- fs/nfs/super.c | 132 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 66 insertions(+), 66 deletions(-) (limited to 'fs/nfs/super.c') diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 3f967cee4072..d3286583009a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -266,7 +266,8 @@ static int nfs_show_options(struct seq_file *, struct vfsmount *); static int nfs_show_devname(struct seq_file *, struct vfsmount *); static int nfs_show_path(struct seq_file *, struct vfsmount *); static int nfs_show_stats(struct seq_file *, struct vfsmount *); -static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); +static struct dentry *nfs_fs_mount(struct file_system_type *, + int, const char *, void *); static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data); static void nfs_put_super(struct super_block *); @@ -276,7 +277,7 @@ static int nfs_remount(struct super_block *sb, int *flags, char *raw_data); static struct file_system_type nfs_fs_type = { .owner = THIS_MODULE, .name = "nfs", - .get_sb = nfs_get_sb, + .mount = nfs_fs_mount, .kill_sb = nfs_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, }; @@ -307,16 +308,16 @@ static const struct super_operations nfs_sops = { #ifdef CONFIG_NFS_V4 static int nfs4_validate_text_mount_data(void *options, struct nfs_parsed_mount_data *args, const char *dev_name); -static int nfs4_try_mount(int flags, const char *dev_name, - struct nfs_parsed_mount_data *data, struct vfsmount *mnt); -static int nfs4_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); +static struct dentry *nfs4_try_mount(int flags, const char *dev_name, + struct nfs_parsed_mount_data *data); +static struct dentry *nfs4_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *raw_data); static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data); static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data); -static int nfs4_referral_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); +static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *raw_data); static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data); static void nfs4_kill_super(struct super_block *sb); @@ -324,7 +325,7 @@ static void nfs4_kill_super(struct super_block *sb); static struct file_system_type nfs4_fs_type = { .owner = THIS_MODULE, .name = "nfs4", - .get_sb = nfs4_get_sb, + .mount = nfs4_mount, .kill_sb = nfs4_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, }; @@ -356,7 +357,7 @@ static struct file_system_type nfs4_remote_referral_fs_type = { struct file_system_type nfs4_referral_fs_type = { .owner = THIS_MODULE, .name = "nfs4", - .get_sb = nfs4_referral_get_sb, + .mount = nfs4_referral_mount, .kill_sb = nfs4_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, }; @@ -2295,19 +2296,19 @@ static int nfs_bdi_register(struct nfs_server *server) return bdi_register_dev(&server->backing_dev_info, server->s_dev); } -static int nfs_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) +static struct dentry *nfs_fs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *raw_data) { struct nfs_server *server = NULL; struct super_block *s; struct nfs_parsed_mount_data *data; struct nfs_fh *mntfh; - struct dentry *mntroot; + struct dentry *mntroot = ERR_PTR(-ENOMEM); int (*compare_super)(struct super_block *, void *) = nfs_compare_super; struct nfs_sb_mountdata sb_mntdata = { .mntflags = flags, }; - int error = -ENOMEM; + int error; data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION); mntfh = nfs_alloc_fhandle(); @@ -2318,12 +2319,14 @@ static int nfs_get_sb(struct file_system_type *fs_type, /* Validate the mount data */ error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name); - if (error < 0) + if (error < 0) { + mntroot = ERR_PTR(error); goto out; + } #ifdef CONFIG_NFS_V4 if (data->version == 4) { - error = nfs4_try_mount(flags, dev_name, data, mnt); + mntroot = nfs4_try_mount(flags, dev_name, data); kfree(data->client_address); kfree(data->nfs_server.export_path); goto out; @@ -2333,7 +2336,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, /* Get a volume representation */ server = nfs_create_server(data, mntfh); if (IS_ERR(server)) { - error = PTR_ERR(server); + mntroot = ERR_CAST(server); goto out; } sb_mntdata.server = server; @@ -2344,7 +2347,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, /* Get a superblock - note that we may end up sharing one that already exists */ s = sget(fs_type, compare_super, nfs_set_super, &sb_mntdata); if (IS_ERR(s)) { - error = PTR_ERR(s); + mntroot = ERR_CAST(s); goto out_err_nosb; } @@ -2353,8 +2356,10 @@ static int nfs_get_sb(struct file_system_type *fs_type, server = NULL; } else { error = nfs_bdi_register(server); - if (error) + if (error) { + mntroot = ERR_PTR(error); goto error_splat_bdi; + } } if (!s->s_root) { @@ -2365,19 +2370,14 @@ static int nfs_get_sb(struct file_system_type *fs_type, } mntroot = nfs_get_root(s, mntfh, dev_name); - if (IS_ERR(mntroot)) { - error = PTR_ERR(mntroot); + if (IS_ERR(mntroot)) goto error_splat_super; - } error = security_sb_set_mnt_opts(s, &data->lsm_opts); if (error) goto error_splat_root; s->s_flags |= MS_ACTIVE; - mnt->mnt_sb = s; - mnt->mnt_root = mntroot; - error = 0; out: kfree(data->nfs_server.hostname); @@ -2387,7 +2387,7 @@ out: out_free_fh: nfs_free_fhandle(mntfh); kfree(data); - return error; + return mntroot; out_err_nosb: nfs_free_server(server); @@ -2395,6 +2395,7 @@ out_err_nosb: error_splat_root: dput(mntroot); + mntroot = ERR_PTR(error); error_splat_super: if (server && !s->s_root) bdi_unregister(&server->backing_dev_info); @@ -2865,17 +2866,18 @@ static void nfs_referral_loop_unprotect(void) kfree(p); } -static int nfs_follow_remote_path(struct vfsmount *root_mnt, - const char *export_path, struct vfsmount *mnt_target) +static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt, + const char *export_path) { struct nameidata *nd = NULL; struct mnt_namespace *ns_private; struct super_block *s; + struct dentry *dentry; int ret; nd = kmalloc(sizeof(*nd), GFP_KERNEL); if (nd == NULL) - return -ENOMEM; + return ERR_PTR(-ENOMEM); ns_private = create_mnt_ns(root_mnt); ret = PTR_ERR(ns_private); @@ -2897,29 +2899,27 @@ static int nfs_follow_remote_path(struct vfsmount *root_mnt, s = nd->path.mnt->mnt_sb; atomic_inc(&s->s_active); - mnt_target->mnt_sb = s; - mnt_target->mnt_root = dget(nd->path.dentry); + dentry = dget(nd->path.dentry); path_put(&nd->path); kfree(nd); down_write(&s->s_umount); - return 0; + return dentry; out_put_mnt_ns: put_mnt_ns(ns_private); out_mntput: mntput(root_mnt); out_err: kfree(nd); - return ret; + return ERR_PTR(ret); } -static int nfs4_try_mount(int flags, const char *dev_name, - struct nfs_parsed_mount_data *data, - struct vfsmount *mnt) +static struct dentry *nfs4_try_mount(int flags, const char *dev_name, + struct nfs_parsed_mount_data *data) { char *export_path; struct vfsmount *root_mnt; - int error; + struct dentry *res; dfprintk(MOUNT, "--> nfs4_try_mount()\n"); @@ -2929,26 +2929,25 @@ static int nfs4_try_mount(int flags, const char *dev_name, data->nfs_server.hostname); data->nfs_server.export_path = export_path; - error = PTR_ERR(root_mnt); - if (IS_ERR(root_mnt)) - goto out; - - error = nfs_follow_remote_path(root_mnt, export_path, mnt); + res = ERR_CAST(root_mnt); + if (!IS_ERR(root_mnt)) + res = nfs_follow_remote_path(root_mnt, export_path); -out: - dfprintk(MOUNT, "<-- nfs4_try_mount() = %d%s\n", error, - error != 0 ? " [error]" : ""); - return error; + dfprintk(MOUNT, "<-- nfs4_try_mount() = %ld%s\n", + IS_ERR(res) ? PTR_ERR(res) : 0, + IS_ERR(res) ? " [error]" : ""); + return res; } /* * Get the superblock for an NFS4 mountpoint */ -static int nfs4_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) +static struct dentry *nfs4_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *raw_data) { struct nfs_parsed_mount_data *data; int error = -ENOMEM; + struct dentry *res = ERR_PTR(-ENOMEM); data = nfs_alloc_parsed_mount_data(4); if (data == NULL) @@ -2956,10 +2955,14 @@ static int nfs4_get_sb(struct file_system_type *fs_type, /* Validate the mount data */ error = nfs4_validate_mount_data(raw_data, data, dev_name); - if (error < 0) + if (error < 0) { + res = ERR_PTR(error); goto out; + } - error = nfs4_try_mount(flags, dev_name, data, mnt); + res = nfs4_try_mount(flags, dev_name, data); + if (IS_ERR(res)) + error = PTR_ERR(res); out: kfree(data->client_address); @@ -2968,9 +2971,9 @@ out: kfree(data->fscache_uniq); out_free_data: kfree(data); - dprintk("<-- nfs4_get_sb() = %d%s\n", error, + dprintk("<-- nfs4_mount() = %d%s\n", error, error != 0 ? " [error]" : ""); - return error; + return res; } static void nfs4_kill_super(struct super_block *sb) @@ -3164,16 +3167,15 @@ error_splat_bdi: /* * Create an NFS4 server record on referral traversal */ -static int nfs4_referral_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data, - struct vfsmount *mnt) +static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *raw_data) { struct nfs_clone_mount *data = raw_data; char *export_path; struct vfsmount *root_mnt; - int error; + struct dentry *res; - dprintk("--> nfs4_referral_get_sb()\n"); + dprintk("--> nfs4_referral_mount()\n"); export_path = data->mnt_path; data->mnt_path = "/"; @@ -3182,15 +3184,13 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, flags, data, data->hostname); data->mnt_path = export_path; - error = PTR_ERR(root_mnt); - if (IS_ERR(root_mnt)) - goto out; - - error = nfs_follow_remote_path(root_mnt, export_path, mnt); -out: - dprintk("<-- nfs4_referral_get_sb() = %d%s\n", error, - error != 0 ? " [error]" : ""); - return error; + res = ERR_CAST(root_mnt); + if (!IS_ERR(root_mnt)) + res = nfs_follow_remote_path(root_mnt, export_path); + dprintk("<-- nfs4_referral_mount() = %ld%s\n", + IS_ERR(res) ? PTR_ERR(res) : 0, + IS_ERR(res) ? " [error]" : ""); + return res; } #endif /* CONFIG_NFS_V4 */ -- cgit v1.2.3