2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A
2N/A#include <stdio.h>
2N/A#include <fcntl.h>
2N/A#include <sys/types.h>
2N/A#include <attr.h>
2N/A#include <libnvpair.h>
2N/A#include <sys/int_fmtio.h>
2N/A#include <string.h>
2N/A#include <atomic.h>
2N/A#include <assert.h>
2N/A#include <libuvfs_impl.h>
2N/A
2N/Auint64_t
2N/Alibuvfs_get_fsid(const char *path)
2N/A{
2N/A nvlist_t *nvl = NULL;
2N/A uint64_t fsid = 0;
2N/A
2N/A if (getattrat(AT_FDCWD, XATTR_VIEW_READONLY, path, &nvl))
2N/A return (0);
2N/A if (nvlist_lookup_uint64(nvl, A_FSID, &fsid))
2N/A return (0);
2N/A if (nvl != NULL)
2N/A nvlist_free(nvl);
2N/A
2N/A return (fsid);
2N/A}
2N/A
2N/Avoid
2N/Alibuvfs_fsid_to_str(const uint64_t fsid, char *result, int size)
2N/A{
2N/A (void) snprintf(result, size, "%016" PRIx64, fsid);
2N/A}
2N/A
2N/Auint64_t
2N/Alibuvfs_str_to_fsid(const char *fsidstr)
2N/A{
2N/A uint64_t fsid;
2N/A
2N/A fsid = strtoll(fsidstr, NULL, 16);
2N/A
2N/A return (fsid);
2N/A}
2N/A
2N/Avoid
2N/Alibuvfs_fid_unique(libuvfs_fs_t *fs, libuvfs_fid_t *fid)
2N/A{
2N/A libuvfs_fh_t fh;
2N/A uint64_t seq;
2N/A
2N/A (void) memcpy(&fh.fs_fid_random, &fs->fs_fid_random,
2N/A sizeof (fh.fs_fid_random));
2N/A seq = atomic_add_64_nv(&fs->fs_fid_seq, 1);
2N/A (void) memcpy(&fh.fs_fid_seq, &seq, sizeof (fh.fs_fid_seq));
2N/A
2N/A fid->uvfid_len = sizeof (fh);
2N/A (void) memcpy(fid->uvfid_data, &fh, sizeof (fh));
2N/A}
2N/A
2N/A/*
2N/A * NB: this must only be called on fids that are generated via
2N/A * libuvfs_fid_unique()! If that is not the case, then another
2N/A * scheme to derive id numbers must be used.
2N/A */
2N/Auint64_t
2N/Alibuvfs_fid_to_id(libuvfs_fs_t *fs, const libuvfs_fid_t *fid)
2N/A{
2N/A libuvfs_fh_t *fh = (libuvfs_fh_t *)(&fid->uvfid_data);
2N/A uint64_t id;
2N/A
2N/A assert(fid->uvfid_len == sizeof (libuvfs_fh_t));
2N/A assert(memcmp(&fh->fs_fid_random, &fs->fs_fid_random,
2N/A sizeof (fh->fs_fid_random)) == 0);
2N/A
2N/A (void) memcpy(&id, &fh->fs_fid_seq, sizeof (id));
2N/A
2N/A return (id);
2N/A}
2N/A
2N/Aint
2N/Alibuvfs_fid_compare(const libuvfs_fid_t *a, const libuvfs_fid_t *b)
2N/A{
2N/A int rc;
2N/A
2N/A rc = a->uvfid_len - b->uvfid_len;
2N/A if (rc < 0)
2N/A return (-1);
2N/A if (rc > 0)
2N/A return (1);
2N/A
2N/A rc = memcmp(a->uvfid_data, b->uvfid_data, a->uvfid_len);
2N/A if (rc < 0)
2N/A return (-1);
2N/A if (rc > 0)
2N/A return (1);
2N/A
2N/A return (0);
2N/A}