| /* |
| * 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(); |
| } |