linux/fs/fscache/netfs.c
David Howells ec0328e46d fscache: Maintain a catalogue of allocated cookies
Maintain a catalogue of allocated cookies so that cookie collisions can be
handled properly.  For the moment, this just involves printing a warning
and returning a NULL cookie to the caller of fscache_acquire_cookie(), but
in future it might make sense to wait for the old cookie to finish being
cleaned up.

This requires the cookie key to be stored attached to the cookie so that we
still have the key available if the netfs relinquishes the cookie.  This is
done by an earlier patch.

The catalogue also renders redundant fscache_netfs_list (used for checking
for duplicates), so that can be removed.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Anna Schumaker <anna.schumaker@netapp.com>
Tested-by: Steve Dickson <steved@redhat.com>
2018-04-06 14:05:14 +01:00

79 lines
2.1 KiB
C

/* FS-Cache netfs (client) registration
*
* Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
#define FSCACHE_DEBUG_LEVEL COOKIE
#include <linux/module.h>
#include <linux/slab.h>
#include "internal.h"
/*
* register a network filesystem for caching
*/
int __fscache_register_netfs(struct fscache_netfs *netfs)
{
struct fscache_cookie *candidate, *cookie;
_enter("{%s}", netfs->name);
/* allocate a cookie for the primary index */
candidate = fscache_alloc_cookie(&fscache_fsdef_index,
&fscache_fsdef_netfs_def,
netfs->name, strlen(netfs->name),
&netfs->version, sizeof(netfs->version),
netfs, 0);
if (!candidate) {
_leave(" = -ENOMEM");
return -ENOMEM;
}
candidate->flags = 1 << FSCACHE_COOKIE_ENABLED;
/* check the netfs type is not already present */
cookie = fscache_hash_cookie(candidate);
if (!cookie)
goto already_registered;
if (cookie != candidate) {
trace_fscache_cookie(candidate, fscache_cookie_discard, 1);
fscache_free_cookie(candidate);
}
fscache_cookie_get(cookie->parent, fscache_cookie_get_register_netfs);
atomic_inc(&cookie->parent->n_children);
netfs->primary_index = cookie;
pr_notice("Netfs '%s' registered for caching\n", netfs->name);
trace_fscache_netfs(netfs);
_leave(" = 0");
return 0;
already_registered:
fscache_cookie_put(candidate, fscache_cookie_put_dup_netfs);
_leave(" = -EEXIST");
return -EEXIST;
}
EXPORT_SYMBOL(__fscache_register_netfs);
/*
* unregister a network filesystem from the cache
* - all cookies must have been released first
*/
void __fscache_unregister_netfs(struct fscache_netfs *netfs)
{
_enter("{%s.%u}", netfs->name, netfs->version);
fscache_relinquish_cookie(netfs->primary_index, NULL, false);
pr_notice("Netfs '%s' unregistered from caching\n", netfs->name);
_leave("");
}
EXPORT_SYMBOL(__fscache_unregister_netfs);