int migrate_nfs_update_server(struct nfs_server *server, const char *hostname, struct sockaddr *sap, size_t salen, struct net *net) { struct nfs_client *clp = server->nfs_client; struct rpc_clnt *clnt = server->client; struct xprt_create xargs = { .ident = clp->cl_proto, .net = net, .dstaddr = sap, .addrlen = salen, .servername = hostname, }; char buf[INET6_ADDRSTRLEN + 1]; struct sockaddr_storage address; struct sockaddr *localaddr = (struct sockaddr *)&address; int error; dfprintk(MOUNT, "zql: --> %s: move FSID %llx:%llx to \"%s\")\n", __func__, (unsigned long long)server->fsid.major, (unsigned long long)server->fsid.minor, hostname); error = rpc_switch_client_transport(clnt, &xargs, clnt->cl_timeout); if (error != 0) { dfprintk(MOUNT, "zql: <-- %s(): rpc_switch_client_transport returned %d\n", __func__, error); goto out; } error = rpc_localaddr(clnt, localaddr, sizeof(address)); if (error != 0) { dfprintk(MOUNT, "zql: <-- %s(): rpc_localaddr returned %d\n", __func__, error); goto out; } error = -EAFNOSUPPORT; if (rpc_ntop(localaddr, buf, sizeof(buf)) == 0) { dfprintk(MOUNT, "zql: <-- %s(): rpc_ntop returned %d\n", __func__, error); goto out; } nfs_server_remove_lists(server); error = migrate_nfs_set_client(server, hostname, sap, salen, buf, clp->cl_rpcclient->cl_auth->au_flavor, clp->cl_proto, clnt->cl_timeout, clp->cl_minorversion, net); nfs_put_client(clp); if (error != 0) { nfs_server_insert_lists(server); dfprintk(MOUNT, "zql: <-- %s(): nfs4_set_client returned %d\n", __func__, error); goto out; } if (server->nfs_client->cl_hostname == NULL) server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL); nfs_server_insert_lists(server); error = migrate_nfs_probe_destination(server); if (error < 0) { dfprintk(MOUNT, "zql: error in migrate_nfs_probe_destination\n"); goto out; } dfprintk(MOUNT, "zql: <-- %s() succeeded\n", __func__); out: dfprintk(MOUNT, "zql: error in %s()\n", __func__); return error; } static void zql_update_server(struct nfs_server *server) { /* * we do not have to free server, * instead, we only update struct nfs_server. */ //nfs_free_server(server); /* free old nfs_client, though we can leave it there and use it when switch back */ //server->nfs_client->rpc_ops->free_client(server->nfs_client); //struct nfs_server parent_server; //struct nfs_client *parent_client; //struct nfs_subversion *nfs_mod; struct nfs_parsed_mount_data *parsed; //char raw_data[] = "addr=162.105.146.169,vers=3,proto=tcp,mountvers=3,mountproto=udp,mountport=20048"; /* keep old server parameter, copy original server to a temporary parameter */ //parent_server = *server; //parent_client = parent_server.nfs_client; /* generate nfs_parsed_mount_data */ parsed = nfs_alloc_parsed_mount_data(); if (parsed == NULL) dfprintk(MOUNT, "zql: nfs_alloc_parsed_mount_data error\n"); /* init nfs_parsed_mount_data */ if (nfs_zql_control == 168) migrate_nfs_validate_text_mount_data168(/*raw_data, */parsed/*, dev_name*/); else if (nfs_zql_control == 169) migrate_nfs_validate_text_mount_data169(parsed); else dfprintk(MOUNT, "zql: nfs_zql_control error\n"); migrate_nfs_update_server(server, parsed->nfs_server.hostname, (struct sockaddr *)&parsed->nfs_server.address, parsed->nfs_server.addrlen, parsed->net); /*nfs_mod = get_nfs_version(parsed->version); if (IS_ERR(nfs_mod)) dfprintk(MOUNT, "zql: get_nfs_version error\n");*/ /* init server->nfs_client */ //migrate_nfs_set_client(server, parsed, nfs_mod, parent_server.client->cl_timeout); //nfs_init_server_rpcclient(server, parent_server.client->cl_timeout, parsed->selected_flavor); //put_nfs_version(nfs_mod); nfs_free_parsed_mount_data(parsed); return; } static void zql_control_test(struct nfs_server *server) { if (nfs_zql_control == 5 || nfs_zql_control == 168 || nfs_zql_control == 169) { dfprintk(MOUNT, "zql: control start ... %d\n", nfs_zql_control); while (nfs_zql_control == 5) { msleep_interruptible(500); } if (nfs_zql_control == 168 || nfs_zql_control == 169) { spin_lock(&zql_switch_status); if (switch_status == 0) { switch_status = 1; spin_unlock(&zql_switch_status); dfprintk(MOUNT, "zql: switch succeed\n"); dfprintk(MOUNT, "zql: start update server\n"); zql_update_server(server); switch_status = 0; nfs_zql_control = 10; dfprintk(MOUNT, "zql: update server done\n"); } else { spin_unlock(&zql_switch_status); dfprintk(MOUNT, "zql: switch_status check\n"); while (switch_status == 1) { msleep_interruptible(100); } dfprintk(MOUNT, "zql: switch_status done\n"); } } else if (nfs_zql_control == 4) dfprintk(MOUNT, "zql: switch failed\n"); else dfprintk(MOUNT, "zql: unknown failure\n"); } } /* zql code end */ static const struct inode_operations nfs3_dir_inode_operations = { .create = nfs_create, .lookup = nfs_lookup, .link = nfs_link, .unlink = nfs_unlink, .symlink = nfs_symlink, .mkdir = nfs_mkdir, .rmdir = nfs_rmdir, .mknod = nfs_mknod, .rename = nfs_rename, .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, #ifdef CONFIG_NFS_V3_ACL .listxattr = nfs3_listxattr, .getxattr = generic_getxattr, .setxattr = generic_setxattr, .removexattr = generic_removexattr, .get_acl = nfs3_get_acl, .set_acl = nfs3_set_acl, #endif }; static const struct inode_operations nfs3_file_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, #ifdef CONFIG_NFS_V3_ACL .listxattr = nfs3_listxattr, .getxattr = generic_getxattr, .setxattr = generic_setxattr, .removexattr = generic_removexattr, .get_acl = nfs3_get_acl, .set_acl = nfs3_set_acl, #endif }; const struct nfs_rpc_ops nfs_v3_clientops = { .version = 3, /* protocol version */ .dentry_ops = &nfs_dentry_operations, .dir_inode_ops = &nfs3_dir_inode_operations, .file_inode_ops = &nfs3_file_inode_operations, .file_ops = &nfs_file_operations, .getroot = nfs3_proc_get_root, .submount = nfs_submount, .try_mount = nfs_try_mount, .getattr = nfs3_proc_getattr, .setattr = nfs3_proc_setattr, .lookup = nfs3_proc_lookup, .access = nfs3_proc_access, .readlink = nfs3_proc_readlink, .create = nfs3_proc_create, .remove = nfs3_proc_remove, .unlink_setup = nfs3_proc_unlink_setup, .unlink_rpc_prepare = nfs3_proc_unlink_rpc_prepare, .unlink_done = nfs3_proc_unlink_done, .rename_setup = nfs3_proc_rename_setup, .rename_rpc_prepare = nfs3_proc_rename_rpc_prepare, .rename_done = nfs3_proc_rename_done, .link = nfs3_proc_link, .symlink = nfs3_proc_symlink, .mkdir = nfs3_proc_mkdir, .rmdir = nfs3_proc_rmdir, .readdir = nfs3_proc_readdir, .mknod = nfs3_proc_mknod, .statfs = nfs3_proc_statfs, .fsinfo = nfs3_proc_fsinfo, .pathconf = nfs3_proc_pathconf, .decode_dirent = nfs3_decode_dirent, .pgio_rpc_prepare = nfs3_proc_pgio_rpc_prepare, .read_setup = nfs3_proc_read_setup, .read_done = nfs3_read_done, .write_setup = nfs3_proc_write_setup, .write_done = nfs3_write_done, .commit_setup = nfs3_proc_commit_setup, .commit_rpc_prepare = nfs3_proc_commit_rpc_prepare, .commit_done = nfs3_commit_done, .lock = nfs3_proc_lock, .clear_acl_cache = forget_all_cached_acls, .close_context = nfs_close_context, .have_delegation = nfs3_have_delegation, .return_delegation = nfs3_return_delegation, .alloc_client = nfs_alloc_client, .init_client = nfs_init_client, .free_client = nfs_free_client, .create_server = nfs3_create_server, .clone_server = nfs3_clone_server, };
/** * nfs4_init_client - Initialise an NFS4 client record * * @clp: nfs_client to initialise * @timeparms: timeout parameters for underlying RPC transport * @ip_addr: callback IP address in presentation format * @authflavor: authentication flavor for underlying RPC transport * * Returns pointer to an NFS client, or an ERR_PTR value. */ struct nfs_client *nfs4_init_client(struct nfs_client *clp, const struct rpc_timeout *timeparms, const char *ip_addr, rpc_authflavor_t authflavour) { char buf[INET6_ADDRSTRLEN + 1]; struct nfs_client *old; int error; if (clp->cl_cons_state == NFS_CS_READY) { /* the client is initialised already */ dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp); return clp; } /* Check NFS protocol revision and initialize RPC op vector */ clp->rpc_ops = &nfs_v4_clientops; if (clp->cl_minorversion != 0) __set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags); __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I); if (error == -EINVAL) error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX); if (error < 0) goto error; /* If no clientaddr= option was specified, find a usable cb address */ if (ip_addr == NULL) { struct sockaddr_storage cb_addr; struct sockaddr *sap = (struct sockaddr *)&cb_addr; error = rpc_localaddr(clp->cl_rpcclient, sap, sizeof(cb_addr)); if (error < 0) goto error; error = rpc_ntop(sap, buf, sizeof(buf)); if (error < 0) goto error; ip_addr = (const char *)buf; } strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); error = nfs_idmap_new(clp); if (error < 0) { dprintk("%s: failed to create idmapper. Error = %d\n", __func__, error); goto error; } __set_bit(NFS_CS_IDMAP, &clp->cl_res_state); error = nfs4_init_client_minor_version(clp); if (error < 0) goto error; if (!nfs4_has_session(clp)) nfs_mark_client_ready(clp, NFS_CS_READY); error = nfs4_discover_server_trunking(clp, &old); if (error < 0) goto error; if (clp != old) clp->cl_preserve_clid = true; nfs_put_client(clp); return old; error: nfs_mark_client_ready(clp, error); nfs_put_client(clp); dprintk("<-- nfs4_init_client() = xerror %d\n", error); return ERR_PTR(error); }