aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorManoj Naik <manoj@almaden.ibm.com>2006-06-09 09:34:27 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-09 09:34:27 -0400
commit61f5164cab1f6fdf06871ea9d60fe2f912184078 (patch)
tree966e8279f9563ceda4b919f309832c3336642abb /fs
parentc818ba43f9ca2e8214412ab5f126b1f436c35098 (diff)
NFS: Expand clone mounts to include other servers
Signed-off-by: Manoj Naik <manoj@almaden.ibm.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/inode.c111
1 files changed, 64 insertions, 47 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index db62a5a7e4fc..ebdab885c475 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1717,14 +1717,13 @@ struct nfs_clone_mount {
1717}; 1717};
1718 1718
1719static struct super_block *nfs_clone_generic_sb(struct nfs_clone_mount *data, 1719static struct super_block *nfs_clone_generic_sb(struct nfs_clone_mount *data,
1720 struct super_block *(*clone_client)(struct nfs_server *, struct nfs_clone_mount *)) 1720 struct super_block *(*fill_sb)(struct nfs_server *, struct nfs_clone_mount *),
1721 struct nfs_server *(*fill_server)(struct super_block *, struct nfs_clone_mount *))
1721{ 1722{
1722 struct nfs_server *server; 1723 struct nfs_server *server;
1723 struct nfs_server *parent = NFS_SB(data->sb); 1724 struct nfs_server *parent = NFS_SB(data->sb);
1724 struct super_block *sb = ERR_PTR(-EINVAL); 1725 struct super_block *sb = ERR_PTR(-EINVAL);
1725 void *err = ERR_PTR(-ENOMEM); 1726 void *err = ERR_PTR(-ENOMEM);
1726 struct inode *root_inode;
1727 struct nfs_fsinfo fsinfo;
1728 int len; 1727 int len;
1729 1728
1730 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); 1729 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL);
@@ -1736,53 +1735,17 @@ static struct super_block *nfs_clone_generic_sb(struct nfs_clone_mount *data,
1736 if (server->hostname == NULL) 1735 if (server->hostname == NULL)
1737 goto free_server; 1736 goto free_server;
1738 memcpy(server->hostname, parent->hostname, len); 1737 memcpy(server->hostname, parent->hostname, len);
1739 server->fsid = data->fattr->fsid;
1740 nfs_copy_fh(&server->fh, data->fh);
1741 if (rpciod_up() != 0) 1738 if (rpciod_up() != 0)
1742 goto free_hostname; 1739 goto free_hostname;
1743 1740
1744 sb = clone_client(server, data); 1741 sb = fill_sb(server, data);
1745 if (IS_ERR((err = sb)) || sb->s_root) 1742 if (IS_ERR((err = sb)) || sb->s_root)
1746 goto kill_rpciod; 1743 goto kill_rpciod;
1747 1744
1748 sb->s_op = data->sb->s_op; 1745 server = fill_server(sb, data);
1749 sb->s_blocksize = data->sb->s_blocksize; 1746 if (IS_ERR((err = server)))
1750 sb->s_blocksize_bits = data->sb->s_blocksize_bits;
1751 sb->s_maxbytes = data->sb->s_maxbytes;
1752
1753 server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
1754 err = ERR_PTR(-ENOMEM);
1755 server->io_stats = nfs_alloc_iostats();
1756 if (server->io_stats == NULL)
1757 goto out_deactivate; 1747 goto out_deactivate;
1758
1759 server->client = rpc_clone_client(parent->client);
1760 if (IS_ERR((err = server->client)))
1761 goto out_deactivate;
1762 if (!IS_ERR(parent->client_sys)) {
1763 server->client_sys = rpc_clone_client(parent->client_sys);
1764 if (IS_ERR((err = server->client_sys)))
1765 goto out_deactivate;
1766 }
1767 if (!IS_ERR(parent->client_acl)) {
1768 server->client_acl = rpc_clone_client(parent->client_acl);
1769 if (IS_ERR((err = server->client_acl)))
1770 goto out_deactivate;
1771 }
1772 root_inode = nfs_fhget(sb, data->fh, data->fattr);
1773 if (!root_inode)
1774 goto out_deactivate;
1775 sb->s_root = d_alloc_root(root_inode);
1776 if (!sb->s_root)
1777 goto out_put_root;
1778 fsinfo.fattr = data->fattr;
1779 if (NFS_PROTO(root_inode)->fsinfo(server, data->fh, &fsinfo) == 0)
1780 nfs_super_set_maxbytes(sb, fsinfo.maxfilesize);
1781 sb->s_root->d_op = server->rpc_ops->dentry_ops;
1782 sb->s_flags |= MS_ACTIVE;
1783 return sb; 1748 return sb;
1784out_put_root:
1785 iput(root_inode);
1786out_deactivate: 1749out_deactivate:
1787 up_write(&sb->s_umount); 1750 up_write(&sb->s_umount);
1788 deactivate_super(sb); 1751 deactivate_super(sb);
@@ -1955,21 +1918,73 @@ static struct file_system_type nfs_fs_type = {
1955 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 1918 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
1956}; 1919};
1957 1920
1958static struct super_block *nfs_clone_client(struct nfs_server *server, struct nfs_clone_mount *data) 1921static struct super_block *nfs_clone_sb(struct nfs_server *server, struct nfs_clone_mount *data)
1959{ 1922{
1960 struct super_block *sb; 1923 struct super_block *sb;
1961 1924
1925 server->fsid = data->fattr->fsid;
1926 nfs_copy_fh(&server->fh, data->fh);
1962 sb = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server); 1927 sb = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
1963 if (!IS_ERR(sb) && sb->s_root == NULL && !(server->flags & NFS_MOUNT_NONLM)) 1928 if (!IS_ERR(sb) && sb->s_root == NULL && !(server->flags & NFS_MOUNT_NONLM))
1964 lockd_up(); 1929 lockd_up();
1965 return sb; 1930 return sb;
1966} 1931}
1967 1932
1933static struct nfs_server *nfs_clone_server(struct super_block *sb, struct nfs_clone_mount *data)
1934{
1935 struct nfs_server *server = NFS_SB(sb);
1936 struct nfs_server *parent = NFS_SB(data->sb);
1937 struct inode *root_inode;
1938 struct nfs_fsinfo fsinfo;
1939 void *err = ERR_PTR(-ENOMEM);
1940
1941 sb->s_op = data->sb->s_op;
1942 sb->s_blocksize = data->sb->s_blocksize;
1943 sb->s_blocksize_bits = data->sb->s_blocksize_bits;
1944 sb->s_maxbytes = data->sb->s_maxbytes;
1945
1946 server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
1947 server->io_stats = nfs_alloc_iostats();
1948 if (server->io_stats == NULL)
1949 goto out;
1950
1951 server->client = rpc_clone_client(parent->client);
1952 if (IS_ERR((err = server->client)))
1953 goto out;
1954
1955 if (!IS_ERR(parent->client_sys)) {
1956 server->client_sys = rpc_clone_client(parent->client_sys);
1957 if (IS_ERR((err = server->client_sys)))
1958 goto out;
1959 }
1960 if (!IS_ERR(parent->client_acl)) {
1961 server->client_acl = rpc_clone_client(parent->client_acl);
1962 if (IS_ERR((err = server->client_acl)))
1963 goto out;
1964 }
1965 root_inode = nfs_fhget(sb, data->fh, data->fattr);
1966 if (!root_inode)
1967 goto out;
1968 sb->s_root = d_alloc_root(root_inode);
1969 if (!sb->s_root)
1970 goto out_put_root;
1971 fsinfo.fattr = data->fattr;
1972 if (NFS_PROTO(root_inode)->fsinfo(server, data->fh, &fsinfo) == 0)
1973 nfs_super_set_maxbytes(sb, fsinfo.maxfilesize);
1974 sb->s_root->d_op = server->rpc_ops->dentry_ops;
1975 sb->s_flags |= MS_ACTIVE;
1976 return server;
1977out_put_root:
1978 iput(root_inode);
1979out:
1980 return err;
1981}
1982
1968static struct super_block *nfs_clone_nfs_sb(struct file_system_type *fs_type, 1983static struct super_block *nfs_clone_nfs_sb(struct file_system_type *fs_type,
1969 int flags, const char *dev_name, void *raw_data) 1984 int flags, const char *dev_name, void *raw_data)
1970{ 1985{
1971 struct nfs_clone_mount *data = raw_data; 1986 struct nfs_clone_mount *data = raw_data;
1972 return nfs_clone_generic_sb(data, nfs_clone_client); 1987 return nfs_clone_generic_sb(data, nfs_clone_sb, nfs_clone_server);
1973} 1988}
1974 1989
1975static struct file_system_type clone_nfs_fs_type = { 1990static struct file_system_type clone_nfs_fs_type = {
@@ -2371,12 +2386,14 @@ static inline char *nfs4_dup_path(const struct dentry *dentry)
2371 return path; 2386 return path;
2372} 2387}
2373 2388
2374static struct super_block *nfs4_clone_client(struct nfs_server *server, struct nfs_clone_mount *data) 2389static struct super_block *nfs4_clone_sb(struct nfs_server *server, struct nfs_clone_mount *data)
2375{ 2390{
2376 const struct dentry *dentry = data->dentry; 2391 const struct dentry *dentry = data->dentry;
2377 struct nfs4_client *clp = server->nfs4_state; 2392 struct nfs4_client *clp = server->nfs4_state;
2378 struct super_block *sb; 2393 struct super_block *sb;
2379 2394
2395 server->fsid = data->fattr->fsid;
2396 nfs_copy_fh(&server->fh, data->fh);
2380 server->mnt_path = nfs4_dup_path(dentry); 2397 server->mnt_path = nfs4_dup_path(dentry);
2381 if (IS_ERR(server->mnt_path)) { 2398 if (IS_ERR(server->mnt_path)) {
2382 sb = (struct super_block *)server->mnt_path; 2399 sb = (struct super_block *)server->mnt_path;
@@ -2403,12 +2420,12 @@ static struct super_block *nfs_clone_nfs4_sb(struct file_system_type *fs_type,
2403 int flags, const char *dev_name, void *raw_data) 2420 int flags, const char *dev_name, void *raw_data)
2404{ 2421{
2405 struct nfs_clone_mount *data = raw_data; 2422 struct nfs_clone_mount *data = raw_data;
2406 return nfs_clone_generic_sb(data, nfs4_clone_client); 2423 return nfs_clone_generic_sb(data, nfs4_clone_sb, nfs_clone_server);
2407} 2424}
2408 2425
2409static struct file_system_type clone_nfs4_fs_type = { 2426static struct file_system_type clone_nfs4_fs_type = {
2410 .owner = THIS_MODULE, 2427 .owner = THIS_MODULE,
2411 .name = "nfs", 2428 .name = "nfs4",
2412 .get_sb = nfs_clone_nfs4_sb, 2429 .get_sb = nfs_clone_nfs4_sb,
2413 .kill_sb = nfs4_kill_super, 2430 .kill_sb = nfs4_kill_super,
2414 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 2431 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,