blob: 654c406f09ec5bc7f479acd8685f0d83c61b1722 [file] [log] [blame]
/*
* Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <libxfs.h>
#include "globals.h"
#include "agheader.h"
#include "protos.h"
#include "err_protos.h"
#include "pthread.h"
#include "avl.h"
#include "dir.h"
#include "bmap.h"
#include "incore.h"
#include "prefetch.h"
#include <sys/resource.h>
/* TODO: dirbuf/freemap key usage is completely b0rked - only used for dirv1 */
static pthread_key_t dirbuf_key;
static pthread_key_t dir_freemap_key;
static pthread_key_t attr_freemap_key;
extern pthread_key_t dblkmap_key;
extern pthread_key_t ablkmap_key;
static void
ts_alloc(pthread_key_t key, unsigned n, size_t size)
{
void *voidp;
voidp = calloc(n, size);
if (voidp == NULL) {
do_error(_("ts_alloc: cannot allocate thread specific storage\n"));
/* NO RETURN */
return;
}
pthread_setspecific(key, voidp);
}
static void
ts_create(void)
{
/* create thread specific keys */
pthread_key_create(&dirbuf_key, NULL);
pthread_key_create(&dir_freemap_key, NULL);
pthread_key_create(&attr_freemap_key, NULL);
pthread_key_create(&dblkmap_key, NULL);
pthread_key_create(&ablkmap_key, NULL);
}
void
ts_init(void)
{
/* allocate thread specific storage */
ts_alloc(dirbuf_key, 1, ts_dirbuf_size);
ts_alloc(dir_freemap_key, 1, ts_dir_freemap_size);
ts_alloc(attr_freemap_key, 1, ts_attr_freemap_size);
}
void *
ts_dirbuf(void)
{
return pthread_getspecific(dirbuf_key);
}
void *
ts_dir_freemap(void)
{
return pthread_getspecific(dir_freemap_key);
}
void *
ts_attr_freemap(void)
{
return pthread_getspecific(attr_freemap_key);
}
static void
increase_rlimit(void)
{
struct rlimit rl;
/* Increase limits */
if (getrlimit(RLIMIT_FSIZE, &rl) == -1) {
perror("getrlimit");
fprintf(stderr, _("getrlimit(RLIMIT_FSIZE) failed!\n"));
exit(1);
}
if (rl.rlim_cur != RLIM_INFINITY) {
rl.rlim_max = rl.rlim_cur = RLIM_INFINITY;
if (setrlimit(RLIMIT_FSIZE, &rl) == -1) {
perror("setrlimit");
fprintf(stderr,
_("setrlimit failed - current: %lld, max: %lld\n"),
(unsigned long long)rl.rlim_cur,
(unsigned long long)rl.rlim_max);
exit(1);
}
}
}
void
xfs_init(libxfs_init_t *args)
{
memset(args, 0, sizeof(libxfs_init_t));
if (isa_file) {
args->disfile = 1;
args->dname = fs_name;
args->volname = NULL;
} else {
args->disfile = 0;
args->volname = fs_name;
args->dname = NULL;
}
if (log_spec) { /* External log specified */
args->logname = log_name;
args->lisfile = (isa_file?1:0);
/* XXX assume data file also means log file */
/* REVISIT: Need to do fs sanity / log validity checking */
}
if (rt_spec) { /* RT device specified */
args->rtname = rt_name;
args->risfile = (isa_file?1:0);
/* XXX assume data file also means rt file */
}
args->usebuflock = do_prefetch;
args->setblksize = !dangerously;
args->isdirect = LIBXFS_DIRECT;
if (no_modify)
args->isreadonly = (LIBXFS_ISREADONLY | LIBXFS_ISINACTIVE);
else if (dangerously)
args->isreadonly = (LIBXFS_ISINACTIVE | LIBXFS_DANGEROUSLY);
else
args->isreadonly = LIBXFS_EXCLUSIVELY;
if (!libxfs_init(args))
do_error(_("couldn't initialize XFS library\n"));
ts_create();
ts_init();
increase_rlimit();
pftrace_init();
}