Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / base / services / nfsd / namespace.c
diff --git a/reactos/base/services/nfsd/namespace.c b/reactos/base/services/nfsd/namespace.c
deleted file mode 100644 (file)
index c593b41..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/* NFSv4.1 client for Windows
- * Copyright © 2012 The Regents of the University of Michigan
- *
- * Olga Kornievskaia <aglo@umich.edu>
- * Casey Bodley <cbodley@umich.edu>
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * without any warranty; without even the implied warranty of merchantability
- * or fitness for a particular purpose.  See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- */
-
-#include <windows.h>
-#include <strsafe.h>
-
-#include "nfs41_ops.h"
-#include "util.h"
-#include "daemon_debug.h"
-
-
-#define NSLVL 2 /* dprintf level for namespace logging */
-
-
-#define client_entry(pos) list_container(pos, nfs41_client, root_entry)
-
-
-/* nfs41_root */
-int nfs41_root_create(
-    IN const char *name,
-    IN uint32_t sec_flavor,
-    IN uint32_t wsize,
-    IN uint32_t rsize,
-    OUT nfs41_root **root_out)
-{
-    int status = NO_ERROR;
-    nfs41_root *root;
-
-    dprintf(NSLVL, "--> nfs41_root_create()\n");
-
-    root = calloc(1, sizeof(nfs41_root));
-    if (root == NULL) {
-        status = GetLastError();
-        goto out;
-    }
-
-    list_init(&root->clients);
-    root->wsize = wsize;
-    root->rsize = rsize;
-    InitializeCriticalSection(&root->lock);
-    root->ref_count = 1;
-    root->sec_flavor = sec_flavor;
-
-    /* generate a unique client_owner */
-    status = nfs41_client_owner(name, sec_flavor, &root->client_owner);
-    if (status) {
-        eprintf("nfs41_client_owner() failed with %d\n", status);
-        free(root);
-        goto out;
-    }
-
-    *root_out = root;
-out:
-    dprintf(NSLVL, "<-- nfs41_root_create() returning %d\n", status);
-    return status;
-}
-
-static void root_free(
-    IN nfs41_root *root)
-{
-    struct list_entry *entry, *tmp;
-
-    dprintf(NSLVL, "--> nfs41_root_free()\n");
-
-    /* free clients */
-    list_for_each_tmp(entry, tmp, &root->clients)
-        nfs41_client_free(client_entry(entry));
-    DeleteCriticalSection(&root->lock);
-    free(root);
-
-    dprintf(NSLVL, "<-- nfs41_root_free()\n");
-}
-
-void nfs41_root_ref(
-    IN nfs41_root *root)
-{
-    const LONG count = InterlockedIncrement(&root->ref_count);
-
-    dprintf(NSLVL, "nfs41_root_ref() count %d\n", count);
-}
-
-void nfs41_root_deref(
-    IN nfs41_root *root)
-{
-    const LONG count = InterlockedDecrement(&root->ref_count);
-
-    dprintf(NSLVL, "nfs41_root_deref() count %d\n", count);
-    if (count == 0)
-        root_free(root);
-}
-
-
-/* root_client_find_addrs() */
-struct cl_addr_info {
-    const multi_addr4       *addrs;
-    uint32_t                roles;
-};
-
-static int cl_addr_compare(
-    IN const struct list_entry *entry,
-    IN const void *value)
-{
-    nfs41_client *client = client_entry(entry);
-    const struct cl_addr_info *info = (const struct cl_addr_info*)value;
-    uint32_t i, roles;
-
-    /* match any of the desired roles */
-    AcquireSRWLockShared(&client->exid_lock);
-    roles = info->roles & client->roles;
-    ReleaseSRWLockShared(&client->exid_lock);
-
-    if (roles == 0)
-        return ERROR_FILE_NOT_FOUND;
-
-    /* match any address in 'addrs' with any address in client->rpc->addrs */
-    for (i = 0; i < info->addrs->count; i++)
-        if (multi_addr_find(&client->rpc->addrs, &info->addrs->arr[i], NULL))
-            return NO_ERROR;
-
-    return ERROR_FILE_NOT_FOUND;
-}
-
-static int root_client_find_addrs(
-    IN nfs41_root *root,
-    IN const multi_addr4 *addrs,
-    IN bool_t is_data,
-    OUT nfs41_client **client_out)
-{
-    struct cl_addr_info info;
-    struct list_entry *entry;
-    int status;
-
-    dprintf(NSLVL, "--> root_client_find_addrs()\n");
-
-    info.addrs = addrs;
-    info.roles = nfs41_exchange_id_flags(is_data) & EXCHGID4_FLAG_MASK_PNFS;
-
-    entry = list_search(&root->clients, &info, cl_addr_compare);
-    if (entry) {
-        *client_out = client_entry(entry);
-        status = NO_ERROR;
-        dprintf(NSLVL, "<-- root_client_find_addrs() returning 0x%p\n",
-            *client_out);
-    } else {
-        status = ERROR_FILE_NOT_FOUND;
-        dprintf(NSLVL, "<-- root_client_find_addrs() failed with %d\n",
-            status);
-    }
-    return status;
-}
-
-/* root_client_find() */
-struct cl_exid_info {
-    const nfs41_exchange_id_res *exchangeid;
-    uint32_t                roles;
-};
-
-static int cl_exid_compare(
-    IN const struct list_entry *entry,
-    IN const void *value)
-{
-    nfs41_client *client = client_entry(entry);
-    const struct cl_exid_info *info = (const struct cl_exid_info*)value;
-    int status = ERROR_FILE_NOT_FOUND;
-
-    AcquireSRWLockShared(&client->exid_lock);
-
-    /* match any of the desired roles */
-    if ((info->roles & client->roles) == 0)
-        goto out;
-    /* match server_owner.major_id */
-    if (strncmp(info->exchangeid->server_owner.so_major_id,
-        client->server->owner, NFS4_OPAQUE_LIMIT) != 0)
-        goto out;
-    /* match server_scope */
-    if (strncmp(info->exchangeid->server_scope,
-        client->server->scope, NFS4_OPAQUE_LIMIT) != 0)
-        goto out;
-    /* match clientid */
-    if (info->exchangeid->clientid != client->clnt_id)
-        goto out;
-
-    status = NO_ERROR;
-out:
-    ReleaseSRWLockShared(&client->exid_lock);
-    return status;
-}
-
-static int root_client_find(
-    IN nfs41_root *root,
-    IN const nfs41_exchange_id_res *exchangeid,
-    IN bool_t is_data,
-    OUT nfs41_client **client_out)
-{
-    struct cl_exid_info info;
-    struct list_entry *entry;
-    int status;
-
-    dprintf(NSLVL, "--> root_client_find()\n");
-
-    info.exchangeid = exchangeid;
-    info.roles = nfs41_exchange_id_flags(is_data) & EXCHGID4_FLAG_MASK_PNFS;
-
-    entry = list_search(&root->clients, &info, cl_exid_compare);
-    if (entry) {
-        *client_out = client_entry(entry);
-        status = NO_ERROR;
-        dprintf(NSLVL, "<-- root_client_find() returning 0x%p\n",
-            *client_out);
-    } else {
-        status = ERROR_FILE_NOT_FOUND;
-        dprintf(NSLVL, "<-- root_client_find() failed with %d\n",
-            status);
-    }
-    return status;
-}
-
-static int session_get_lease(
-    IN nfs41_session *session,
-    IN OPTIONAL uint32_t lease_time)
-{
-    bool_t use_mds_lease;
-    int status;
-
-    /* http://tools.ietf.org/html/rfc5661#section-13.1.1
-     * 13.1.1. Sessions Considerations for Data Servers:
-     * If the reply to EXCHANGE_ID has just the EXCHGID4_FLAG_USE_PNFS_DS role
-     * set, then (as noted in Section 13.6) the client will not be able to
-     * determine the data server's lease_time attribute because GETATTR will
-     * not be permitted.  Instead, the rule is that any time a client
-     * receives a layout referring it to a data server that returns just the
-     * EXCHGID4_FLAG_USE_PNFS_DS role, the client MAY assume that the
-     * lease_time attribute from the metadata server that returned the
-     * layout applies to the data server. */
-    AcquireSRWLockShared(&session->client->exid_lock);
-    use_mds_lease = session->client->roles == EXCHGID4_FLAG_USE_PNFS_DS;
-    ReleaseSRWLockShared(&session->client->exid_lock);
-
-    if (!use_mds_lease) {
-        /* the client is allowed to GETATTR, so query the lease_time */
-        nfs41_file_info info = { 0 };
-        bitmap4 attr_request = { 1, { FATTR4_WORD0_LEASE_TIME, 0, 0 } };
-
-        status = nfs41_getattr(session, NULL, &attr_request, &info);
-        if (status) {
-            eprintf("nfs41_getattr() failed with %s\n",
-                nfs_error_string(status));
-            status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
-            goto out;
-        }
-        lease_time = info.lease_time;
-    }
-
-    status = nfs41_session_set_lease(session, lease_time);
-    if (status) {
-        eprintf("nfs41_session_set_lease() failed %d\n", status);
-        goto out;
-    }
-out:
-    return status;
-}
-
-static int root_client_create(
-    IN nfs41_root *root,
-    IN nfs41_rpc_clnt *rpc,
-    IN bool_t is_data,
-    IN OPTIONAL uint32_t lease_time,
-    IN const nfs41_exchange_id_res *exchangeid,
-    OUT nfs41_client **client_out)
-{
-    nfs41_client *client;
-    nfs41_session *session;
-    int status;
-
-    /* create client (transfers ownership of rpc to client) */
-    status = nfs41_client_create(rpc, &root->client_owner,
-        is_data, exchangeid, &client);
-    if (status) {
-        eprintf("nfs41_client_create() failed with %d\n", status);
-        goto out;
-    }
-    client->root = root;
-    rpc->client = client;
-
-    /* create session (and client takes ownership) */
-    status = nfs41_session_create(client, &session);
-    if (status) {
-        eprintf("nfs41_session_create failed %d\n", status);
-        goto out_err;
-    }
-
-    if (!is_data) {
-        /* send RECLAIM_COMPLETE, but don't fail on ERR_NOTSUPP */
-        status = nfs41_reclaim_complete(session);
-        if (status && status != NFS4ERR_NOTSUPP) {
-            eprintf("nfs41_reclaim_complete() failed with %s\n",
-                nfs_error_string(status));
-            status = ERROR_BAD_NETPATH;
-            goto out_err;
-        }
-    }
-
-    /* get least time and start session renewal thread */
-    status = session_get_lease(session, lease_time);
-    if (status)
-        goto out_err;
-
-    *client_out = client;
-out:
-    return status;
-
-out_err:
-    nfs41_client_free(client);
-    goto out;
-}
-
-int nfs41_root_mount_addrs(
-    IN nfs41_root *root,
-    IN const multi_addr4 *addrs,
-    IN bool_t is_data,
-    IN OPTIONAL uint32_t lease_time,
-    OUT nfs41_client **client_out)
-{
-    nfs41_exchange_id_res exchangeid = { 0 };
-    nfs41_rpc_clnt *rpc;
-    nfs41_client *client, *existing;
-    int status;
-
-    dprintf(NSLVL, "--> nfs41_root_mount_addrs()\n");
-
-    /* look for an existing client that matches the address and role */
-    EnterCriticalSection(&root->lock);
-    status = root_client_find_addrs(root, addrs, is_data, &client);
-    LeaveCriticalSection(&root->lock);
-
-    if (status == NO_ERROR)
-        goto out;
-
-    /* create an rpc client */
-    status = nfs41_rpc_clnt_create(addrs, root->wsize, root->rsize,
-        root->uid, root->gid, root->sec_flavor, &rpc);
-    if (status) {
-        eprintf("nfs41_rpc_clnt_create() failed %d\n", status);
-        goto out;
-    }
-
-    /* get a clientid with exchangeid */
-    status = nfs41_exchange_id(rpc, &root->client_owner,
-        nfs41_exchange_id_flags(is_data), &exchangeid);
-    if (status) {
-        eprintf("nfs41_exchange_id() failed %s\n", nfs_error_string(status));
-        status = ERROR_BAD_NET_RESP;
-        goto out_free_rpc;
-    }
-
-    /* attempt to match existing clients by the exchangeid response */
-    EnterCriticalSection(&root->lock);
-    status = root_client_find(root, &exchangeid, is_data, &client);
-    LeaveCriticalSection(&root->lock);
-
-    if (status == NO_ERROR)
-        goto out_free_rpc;
-
-    /* create a client for this clientid */
-    status = root_client_create(root, rpc, is_data,
-        lease_time, &exchangeid, &client);
-    if (status) {
-        eprintf("nfs41_client_create() failed %d\n", status);
-        /* root_client_create takes care of cleaning up 
-         * thus don't go to out_free_rpc */
-        goto out;
-    }
-
-    /* because we don't hold the root's lock over session creation,
-     * we could end up creating multiple clients with the same
-     * server and roles */
-    EnterCriticalSection(&root->lock);
-    status = root_client_find(root, &exchangeid, is_data, &existing);
-
-    if (status) {
-        dprintf(NSLVL, "caching new client 0x%p\n", client);
-
-        /* the client is not a duplicate, so add it to the list */
-        list_add_tail(&root->clients, &client->root_entry);
-        status = NO_ERROR;
-    } else {
-        dprintf(NSLVL, "created a duplicate client 0x%p! using "
-            "existing client 0x%p instead\n", client, existing);
-
-        /* a matching client has been created in parallel, so free
-         * the one we created and use the existing client instead */
-        nfs41_client_free(client);
-        client = existing;
-    }
-    LeaveCriticalSection(&root->lock);
-
-out:
-    if (status == NO_ERROR)
-        *client_out = client;
-    dprintf(NSLVL, "<-- nfs41_root_mount_addrs() returning %d\n", status);
-    return status;
-
-out_free_rpc:
-    nfs41_rpc_clnt_free(rpc);
-    goto out;
-}
-
-
-/* http://tools.ietf.org/html/rfc5661#section-11.9
- * 11.9. The Attribute fs_locations
- * An entry in the server array is a UTF-8 string and represents one of a
- * traditional DNS host name, IPv4 address, IPv6 address, or a zero-length
- * string.  An IPv4 or IPv6 address is represented as a universal address
- * (see Section 3.3.9 and [15]), minus the netid, and either with or without
- * the trailing ".p1.p2" suffix that represents the port number.  If the
- * suffix is omitted, then the default port, 2049, SHOULD be assumed.  A
- * zero-length string SHOULD be used to indicate the current address being
- * used for the RPC call. */
-static int referral_mount_location(
-    IN nfs41_root *root,
-    IN const fs_location4 *loc,
-    OUT nfs41_client **client_out)
-{
-    multi_addr4 addrs;
-    int status = ERROR_BAD_NET_NAME;
-    uint32_t i;
-
-    /* create a client and session for the first available server */
-    for (i = 0; i < loc->server_count; i++) {
-        /* XXX: only deals with 'address' as a hostname with default port */
-        status = nfs41_server_resolve(loc->servers[i].address, 2049, &addrs);
-        if (status) continue;
-
-        status = nfs41_root_mount_addrs(root, &addrs, 0, 0, client_out);
-        if (status == NO_ERROR)
-            break;
-    }
-    return status;
-}
-
-int nfs41_root_mount_referral(
-    IN nfs41_root *root,
-    IN const fs_locations4 *locations,
-    OUT const fs_location4 **loc_out,
-    OUT nfs41_client **client_out)
-{
-    int status = ERROR_BAD_NET_NAME;
-    uint32_t i;
-
-    /* establish a mount to the first available location */
-    for (i = 0; i < locations->location_count; i++) {
-        status = referral_mount_location(root,
-            &locations->locations[i], client_out);
-        if (status == NO_ERROR) {
-            *loc_out = &locations->locations[i];
-            break;
-        }
-    }
-    return status;
-}