From 458ecb1bc04594b00c4f29b636e9d1b073ad257b Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 7 Aug 2012 12:37:53 -0700 Subject: [PATCH] hammer2 - add HAMMER2IOC_PFS_LOOKUP * Add the HAMMER2IOC_PFS_LOOKUP ioctl which looks up a specific PFS by name. --- sys/vfs/hammer2/hammer2_ioctl.c | 64 +++++++++++++++++++++++++++++++++ sys/vfs/hammer2/hammer2_ioctl.h | 1 + 2 files changed, 65 insertions(+) diff --git a/sys/vfs/hammer2/hammer2_ioctl.c b/sys/vfs/hammer2/hammer2_ioctl.c index 6ed6ca5e3f..7df7e88019 100644 --- a/sys/vfs/hammer2/hammer2_ioctl.c +++ b/sys/vfs/hammer2/hammer2_ioctl.c @@ -50,6 +50,7 @@ static int hammer2_ioctl_remote_rep(hammer2_inode_t *ip, void *data); static int hammer2_ioctl_socket_get(hammer2_inode_t *ip, void *data); static int hammer2_ioctl_socket_set(hammer2_inode_t *ip, void *data); static int hammer2_ioctl_pfs_get(hammer2_inode_t *ip, void *data); +static int hammer2_ioctl_pfs_lookup(hammer2_inode_t *ip, void *data); static int hammer2_ioctl_pfs_create(hammer2_inode_t *ip, void *data); static int hammer2_ioctl_pfs_delete(hammer2_inode_t *ip, void *data); static int hammer2_ioctl_inode_get(hammer2_inode_t *ip, void *data); @@ -99,6 +100,10 @@ hammer2_ioctl(hammer2_inode_t *ip, u_long com, void *data, int fflag, if (error == 0) error = hammer2_ioctl_pfs_get(ip, data); break; + case HAMMER2IOC_PFS_LOOKUP: + if (error == 0) + error = hammer2_ioctl_pfs_lookup(ip, data); + break; case HAMMER2IOC_PFS_CREATE: if (error == 0) error = hammer2_ioctl_pfs_create(ip, data); @@ -352,6 +357,65 @@ done: return (error); } +/* + * Find a specific PFS by name + */ +static int +hammer2_ioctl_pfs_lookup(hammer2_inode_t *ip, void *data) +{ + hammer2_mount_t *hmp = ip->hmp; + hammer2_ioc_pfs_t *pfs = data; + hammer2_chain_t *parent; + hammer2_chain_t *chain; + hammer2_inode_t *xip; + hammer2_key_t lhc; + int error = 0; + size_t len; + + parent = hmp->schain; + error = hammer2_chain_lock(hmp, parent, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); + if (error) + goto done; + + pfs->name[sizeof(pfs->name) - 1] = 0; + len = strlen(pfs->name); + lhc = hammer2_dirhash(pfs->name, len); + + chain = hammer2_chain_lookup(hmp, &parent, + lhc, lhc + HAMMER2_DIRHASH_LOMASK, + HAMMER2_LOOKUP_SHARED); + while (chain) { + if (chain->bref.type == HAMMER2_BREF_TYPE_INODE && + chain->u.ip && + len == chain->data->ipdata.name_len && + bcmp(pfs->name, chain->data->ipdata.filename, len) == 0) { + break; + } + chain = hammer2_chain_next(hmp, &parent, chain, + lhc, lhc + HAMMER2_DIRHASH_LOMASK, + HAMMER2_LOOKUP_SHARED); + } + + /* + * Load the data being returned by the ioctl. + */ + if (chain) { + xip = chain->u.ip; + pfs->name_key = xip->ip_data.name_key; + pfs->pfs_type = xip->ip_data.pfs_type; + pfs->pfs_clid = xip->ip_data.pfs_clid; + pfs->pfs_fsid = xip->ip_data.pfs_fsid; + + hammer2_chain_unlock(hmp, chain); + } else { + error = ENOENT; + } +done: + hammer2_chain_unlock(hmp, parent); + return (error); +} + /* * Create a new PFS under the super-root */ diff --git a/sys/vfs/hammer2/hammer2_ioctl.h b/sys/vfs/hammer2/hammer2_ioctl.h index 0dc8f2b3bc..6d96b28458 100644 --- a/sys/vfs/hammer2/hammer2_ioctl.h +++ b/sys/vfs/hammer2/hammer2_ioctl.h @@ -126,6 +126,7 @@ typedef struct hammer2_ioc_inode hammer2_ioc_inode_t; #define HAMMER2IOC_PFS_GET _IOWR('h', 80, struct hammer2_ioc_pfs) #define HAMMER2IOC_PFS_CREATE _IOWR('h', 81, struct hammer2_ioc_pfs) #define HAMMER2IOC_PFS_DELETE _IOWR('h', 82, struct hammer2_ioc_pfs) +#define HAMMER2IOC_PFS_LOOKUP _IOWR('h', 83, struct hammer2_ioc_pfs) #define HAMMER2IOC_INODE_GET _IOWR('h', 86, struct hammer2_ioc_inode) #define HAMMER2IOC_INODE_SET _IOWR('h', 87, struct hammer2_ioc_inode) -- 2.41.0