~barry/ubuntu/maverick/fuse/bug-697792-m

« back to all changes in this revision

Viewing changes to lib/fuse.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2007-08-04 08:09:00 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20070804080900-m1e9xpk5eitzmelg
Tags: 2.7.0-1ubuntu1
* Resynchronise with Debian (LP: #128292). Remaining changes:
  - Don't install the init script; install the udev rule and the module
    configuration file instead.
  - debian/45-fuse.rules: set /dev/fuse group to fuse.
  - debian/fuse-utils.modprobe: module configuration file that mounts the
    control filesystem when fuse is loaded and unmounts it when fuse is
    unloaded, along with checking that the control FS is mounting before
    unmounting it.
  - debian/fuse-utils.install: add the udev rule, the module configuration
    file, and ulockmgr_server.
  - Load fuse on install, and set it so it gets loaded on reboot.
  - Move fusermount and ulockmgr_server to /bin and associated libraries
    to /lib.
* Use dpkg-query to fetch conffile md5sums rather than parsing
  /var/lib/dpkg/status directly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
    FUSE: Filesystem in Userspace
3
 
    Copyright (C) 2001-2006  Miklos Szeredi <miklos@szeredi.hu>
 
3
    Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
4
4
 
5
5
    This program can be distributed under the terms of the GNU LGPL.
6
6
    See the file COPYING.LIB
14
14
#include "fuse_lowlevel.h"
15
15
#include "fuse_opt.h"
16
16
#include "fuse_misc.h"
 
17
#include "fuse_common_compat.h"
 
18
#include "fuse_compat.h"
17
19
 
18
20
#include <stdio.h>
19
21
#include <string.h>
25
27
#include <limits.h>
26
28
#include <errno.h>
27
29
#include <signal.h>
 
30
#include <dlfcn.h>
28
31
#include <assert.h>
29
32
#include <sys/param.h>
30
33
#include <sys/uio.h>
57
60
    int auto_cache;
58
61
    int intr;
59
62
    int intr_signal;
 
63
    int help;
 
64
    char *modules;
 
65
};
 
66
 
 
67
struct fuse_fs {
 
68
    struct fuse_operations op;
 
69
    struct fuse_module *m;
 
70
    void *user_data;
 
71
    int compat;
 
72
};
 
73
 
 
74
struct fusemod_so {
 
75
    void *handle;
 
76
    int ctr;
60
77
};
61
78
 
62
79
struct fuse {
63
80
    struct fuse_session *se;
64
 
    struct fuse_operations op;
65
 
    int compat;
66
81
    struct node **name_table;
67
82
    size_t name_table_size;
68
83
    struct node **id_table;
72
87
    unsigned int hidectr;
73
88
    pthread_mutex_t lock;
74
89
    pthread_rwlock_t tree_lock;
75
 
    void *user_data;
76
90
    struct fuse_config conf;
77
91
    int intr_installed;
 
92
    struct fuse_fs *fs;
78
93
};
79
94
 
80
95
struct lock {
92
107
    fuse_ino_t nodeid;
93
108
    unsigned int generation;
94
109
    int refctr;
95
 
    fuse_ino_t parent;
 
110
    struct node *parent;
96
111
    char *name;
97
112
    uint64_t nlookup;
98
113
    int open_count;
104
119
    struct lock *locks;
105
120
};
106
121
 
107
 
struct fuse_dirhandle {
 
122
struct fuse_dh {
108
123
    pthread_mutex_t lock;
109
124
    struct fuse *fuse;
110
125
    fuse_req_t req;
119
134
    fuse_ino_t nodeid;
120
135
};
121
136
 
 
137
/* old dir handle */
 
138
struct fuse_dirhandle {
 
139
    fuse_fill_dir_t filler;
 
140
    void *buf;
 
141
};
 
142
 
122
143
struct fuse_context_i {
123
144
    struct fuse_context ctx;
124
145
    fuse_req_t req;
127
148
static pthread_key_t fuse_context_key;
128
149
static pthread_mutex_t fuse_context_lock = PTHREAD_MUTEX_INITIALIZER;
129
150
static int fuse_context_ref;
130
 
 
131
 
static int fuse_compat_open(struct fuse *, fuse_req_t, char *,
132
 
                            struct fuse_file_info *);
133
 
static void fuse_compat_release(struct fuse *, fuse_req_t, char *,
134
 
                                struct fuse_file_info *);
135
 
static int fuse_compat_opendir(struct fuse *, fuse_req_t, char *,
136
 
                               struct fuse_file_info *);
137
 
static int fuse_compat_statfs(struct fuse *, fuse_req_t, struct statvfs *);
 
151
static struct fusemod_so *fuse_current_so;
 
152
static struct fuse_module *fuse_modules;
 
153
 
 
154
static int fuse_load_so_name(const char *soname)
 
155
{
 
156
    struct fusemod_so *so;
 
157
 
 
158
    so = calloc(1, sizeof(struct fusemod_so));
 
159
    if (!so) {
 
160
        fprintf(stderr, "fuse: memory allocation failed\n");
 
161
        return -1;
 
162
    }
 
163
 
 
164
    fuse_current_so = so;
 
165
    so->handle = dlopen(soname, RTLD_NOW);
 
166
    fuse_current_so = NULL;
 
167
    if (!so->handle) {
 
168
        fprintf(stderr, "fuse: %s\n", dlerror());
 
169
        goto err;
 
170
    }
 
171
    if (!so->ctr) {
 
172
        fprintf(stderr, "fuse: %s did not register any modules", soname);
 
173
        goto err;
 
174
    }
 
175
    return 0;
 
176
 
 
177
 err:
 
178
    if (so->handle)
 
179
        dlclose(so->handle);
 
180
    free(so);
 
181
    return -1;
 
182
}
 
183
 
 
184
static int fuse_load_so_module(const char *module)
 
185
{
 
186
    int res;
 
187
    char *soname = malloc(strlen(module) + 64);
 
188
    if (!soname) {
 
189
        fprintf(stderr, "fuse: memory allocation failed\n");
 
190
        return -1;
 
191
    }
 
192
    sprintf(soname, "libfusemod_%s.so", module);
 
193
    res = fuse_load_so_name(soname);
 
194
    free(soname);
 
195
    return res;
 
196
}
 
197
 
 
198
static struct fuse_module *fuse_find_module(const char *module)
 
199
{
 
200
    struct fuse_module *m;
 
201
    for (m = fuse_modules; m; m = m->next) {
 
202
        if (strcmp(module, m->name) == 0) {
 
203
            m->ctr++;
 
204
            break;
 
205
        }
 
206
    }
 
207
    return m;
 
208
}
 
209
 
 
210
static struct fuse_module *fuse_get_module(const char *module)
 
211
{
 
212
    struct fuse_module *m;
 
213
 
 
214
    pthread_mutex_lock(&fuse_context_lock);
 
215
    m = fuse_find_module(module);
 
216
    if (!m) {
 
217
        int err = fuse_load_so_module(module);
 
218
        if (!err)
 
219
            m = fuse_find_module(module);
 
220
    }
 
221
    pthread_mutex_unlock(&fuse_context_lock);
 
222
    return m;
 
223
}
 
224
 
 
225
static void fuse_put_module(struct fuse_module *m)
 
226
{
 
227
    pthread_mutex_lock(&fuse_context_lock);
 
228
    assert(m->ctr > 0);
 
229
    m->ctr--;
 
230
    if (!m->ctr && m->so) {
 
231
        struct fusemod_so *so = m->so;
 
232
        assert(so->ctr > 0);
 
233
        so->ctr--;
 
234
        if (!so->ctr) {
 
235
            struct fuse_module **mp;
 
236
            for (mp = &fuse_modules; *mp;) {
 
237
                if ((*mp)->so == so)
 
238
                    *mp = (*mp)->next;
 
239
                else
 
240
                    mp = &(*mp)->next;
 
241
            }
 
242
            dlclose(so->handle);
 
243
            free(so);
 
244
        }
 
245
    }
 
246
    pthread_mutex_unlock(&fuse_context_lock);
 
247
}
138
248
 
139
249
static struct node *get_node_nocheck(struct fuse *f, fuse_ino_t nodeid)
140
250
{
184
294
    f->id_table[hash] = node;
185
295
}
186
296
 
187
 
static unsigned int name_hash(struct fuse *f, fuse_ino_t parent, const char *name)
 
297
static unsigned int name_hash(struct fuse *f, fuse_ino_t parent,
 
298
                              const char *name)
188
299
{
189
300
    unsigned int hash = *name;
190
301
 
200
311
static void unhash_name(struct fuse *f, struct node *node)
201
312
{
202
313
    if (node->name) {
203
 
        size_t hash = name_hash(f, node->parent, node->name);
 
314
        size_t hash = name_hash(f, node->parent->nodeid, node->name);
204
315
        struct node **nodep = &f->name_table[hash];
205
316
 
206
317
        for (; *nodep != NULL; nodep = &(*nodep)->name_next)
207
318
            if (*nodep == node) {
208
319
                *nodep = node->name_next;
209
320
                node->name_next = NULL;
210
 
                unref_node(f, get_node(f, node->parent));
 
321
                unref_node(f, node->parent);
211
322
                free(node->name);
212
323
                node->name = NULL;
213
 
                node->parent = 0;
 
324
                node->parent = NULL;
214
325
                return;
215
326
            }
216
327
        fprintf(stderr, "fuse internal error: unable to unhash node: %llu\n",
219
330
    }
220
331
}
221
332
 
222
 
static int hash_name(struct fuse *f, struct node *node, fuse_ino_t parent,
 
333
static int hash_name(struct fuse *f, struct node *node, fuse_ino_t parentid,
223
334
                     const char *name)
224
335
{
225
 
    size_t hash = name_hash(f, parent, name);
 
336
    size_t hash = name_hash(f, parentid, name);
 
337
    struct node *parent = get_node(f, parentid);
226
338
    node->name = strdup(name);
227
339
    if (node->name == NULL)
228
340
        return -1;
229
341
 
230
 
    get_node(f, parent)->refctr ++;
 
342
    parent->refctr ++;
231
343
    node->parent = parent;
232
344
    node->name_next = f->name_table[hash];
233
345
    f->name_table[hash] = node;
236
348
 
237
349
static void delete_node(struct fuse *f, struct node *node)
238
350
{
239
 
    if (f->conf.debug) {
240
 
        printf("delete: %llu\n", (unsigned long long) node->nodeid);
241
 
        fflush(stdout);
242
 
    }
 
351
    if (f->conf.debug)
 
352
        fprintf(stderr, "delete: %llu\n", (unsigned long long) node->nodeid);
 
353
 
243
354
    assert(!node->name);
244
355
    unhash_id(f, node);
245
356
    free_node(node);
271
382
    struct node *node;
272
383
 
273
384
    for (node = f->name_table[hash]; node != NULL; node = node->name_next)
274
 
        if (node->parent == parent && strcmp(node->name, name) == 0)
 
385
        if (node->parent->nodeid == parent && strcmp(node->name, name) == 0)
275
386
            return node;
276
387
 
277
388
    return NULL;
338
449
 
339
450
    pthread_mutex_lock(&f->lock);
340
451
    for (node = get_node(f, nodeid); node && node->nodeid != FUSE_ROOT_ID;
341
 
         node = get_node(f, node->parent)) {
 
452
         node = node->parent) {
342
453
        if (node->name == NULL) {
343
454
            s = NULL;
344
455
            break;
510
621
        fuse_do_prepare_interrupt(req, d);
511
622
}
512
623
 
513
 
static int fuse_do_getattr(struct fuse *f, fuse_req_t req, const char *path,
514
 
                           struct stat *buf)
515
 
{
516
 
    int res;
517
 
    struct fuse_intr_data d;
518
 
    fuse_prepare_interrupt(f, req, &d);
519
 
    res = f->op.getattr(path, buf);
520
 
    fuse_finish_interrupt(f, req, &d);
521
 
    return res;
522
 
}
523
 
 
524
 
static int fuse_do_fgetattr(struct fuse *f, fuse_req_t req, const char *path,
525
 
                            struct stat *buf, struct fuse_file_info *fi)
526
 
{
527
 
    int res;
528
 
    struct fuse_intr_data d;
529
 
    fuse_prepare_interrupt(f, req, &d);
530
 
    res = f->op.fgetattr(path, buf, fi);
531
 
    fuse_finish_interrupt(f, req, &d);
532
 
    return res;
533
 
}
534
 
 
535
 
static int fuse_do_rename(struct fuse *f, fuse_req_t req, const char *oldpath,
536
 
                          const char *newpath)
537
 
{
538
 
    int res;
539
 
    struct fuse_intr_data d;
540
 
    fuse_prepare_interrupt(f, req, &d);
541
 
    res = f->op.rename(oldpath, newpath);
542
 
    fuse_finish_interrupt(f, req, &d);
543
 
    return res;
544
 
}
545
 
 
546
 
static int fuse_do_unlink(struct fuse *f, fuse_req_t req, const char *path)
547
 
{
548
 
    int res;
549
 
    struct fuse_intr_data d;
550
 
    fuse_prepare_interrupt(f, req, &d);
551
 
    res = f->op.unlink(path);
552
 
    fuse_finish_interrupt(f, req, &d);
553
 
    return res;
554
 
}
555
 
 
556
 
static void fuse_do_release(struct fuse *f, fuse_req_t req, const char *path,
 
624
#ifndef __FreeBSD__
 
625
 
 
626
static int fuse_compat_open(struct fuse_fs *fs, const char *path,
557
627
                            struct fuse_file_info *fi)
558
628
{
559
 
    struct fuse_intr_data d;
560
 
    fuse_prepare_interrupt(f, req, &d);
561
 
    f->op.release(path, fi);
562
 
    fuse_finish_interrupt(f, req, &d);
563
 
}
564
 
 
565
 
static int fuse_do_opendir(struct fuse *f, fuse_req_t req, char *path,
566
 
                           struct fuse_file_info *fi)
567
 
{
568
 
    int res;
569
 
    struct fuse_intr_data d;
570
 
    fuse_prepare_interrupt(f, req, &d);
571
 
    res = f->op.opendir(path, fi);
572
 
    fuse_finish_interrupt(f, req, &d);
573
 
    return res;
574
 
}
575
 
 
576
 
static int fuse_do_open(struct fuse *f, fuse_req_t req, char *path,
577
 
                           struct fuse_file_info *fi)
578
 
{
579
 
    int res;
580
 
    struct fuse_intr_data d;
581
 
    fuse_prepare_interrupt(f, req, &d);
582
 
    res = f->op.open(path, fi);
583
 
    fuse_finish_interrupt(f, req, &d);
584
 
    return res;
585
 
}
586
 
 
587
 
static int fuse_do_flush(struct fuse *f, fuse_req_t req, const char *path,
588
 
                         struct fuse_file_info *fi)
589
 
{
590
 
    int res;
591
 
    struct fuse_intr_data d;
592
 
    fuse_prepare_interrupt(f, req, &d);
593
 
    res = f->op.flush(path, fi);
594
 
    fuse_finish_interrupt(f, req, &d);
595
 
    return res;
596
 
}
597
 
 
598
 
static int fuse_do_statfs(struct fuse *f, fuse_req_t req, const char *path,
599
 
                          struct statvfs *buf)
600
 
{
601
 
    int res;
602
 
    struct fuse_intr_data d;
603
 
    fuse_prepare_interrupt(f, req, &d);
604
 
    res = f->op.statfs(path, buf);
605
 
    fuse_finish_interrupt(f, req, &d);
606
 
    return res;
607
 
}
608
 
 
609
 
static void fuse_do_releasedir(struct fuse *f, fuse_req_t req,
610
 
                               const char *path, struct fuse_file_info *fi)
611
 
{
612
 
    struct fuse_intr_data d;
613
 
    fuse_prepare_interrupt(f, req, &d);
614
 
    f->op.releasedir(path, fi);
615
 
    fuse_finish_interrupt(f, req, &d);
616
 
}
617
 
 
618
 
static int fuse_do_create(struct fuse *f, fuse_req_t req, const char *path,
619
 
                          mode_t mode, struct fuse_file_info *fi)
620
 
{
621
 
    int res;
622
 
    struct fuse_intr_data d;
623
 
    fuse_prepare_interrupt(f, req, &d);
624
 
    res = f->op.create(path, mode, fi);
625
 
    fuse_finish_interrupt(f, req, &d);
626
 
    return res;
627
 
}
628
 
 
629
 
static int fuse_do_lock(struct fuse *f, fuse_req_t req, const char *path,
630
 
                        struct fuse_file_info *fi, int cmd, struct flock *lock)
631
 
{
632
 
    int res;
633
 
    struct fuse_intr_data d;
634
 
    fuse_prepare_interrupt(f, req, &d);
635
 
    res = f->op.lock(path, fi, cmd, lock);
636
 
    fuse_finish_interrupt(f, req, &d);
637
 
    return res;
 
629
    int err;
 
630
    if (!fs->compat || fs->compat >= 25)
 
631
        err = fs->op.open(path, fi);
 
632
    else if (fs->compat == 22) {
 
633
        struct fuse_file_info_compat tmp;
 
634
        memcpy(&tmp, fi, sizeof(tmp));
 
635
        err = ((struct fuse_operations_compat22 *) &fs->op)->open(path, &tmp);
 
636
        memcpy(fi, &tmp, sizeof(tmp));
 
637
        fi->fh = tmp.fh;
 
638
    } else
 
639
        err = ((struct fuse_operations_compat2 *) &fs->op)
 
640
            ->open(path, fi->flags);
 
641
    return err;
 
642
}
 
643
 
 
644
static int fuse_compat_release(struct fuse_fs *fs, const char *path,
 
645
                               struct fuse_file_info *fi)
 
646
{
 
647
    if (!fs->compat || fs->compat >= 22)
 
648
        return fs->op.release(path, fi);
 
649
    else
 
650
        return ((struct fuse_operations_compat2 *) &fs->op)
 
651
            ->release(path, fi->flags);
 
652
}
 
653
 
 
654
static int fuse_compat_opendir(struct fuse_fs *fs, const char *path,
 
655
                               struct fuse_file_info *fi)
 
656
{
 
657
    if (!fs->compat || fs->compat >= 25)
 
658
        return fs->op.opendir(path, fi);
 
659
    else {
 
660
        int err;
 
661
        struct fuse_file_info_compat tmp;
 
662
        memcpy(&tmp, fi, sizeof(tmp));
 
663
        err = ((struct fuse_operations_compat22 *) &fs->op)
 
664
            ->opendir(path, &tmp);
 
665
        memcpy(fi, &tmp, sizeof(tmp));
 
666
        fi->fh = tmp.fh;
 
667
        return err;
 
668
    }
 
669
}
 
670
 
 
671
static void convert_statfs_compat(struct fuse_statfs_compat1 *compatbuf,
 
672
                                  struct statvfs *stbuf)
 
673
{
 
674
    stbuf->f_bsize   = compatbuf->block_size;
 
675
    stbuf->f_blocks  = compatbuf->blocks;
 
676
    stbuf->f_bfree   = compatbuf->blocks_free;
 
677
    stbuf->f_bavail  = compatbuf->blocks_free;
 
678
    stbuf->f_files   = compatbuf->files;
 
679
    stbuf->f_ffree   = compatbuf->files_free;
 
680
    stbuf->f_namemax = compatbuf->namelen;
 
681
}
 
682
 
 
683
static void convert_statfs_old(struct statfs *oldbuf, struct statvfs *stbuf)
 
684
{
 
685
    stbuf->f_bsize   = oldbuf->f_bsize;
 
686
    stbuf->f_blocks  = oldbuf->f_blocks;
 
687
    stbuf->f_bfree   = oldbuf->f_bfree;
 
688
    stbuf->f_bavail  = oldbuf->f_bavail;
 
689
    stbuf->f_files   = oldbuf->f_files;
 
690
    stbuf->f_ffree   = oldbuf->f_ffree;
 
691
    stbuf->f_namemax = oldbuf->f_namelen;
 
692
}
 
693
 
 
694
static int fuse_compat_statfs(struct fuse_fs *fs, const char *path,
 
695
                              struct statvfs *buf)
 
696
{
 
697
    int err;
 
698
 
 
699
    if (!fs->compat || fs->compat >= 25) {
 
700
        err = fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
 
701
    } else if (fs->compat > 11) {
 
702
        struct statfs oldbuf;
 
703
        err = ((struct fuse_operations_compat22 *) &fs->op)
 
704
            ->statfs("/", &oldbuf);
 
705
        if (!err)
 
706
            convert_statfs_old(&oldbuf, buf);
 
707
    } else {
 
708
        struct fuse_statfs_compat1 compatbuf;
 
709
        memset(&compatbuf, 0, sizeof(struct fuse_statfs_compat1));
 
710
        err = ((struct fuse_operations_compat1 *) &fs->op)->statfs(&compatbuf);
 
711
        if (!err)
 
712
            convert_statfs_compat(&compatbuf, buf);
 
713
    }
 
714
    return err;
 
715
}
 
716
 
 
717
#else /* __FreeBSD__ */
 
718
 
 
719
static inline int fuse_compat_open(struct fuse_fs *fs, char *path,
 
720
                                   struct fuse_file_info *fi)
 
721
{
 
722
    return fs->op.open(path, fi);
 
723
}
 
724
 
 
725
static inline int fuse_compat_release(struct fuse_fs *fs, const char *path,
 
726
                                      struct fuse_file_info *fi)
 
727
{
 
728
    return fs->op.release(path, fi);
 
729
}
 
730
 
 
731
static inline int fuse_compat_opendir(struct fuse_fs *fs, const char *path,
 
732
                                      struct fuse_file_info *fi)
 
733
{
 
734
    return fs->op.opendir(path, fi);
 
735
}
 
736
 
 
737
static inline int fuse_compat_statfs(struct fuse_fs *fs, const char *path,
 
738
                                     struct statvfs *buf)
 
739
{
 
740
    return fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
 
741
}
 
742
 
 
743
#endif /* __FreeBSD__ */
 
744
 
 
745
int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf)
 
746
{
 
747
    fuse_get_context()->private_data = fs->user_data;
 
748
    if (fs->op.getattr)
 
749
        return fs->op.getattr(path, buf);
 
750
    else
 
751
        return -ENOSYS;
 
752
}
 
753
 
 
754
int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf,
 
755
                     struct fuse_file_info *fi)
 
756
{
 
757
    fuse_get_context()->private_data = fs->user_data;
 
758
    if (fs->op.fgetattr)
 
759
        return fs->op.fgetattr(path, buf, fi);
 
760
    else if (fs->op.getattr)
 
761
        return fs->op.getattr(path, buf);
 
762
    else
 
763
        return -ENOSYS;
 
764
}
 
765
 
 
766
int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
 
767
                   const char *newpath)
 
768
{
 
769
    fuse_get_context()->private_data = fs->user_data;
 
770
    if (fs->op.rename)
 
771
        return fs->op.rename(oldpath, newpath);
 
772
    else
 
773
        return -ENOSYS;
 
774
}
 
775
 
 
776
int fuse_fs_unlink(struct fuse_fs *fs, const char *path)
 
777
{
 
778
    fuse_get_context()->private_data = fs->user_data;
 
779
    if (fs->op.unlink)
 
780
        return fs->op.unlink(path);
 
781
    else
 
782
        return -ENOSYS;
 
783
}
 
784
 
 
785
int fuse_fs_rmdir(struct fuse_fs *fs, const char *path)
 
786
{
 
787
    fuse_get_context()->private_data = fs->user_data;
 
788
    if (fs->op.rmdir)
 
789
        return fs->op.rmdir(path);
 
790
    else
 
791
        return -ENOSYS;
 
792
}
 
793
 
 
794
int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, const char *path)
 
795
{
 
796
    fuse_get_context()->private_data = fs->user_data;
 
797
    if (fs->op.symlink)
 
798
        return fs->op.symlink(linkname, path);
 
799
    else
 
800
        return -ENOSYS;
 
801
}
 
802
 
 
803
int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath)
 
804
{
 
805
    fuse_get_context()->private_data = fs->user_data;
 
806
    if (fs->op.link)
 
807
        return fs->op.link(oldpath, newpath);
 
808
    else
 
809
        return -ENOSYS;
 
810
}
 
811
 
 
812
int fuse_fs_release(struct fuse_fs *fs,  const char *path,
 
813
                    struct fuse_file_info *fi)
 
814
{
 
815
    fuse_get_context()->private_data = fs->user_data;
 
816
    if (fs->op.release)
 
817
        return fuse_compat_release(fs, path, fi);
 
818
    else
 
819
        return 0;
 
820
}
 
821
 
 
822
int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
 
823
                    struct fuse_file_info *fi)
 
824
{
 
825
    fuse_get_context()->private_data = fs->user_data;
 
826
    if (fs->op.opendir)
 
827
        return fuse_compat_opendir(fs, path, fi);
 
828
    else
 
829
        return 0;
 
830
}
 
831
 
 
832
int fuse_fs_open(struct fuse_fs *fs, const char *path,
 
833
                 struct fuse_file_info *fi)
 
834
{
 
835
    fuse_get_context()->private_data = fs->user_data;
 
836
    if (fs->op.open)
 
837
        return fuse_compat_open(fs, path, fi);
 
838
    else
 
839
        return 0;
 
840
}
 
841
 
 
842
int fuse_fs_read(struct fuse_fs *fs, const char *path, char *buf, size_t size,
 
843
                 off_t off, struct fuse_file_info *fi)
 
844
{
 
845
    fuse_get_context()->private_data = fs->user_data;
 
846
    if (fs->op.read)
 
847
        return fs->op.read(path, buf, size, off, fi);
 
848
    else
 
849
        return -ENOSYS;
 
850
}
 
851
 
 
852
int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *buf,
 
853
                  size_t size, off_t off, struct fuse_file_info *fi)
 
854
{
 
855
    fuse_get_context()->private_data = fs->user_data;
 
856
    if (fs->op.write)
 
857
        return fs->op.write(path, buf, size, off, fi);
 
858
    else
 
859
        return -ENOSYS;
 
860
}
 
861
 
 
862
int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,
 
863
                  struct fuse_file_info *fi)
 
864
{
 
865
    fuse_get_context()->private_data = fs->user_data;
 
866
    if (fs->op.fsync)
 
867
        return fs->op.fsync(path, datasync, fi);
 
868
    else
 
869
        return -ENOSYS;
 
870
}
 
871
 
 
872
int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,
 
873
                     struct fuse_file_info *fi)
 
874
{
 
875
    fuse_get_context()->private_data = fs->user_data;
 
876
    if (fs->op.fsyncdir)
 
877
        return fs->op.fsyncdir(path, datasync, fi);
 
878
    else
 
879
        return -ENOSYS;
 
880
}
 
881
 
 
882
int fuse_fs_flush(struct fuse_fs *fs, const char *path,
 
883
                  struct fuse_file_info *fi)
 
884
{
 
885
    fuse_get_context()->private_data = fs->user_data;
 
886
    if (fs->op.flush)
 
887
        return fs->op.flush(path, fi);
 
888
    else
 
889
        return -ENOSYS;
 
890
}
 
891
 
 
892
int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf)
 
893
{
 
894
    fuse_get_context()->private_data = fs->user_data;
 
895
    if (fs->op.statfs)
 
896
        return fuse_compat_statfs(fs, path, buf);
 
897
    else {
 
898
        buf->f_namemax = 255;
 
899
        buf->f_bsize = 512;
 
900
        return 0;
 
901
    }
 
902
}
 
903
 
 
904
int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,
 
905
                       struct fuse_file_info *fi)
 
906
{
 
907
    fuse_get_context()->private_data = fs->user_data;
 
908
    if (fs->op.releasedir)
 
909
        return fs->op.releasedir(path, fi);
 
910
    else
 
911
        return 0;
 
912
}
 
913
 
 
914
static int fill_dir_old(struct fuse_dirhandle *dh, const char *name, int type,
 
915
                        ino_t ino)
 
916
{
 
917
    int res;
 
918
    struct stat stbuf;
 
919
 
 
920
    memset(&stbuf, 0, sizeof(stbuf));
 
921
    stbuf.st_mode = type << 12;
 
922
    stbuf.st_ino = ino;
 
923
 
 
924
    res = dh->filler(dh->buf, name, &stbuf, 0);
 
925
    return res ? -ENOMEM : 0;
 
926
}
 
927
 
 
928
int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
 
929
                    fuse_fill_dir_t filler, off_t off,
 
930
                    struct fuse_file_info *fi)
 
931
{
 
932
    fuse_get_context()->private_data = fs->user_data;
 
933
    if (fs->op.readdir)
 
934
        return fs->op.readdir(path, buf, filler, off, fi);
 
935
    else if (fs->op.getdir) {
 
936
        struct fuse_dirhandle dh;
 
937
        dh.filler = filler;
 
938
        dh.buf = buf;
 
939
        return fs->op.getdir(path, &dh, fill_dir_old);
 
940
    } else
 
941
        return -ENOSYS;
 
942
}
 
943
 
 
944
int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
 
945
                   struct fuse_file_info *fi)
 
946
{
 
947
    fuse_get_context()->private_data = fs->user_data;
 
948
    if (fs->op.create)
 
949
        return fs->op.create(path, mode, fi);
 
950
    else
 
951
        return -ENOSYS;
 
952
}
 
953
 
 
954
int fuse_fs_lock(struct fuse_fs *fs, const char *path,
 
955
                 struct fuse_file_info *fi, int cmd, struct flock *lock)
 
956
{
 
957
    fuse_get_context()->private_data = fs->user_data;
 
958
    if (fs->op.lock)
 
959
        return fs->op.lock(path, fi, cmd, lock);
 
960
    else
 
961
        return -ENOSYS;
 
962
}
 
963
 
 
964
int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid)
 
965
{
 
966
    fuse_get_context()->private_data = fs->user_data;
 
967
    if (fs->op.chown)
 
968
        return fs->op.chown(path, uid, gid);
 
969
    else
 
970
        return -ENOSYS;
 
971
}
 
972
 
 
973
int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size)
 
974
{
 
975
    fuse_get_context()->private_data = fs->user_data;
 
976
    if (fs->op.truncate)
 
977
        return fs->op.truncate(path, size);
 
978
    else
 
979
        return -ENOSYS;
 
980
}
 
981
 
 
982
int fuse_fs_ftruncate(struct fuse_fs *fs, const char *path, off_t size,
 
983
                      struct fuse_file_info *fi)
 
984
{
 
985
    fuse_get_context()->private_data = fs->user_data;
 
986
    if (fs->op.ftruncate)
 
987
        return fs->op.ftruncate(path, size, fi);
 
988
    else if (fs->op.truncate)
 
989
        return fs->op.truncate(path, size);
 
990
    else
 
991
        return -ENOSYS;
 
992
}
 
993
 
 
994
int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
 
995
                    const struct timespec tv[2])
 
996
{
 
997
    fuse_get_context()->private_data = fs->user_data;
 
998
    if (fs->op.utimens)
 
999
        return fs->op.utimens(path, tv);
 
1000
    else if(fs->op.utime) {
 
1001
        struct utimbuf buf;
 
1002
        buf.actime = tv[0].tv_sec;
 
1003
        buf.modtime = tv[1].tv_sec;
 
1004
        return fs->op.utime(path, &buf);
 
1005
    } else
 
1006
        return -ENOSYS;
 
1007
}
 
1008
 
 
1009
int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask)
 
1010
{
 
1011
    fuse_get_context()->private_data = fs->user_data;
 
1012
    if (fs->op.access)
 
1013
        return fs->op.access(path, mask);
 
1014
    else
 
1015
        return -ENOSYS;
 
1016
}
 
1017
 
 
1018
int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
 
1019
                     size_t len)
 
1020
{
 
1021
    fuse_get_context()->private_data = fs->user_data;
 
1022
    if (fs->op.readlink)
 
1023
        return fs->op.readlink(path, buf, len);
 
1024
    else
 
1025
        return -ENOSYS;
 
1026
}
 
1027
 
 
1028
int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,
 
1029
                  dev_t rdev)
 
1030
{
 
1031
    fuse_get_context()->private_data = fs->user_data;
 
1032
    if (fs->op.mknod)
 
1033
        return fs->op.mknod(path, mode, rdev);
 
1034
    else
 
1035
        return -ENOSYS;
 
1036
}
 
1037
 
 
1038
int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode)
 
1039
{
 
1040
    fuse_get_context()->private_data = fs->user_data;
 
1041
    if (fs->op.mkdir)
 
1042
        return fs->op.mkdir(path, mode);
 
1043
    else
 
1044
        return -ENOSYS;
 
1045
}
 
1046
 
 
1047
int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,
 
1048
                     const char *value, size_t size, int flags)
 
1049
{
 
1050
    fuse_get_context()->private_data = fs->user_data;
 
1051
    if (fs->op.setxattr)
 
1052
        return fs->op.setxattr(path, name, value, size, flags);
 
1053
    else
 
1054
        return -ENOSYS;
 
1055
}
 
1056
 
 
1057
int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,
 
1058
                     char *value, size_t size)
 
1059
{
 
1060
    fuse_get_context()->private_data = fs->user_data;
 
1061
    if (fs->op.getxattr)
 
1062
        return fs->op.getxattr(path, name, value, size);
 
1063
    else
 
1064
        return -ENOSYS;
 
1065
}
 
1066
 
 
1067
int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,
 
1068
                      size_t size)
 
1069
{
 
1070
    fuse_get_context()->private_data = fs->user_data;
 
1071
    if (fs->op.listxattr)
 
1072
        return fs->op.listxattr(path, list, size);
 
1073
    else
 
1074
        return -ENOSYS;
 
1075
}
 
1076
 
 
1077
int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
 
1078
                 uint64_t *idx)
 
1079
{
 
1080
    fuse_get_context()->private_data = fs->user_data;
 
1081
    if (fs->op.bmap)
 
1082
        return fs->op.bmap(path, blocksize, idx);
 
1083
    else
 
1084
        return -ENOSYS;
 
1085
}
 
1086
 
 
1087
int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, const char *name)
 
1088
{
 
1089
    fuse_get_context()->private_data = fs->user_data;
 
1090
    if (fs->op.removexattr)
 
1091
        return fs->op.removexattr(path, name);
 
1092
    else
 
1093
        return -ENOSYS;
638
1094
}
639
1095
 
640
1096
static int is_open(struct fuse *f, fuse_ino_t dir, const char *name)
649
1105
    return isopen;
650
1106
}
651
1107
 
652
 
static char *hidden_name(struct fuse *f, fuse_req_t req, fuse_ino_t dir,
653
 
                         const char *oldname, char *newname, size_t bufsize)
 
1108
static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname,
 
1109
                         char *newname, size_t bufsize)
654
1110
{
655
1111
    struct stat buf;
656
1112
    struct node *node;
659
1115
    int res;
660
1116
    int failctr = 10;
661
1117
 
662
 
    if (!f->op.getattr)
663
 
        return NULL;
664
 
 
665
1118
    do {
666
1119
        pthread_mutex_lock(&f->lock);
667
1120
        node = lookup_node(f, dir, oldname);
681
1134
        if (!newpath)
682
1135
            break;
683
1136
 
684
 
        res = fuse_do_getattr(f, req, newpath, &buf);
685
 
        if (res != 0)
 
1137
        res = fuse_fs_getattr(f->fs, newpath, &buf);
 
1138
        if (res == -ENOENT)
686
1139
            break;
687
1140
        free(newpath);
688
1141
        newpath = NULL;
689
 
    } while(--failctr);
 
1142
    } while(res == 0 && --failctr);
690
1143
 
691
1144
    return newpath;
692
1145
}
693
1146
 
694
 
static int hide_node(struct fuse *f, fuse_req_t req, const char *oldpath,
 
1147
static int hide_node(struct fuse *f, const char *oldpath,
695
1148
                     fuse_ino_t dir, const char *oldname)
696
1149
{
697
1150
    char newname[64];
698
1151
    char *newpath;
699
1152
    int err = -EBUSY;
700
1153
 
701
 
    if (f->op.rename && f->op.unlink) {
702
 
        newpath = hidden_name(f, req, dir, oldname, newname, sizeof(newname));
703
 
        if (newpath) {
704
 
            err = fuse_do_rename(f, req, oldpath, newpath);
705
 
            if (!err)
706
 
                err = rename_node(f, dir, oldname, dir, newname, 1);
707
 
            free(newpath);
708
 
        }
 
1154
    newpath = hidden_name(f, dir, oldname, newname, sizeof(newname));
 
1155
    if (newpath) {
 
1156
        err = fuse_fs_rename(f->fs, oldpath, newpath);
 
1157
        if (!err)
 
1158
            err = rename_node(f, dir, oldname, dir, newname, 1);
 
1159
        free(newpath);
709
1160
    }
710
1161
    return err;
711
1162
}
712
1163
 
713
1164
static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
714
1165
{
715
 
    return stbuf->st_mtime == ts->tv_sec
716
 
#ifdef FUSE_STAT_HAS_NANOSEC
717
 
        && ST_MTIM(stbuf).tv_nsec == ts->tv_nsec
718
 
#endif
719
 
        ;
720
 
}
721
 
 
722
 
static void mtime_set(const struct stat *stbuf, struct timespec *ts)
723
 
{
724
 
#ifdef FUSE_STAT_HAS_NANOSEC
725
 
    *ts = ST_MTIM(stbuf);
726
 
#else
727
 
    ts->tv_sec = stbuf->st_mtime;
728
 
#endif
 
1166
    return stbuf->st_mtime == ts->tv_sec && ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
729
1167
}
730
1168
 
731
1169
#ifndef CLOCK_MONOTONIC
751
1189
    if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
752
1190
                              stbuf->st_size != node->size))
753
1191
        node->cache_valid = 0;
754
 
    mtime_set(stbuf, &node->mtime);
 
1192
    node->mtime.tv_sec = stbuf->st_mtime;
 
1193
    node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
755
1194
    node->size = stbuf->st_size;
756
1195
    curr_time(&node->stat_updated);
757
1196
}
758
1197
 
759
 
static int lookup_path(struct fuse *f, fuse_req_t req, fuse_ino_t nodeid,
 
1198
static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
760
1199
                       const char *name, const char *path,
761
1200
                       struct fuse_entry_param *e, struct fuse_file_info *fi)
762
1201
{
763
1202
    int res;
764
1203
 
765
1204
    memset(e, 0, sizeof(struct fuse_entry_param));
766
 
    if (fi && f->op.fgetattr)
767
 
        res = fuse_do_fgetattr(f, req, path, &e->attr, fi);
 
1205
    if (fi)
 
1206
        res = fuse_fs_fgetattr(f->fs, path, &e->attr, fi);
768
1207
    else
769
 
        res = fuse_do_getattr(f, req, path, &e->attr);
 
1208
        res = fuse_fs_getattr(f->fs, path, &e->attr);
770
1209
    if (res == 0) {
771
1210
        struct node *node;
772
1211
 
784
1223
                pthread_mutex_unlock(&f->lock);
785
1224
            }
786
1225
            set_stat(f, e->ino, &e->attr);
787
 
            if (f->conf.debug) {
788
 
                printf("   NODEID: %lu\n", (unsigned long) e->ino);
789
 
                fflush(stdout);
790
 
            }
 
1226
            if (f->conf.debug)
 
1227
                fprintf(stderr, "   NODEID: %lu\n", (unsigned long) e->ino);
791
1228
        }
792
1229
    }
793
1230
    return res;
855
1292
    c->ctx.uid = ctx->uid;
856
1293
    c->ctx.gid = ctx->gid;
857
1294
    c->ctx.pid = ctx->pid;
858
 
    c->ctx.private_data = c->ctx.fuse->user_data;
859
1295
    return c->ctx.fuse;
860
1296
}
861
1297
 
876
1312
        reply_err(req, err);
877
1313
}
878
1314
 
879
 
static void fuse_data_init(void *data, struct fuse_conn_info *conn)
880
 
{
881
 
    struct fuse *f = (struct fuse *) data;
882
 
    struct fuse_context_i *c = fuse_get_context_internal();
883
 
 
884
 
    memset(c, 0, sizeof(*c));
885
 
    c->ctx.fuse = f;
886
 
    c->ctx.private_data = f->user_data;
887
 
 
888
 
    if (f->op.init)
889
 
        f->user_data = f->op.init(conn);
890
 
}
891
 
 
892
 
static void fuse_data_destroy(void *data)
893
 
{
894
 
    struct fuse *f = (struct fuse *) data;
895
 
    struct fuse_context_i *c = fuse_get_context_internal();
896
 
 
897
 
    memset(c, 0, sizeof(*c));
898
 
    c->ctx.fuse = f;
899
 
    c->ctx.private_data = f->user_data;
900
 
 
901
 
    if (f->op.destroy)
902
 
        f->op.destroy(f->user_data);
903
 
}
904
 
 
905
 
static void fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
 
1315
void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn)
 
1316
{
 
1317
    fuse_get_context()->private_data = fs->user_data;
 
1318
    if (fs->op.init)
 
1319
        fs->user_data = fs->op.init(conn);
 
1320
}
 
1321
 
 
1322
static void fuse_lib_init(void *data, struct fuse_conn_info *conn)
 
1323
{
 
1324
    struct fuse *f = (struct fuse *) data;
 
1325
    struct fuse_context_i *c = fuse_get_context_internal();
 
1326
 
 
1327
    memset(c, 0, sizeof(*c));
 
1328
    c->ctx.fuse = f;
 
1329
    fuse_fs_init(f->fs, conn);
 
1330
}
 
1331
 
 
1332
void fuse_fs_destroy(struct fuse_fs *fs)
 
1333
{
 
1334
    fuse_get_context()->private_data = fs->user_data;
 
1335
    if (fs->op.destroy)
 
1336
        fs->op.destroy(fs->user_data);
 
1337
    if (fs->m)
 
1338
        fuse_put_module(fs->m);
 
1339
    free(fs);
 
1340
}
 
1341
 
 
1342
static void fuse_lib_destroy(void *data)
 
1343
{
 
1344
    struct fuse *f = (struct fuse *) data;
 
1345
    struct fuse_context_i *c = fuse_get_context_internal();
 
1346
 
 
1347
    memset(c, 0, sizeof(*c));
 
1348
    c->ctx.fuse = f;
 
1349
    fuse_fs_destroy(f->fs);
 
1350
    f->fs = NULL;
 
1351
}
 
1352
 
 
1353
static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent,
 
1354
                            const char *name)
906
1355
{
907
1356
    struct fuse *f = req_fuse_prepare(req);
908
1357
    struct fuse_entry_param e;
913
1362
    pthread_rwlock_rdlock(&f->tree_lock);
914
1363
    path = get_path_name(f, parent, name);
915
1364
    if (path != NULL) {
916
 
        if (f->conf.debug) {
917
 
            printf("LOOKUP %s\n", path);
918
 
            fflush(stdout);
919
 
        }
920
 
        err = -ENOSYS;
921
 
        if (f->op.getattr) {
922
 
            err = lookup_path(f, req, parent, name, path, &e, NULL);
923
 
            if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
924
 
                e.ino = 0;
925
 
                e.entry_timeout = f->conf.negative_timeout;
926
 
                err = 0;
927
 
            }
928
 
        }
 
1365
        struct fuse_intr_data d;
 
1366
        if (f->conf.debug)
 
1367
            fprintf(stderr, "LOOKUP %s\n", path);
 
1368
        fuse_prepare_interrupt(f, req, &d); 
 
1369
        err = lookup_path(f, parent, name, path, &e, NULL);
 
1370
        if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
 
1371
            e.ino = 0;
 
1372
            e.entry_timeout = f->conf.negative_timeout;
 
1373
            err = 0;
 
1374
        }
 
1375
        fuse_finish_interrupt(f, req, &d);
929
1376
        free(path);
930
1377
    }
931
1378
    pthread_rwlock_unlock(&f->tree_lock);
932
1379
    reply_entry(req, &e, err);
933
1380
}
934
1381
 
935
 
static void fuse_forget(fuse_req_t req, fuse_ino_t ino, unsigned long nlookup)
 
1382
static void fuse_lib_forget(fuse_req_t req, fuse_ino_t ino,
 
1383
                            unsigned long nlookup)
936
1384
{
937
1385
    struct fuse *f = req_fuse(req);
938
 
    if (f->conf.debug) {
939
 
        printf("FORGET %llu/%lu\n", (unsigned long long) ino, nlookup);
940
 
        fflush(stdout);
941
 
    }
 
1386
    if (f->conf.debug)
 
1387
        fprintf(stderr, "FORGET %llu/%lu\n", (unsigned long long)ino, nlookup);
942
1388
    forget_node(f, ino, nlookup);
943
1389
    fuse_reply_none(req);
944
1390
}
945
1391
 
946
 
static void fuse_getattr(fuse_req_t req, fuse_ino_t ino,
947
 
                         struct fuse_file_info *fi)
 
1392
static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
 
1393
                             struct fuse_file_info *fi)
948
1394
{
949
1395
    struct fuse *f = req_fuse_prepare(req);
950
1396
    struct stat buf;
958
1404
    pthread_rwlock_rdlock(&f->tree_lock);
959
1405
    path = get_path(f, ino);
960
1406
    if (path != NULL) {
961
 
        err = -ENOSYS;
962
 
        if (f->op.getattr)
963
 
            err = fuse_do_getattr(f, req, path, &buf);
 
1407
        struct fuse_intr_data d;
 
1408
        fuse_prepare_interrupt(f, req, &d);
 
1409
        err = fuse_fs_getattr(f->fs, path, &buf);
 
1410
        fuse_finish_interrupt(f, req, &d);
964
1411
        free(path);
965
1412
    }
966
1413
    pthread_rwlock_unlock(&f->tree_lock);
976
1423
        reply_err(req, err);
977
1424
}
978
1425
 
979
 
static int do_chmod(struct fuse *f, fuse_req_t req, const char *path,
980
 
                    struct stat *attr)
981
 
{
982
 
    int err;
983
 
 
984
 
    err = -ENOSYS;
985
 
    if (f->op.chmod) {
986
 
        struct fuse_intr_data d;
987
 
        fuse_prepare_interrupt(f, req, &d);
988
 
        err = f->op.chmod(path, attr->st_mode);
989
 
        fuse_finish_interrupt(f, req, &d);
990
 
    }
991
 
 
992
 
    return err;
993
 
}
994
 
 
995
 
static int do_chown(struct fuse *f, fuse_req_t req, const char *path,
996
 
                    struct stat *attr, int valid)
997
 
{
998
 
    int err;
999
 
    uid_t uid = (valid & FUSE_SET_ATTR_UID) ? attr->st_uid : (uid_t) -1;
1000
 
    gid_t gid = (valid & FUSE_SET_ATTR_GID) ? attr->st_gid : (gid_t) -1;
1001
 
 
1002
 
    err = -ENOSYS;
1003
 
    if (f->op.chown) {
1004
 
        struct fuse_intr_data d;
1005
 
        fuse_prepare_interrupt(f, req, &d);
1006
 
        err = f->op.chown(path, uid, gid);
1007
 
        fuse_finish_interrupt(f, req, &d);
1008
 
    }
1009
 
 
1010
 
    return err;
1011
 
}
1012
 
 
1013
 
static int do_truncate(struct fuse *f, fuse_req_t req,  const char *path,
1014
 
                       struct stat *attr, struct fuse_file_info *fi)
1015
 
{
1016
 
    int err;
1017
 
    struct fuse_intr_data d;
1018
 
 
1019
 
    err = -ENOSYS;
1020
 
    if (fi && f->op.ftruncate) {
1021
 
        fuse_prepare_interrupt(f, req, &d);
1022
 
        err = f->op.ftruncate(path, attr->st_size, fi);
1023
 
        fuse_finish_interrupt(f, req, &d);
1024
 
    } else if (f->op.truncate) {
1025
 
        fuse_prepare_interrupt(f, req, &d);
1026
 
        err = f->op.truncate(path, attr->st_size);
1027
 
        fuse_finish_interrupt(f, req, &d);
1028
 
    }
1029
 
    return err;
1030
 
}
1031
 
 
1032
 
static int do_utimens(struct fuse *f, fuse_req_t req, const char *path,
1033
 
                      struct stat *attr)
1034
 
{
1035
 
    int err;
1036
 
    struct fuse_intr_data d;
1037
 
 
1038
 
    err = -ENOSYS;
1039
 
    if (f->op.utimens) {
1040
 
        struct timespec tv[2];
1041
 
#ifdef FUSE_STAT_HAS_NANOSEC
1042
 
        tv[0] = ST_ATIM(attr);
1043
 
        tv[1] = ST_MTIM(attr);
1044
 
#else
1045
 
        tv[0].tv_sec = attr->st_atime;
1046
 
        tv[0].tv_nsec = 0;
1047
 
        tv[1].tv_sec = attr->st_mtime;
1048
 
        tv[1].tv_nsec = 0;
1049
 
#endif
1050
 
        fuse_prepare_interrupt(f, req, &d);
1051
 
        err = f->op.utimens(path, tv);
1052
 
        fuse_finish_interrupt(f, req, &d);
1053
 
    } else if (f->op.utime) {
1054
 
        struct utimbuf buf;
1055
 
        buf.actime = attr->st_atime;
1056
 
        buf.modtime = attr->st_mtime;
1057
 
        fuse_prepare_interrupt(f, req, &d);
1058
 
        err = f->op.utime(path, &buf);
1059
 
        fuse_finish_interrupt(f, req, &d);
1060
 
    }
1061
 
 
1062
 
    return err;
1063
 
}
1064
 
 
1065
 
static void fuse_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
1066
 
                         int valid, struct fuse_file_info *fi)
 
1426
int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode)
 
1427
{
 
1428
    if (fs->op.chmod)
 
1429
        return fs->op.chmod(path, mode);
 
1430
    else
 
1431
        return -ENOSYS;
 
1432
}
 
1433
 
 
1434
static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
 
1435
                             int valid, struct fuse_file_info *fi)
1067
1436
{
1068
1437
    struct fuse *f = req_fuse_prepare(req);
1069
1438
    struct stat buf;
1074
1443
    pthread_rwlock_rdlock(&f->tree_lock);
1075
1444
    path = get_path(f, ino);
1076
1445
    if (path != NULL) {
1077
 
        err = -ENOSYS;
1078
 
        if (f->op.getattr) {
1079
 
            err = 0;
1080
 
            if (!err && (valid & FUSE_SET_ATTR_MODE))
1081
 
                err = do_chmod(f, req, path, attr);
1082
 
            if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID)))
1083
 
                err = do_chown(f, req, path, attr, valid);
1084
 
            if (!err && (valid & FUSE_SET_ATTR_SIZE))
1085
 
                err = do_truncate(f, req, path, attr, fi);
1086
 
            if (!err && (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) == (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))
1087
 
                err = do_utimens(f, req, path, attr);
1088
 
            if (!err)
1089
 
                err = fuse_do_getattr(f, req, path, &buf);
1090
 
        }
 
1446
        struct fuse_intr_data d;
 
1447
        fuse_prepare_interrupt(f, req, &d);
 
1448
        err = 0;
 
1449
        if (!err && (valid & FUSE_SET_ATTR_MODE))
 
1450
            err = fuse_fs_chmod(f->fs, path, attr->st_mode);
 
1451
        if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
 
1452
            uid_t uid = 
 
1453
                (valid & FUSE_SET_ATTR_UID) ? attr->st_uid : (uid_t) -1;
 
1454
            gid_t gid = 
 
1455
                (valid & FUSE_SET_ATTR_GID) ? attr->st_gid : (gid_t) -1;
 
1456
            err = fuse_fs_chown(f->fs, path, uid, gid);
 
1457
        }
 
1458
        if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
 
1459
            if (fi)
 
1460
                err = fuse_fs_ftruncate(f->fs, path, attr->st_size, fi);
 
1461
            else
 
1462
                err = fuse_fs_truncate(f->fs, path, attr->st_size);
 
1463
        }
 
1464
        if (!err && (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
 
1465
            (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
 
1466
            struct timespec tv[2];
 
1467
            tv[0].tv_sec = attr->st_atime;
 
1468
            tv[0].tv_nsec = ST_ATIM_NSEC(attr);
 
1469
            tv[1].tv_sec = attr->st_mtime;
 
1470
            tv[1].tv_nsec = ST_MTIM_NSEC(attr);
 
1471
            err = fuse_fs_utimens(f->fs, path, tv);
 
1472
        }
 
1473
        if (!err)
 
1474
            err = fuse_fs_getattr(f->fs,  path, &buf);
 
1475
        fuse_finish_interrupt(f, req, &d);
1091
1476
        free(path);
1092
1477
    }
1093
1478
    pthread_rwlock_unlock(&f->tree_lock);
1103
1488
        reply_err(req, err);
1104
1489
}
1105
1490
 
1106
 
static void fuse_access(fuse_req_t req, fuse_ino_t ino, int mask)
 
1491
static void fuse_lib_access(fuse_req_t req, fuse_ino_t ino, int mask)
1107
1492
{
1108
1493
    struct fuse *f = req_fuse_prepare(req);
1109
1494
    char *path;
1113
1498
    pthread_rwlock_rdlock(&f->tree_lock);
1114
1499
    path = get_path(f, ino);
1115
1500
    if (path != NULL) {
1116
 
        if (f->conf.debug) {
1117
 
            printf("ACCESS %s 0%o\n", path, mask);
1118
 
            fflush(stdout);
1119
 
        }
1120
 
        err = -ENOSYS;
1121
 
        if (f->op.access) {
1122
 
            struct fuse_intr_data d;
1123
 
            fuse_prepare_interrupt(f, req, &d);
1124
 
            err = f->op.access(path, mask);
1125
 
            fuse_finish_interrupt(f, req, &d);
1126
 
        }
 
1501
        struct fuse_intr_data d;
 
1502
        if (f->conf.debug)
 
1503
            fprintf(stderr, "ACCESS %s 0%o\n", path, mask);
 
1504
        fuse_prepare_interrupt(f, req, &d);
 
1505
        err = fuse_fs_access(f->fs, path, mask);
 
1506
        fuse_finish_interrupt(f, req, &d);
1127
1507
        free(path);
1128
1508
    }
1129
1509
    pthread_rwlock_unlock(&f->tree_lock);
1130
1510
    reply_err(req, err);
1131
1511
}
1132
1512
 
1133
 
static void fuse_readlink(fuse_req_t req, fuse_ino_t ino)
 
1513
static void fuse_lib_readlink(fuse_req_t req, fuse_ino_t ino)
1134
1514
{
1135
1515
    struct fuse *f = req_fuse_prepare(req);
1136
1516
    char linkname[PATH_MAX + 1];
1141
1521
    pthread_rwlock_rdlock(&f->tree_lock);
1142
1522
    path = get_path(f, ino);
1143
1523
    if (path != NULL) {
1144
 
        err = -ENOSYS;
1145
 
        if (f->op.readlink) {
1146
 
            struct fuse_intr_data d;
1147
 
            fuse_prepare_interrupt(f, req, &d);
1148
 
            err = f->op.readlink(path, linkname, sizeof(linkname));
1149
 
            fuse_finish_interrupt(f, req, &d);
1150
 
        }
 
1524
        struct fuse_intr_data d;
 
1525
        fuse_prepare_interrupt(f, req, &d);
 
1526
        err = fuse_fs_readlink(f->fs, path, linkname, sizeof(linkname));
 
1527
        fuse_finish_interrupt(f, req, &d);
1151
1528
        free(path);
1152
1529
    }
1153
1530
    pthread_rwlock_unlock(&f->tree_lock);
1158
1535
        reply_err(req, err);
1159
1536
}
1160
1537
 
1161
 
static void fuse_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
1162
 
                       mode_t mode, dev_t rdev)
 
1538
static void fuse_lib_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
 
1539
                           mode_t mode, dev_t rdev)
1163
1540
{
1164
1541
    struct fuse *f = req_fuse_prepare(req);
1165
1542
    struct fuse_entry_param e;
1169
1546
    err = -ENOENT;
1170
1547
    pthread_rwlock_rdlock(&f->tree_lock);
1171
1548
    path = get_path_name(f, parent, name);
1172
 
    if (path != NULL) {
1173
 
        if (f->conf.debug) {
1174
 
            printf("MKNOD %s\n", path);
1175
 
            fflush(stdout);
1176
 
        }
 
1549
    if (path) {
 
1550
        struct fuse_intr_data d;
 
1551
        if (f->conf.debug)
 
1552
            fprintf(stderr, "MKNOD %s\n", path);
 
1553
        fuse_prepare_interrupt(f, req, &d);
1177
1554
        err = -ENOSYS;
1178
 
        if (S_ISREG(mode) && f->op.create && f->op.getattr) {
 
1555
        if (S_ISREG(mode)) {
1179
1556
            struct fuse_file_info fi;
1180
1557
 
1181
1558
            memset(&fi, 0, sizeof(fi));
1182
1559
            fi.flags = O_CREAT | O_EXCL | O_WRONLY;
1183
 
            err = fuse_do_create(f, req, path, mode, &fi);
 
1560
            err = fuse_fs_create(f->fs, path, mode, &fi);
1184
1561
            if (!err) {
1185
 
                err = lookup_path(f, req, parent, name, path, &e, &fi);
1186
 
                if (f->op.release)
1187
 
                    fuse_do_release(f, req, path, &fi);
 
1562
                err = lookup_path(f, parent, name, path, &e, &fi);
 
1563
                fuse_fs_release(f->fs, path, &fi);
1188
1564
            }
1189
 
        } else if (f->op.mknod && f->op.getattr) {
1190
 
            struct fuse_intr_data d;
1191
 
            fuse_prepare_interrupt(f, req, &d);
1192
 
            err = f->op.mknod(path, mode, rdev);
1193
 
            fuse_finish_interrupt(f, req, &d);
 
1565
        }
 
1566
        if (err == -ENOSYS) {
 
1567
            err = fuse_fs_mknod(f->fs, path, mode, rdev);
1194
1568
            if (!err)
1195
 
                err = lookup_path(f, req, parent, name, path, &e, NULL);
 
1569
                err = lookup_path(f, parent, name, path, &e, NULL);
1196
1570
        }
 
1571
        fuse_finish_interrupt(f, req, &d);
1197
1572
        free(path);
1198
1573
    }
1199
1574
    pthread_rwlock_unlock(&f->tree_lock);
1200
1575
    reply_entry(req, &e, err);
1201
1576
}
1202
1577
 
1203
 
static void fuse_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
1204
 
                       mode_t mode)
 
1578
static void fuse_lib_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
 
1579
                           mode_t mode)
1205
1580
{
1206
1581
    struct fuse *f = req_fuse_prepare(req);
1207
1582
    struct fuse_entry_param e;
1212
1587
    pthread_rwlock_rdlock(&f->tree_lock);
1213
1588
    path = get_path_name(f, parent, name);
1214
1589
    if (path != NULL) {
1215
 
        if (f->conf.debug) {
1216
 
            printf("MKDIR %s\n", path);
1217
 
            fflush(stdout);
1218
 
        }
1219
 
        err = -ENOSYS;
1220
 
        if (f->op.mkdir && f->op.getattr) {
1221
 
            struct fuse_intr_data d;
1222
 
            fuse_prepare_interrupt(f, req, &d);
1223
 
            err = f->op.mkdir(path, mode);
1224
 
            fuse_finish_interrupt(f, req, &d);
1225
 
            if (!err)
1226
 
                err = lookup_path(f, req, parent, name, path, &e, NULL);
1227
 
        }
 
1590
        struct fuse_intr_data d;
 
1591
        if (f->conf.debug)
 
1592
            fprintf(stderr, "MKDIR %s\n", path);
 
1593
        fuse_prepare_interrupt(f, req, &d);
 
1594
        err = fuse_fs_mkdir(f->fs, path, mode);
 
1595
        if (!err)
 
1596
            err = lookup_path(f, parent, name, path, &e, NULL);
 
1597
        fuse_finish_interrupt(f, req, &d);
1228
1598
        free(path);
1229
1599
    }
1230
1600
    pthread_rwlock_unlock(&f->tree_lock);
1231
1601
    reply_entry(req, &e, err);
1232
1602
}
1233
1603
 
1234
 
static void fuse_unlink(fuse_req_t req, fuse_ino_t parent, const char *name)
1235
 
{
1236
 
    struct fuse *f = req_fuse_prepare(req);
1237
 
    char *path;
1238
 
    int err;
1239
 
 
1240
 
    err = -ENOENT;
1241
 
    pthread_rwlock_wrlock(&f->tree_lock);
1242
 
    path = get_path_name(f, parent, name);
1243
 
    if (path != NULL) {
1244
 
        if (f->conf.debug) {
1245
 
            printf("UNLINK %s\n", path);
1246
 
            fflush(stdout);
1247
 
        }
1248
 
        err = -ENOSYS;
1249
 
        if (f->op.unlink) {
1250
 
            if (!f->conf.hard_remove && is_open(f, parent, name))
1251
 
                err = hide_node(f, req, path, parent, name);
1252
 
            else {
1253
 
                err = fuse_do_unlink(f, req, path);
1254
 
                if (!err)
1255
 
                    remove_node(f, parent, name);
1256
 
            }
1257
 
        }
1258
 
        free(path);
1259
 
    }
1260
 
    pthread_rwlock_unlock(&f->tree_lock);
1261
 
    reply_err(req, err);
1262
 
}
1263
 
 
1264
 
static void fuse_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
1265
 
{
1266
 
    struct fuse *f = req_fuse_prepare(req);
1267
 
    char *path;
1268
 
    int err;
1269
 
 
1270
 
    err = -ENOENT;
1271
 
    pthread_rwlock_wrlock(&f->tree_lock);
1272
 
    path = get_path_name(f, parent, name);
1273
 
    if (path != NULL) {
1274
 
        if (f->conf.debug) {
1275
 
            printf("RMDIR %s\n", path);
1276
 
            fflush(stdout);
1277
 
        }
1278
 
        err = -ENOSYS;
1279
 
        if (f->op.rmdir) {
1280
 
            struct fuse_intr_data d;
1281
 
            fuse_prepare_interrupt(f, req, &d);
1282
 
            err = f->op.rmdir(path);
1283
 
            fuse_finish_interrupt(f, req, &d);
 
1604
static void fuse_lib_unlink(fuse_req_t req, fuse_ino_t parent,
 
1605
                            const char *name)
 
1606
{
 
1607
    struct fuse *f = req_fuse_prepare(req);
 
1608
    char *path;
 
1609
    int err;
 
1610
 
 
1611
    err = -ENOENT;
 
1612
    pthread_rwlock_wrlock(&f->tree_lock);
 
1613
    path = get_path_name(f, parent, name);
 
1614
    if (path != NULL) {
 
1615
        struct fuse_intr_data d;
 
1616
        if (f->conf.debug)
 
1617
            fprintf(stderr, "UNLINK %s\n", path);
 
1618
        fuse_prepare_interrupt(f, req, &d);
 
1619
        if (!f->conf.hard_remove && is_open(f, parent, name))
 
1620
            err = hide_node(f, path, parent, name);
 
1621
        else {
 
1622
            err = fuse_fs_unlink(f->fs, path);
1284
1623
            if (!err)
1285
1624
                remove_node(f, parent, name);
1286
1625
        }
1287
 
        free(path);
1288
 
    }
1289
 
    pthread_rwlock_unlock(&f->tree_lock);
1290
 
    reply_err(req, err);
1291
 
}
1292
 
 
1293
 
static void fuse_symlink(fuse_req_t req, const char *linkname,
1294
 
                         fuse_ino_t parent, const char *name)
 
1626
        fuse_finish_interrupt(f, req, &d);
 
1627
        free(path);
 
1628
    }
 
1629
    pthread_rwlock_unlock(&f->tree_lock);
 
1630
    reply_err(req, err);
 
1631
}
 
1632
 
 
1633
static void fuse_lib_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
 
1634
{
 
1635
    struct fuse *f = req_fuse_prepare(req);
 
1636
    char *path;
 
1637
    int err;
 
1638
 
 
1639
    err = -ENOENT;
 
1640
    pthread_rwlock_wrlock(&f->tree_lock);
 
1641
    path = get_path_name(f, parent, name);
 
1642
    if (path != NULL) {
 
1643
        struct fuse_intr_data d;
 
1644
        if (f->conf.debug)
 
1645
            fprintf(stderr, "RMDIR %s\n", path);
 
1646
        fuse_prepare_interrupt(f, req, &d);
 
1647
        err = fuse_fs_rmdir(f->fs, path);
 
1648
        fuse_finish_interrupt(f, req, &d);
 
1649
        if (!err)
 
1650
            remove_node(f, parent, name);
 
1651
        free(path);
 
1652
    }
 
1653
    pthread_rwlock_unlock(&f->tree_lock);
 
1654
    reply_err(req, err);
 
1655
}
 
1656
 
 
1657
static void fuse_lib_symlink(fuse_req_t req, const char *linkname,
 
1658
                             fuse_ino_t parent, const char *name)
1295
1659
{
1296
1660
    struct fuse *f = req_fuse_prepare(req);
1297
1661
    struct fuse_entry_param e;
1302
1666
    pthread_rwlock_rdlock(&f->tree_lock);
1303
1667
    path = get_path_name(f, parent, name);
1304
1668
    if (path != NULL) {
1305
 
        if (f->conf.debug) {
1306
 
            printf("SYMLINK %s\n", path);
1307
 
            fflush(stdout);
1308
 
        }
1309
 
        err = -ENOSYS;
1310
 
        if (f->op.symlink && f->op.getattr) {
1311
 
            struct fuse_intr_data d;
1312
 
            fuse_prepare_interrupt(f, req, &d);
1313
 
            err = f->op.symlink(linkname, path);
1314
 
            fuse_finish_interrupt(f, req, &d);
1315
 
            if (!err)
1316
 
                err = lookup_path(f, req, parent, name, path, &e, NULL);
1317
 
        }
 
1669
        struct fuse_intr_data d;
 
1670
        if (f->conf.debug)
 
1671
            fprintf(stderr, "SYMLINK %s\n", path);
 
1672
        fuse_prepare_interrupt(f, req, &d);
 
1673
        err = fuse_fs_symlink(f->fs, linkname, path);
 
1674
        if (!err)
 
1675
            err = lookup_path(f, parent, name, path, &e, NULL);
 
1676
        fuse_finish_interrupt(f, req, &d);
1318
1677
        free(path);
1319
1678
    }
1320
1679
    pthread_rwlock_unlock(&f->tree_lock);
1321
1680
    reply_entry(req, &e, err);
1322
1681
}
1323
1682
 
1324
 
static void fuse_rename(fuse_req_t req, fuse_ino_t olddir, const char *oldname,
1325
 
                        fuse_ino_t newdir, const char *newname)
 
1683
static void fuse_lib_rename(fuse_req_t req, fuse_ino_t olddir,
 
1684
                            const char *oldname, fuse_ino_t newdir,
 
1685
                            const char *newname)
1326
1686
{
1327
1687
    struct fuse *f = req_fuse_prepare(req);
1328
1688
    char *oldpath;
1335
1695
    if (oldpath != NULL) {
1336
1696
        newpath = get_path_name(f, newdir, newname);
1337
1697
        if (newpath != NULL) {
1338
 
            if (f->conf.debug) {
1339
 
                printf("RENAME %s -> %s\n", oldpath, newpath);
1340
 
                fflush(stdout);
1341
 
            }
1342
 
            err = -ENOSYS;
1343
 
            if (f->op.rename) {
1344
 
                err = 0;
1345
 
                if (!f->conf.hard_remove &&
1346
 
                    is_open(f, newdir, newname))
1347
 
                    err = hide_node(f, req, newpath, newdir, newname);
1348
 
                if (!err) {
1349
 
                    err = fuse_do_rename(f, req, oldpath, newpath);
1350
 
                    if (!err)
1351
 
                        err = rename_node(f, olddir, oldname, newdir, newname, 0);
1352
 
                }
1353
 
            }
 
1698
            struct fuse_intr_data d;
 
1699
            if (f->conf.debug)
 
1700
                fprintf(stderr, "RENAME %s -> %s\n", oldpath, newpath);
 
1701
            err = 0;
 
1702
            fuse_prepare_interrupt(f, req, &d);
 
1703
            if (!f->conf.hard_remove && is_open(f, newdir, newname))
 
1704
                err = hide_node(f, newpath, newdir, newname);
 
1705
            if (!err) {
 
1706
                err = fuse_fs_rename(f->fs, oldpath, newpath);
 
1707
                if (!err)
 
1708
                    err = rename_node(f, olddir, oldname, newdir, newname, 0);
 
1709
            }
 
1710
            fuse_finish_interrupt(f, req, &d);
1354
1711
            free(newpath);
1355
1712
        }
1356
1713
        free(oldpath);
1359
1716
    reply_err(req, err);
1360
1717
}
1361
1718
 
1362
 
static void fuse_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
1363
 
                      const char *newname)
 
1719
static void fuse_lib_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
 
1720
                          const char *newname)
1364
1721
{
1365
1722
    struct fuse *f = req_fuse_prepare(req);
1366
1723
    struct fuse_entry_param e;
1374
1731
    if (oldpath != NULL) {
1375
1732
        newpath =  get_path_name(f, newparent, newname);
1376
1733
        if (newpath != NULL) {
1377
 
            if (f->conf.debug) {
1378
 
                printf("LINK %s\n", newpath);
1379
 
                fflush(stdout);
1380
 
            }
1381
 
            err = -ENOSYS;
1382
 
            if (f->op.link && f->op.getattr) {
1383
 
                struct fuse_intr_data d;
1384
 
                fuse_prepare_interrupt(f, req, &d);
1385
 
                err = f->op.link(oldpath, newpath);
1386
 
                fuse_finish_interrupt(f, req, &d);
1387
 
                if (!err)
1388
 
                    err = lookup_path(f, req, newparent, newname, newpath, &e,
1389
 
                                      NULL);
1390
 
            }
 
1734
            struct fuse_intr_data d;
 
1735
            if (f->conf.debug)
 
1736
                fprintf(stderr, "LINK %s\n", newpath);
 
1737
            fuse_prepare_interrupt(f, req, &d);
 
1738
            err = fuse_fs_link(f->fs, oldpath, newpath);
 
1739
            if (!err)
 
1740
                err = lookup_path(f, newparent, newname, newpath, &e, NULL);
 
1741
            fuse_finish_interrupt(f, req, &d);
1391
1742
            free(newpath);
1392
1743
        }
1393
1744
        free(oldpath);
1396
1747
    reply_entry(req, &e, err);
1397
1748
}
1398
1749
 
1399
 
static void fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name,
1400
 
                        mode_t mode, struct fuse_file_info *fi)
 
1750
static void fuse_do_release(struct fuse *f, fuse_ino_t ino, const char *path,
 
1751
                            struct fuse_file_info *fi)
 
1752
{
 
1753
    struct node *node;
 
1754
    int unlink_hidden = 0;
 
1755
 
 
1756
    fuse_fs_release(f->fs, path ? path : "-", fi);
 
1757
 
 
1758
    pthread_mutex_lock(&f->lock);
 
1759
    node = get_node(f, ino);
 
1760
    assert(node->open_count > 0);
 
1761
    --node->open_count;
 
1762
    if (node->is_hidden && !node->open_count) {
 
1763
        unlink_hidden = 1;
 
1764
        node->is_hidden = 0;
 
1765
    }
 
1766
    pthread_mutex_unlock(&f->lock);
 
1767
 
 
1768
    if(unlink_hidden && path)
 
1769
        fuse_fs_unlink(f->fs, path);
 
1770
}
 
1771
 
 
1772
static void fuse_lib_create(fuse_req_t req, fuse_ino_t parent,
 
1773
                            const char *name, mode_t mode,
 
1774
                            struct fuse_file_info *fi)
1401
1775
{
1402
1776
    struct fuse *f = req_fuse_prepare(req);
 
1777
    struct fuse_intr_data d;
1403
1778
    struct fuse_entry_param e;
1404
1779
    char *path;
1405
1780
    int err;
1407
1782
    err = -ENOENT;
1408
1783
    pthread_rwlock_rdlock(&f->tree_lock);
1409
1784
    path = get_path_name(f, parent, name);
1410
 
    if (path != NULL) {
1411
 
        err = -ENOSYS;
1412
 
        if (f->op.create && f->op.getattr) {
1413
 
            err = fuse_do_create(f, req, path, mode, fi);
1414
 
            if (!err) {
1415
 
                if (f->conf.debug) {
1416
 
                    printf("CREATE[%llu] flags: 0x%x %s\n",
1417
 
                           (unsigned long long) fi->fh, fi->flags, path);
1418
 
                    fflush(stdout);
1419
 
                }
1420
 
                err = lookup_path(f, req, parent, name, path, &e, fi);
1421
 
                if (err) {
1422
 
                    if (f->op.release)
1423
 
                        fuse_do_release(f, req, path, fi);
1424
 
                } else if (!S_ISREG(e.attr.st_mode)) {
1425
 
                    err = -EIO;
1426
 
                    if (f->op.release)
1427
 
                        fuse_do_release(f, req, path, fi);
1428
 
                    forget_node(f, e.ino, 1);
1429
 
                }
 
1785
    if (path) {
 
1786
        fuse_prepare_interrupt(f, req, &d);
 
1787
        err = fuse_fs_create(f->fs, path, mode, fi);
 
1788
        if (!err) {
 
1789
            err = lookup_path(f, parent, name, path, &e, fi);
 
1790
            if (err)
 
1791
                fuse_fs_release(f->fs, path, fi);
 
1792
            else if (!S_ISREG(e.attr.st_mode)) {
 
1793
                err = -EIO;
 
1794
                fuse_fs_release(f->fs, path, fi);
 
1795
                forget_node(f, e.ino, 1);
 
1796
            } else {
 
1797
                if (f->conf.direct_io)
 
1798
                    fi->direct_io = 1;
 
1799
                if (f->conf.kernel_cache)
 
1800
                    fi->keep_cache = 1;
 
1801
 
1430
1802
            }
1431
1803
        }
 
1804
        fuse_finish_interrupt(f, req, &d);
1432
1805
    }
1433
 
 
1434
1806
    if (!err) {
1435
 
        if (f->conf.direct_io)
1436
 
            fi->direct_io = 1;
1437
 
        if (f->conf.kernel_cache)
1438
 
            fi->keep_cache = 1;
1439
 
 
1440
 
        /* see comment for open */
1441
1807
        pthread_mutex_lock(&f->lock);
 
1808
        get_node(f, e.ino)->open_count++;
 
1809
        pthread_mutex_unlock(&f->lock);
1442
1810
        if (fuse_reply_create(req, &e, fi) == -ENOENT) {
1443
1811
            /* The open syscall was interrupted, so it must be cancelled */
1444
 
            pthread_mutex_unlock(&f->lock);
1445
 
            if(f->op.release)
1446
 
                fuse_do_release(f, req, path, fi);
 
1812
            fuse_prepare_interrupt(f, req, &d);
 
1813
            fuse_do_release(f, e.ino, path, fi);
 
1814
            fuse_finish_interrupt(f, req, &d);
1447
1815
            forget_node(f, e.ino, 1);
1448
 
        } else {
1449
 
            get_node(f, e.ino)->open_count++;
1450
 
            pthread_mutex_unlock(&f->lock);
 
1816
        } else if (f->conf.debug) {
 
1817
            fprintf(stderr, "  CREATE[%llu] flags: 0x%x %s\n",
 
1818
                    (unsigned long long) fi->fh, fi->flags, path);
1451
1819
        }
1452
1820
    } else
1453
1821
        reply_err(req, err);
1454
1822
 
1455
1823
    if (path)
1456
1824
        free(path);
 
1825
 
1457
1826
    pthread_rwlock_unlock(&f->tree_lock);
1458
1827
}
1459
1828
 
1464
1833
        ((double) t1->tv_nsec - (double) t2->tv_nsec) / 1000000000.0;
1465
1834
}
1466
1835
 
1467
 
static void open_auto_cache(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
1468
 
                            const char *path, struct fuse_file_info *fi)
 
1836
static void open_auto_cache(struct fuse *f, fuse_ino_t ino, const char *path,
 
1837
                            struct fuse_file_info *fi)
1469
1838
{
1470
1839
    struct node *node;
1471
1840
 
1478
1847
        if (diff_timespec(&now, &node->stat_updated) > f->conf.ac_attr_timeout) {
1479
1848
            struct stat stbuf;
1480
1849
            int err;
1481
 
 
1482
1850
            pthread_mutex_unlock(&f->lock);
1483
 
            if (f->op.fgetattr)
1484
 
                err = fuse_do_fgetattr(f, req, path, &stbuf, fi);
1485
 
            else
1486
 
                err = fuse_do_getattr(f, req, path, &stbuf);
 
1851
            err = fuse_fs_fgetattr(f->fs, path, &stbuf, fi);
1487
1852
            pthread_mutex_lock(&f->lock);
1488
 
 
1489
1853
            if (!err)
1490
1854
                update_stat(node, &stbuf);
1491
1855
            else
1499
1863
    pthread_mutex_unlock(&f->lock);
1500
1864
}
1501
1865
 
1502
 
static void fuse_open(fuse_req_t req, fuse_ino_t ino,
1503
 
                      struct fuse_file_info *fi)
 
1866
static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,
 
1867
                          struct fuse_file_info *fi)
1504
1868
{
1505
1869
    struct fuse *f = req_fuse_prepare(req);
 
1870
    struct fuse_intr_data d;
1506
1871
    char *path = NULL;
1507
1872
    int err = 0;
1508
1873
 
 
1874
    err = -ENOENT;
1509
1875
    pthread_rwlock_rdlock(&f->tree_lock);
1510
 
    if (f->op.open) {
1511
 
        err = -ENOENT;
1512
 
        path = get_path(f, ino);
1513
 
        if (path != NULL)
1514
 
            err = fuse_compat_open(f, req, path, fi);
 
1876
    path = get_path(f, ino);
 
1877
    if (path) {
 
1878
        fuse_prepare_interrupt(f, req, &d);
 
1879
        err = fuse_fs_open(f->fs, path, fi);
 
1880
        if (!err) {
 
1881
            if (f->conf.direct_io)
 
1882
                fi->direct_io = 1;
 
1883
            if (f->conf.kernel_cache)
 
1884
                fi->keep_cache = 1;
 
1885
 
 
1886
            if (f->conf.auto_cache)
 
1887
                open_auto_cache(f, ino, path, fi);
 
1888
        }
 
1889
        fuse_finish_interrupt(f, req, &d);
1515
1890
    }
1516
1891
    if (!err) {
1517
 
        if (f->conf.debug) {
1518
 
            printf("OPEN[%llu] flags: 0x%x\n", (unsigned long long) fi->fh,
1519
 
                   fi->flags);
1520
 
            fflush(stdout);
1521
 
        }
1522
 
 
1523
 
        if (f->conf.direct_io)
1524
 
            fi->direct_io = 1;
1525
 
        if (f->conf.kernel_cache)
1526
 
            fi->keep_cache = 1;
1527
 
 
1528
 
        if (f->conf.auto_cache)
1529
 
            open_auto_cache(f, req, ino, path, fi);
1530
 
 
1531
 
        /* The reply and the open count increase needs to be under a
1532
 
           single locked section, otherwise a release could come in
1533
 
           between and screw up the accounting */
1534
1892
        pthread_mutex_lock(&f->lock);
 
1893
        get_node(f, ino)->open_count++;
 
1894
        pthread_mutex_unlock(&f->lock);
1535
1895
        if (fuse_reply_open(req, fi) == -ENOENT) {
1536
1896
            /* The open syscall was interrupted, so it must be cancelled */
1537
 
            pthread_mutex_unlock(&f->lock);
1538
 
            if(f->op.release && path != NULL)
1539
 
                fuse_compat_release(f, req, path, fi);
1540
 
        } else {
1541
 
            get_node(f, ino)->open_count++;
1542
 
            pthread_mutex_unlock(&f->lock);
 
1897
            fuse_prepare_interrupt(f, req, &d);
 
1898
            fuse_do_release(f, ino, path, fi);
 
1899
            fuse_finish_interrupt(f, req, &d);
 
1900
        } else if (f->conf.debug) {
 
1901
            fprintf(stderr, "OPEN[%llu] flags: 0x%x %s\n",
 
1902
                    (unsigned long long) fi->fh, fi->flags, path);
1543
1903
        }
1544
1904
    } else
1545
1905
        reply_err(req, err);
1549
1909
    pthread_rwlock_unlock(&f->tree_lock);
1550
1910
}
1551
1911
 
1552
 
static void fuse_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
1553
 
                      struct fuse_file_info *fi)
 
1912
static void fuse_lib_read(fuse_req_t req, fuse_ino_t ino, size_t size,
 
1913
                          off_t off, struct fuse_file_info *fi)
1554
1914
{
1555
1915
    struct fuse *f = req_fuse_prepare(req);
1556
1916
    char *path;
1567
1927
    pthread_rwlock_rdlock(&f->tree_lock);
1568
1928
    path = get_path(f, ino);
1569
1929
    if (path != NULL) {
1570
 
        if (f->conf.debug) {
1571
 
            printf("READ[%llu] %lu bytes from %llu\n",
1572
 
                   (unsigned long long) fi->fh, (unsigned long) size,
1573
 
                   (unsigned long long) off);
1574
 
            fflush(stdout);
1575
 
        }
 
1930
        struct fuse_intr_data d;
 
1931
        if (f->conf.debug)
 
1932
            fprintf(stderr, "READ[%llu] %lu bytes from %llu\n",
 
1933
                    (unsigned long long) fi->fh, (unsigned long) size,
 
1934
                    (unsigned long long) off);
1576
1935
 
1577
 
        res = -ENOSYS;
1578
 
        if (f->op.read) {
1579
 
            struct fuse_intr_data d;
1580
 
            fuse_prepare_interrupt(f, req, &d);
1581
 
            res = f->op.read(path, buf, size, off, fi);
1582
 
            fuse_finish_interrupt(f, req, &d);
1583
 
        }
 
1936
        fuse_prepare_interrupt(f, req, &d);
 
1937
        res = fuse_fs_read(f->fs, path, buf, size, off, fi);
 
1938
        fuse_finish_interrupt(f, req, &d);
1584
1939
        free(path);
1585
1940
    }
1586
1941
    pthread_rwlock_unlock(&f->tree_lock);
1587
1942
 
1588
1943
    if (res >= 0) {
1589
 
        if (f->conf.debug) {
1590
 
            printf("   READ[%llu] %u bytes\n", (unsigned long long) fi->fh,
1591
 
                   res);
1592
 
            fflush(stdout);
1593
 
        }
 
1944
        if (f->conf.debug)
 
1945
            fprintf(stderr, "   READ[%llu] %u bytes\n",
 
1946
                    (unsigned long long)fi->fh, res);
1594
1947
        if ((size_t) res > size)
1595
1948
            fprintf(stderr, "fuse: read too many bytes");
1596
1949
        fuse_reply_buf(req, buf, res);
1600
1953
    free(buf);
1601
1954
}
1602
1955
 
1603
 
static void fuse_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
 
1956
static void fuse_lib_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
1604
1957
                       size_t size, off_t off, struct fuse_file_info *fi)
1605
1958
{
1606
1959
    struct fuse *f = req_fuse_prepare(req);
1611
1964
    pthread_rwlock_rdlock(&f->tree_lock);
1612
1965
    path = get_path(f, ino);
1613
1966
    if (path != NULL) {
1614
 
        if (f->conf.debug) {
1615
 
            printf("WRITE%s[%llu] %lu bytes to %llu\n",
1616
 
                   fi->writepage ? "PAGE" : "", (unsigned long long) fi->fh,
1617
 
                   (unsigned long) size, (unsigned long long) off);
1618
 
            fflush(stdout);
1619
 
        }
 
1967
        struct fuse_intr_data d;
 
1968
        if (f->conf.debug)
 
1969
            fprintf(stderr, "WRITE%s[%llu] %lu bytes to %llu\n",
 
1970
                    fi->writepage ? "PAGE" : "", (unsigned long long) fi->fh,
 
1971
                    (unsigned long) size, (unsigned long long) off);
1620
1972
 
1621
 
        res = -ENOSYS;
1622
 
        if (f->op.write) {
1623
 
            struct fuse_intr_data d;
1624
 
            fuse_prepare_interrupt(f, req, &d);
1625
 
            res = f->op.write(path, buf, size, off, fi);
1626
 
            fuse_finish_interrupt(f, req, &d);
1627
 
        }
 
1973
        fuse_prepare_interrupt(f, req, &d);
 
1974
        res = fuse_fs_write(f->fs, path, buf, size, off, fi);
 
1975
        fuse_finish_interrupt(f, req, &d);
1628
1976
        free(path);
1629
1977
    }
1630
1978
    pthread_rwlock_unlock(&f->tree_lock);
1631
1979
 
1632
1980
    if (res >= 0) {
1633
 
        if (f->conf.debug) {
1634
 
            printf("   WRITE%s[%llu] %u bytes\n",
1635
 
                   fi->writepage ? "PAGE" : "", (unsigned long long) fi->fh,
1636
 
                   res);
1637
 
            fflush(stdout);
1638
 
        }
 
1981
        if (f->conf.debug)
 
1982
            fprintf(stderr, "   WRITE%s[%llu] %u bytes\n",
 
1983
                    fi->writepage ? "PAGE" : "", (unsigned long long) fi->fh,
 
1984
                    res);
1639
1985
        if ((size_t) res > size)
1640
1986
            fprintf(stderr, "fuse: wrote too many bytes");
1641
1987
        fuse_reply_write(req, res);
1643
1989
        reply_err(req, res);
1644
1990
}
1645
1991
 
1646
 
static void fuse_release(fuse_req_t req, fuse_ino_t ino,
1647
 
                         struct fuse_file_info *fi)
1648
 
{
1649
 
    struct fuse *f = req_fuse_prepare(req);
1650
 
    char *path;
1651
 
    struct node *node;
1652
 
    int unlink_hidden = 0;
1653
 
    int err = 0;
1654
 
 
1655
 
    pthread_rwlock_rdlock(&f->tree_lock);
1656
 
    path = get_path(f, ino);
1657
 
    if (f->conf.debug) {
1658
 
        printf("RELEASE%s[%llu] flags: 0x%x\n", fi->flush ? "+FLUSH" : "", 
1659
 
               (unsigned long long) fi->fh, fi->flags);
1660
 
        fflush(stdout);
1661
 
    }
1662
 
    if (fi->flush && path && f->op.flush)
1663
 
        err = fuse_do_flush(f, req, path, fi);
1664
 
    if (f->op.release)
1665
 
        fuse_compat_release(f, req, path, fi);
1666
 
 
1667
 
    pthread_mutex_lock(&f->lock);
1668
 
    node = get_node(f, ino);
1669
 
    assert(node->open_count > 0);
1670
 
    --node->open_count;
1671
 
    if (node->is_hidden && !node->open_count) {
1672
 
        unlink_hidden = 1;
1673
 
        node->is_hidden = 0;
1674
 
    }
1675
 
    pthread_mutex_unlock(&f->lock);
1676
 
 
1677
 
    if(unlink_hidden && path)
1678
 
        fuse_do_unlink(f, req, path);
1679
 
 
1680
 
    if (path)
1681
 
        free(path);
1682
 
    pthread_rwlock_unlock(&f->tree_lock);
1683
 
 
1684
 
    reply_err(req, err);
1685
 
}
1686
 
 
1687
 
static void fuse_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
 
1992
static void fuse_lib_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
1688
1993
                       struct fuse_file_info *fi)
1689
1994
{
1690
1995
    struct fuse *f = req_fuse_prepare(req);
1695
2000
    pthread_rwlock_rdlock(&f->tree_lock);
1696
2001
    path = get_path(f, ino);
1697
2002
    if (path != NULL) {
1698
 
        if (f->conf.debug) {
1699
 
            printf("FSYNC[%llu]\n", (unsigned long long) fi->fh);
1700
 
            fflush(stdout);
1701
 
        }
1702
 
        err = -ENOSYS;
1703
 
        if (f->op.fsync) {
1704
 
            struct fuse_intr_data d;
1705
 
            fuse_prepare_interrupt(f, req, &d);
1706
 
            err = f->op.fsync(path, datasync, fi);
1707
 
            fuse_finish_interrupt(f, req, &d);
1708
 
        }
 
2003
        struct fuse_intr_data d;
 
2004
        if (f->conf.debug)
 
2005
            fprintf(stderr, "FSYNC[%llu]\n", (unsigned long long) fi->fh);
 
2006
        fuse_prepare_interrupt(f, req, &d);
 
2007
        err = fuse_fs_fsync(f->fs, path, datasync, fi);
 
2008
        fuse_finish_interrupt(f, req, &d);
1709
2009
        free(path);
1710
2010
    }
1711
2011
    pthread_rwlock_unlock(&f->tree_lock);
1712
2012
    reply_err(req, err);
1713
2013
}
1714
2014
 
1715
 
static struct fuse_dirhandle *get_dirhandle(const struct fuse_file_info *llfi,
1716
 
                                            struct fuse_file_info *fi)
 
2015
static struct fuse_dh *get_dirhandle(const struct fuse_file_info *llfi,
 
2016
                                     struct fuse_file_info *fi)
1717
2017
{
1718
 
    struct fuse_dirhandle *dh = (struct fuse_dirhandle *) (uintptr_t) llfi->fh;
 
2018
    struct fuse_dh *dh = (struct fuse_dh *) (uintptr_t) llfi->fh;
1719
2019
    memset(fi, 0, sizeof(struct fuse_file_info));
1720
2020
    fi->fh = dh->fh;
1721
2021
    fi->fh_old = dh->fh;
1722
2022
    return dh;
1723
2023
}
1724
2024
 
1725
 
static void fuse_opendir(fuse_req_t req, fuse_ino_t ino,
 
2025
static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
1726
2026
                       struct fuse_file_info *llfi)
1727
2027
{
1728
2028
    struct fuse *f = req_fuse_prepare(req);
1729
 
    struct fuse_dirhandle *dh;
 
2029
    struct fuse_intr_data d;
 
2030
    struct fuse_dh *dh;
 
2031
    struct fuse_file_info fi;
 
2032
    char *path;
 
2033
    int err;
1730
2034
 
1731
 
    dh = (struct fuse_dirhandle *) malloc(sizeof(struct fuse_dirhandle));
 
2035
    dh = (struct fuse_dh *) malloc(sizeof(struct fuse_dh));
1732
2036
    if (dh == NULL) {
1733
2037
        reply_err(req, -ENOMEM);
1734
2038
        return;
1735
2039
    }
1736
 
    memset(dh, 0, sizeof(struct fuse_dirhandle));
 
2040
    memset(dh, 0, sizeof(struct fuse_dh));
1737
2041
    dh->fuse = f;
1738
2042
    dh->contents = NULL;
1739
2043
    dh->len = 0;
1743
2047
 
1744
2048
    llfi->fh = (uintptr_t) dh;
1745
2049
 
1746
 
    if (f->op.opendir) {
1747
 
        struct fuse_file_info fi;
1748
 
        char *path;
1749
 
        int err;
1750
 
 
1751
 
        memset(&fi, 0, sizeof(fi));
1752
 
        fi.flags = llfi->flags;
1753
 
 
1754
 
        err = -ENOENT;
1755
 
        pthread_rwlock_rdlock(&f->tree_lock);
1756
 
        path = get_path(f, ino);
1757
 
        if (path != NULL) {
1758
 
            err = fuse_compat_opendir(f, req, path, &fi);
1759
 
            dh->fh = fi.fh;
1760
 
        }
1761
 
        if (!err) {
1762
 
            if (fuse_reply_open(req, llfi) == -ENOENT) {
1763
 
                /* The opendir syscall was interrupted, so it must be
1764
 
                   cancelled */
1765
 
                if(f->op.releasedir)
1766
 
                    fuse_do_releasedir(f, req, path, &fi);
1767
 
                pthread_mutex_destroy(&dh->lock);
1768
 
                free(dh);
1769
 
            }
1770
 
        } else {
1771
 
            reply_err(req, err);
 
2050
    memset(&fi, 0, sizeof(fi));
 
2051
    fi.flags = llfi->flags;
 
2052
 
 
2053
    err = -ENOENT;
 
2054
    pthread_rwlock_rdlock(&f->tree_lock);
 
2055
    path = get_path(f, ino);
 
2056
    if (path != NULL) {
 
2057
        fuse_prepare_interrupt(f, req, &d);
 
2058
        err = fuse_fs_opendir(f->fs, path, &fi);
 
2059
        fuse_finish_interrupt(f, req, &d);
 
2060
        dh->fh = fi.fh;
 
2061
    }
 
2062
    if (!err) {
 
2063
        if (fuse_reply_open(req, llfi) == -ENOENT) {
 
2064
            /* The opendir syscall was interrupted, so it must be cancelled */
 
2065
            fuse_prepare_interrupt(f, req, &d);
 
2066
            fuse_fs_releasedir(f->fs, path, &fi);
 
2067
            fuse_finish_interrupt(f, req, &d);
 
2068
            pthread_mutex_destroy(&dh->lock);
1772
2069
            free(dh);
1773
2070
        }
1774
 
        free(path);
1775
 
        pthread_rwlock_unlock(&f->tree_lock);
1776
 
    } else
1777
 
        fuse_reply_open(req, llfi);
 
2071
    } else {
 
2072
        reply_err(req, err);
 
2073
        free(dh);
 
2074
    }
 
2075
    free(path);
 
2076
    pthread_rwlock_unlock(&f->tree_lock);
1778
2077
}
1779
2078
 
1780
 
static int extend_contents(struct fuse_dirhandle *dh, unsigned minsize)
 
2079
static int extend_contents(struct fuse_dh *dh, unsigned minsize)
1781
2080
{
1782
2081
    if (minsize > dh->size) {
1783
2082
        char *newptr;
1798
2097
    return 0;
1799
2098
}
1800
2099
 
1801
 
static int fill_dir_common(struct fuse_dirhandle *dh, const char *name,
1802
 
                           const struct stat *statp, off_t off)
 
2100
static int fill_dir(void *dh_, const char *name, const struct stat *statp,
 
2101
                    off_t off)
1803
2102
{
 
2103
    struct fuse_dh *dh = (struct fuse_dh *) dh_;
1804
2104
    struct stat stbuf;
1805
2105
    size_t newlen;
1806
2106
 
1845
2145
    return 0;
1846
2146
}
1847
2147
 
1848
 
static int fill_dir(void *buf, const char *name, const struct stat *stbuf,
1849
 
                    off_t off)
1850
 
{
1851
 
    return fill_dir_common((struct fuse_dirhandle *) buf, name, stbuf, off);
1852
 
}
1853
 
 
1854
 
static int fill_dir_old(struct fuse_dirhandle *dh, const char *name, int type,
1855
 
                        ino_t ino)
1856
 
{
1857
 
    struct stat stbuf;
1858
 
 
1859
 
    memset(&stbuf, 0, sizeof(stbuf));
1860
 
    stbuf.st_mode = type << 12;
1861
 
    stbuf.st_ino = ino;
1862
 
 
1863
 
    fill_dir_common(dh, name, &stbuf, 0);
1864
 
    return dh->error;
1865
 
}
1866
 
 
1867
2148
static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
1868
 
                        size_t size, off_t off, struct fuse_dirhandle *dh,
 
2149
                        size_t size, off_t off, struct fuse_dh *dh,
1869
2150
                        struct fuse_file_info *fi)
1870
2151
{
1871
2152
    int err = -ENOENT;
1873
2154
    pthread_rwlock_rdlock(&f->tree_lock);
1874
2155
    path = get_path(f, ino);
1875
2156
    if (path != NULL) {
 
2157
        struct fuse_intr_data d;
 
2158
 
1876
2159
        dh->len = 0;
1877
2160
        dh->error = 0;
1878
2161
        dh->needlen = size;
1879
2162
        dh->filled = 1;
1880
2163
        dh->req = req;
1881
 
        err = -ENOSYS;
1882
 
        if (f->op.readdir) {
1883
 
            struct fuse_intr_data d;
1884
 
            fuse_prepare_interrupt(f, req, &d);
1885
 
            err = f->op.readdir(path, dh, fill_dir, off, fi);
1886
 
            fuse_finish_interrupt(f, req, &d);
1887
 
        } else if (f->op.getdir) {
1888
 
            struct fuse_intr_data d;
1889
 
            fuse_prepare_interrupt(f, req, &d);
1890
 
            err = f->op.getdir(path, dh, fill_dir_old);
1891
 
            fuse_finish_interrupt(f, req, &d);
1892
 
        }
 
2164
        fuse_prepare_interrupt(f, req, &d);
 
2165
        err = fuse_fs_readdir(f->fs, path, dh, fill_dir, off, fi);
 
2166
        fuse_finish_interrupt(f, req, &d);
1893
2167
        dh->req = NULL;
1894
2168
        if (!err)
1895
2169
            err = dh->error;
1901
2175
    return err;
1902
2176
}
1903
2177
 
1904
 
static void fuse_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
1905
 
                         off_t off, struct fuse_file_info *llfi)
 
2178
static void fuse_lib_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
 
2179
                             off_t off, struct fuse_file_info *llfi)
1906
2180
{
1907
2181
    struct fuse *f = req_fuse_prepare(req);
1908
2182
    struct fuse_file_info fi;
1909
 
    struct fuse_dirhandle *dh = get_dirhandle(llfi, &fi);
 
2183
    struct fuse_dh *dh = get_dirhandle(llfi, &fi);
1910
2184
 
1911
2185
    pthread_mutex_lock(&dh->lock);
1912
2186
    /* According to SUS, directory contents need to be refreshed on
1936
2210
    pthread_mutex_unlock(&dh->lock);
1937
2211
}
1938
2212
 
1939
 
static void fuse_releasedir(fuse_req_t req, fuse_ino_t ino,
 
2213
static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
1940
2214
                            struct fuse_file_info *llfi)
1941
2215
{
1942
2216
    struct fuse *f = req_fuse_prepare(req);
 
2217
    struct fuse_intr_data d;
1943
2218
    struct fuse_file_info fi;
1944
 
    struct fuse_dirhandle *dh = get_dirhandle(llfi, &fi);
1945
 
    if (f->op.releasedir) {
1946
 
        char *path;
 
2219
    struct fuse_dh *dh = get_dirhandle(llfi, &fi);
 
2220
    char *path;
1947
2221
 
1948
 
        pthread_rwlock_rdlock(&f->tree_lock);
1949
 
        path = get_path(f, ino);
1950
 
        fuse_do_releasedir(f, req, path ? path : "-", &fi);
 
2222
    pthread_rwlock_rdlock(&f->tree_lock);
 
2223
    path = get_path(f, ino);
 
2224
    fuse_prepare_interrupt(f, req, &d);
 
2225
    fuse_fs_releasedir(f->fs, path ? path : "-", &fi);
 
2226
    fuse_finish_interrupt(f, req, &d);
 
2227
    if (path)
1951
2228
        free(path);
1952
 
        pthread_rwlock_unlock(&f->tree_lock);
1953
 
    }
 
2229
    pthread_rwlock_unlock(&f->tree_lock);
1954
2230
    pthread_mutex_lock(&dh->lock);
1955
2231
    pthread_mutex_unlock(&dh->lock);
1956
2232
    pthread_mutex_destroy(&dh->lock);
1959
2235
    reply_err(req, 0);
1960
2236
}
1961
2237
 
1962
 
static void fuse_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
 
2238
static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
1963
2239
                          struct fuse_file_info *llfi)
1964
2240
{
1965
2241
    struct fuse *f = req_fuse_prepare(req);
1973
2249
    pthread_rwlock_rdlock(&f->tree_lock);
1974
2250
    path = get_path(f, ino);
1975
2251
    if (path != NULL) {
1976
 
        err = -ENOSYS;
1977
 
        if (f->op.fsyncdir) {
1978
 
            struct fuse_intr_data d;
1979
 
            fuse_prepare_interrupt(f, req, &d);
1980
 
            err = f->op.fsyncdir(path, datasync, &fi);
1981
 
            fuse_finish_interrupt(f, req, &d);
1982
 
        }
 
2252
        struct fuse_intr_data d;
 
2253
        fuse_prepare_interrupt(f, req, &d);
 
2254
        err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
 
2255
        fuse_finish_interrupt(f, req, &d);
1983
2256
        free(path);
1984
2257
    }
1985
2258
    pthread_rwlock_unlock(&f->tree_lock);
1986
2259
    reply_err(req, err);
1987
2260
}
1988
2261
 
1989
 
static int default_statfs(struct statvfs *buf)
1990
 
{
1991
 
    buf->f_namemax = 255;
1992
 
    buf->f_bsize = 512;
1993
 
    return 0;
1994
 
}
1995
 
 
1996
 
static void fuse_statfs(fuse_req_t req, fuse_ino_t ino)
 
2262
static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
1997
2263
{
1998
2264
    struct fuse *f = req_fuse_prepare(req);
1999
2265
    struct statvfs buf;
 
2266
    char *path;
2000
2267
    int err;
2001
2268
 
2002
2269
    memset(&buf, 0, sizeof(buf));
2003
 
    if (f->op.statfs) {
2004
 
        if (ino && (!f->compat || f->compat >= 26)) {
2005
 
            char *path;
2006
 
            pthread_rwlock_rdlock(&f->tree_lock);
2007
 
            err = -ENOENT;
2008
 
            path = get_path(f, ino);
2009
 
            if (path) {
2010
 
                err = fuse_do_statfs(f, req, path, &buf);
2011
 
                free(path);
2012
 
            }
2013
 
            pthread_rwlock_unlock(&f->tree_lock);
2014
 
        } else
2015
 
            err = fuse_compat_statfs(f, req, &buf);
2016
 
    } else
2017
 
        err = default_statfs(&buf);
 
2270
    pthread_rwlock_rdlock(&f->tree_lock);
 
2271
    if (!ino) {
 
2272
        err = -ENOMEM;
 
2273
        path = strdup("/");
 
2274
    } else {
 
2275
        err = -ENOENT;
 
2276
        path = get_path(f, ino);
 
2277
    }
 
2278
    if (path) {
 
2279
        struct fuse_intr_data d;
 
2280
        fuse_prepare_interrupt(f, req, &d);
 
2281
        err = fuse_fs_statfs(f->fs, path, &buf);
 
2282
        fuse_finish_interrupt(f, req, &d);
 
2283
        free(path);
 
2284
    }
 
2285
    pthread_rwlock_unlock(&f->tree_lock);
2018
2286
 
2019
2287
    if (!err)
2020
2288
        fuse_reply_statfs(req, &buf);
2022
2290
        reply_err(req, err);
2023
2291
}
2024
2292
 
2025
 
static void fuse_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
2026
 
                          const char *value, size_t size, int flags)
 
2293
static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
 
2294
                              const char *value, size_t size, int flags)
2027
2295
{
2028
2296
    struct fuse *f = req_fuse_prepare(req);
2029
2297
    char *path;
2033
2301
    pthread_rwlock_rdlock(&f->tree_lock);
2034
2302
    path = get_path(f, ino);
2035
2303
    if (path != NULL) {
2036
 
        err = -ENOSYS;
2037
 
        if (f->op.setxattr) {
2038
 
            struct fuse_intr_data d;
2039
 
            fuse_prepare_interrupt(f, req, &d);
2040
 
            err = f->op.setxattr(path, name, value, size, flags);
2041
 
            fuse_finish_interrupt(f, req, &d);
2042
 
        }
 
2304
        struct fuse_intr_data d;
 
2305
        fuse_prepare_interrupt(f, req, &d);
 
2306
        err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
 
2307
        fuse_finish_interrupt(f, req, &d);
2043
2308
        free(path);
2044
2309
    }
2045
2310
    pthread_rwlock_unlock(&f->tree_lock);
2056
2321
    pthread_rwlock_rdlock(&f->tree_lock);
2057
2322
    path = get_path(f, ino);
2058
2323
    if (path != NULL) {
2059
 
        err = -ENOSYS;
2060
 
        if (f->op.getxattr) {
2061
 
            struct fuse_intr_data d;
2062
 
            fuse_prepare_interrupt(f, req, &d);
2063
 
            err = f->op.getxattr(path, name, value, size);
2064
 
            fuse_finish_interrupt(f, req, &d);
2065
 
        }
 
2324
        struct fuse_intr_data d;
 
2325
        fuse_prepare_interrupt(f, req, &d);
 
2326
        err = fuse_fs_getxattr(f->fs, path, name, value, size);
 
2327
        fuse_finish_interrupt(f, req, &d);
2066
2328
        free(path);
2067
2329
    }
2068
2330
    pthread_rwlock_unlock(&f->tree_lock);
2069
2331
    return err;
2070
2332
}
2071
2333
 
2072
 
static void fuse_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
2073
 
                        size_t size)
 
2334
static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
 
2335
                              size_t size)
2074
2336
{
2075
2337
    struct fuse *f = req_fuse_prepare(req);
2076
2338
    int res;
2106
2368
    pthread_rwlock_rdlock(&f->tree_lock);
2107
2369
    path = get_path(f, ino);
2108
2370
    if (path != NULL) {
2109
 
        err = -ENOSYS;
2110
 
        if (f->op.listxattr) {
2111
 
            struct fuse_intr_data d;
2112
 
            fuse_prepare_interrupt(f, req, &d);
2113
 
            err = f->op.listxattr(path, list, size);
2114
 
            fuse_finish_interrupt(f, req, &d);
2115
 
        }
 
2371
        struct fuse_intr_data d;
 
2372
        fuse_prepare_interrupt(f, req, &d);
 
2373
        err = fuse_fs_listxattr(f->fs, path, list, size);
 
2374
        fuse_finish_interrupt(f, req, &d);
2116
2375
        free(path);
2117
2376
    }
2118
2377
    pthread_rwlock_unlock(&f->tree_lock);
2119
2378
    return err;
2120
2379
}
2121
2380
 
2122
 
static void fuse_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
 
2381
static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
2123
2382
{
2124
2383
    struct fuse *f = req_fuse_prepare(req);
2125
2384
    int res;
2145
2404
    }
2146
2405
}
2147
2406
 
2148
 
static void fuse_removexattr(fuse_req_t req, fuse_ino_t ino, const char *name)
 
2407
static void fuse_lib_removexattr(fuse_req_t req, fuse_ino_t ino,
 
2408
                                 const char *name)
2149
2409
{
2150
2410
    struct fuse *f = req_fuse_prepare(req);
2151
2411
    char *path;
2155
2415
    pthread_rwlock_rdlock(&f->tree_lock);
2156
2416
    path = get_path(f, ino);
2157
2417
    if (path != NULL) {
2158
 
        err = -ENOSYS;
2159
 
        if (f->op.removexattr) {
2160
 
            struct fuse_intr_data d;
2161
 
            fuse_prepare_interrupt(f, req, &d);
2162
 
            err = f->op.removexattr(path, name);
2163
 
            fuse_finish_interrupt(f, req, &d);
2164
 
        }
 
2418
        struct fuse_intr_data d;
 
2419
        fuse_prepare_interrupt(f, req, &d);
 
2420
        err = fuse_fs_removexattr(f->fs, path, name);
 
2421
        fuse_finish_interrupt(f, req, &d);
2165
2422
        free(path);
2166
2423
    }
2167
2424
    pthread_rwlock_unlock(&f->tree_lock);
2284
2541
    flock->l_pid = lock->pid;
2285
2542
}
2286
2543
 
2287
 
static void fuse_flush(fuse_req_t req, fuse_ino_t ino,
2288
 
                       struct fuse_file_info *fi)
 
2544
static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
 
2545
                             const char *path, struct fuse_file_info *fi)
2289
2546
{
2290
 
    struct fuse *f = req_fuse_prepare(req);
2291
 
    char *path;
 
2547
    struct fuse_intr_data d;
 
2548
    struct flock lock;
 
2549
    struct lock l;
2292
2550
    int err;
2293
 
 
2294
 
    err = -ENOENT;
2295
 
    pthread_rwlock_rdlock(&f->tree_lock);
2296
 
    path = get_path(f, ino);
2297
 
    if (path != NULL) {
2298
 
        if (f->conf.debug) {
2299
 
            printf("FLUSH[%llu]\n", (unsigned long long) fi->fh);
2300
 
            fflush(stdout);
2301
 
        }
2302
 
        err = -ENOSYS;
2303
 
        if (f->op.flush)
2304
 
            err = fuse_do_flush(f, req, path, fi);
2305
 
    }
2306
 
    if (f->op.lock) {
2307
 
        struct flock lock;
2308
 
        struct lock l;
2309
 
        memset(&lock, 0, sizeof(lock));
2310
 
        lock.l_type = F_UNLCK;
2311
 
        lock.l_whence = SEEK_SET;
2312
 
        fuse_do_lock(f, req, path, fi, F_SETLK, &lock);
 
2551
    int errlock;
 
2552
 
 
2553
    fuse_prepare_interrupt(f, req, &d);
 
2554
    memset(&lock, 0, sizeof(lock));
 
2555
    lock.l_type = F_UNLCK;
 
2556
    lock.l_whence = SEEK_SET;
 
2557
    err = fuse_fs_flush(f->fs, path, fi);
 
2558
    errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
 
2559
    fuse_finish_interrupt(f, req, &d);
 
2560
 
 
2561
    if (errlock != -ENOSYS) {
2313
2562
        flock_to_lock(&lock, &l);
2314
2563
        l.owner = fi->lock_owner;
2315
2564
        pthread_mutex_lock(&f->lock);
2320
2569
        if (err == -ENOSYS)
2321
2570
            err = 0;
2322
2571
    }
 
2572
    return err;
 
2573
}
 
2574
 
 
2575
static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
 
2576
                             struct fuse_file_info *fi)
 
2577
{
 
2578
    struct fuse *f = req_fuse_prepare(req);
 
2579
    struct fuse_intr_data d;
 
2580
    char *path;
 
2581
    int err = 0;
 
2582
 
 
2583
    pthread_rwlock_rdlock(&f->tree_lock);
 
2584
    path = get_path(f, ino);
 
2585
    if (f->conf.debug)
 
2586
        fprintf(stderr, "RELEASE%s[%llu] flags: 0x%x\n",
 
2587
                fi->flush ? "+FLUSH" : "",
 
2588
                (unsigned long long) fi->fh, fi->flags);
 
2589
 
 
2590
    if (fi->flush) {
 
2591
        err = fuse_flush_common(f, req, ino, path, fi);
 
2592
        if (err == -ENOSYS)
 
2593
            err = 0;
 
2594
    }
 
2595
 
 
2596
    fuse_prepare_interrupt(f, req, &d);
 
2597
    fuse_do_release(f, ino, path, fi);
 
2598
    fuse_finish_interrupt(f, req, &d);
 
2599
    free(path);
 
2600
    pthread_rwlock_unlock(&f->tree_lock);
 
2601
 
 
2602
    reply_err(req, err);
 
2603
}
 
2604
 
 
2605
static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,
 
2606
                       struct fuse_file_info *fi)
 
2607
{
 
2608
    struct fuse *f = req_fuse_prepare(req);
 
2609
    char *path;
 
2610
    int err;
 
2611
 
 
2612
    pthread_rwlock_rdlock(&f->tree_lock);
 
2613
    path = get_path(f, ino);
 
2614
    if (path && f->conf.debug)
 
2615
        fprintf(stderr, "FLUSH[%llu]\n", (unsigned long long) fi->fh);
 
2616
    err = fuse_flush_common(f, req, ino, path, fi);
2323
2617
    free(path);
2324
2618
    pthread_rwlock_unlock(&f->tree_lock);
2325
2619
    reply_err(req, err);
2337
2631
    pthread_rwlock_rdlock(&f->tree_lock);
2338
2632
    path = get_path(f, ino);
2339
2633
    if (path != NULL) {
2340
 
        err = fuse_do_lock(f, req, path, fi, cmd, lock);
 
2634
        struct fuse_intr_data d;
 
2635
        fuse_prepare_interrupt(f, req, &d);
 
2636
        err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
 
2637
        fuse_finish_interrupt(f, req, &d);
2341
2638
        free(path);
2342
2639
    }
2343
2640
    pthread_rwlock_unlock(&f->tree_lock);
2344
2641
    return err;
2345
2642
}
2346
2643
 
2347
 
static void fuse_getlk(fuse_req_t req, fuse_ino_t ino,
2348
 
                       struct fuse_file_info *fi, struct flock *lock)
 
2644
static void fuse_lib_getlk(fuse_req_t req, fuse_ino_t ino,
 
2645
                           struct fuse_file_info *fi, struct flock *lock)
2349
2646
{
2350
2647
    int err;
2351
2648
    struct lock l;
2370
2667
        reply_err(req, err);
2371
2668
}
2372
2669
 
2373
 
static void fuse_setlk(fuse_req_t req, fuse_ino_t ino,
2374
 
                       struct fuse_file_info *fi, struct flock *lock,
2375
 
                       int sleep)
 
2670
static void fuse_lib_setlk(fuse_req_t req, fuse_ino_t ino,
 
2671
                           struct fuse_file_info *fi, struct flock *lock,
 
2672
                           int sleep)
2376
2673
{
2377
2674
    int err = fuse_lock_common(req, ino, fi, lock, sleep ? F_SETLKW : F_SETLK);
2378
2675
    if (!err) {
2387
2684
    reply_err(req, err);
2388
2685
}
2389
2686
 
2390
 
static void fuse_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
2391
 
                      uint64_t idx)
 
2687
static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
 
2688
                          uint64_t idx)
2392
2689
{
2393
2690
    struct fuse *f = req_fuse_prepare(req);
 
2691
    struct fuse_intr_data d;
2394
2692
    char *path;
2395
2693
    int err;
2396
2694
 
2398
2696
    pthread_rwlock_rdlock(&f->tree_lock);
2399
2697
    path = get_path(f, ino);
2400
2698
    if (path != NULL) {
2401
 
        err = -ENOSYS;
2402
 
        if (f->op.bmap)
2403
 
            err = f->op.bmap(path, blocksize, &idx);
 
2699
        fuse_prepare_interrupt(f, req, &d);
 
2700
        err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
 
2701
        fuse_finish_interrupt(f, req, &d);
2404
2702
        free(path);
2405
2703
    }
2406
2704
    pthread_rwlock_unlock(&f->tree_lock);
2411
2709
}
2412
2710
 
2413
2711
static struct fuse_lowlevel_ops fuse_path_ops = {
2414
 
    .init = fuse_data_init,
2415
 
    .destroy = fuse_data_destroy,
2416
 
    .lookup = fuse_lookup,
2417
 
    .forget = fuse_forget,
2418
 
    .getattr = fuse_getattr,
2419
 
    .setattr = fuse_setattr,
2420
 
    .access = fuse_access,
2421
 
    .readlink = fuse_readlink,
2422
 
    .mknod = fuse_mknod,
2423
 
    .mkdir = fuse_mkdir,
2424
 
    .unlink = fuse_unlink,
2425
 
    .rmdir = fuse_rmdir,
2426
 
    .symlink = fuse_symlink,
2427
 
    .rename = fuse_rename,
2428
 
    .link = fuse_link,
2429
 
    .create = fuse_create,
2430
 
    .open = fuse_open,
2431
 
    .read = fuse_read,
2432
 
    .write = fuse_write,
2433
 
    .flush = fuse_flush,
2434
 
    .release = fuse_release,
2435
 
    .fsync = fuse_fsync,
2436
 
    .opendir = fuse_opendir,
2437
 
    .readdir = fuse_readdir,
2438
 
    .releasedir = fuse_releasedir,
2439
 
    .fsyncdir = fuse_fsyncdir,
2440
 
    .statfs = fuse_statfs,
2441
 
    .setxattr = fuse_setxattr,
2442
 
    .getxattr = fuse_getxattr,
2443
 
    .listxattr = fuse_listxattr,
2444
 
    .removexattr = fuse_removexattr,
2445
 
    .getlk = fuse_getlk,
2446
 
    .setlk = fuse_setlk,
2447
 
    .bmap = fuse_bmap,
 
2712
    .init = fuse_lib_init,
 
2713
    .destroy = fuse_lib_destroy,
 
2714
    .lookup = fuse_lib_lookup,
 
2715
    .forget = fuse_lib_forget,
 
2716
    .getattr = fuse_lib_getattr,
 
2717
    .setattr = fuse_lib_setattr,
 
2718
    .access = fuse_lib_access,
 
2719
    .readlink = fuse_lib_readlink,
 
2720
    .mknod = fuse_lib_mknod,
 
2721
    .mkdir = fuse_lib_mkdir,
 
2722
    .unlink = fuse_lib_unlink,
 
2723
    .rmdir = fuse_lib_rmdir,
 
2724
    .symlink = fuse_lib_symlink,
 
2725
    .rename = fuse_lib_rename,
 
2726
    .link = fuse_lib_link,
 
2727
    .create = fuse_lib_create,
 
2728
    .open = fuse_lib_open,
 
2729
    .read = fuse_lib_read,
 
2730
    .write = fuse_lib_write,
 
2731
    .flush = fuse_lib_flush,
 
2732
    .release = fuse_lib_release,
 
2733
    .fsync = fuse_lib_fsync,
 
2734
    .opendir = fuse_lib_opendir,
 
2735
    .readdir = fuse_lib_readdir,
 
2736
    .releasedir = fuse_lib_releasedir,
 
2737
    .fsyncdir = fuse_lib_fsyncdir,
 
2738
    .statfs = fuse_lib_statfs,
 
2739
    .setxattr = fuse_lib_setxattr,
 
2740
    .getxattr = fuse_lib_getxattr,
 
2741
    .listxattr = fuse_lib_listxattr,
 
2742
    .removexattr = fuse_lib_removexattr,
 
2743
    .getlk = fuse_lib_getlk,
 
2744
    .setlk = fuse_lib_setlk,
 
2745
    .bmap = fuse_lib_bmap,
2448
2746
};
2449
2747
 
2450
2748
static void free_cmd(struct fuse_cmd *cmd)
2573
2871
    FUSE_LIB_OPT("negative_timeout=%lf",  negative_timeout, 0),
2574
2872
    FUSE_LIB_OPT("intr",                  intr, 1),
2575
2873
    FUSE_LIB_OPT("intr_signal=%d",        intr_signal, 0),
 
2874
    FUSE_LIB_OPT("modules=%s",            modules, 0),
2576
2875
    FUSE_OPT_END
2577
2876
};
2578
2877
 
2594
2893
"    -o ac_attr_timeout=T   auto cache timeout for attributes (attr_timeout)\n"
2595
2894
"    -o intr                allow requests to be interrupted\n"
2596
2895
"    -o intr_signal=NUM     signal to send on interrupt (%i)\n"
 
2896
"    -o modules=M1[:M2...]  names of modules to push onto filesystem stack\n"
2597
2897
"\n", FUSE_DEFAULT_INTR_SIGNAL);
2598
2898
}
2599
2899
 
 
2900
static void fuse_lib_help_modules(void)
 
2901
{
 
2902
    struct fuse_module *m;
 
2903
    fprintf(stderr, "\nModule options:\n");
 
2904
    pthread_mutex_lock(&fuse_context_lock);
 
2905
    for (m = fuse_modules; m; m = m->next) {
 
2906
        struct fuse_fs *fs = NULL;
 
2907
        struct fuse_fs *newfs;
 
2908
        struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
 
2909
        if (fuse_opt_add_arg(&args, "") != -1 &&
 
2910
            fuse_opt_add_arg(&args, "-h") != -1) {
 
2911
            fprintf(stderr, "\n[%s]\n", m->name);
 
2912
            newfs = m->factory(&args, &fs);
 
2913
            assert(newfs == NULL);
 
2914
        }
 
2915
        fuse_opt_free_args(&args);
 
2916
    }
 
2917
    pthread_mutex_unlock(&fuse_context_lock);
 
2918
}
 
2919
 
2600
2920
static int fuse_lib_opt_proc(void *data, const char *arg, int key,
2601
2921
                             struct fuse_args *outargs)
2602
2922
{
2603
 
    (void) data; (void) arg; (void) outargs;
 
2923
    (void) arg; (void) outargs;
2604
2924
 
2605
 
    if (key == KEY_HELP)
 
2925
    if (key == KEY_HELP) {
 
2926
        struct fuse_config *conf = (struct fuse_config *) data;
2606
2927
        fuse_lib_help();
 
2928
        conf->help = 1;
 
2929
    }
2607
2930
 
2608
2931
    return 1;
2609
2932
}
2610
2933
 
2611
 
 
2612
2934
int fuse_is_lib_option(const char *opt)
2613
2935
{
2614
2936
    return fuse_lowlevel_is_lib_option(opt) ||
2649
2971
    sigaction(signum, &sa, NULL);
2650
2972
}
2651
2973
 
 
2974
 
 
2975
static int fuse_push_module(struct fuse *f, const char *module,
 
2976
                            struct fuse_args *args)
 
2977
{
 
2978
    struct fuse_fs *fs[2] = { f->fs, NULL };
 
2979
    struct fuse_fs *newfs;
 
2980
    struct fuse_module *m = fuse_get_module(module);
 
2981
 
 
2982
    if (!m)
 
2983
        return -1;
 
2984
 
 
2985
    newfs = m->factory(args, fs);
 
2986
    if (!newfs) {
 
2987
        fuse_put_module(m);
 
2988
        return -1;
 
2989
    }
 
2990
    newfs->m = m;
 
2991
    f->fs = newfs;
 
2992
    return 0;
 
2993
}
 
2994
 
 
2995
struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
 
2996
                            void *user_data)
 
2997
{
 
2998
    struct fuse_fs *fs;
 
2999
 
 
3000
    if (sizeof(struct fuse_operations) < op_size) {
 
3001
        fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n");
 
3002
        op_size = sizeof(struct fuse_operations);
 
3003
    }
 
3004
 
 
3005
    fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
 
3006
    if (!fs) {
 
3007
        fprintf(stderr, "fuse: failed to allocate fuse_fs object\n");
 
3008
        return NULL;
 
3009
    }
 
3010
 
 
3011
    fs->user_data = user_data;
 
3012
    if (op)
 
3013
        memcpy(&fs->op, op, op_size);
 
3014
    return fs;
 
3015
}
 
3016
 
2652
3017
struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
2653
3018
                             const struct fuse_operations *op,
2654
3019
                             size_t op_size, void *user_data, int compat)
2655
3020
{
2656
3021
    struct fuse *f;
2657
3022
    struct node *root;
 
3023
    struct fuse_fs *fs;
2658
3024
    struct fuse_lowlevel_ops llop = fuse_path_ops;
2659
3025
 
2660
 
    if (sizeof(struct fuse_operations) < op_size) {
2661
 
        fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n");
2662
 
        op_size = sizeof(struct fuse_operations);
2663
 
    }
2664
 
 
2665
3026
    if (fuse_create_context_key() == -1)
2666
3027
        goto out;
2667
3028
 
2671
3032
        goto out_delete_context_key;
2672
3033
    }
2673
3034
 
2674
 
    f->user_data = user_data;
 
3035
    fs = fuse_fs_new(op, op_size, user_data);
 
3036
    if (!fs)
 
3037
        goto out_free;
 
3038
 
 
3039
    fs->compat = compat;
 
3040
    f->fs = fs;
 
3041
 
 
3042
    /* Oh f**k, this is ugly! */
 
3043
    if (!fs->op.lock) {
 
3044
        llop.getlk = NULL;
 
3045
        llop.setlk = NULL;
 
3046
    }
 
3047
 
2675
3048
    f->conf.entry_timeout = 1.0;
2676
3049
    f->conf.attr_timeout = 1.0;
2677
3050
    f->conf.negative_timeout = 0.0;
2678
3051
    f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
2679
3052
 
2680
3053
    if (fuse_opt_parse(args, &f->conf, fuse_lib_opts, fuse_lib_opt_proc) == -1)
2681
 
            goto out_free;
 
3054
        goto out_free_fs;
 
3055
 
 
3056
    if (f->conf.modules) {
 
3057
        char *module;
 
3058
        char *next;
 
3059
 
 
3060
        for (module = f->conf.modules; module; module = next) {
 
3061
            char *p;
 
3062
            for (p = module; *p && *p != ':'; p++);
 
3063
            next = *p ? p + 1 : NULL;
 
3064
            *p = '\0';
 
3065
            if (module[0] && fuse_push_module(f, module, args) == -1)
 
3066
                goto out_free_fs;
 
3067
        }
 
3068
    }
2682
3069
 
2683
3070
    if (!f->conf.ac_attr_timeout_set)
2684
3071
        f->conf.ac_attr_timeout = f->conf.attr_timeout;
2693
3080
 
2694
3081
    if (compat && compat <= 25) {
2695
3082
        if (fuse_sync_compat_args(args) == -1)
2696
 
            goto out_free;
2697
 
    }
2698
 
 
2699
 
    memcpy(&f->op, op, op_size);
2700
 
    if (!f->op.lock) {
2701
 
        llop.getlk = NULL;
2702
 
        llop.setlk = NULL;
 
3083
            goto out_free_fs;
2703
3084
    }
2704
3085
 
2705
3086
    f->se = fuse_lowlevel_new_common(args, &llop, sizeof(llop), f);
2706
 
    if (f->se == NULL)
2707
 
        goto out_free;
 
3087
    if (f->se == NULL) {
 
3088
        if (f->conf.help)
 
3089
            fuse_lib_help_modules();
 
3090
        goto out_free_fs;
 
3091
    }
2708
3092
 
2709
3093
    fuse_session_add_chan(f->se, ch);
2710
3094
 
2729
3113
 
2730
3114
    fuse_mutex_init(&f->lock);
2731
3115
    pthread_rwlock_init(&f->tree_lock, NULL);
2732
 
    f->compat = compat;
2733
3116
 
2734
3117
    root = (struct node *) calloc(1, sizeof(struct node));
2735
3118
    if (root == NULL) {
2747
3130
        fuse_init_intr_signal(f->conf.intr_signal, &f->intr_installed) == -1)
2748
3131
        goto out_free_root_name;
2749
3132
 
2750
 
    root->parent = 0;
 
3133
    root->parent = NULL;
2751
3134
    root->nodeid = FUSE_ROOT_ID;
2752
3135
    root->generation = 0;
2753
3136
    root->refctr = 1;
2766
3149
    free(f->name_table);
2767
3150
 out_free_session:
2768
3151
    fuse_session_destroy(f->se);
 
3152
 out_free_fs:
 
3153
    /* Horrible compatibility hack to stop the destructor from being
 
3154
       called on the filesystem without init being called first */
 
3155
    fs->op.destroy = NULL;
 
3156
    fuse_fs_destroy(f->fs);
 
3157
    free(f->conf.modules);
2769
3158
 out_free:
2770
3159
    free(f);
2771
3160
 out_delete_context_key:
2784
3173
void fuse_destroy(struct fuse *f)
2785
3174
{
2786
3175
    size_t i;
2787
 
    struct fuse_context_i *c = fuse_get_context_internal();
2788
3176
 
2789
3177
    if (f->conf.intr && f->intr_installed)
2790
3178
        fuse_restore_intr_signal(f->conf.intr_signal);
2791
3179
 
2792
 
    memset(c, 0, sizeof(*c));
2793
 
    c->ctx.fuse = f;
2794
 
    c->ctx.private_data = f->user_data;
2795
 
 
2796
 
    for (i = 0; i < f->id_table_size; i++) {
2797
 
        struct node *node;
2798
 
 
2799
 
        for (node = f->id_table[i]; node != NULL; node = node->id_next) {
2800
 
            if (node->is_hidden) {
2801
 
                char *path = get_path(f, node->nodeid);
2802
 
                if (path) {
2803
 
                    f->op.unlink(path);
2804
 
                    free(path);
 
3180
    if (f->fs) {
 
3181
        struct fuse_context_i *c = fuse_get_context_internal();
 
3182
 
 
3183
        memset(c, 0, sizeof(*c));
 
3184
        c->ctx.fuse = f;
 
3185
 
 
3186
        for (i = 0; i < f->id_table_size; i++) {
 
3187
            struct node *node;
 
3188
 
 
3189
            for (node = f->id_table[i]; node != NULL; node = node->id_next) {
 
3190
                if (node->is_hidden) {
 
3191
                    char *path = get_path(f, node->nodeid);
 
3192
                    if (path) {
 
3193
                        fuse_fs_unlink(f->fs, path);
 
3194
                        free(path);
 
3195
                    }
2805
3196
                }
2806
3197
            }
2807
3198
        }
2820
3211
    pthread_mutex_destroy(&f->lock);
2821
3212
    pthread_rwlock_destroy(&f->tree_lock);
2822
3213
    fuse_session_destroy(f->se);
 
3214
    free(f->conf.modules);
2823
3215
    free(f);
2824
3216
    fuse_delete_context_key();
2825
3217
}
2826
3218
 
2827
 
#include "fuse_common_compat.h"
2828
 
#include "fuse_compat.h"
2829
 
 
2830
3219
static struct fuse *fuse_new_common_compat25(int fd, struct fuse_args *args,
2831
3220
                                             const struct fuse_operations *op,
2832
3221
                                             size_t op_size, int compat)
2840
3229
    return f;
2841
3230
}
2842
3231
 
 
3232
/* called with fuse_context_lock held or during initialization (before
 
3233
   main() has been called) */
 
3234
void fuse_register_module(struct fuse_module *mod)
 
3235
{
 
3236
    mod->ctr = 0;
 
3237
    mod->so = fuse_current_so;
 
3238
    if (mod->so)
 
3239
        mod->so->ctr++;
 
3240
    mod->next = fuse_modules;
 
3241
    fuse_modules = mod;
 
3242
}
 
3243
 
2843
3244
#ifndef __FreeBSD__
2844
3245
 
2845
 
static int fuse_compat_open(struct fuse *f, fuse_req_t req, char *path,
2846
 
                            struct fuse_file_info *fi)
2847
 
{
2848
 
    int err;
2849
 
    struct fuse_intr_data d;
2850
 
    if (!f->compat || f->compat >= 25)
2851
 
        err = fuse_do_open(f, req, path, fi);
2852
 
    else if (f->compat == 22) {
2853
 
        struct fuse_file_info_compat tmp;
2854
 
        memcpy(&tmp, fi, sizeof(tmp));
2855
 
        fuse_prepare_interrupt(f, req, &d);
2856
 
        err = ((struct fuse_operations_compat22 *) &f->op)->open(path, &tmp);
2857
 
        fuse_finish_interrupt(f, req, &d);
2858
 
        memcpy(fi, &tmp, sizeof(tmp));
2859
 
        fi->fh = tmp.fh;
2860
 
    } else {
2861
 
        fuse_prepare_interrupt(f, req, &d);
2862
 
        err =
2863
 
            ((struct fuse_operations_compat2 *) &f->op)->open(path, fi->flags);
2864
 
        fuse_finish_interrupt(f, req, &d);
2865
 
    }
2866
 
    return err;
2867
 
}
2868
 
 
2869
 
static void fuse_compat_release(struct fuse *f, fuse_req_t req, char *path,
2870
 
                                struct fuse_file_info *fi)
2871
 
{
2872
 
    if (!f->compat || f->compat >= 22)
2873
 
        fuse_do_release(f, req, path ? path : "-", fi);
2874
 
    else if (path) {
2875
 
        struct fuse_intr_data d;
2876
 
        fuse_prepare_interrupt(f, req, &d);
2877
 
        ((struct fuse_operations_compat2 *) &f->op)->release(path, fi->flags);
2878
 
        fuse_finish_interrupt(f, req, &d);
2879
 
    }
2880
 
}
2881
 
 
2882
 
static int fuse_compat_opendir(struct fuse *f, fuse_req_t req, char *path,
2883
 
                               struct fuse_file_info *fi)
2884
 
{
2885
 
    if (!f->compat || f->compat >= 25) {
2886
 
        return fuse_do_opendir(f, req, path, fi);
2887
 
    } else {
2888
 
        int err;
2889
 
        struct fuse_file_info_compat tmp;
2890
 
        struct fuse_intr_data d;
2891
 
        memcpy(&tmp, fi, sizeof(tmp));
2892
 
        fuse_prepare_interrupt(f, req, &d);
2893
 
        err = ((struct fuse_operations_compat22 *) &f->op)->opendir(path, &tmp);
2894
 
        fuse_finish_interrupt(f, req, &d);
2895
 
        memcpy(fi, &tmp, sizeof(tmp));
2896
 
        fi->fh = tmp.fh;
2897
 
        return err;
2898
 
    }
2899
 
}
2900
 
 
2901
 
static void convert_statfs_compat(struct fuse_statfs_compat1 *compatbuf,
2902
 
                                  struct statvfs *stbuf)
2903
 
{
2904
 
    stbuf->f_bsize   = compatbuf->block_size;
2905
 
    stbuf->f_blocks  = compatbuf->blocks;
2906
 
    stbuf->f_bfree   = compatbuf->blocks_free;
2907
 
    stbuf->f_bavail  = compatbuf->blocks_free;
2908
 
    stbuf->f_files   = compatbuf->files;
2909
 
    stbuf->f_ffree   = compatbuf->files_free;
2910
 
    stbuf->f_namemax = compatbuf->namelen;
2911
 
}
2912
 
 
2913
 
static void convert_statfs_old(struct statfs *oldbuf, struct statvfs *stbuf)
2914
 
{
2915
 
    stbuf->f_bsize   = oldbuf->f_bsize;
2916
 
    stbuf->f_blocks  = oldbuf->f_blocks;
2917
 
    stbuf->f_bfree   = oldbuf->f_bfree;
2918
 
    stbuf->f_bavail  = oldbuf->f_bavail;
2919
 
    stbuf->f_files   = oldbuf->f_files;
2920
 
    stbuf->f_ffree   = oldbuf->f_ffree;
2921
 
    stbuf->f_namemax = oldbuf->f_namelen;
2922
 
}
2923
 
 
2924
 
static int fuse_compat_statfs(struct fuse *f, fuse_req_t req,
2925
 
                              struct statvfs *buf)
2926
 
{
2927
 
    int err;
2928
 
    struct fuse_intr_data d;
2929
 
 
2930
 
    if (!f->compat || f->compat >= 25) {
2931
 
        err = fuse_do_statfs(f, req, "/", buf);
2932
 
    } else if (f->compat > 11) {
2933
 
        struct statfs oldbuf;
2934
 
        fuse_prepare_interrupt(f, req, &d);
2935
 
        err = ((struct fuse_operations_compat22 *) &f->op)->statfs("/", &oldbuf);
2936
 
        fuse_finish_interrupt(f, req, &d);
2937
 
        if (!err)
2938
 
            convert_statfs_old(&oldbuf, buf);
2939
 
    } else {
2940
 
        struct fuse_statfs_compat1 compatbuf;
2941
 
        memset(&compatbuf, 0, sizeof(struct fuse_statfs_compat1));
2942
 
        fuse_prepare_interrupt(f, req, &d);
2943
 
        err = ((struct fuse_operations_compat1 *) &f->op)->statfs(&compatbuf);
2944
 
        fuse_finish_interrupt(f, req, &d);
2945
 
        if (!err)
2946
 
            convert_statfs_compat(&compatbuf, buf);
2947
 
    }
2948
 
    return err;
2949
 
}
2950
 
 
2951
3246
static struct fuse *fuse_new_common_compat(int fd, const char *opts,
2952
3247
                                           const struct fuse_operations *op,
2953
3248
                                           size_t op_size, int compat)
3001
3296
__asm__(".symver fuse_new_compat2,fuse_new@");
3002
3297
__asm__(".symver fuse_new_compat22,fuse_new@FUSE_2.2");
3003
3298
 
3004
 
#else /* __FreeBSD__ */
3005
 
 
3006
 
static int fuse_compat_open(struct fuse *f, fuse_req_t req, char *path,
3007
 
                            struct fuse_file_info *fi)
3008
 
{
3009
 
    return fuse_do_open(f, req, path, fi);
3010
 
}
3011
 
 
3012
 
static void fuse_compat_release(struct fuse *f, fuse_req_t req, char *path,
3013
 
                                struct fuse_file_info *fi)
3014
 
{
3015
 
    fuse_do_release(f, req, path ? path : "-", fi);
3016
 
}
3017
 
 
3018
 
static int fuse_compat_opendir(struct fuse *f, fuse_req_t req, char *path,
3019
 
                               struct fuse_file_info *fi)
3020
 
{
3021
 
    return fuse_do_opendir(f, req, path, fi);
3022
 
}
3023
 
 
3024
 
static int fuse_compat_statfs(struct fuse *f, fuse_req_t req, struct statvfs *buf)
3025
 
{
3026
 
    return fuse_do_statfs(f, req, "/", buf);
3027
 
}
3028
 
 
3029
3299
#endif /* __FreeBSD__ */
3030
3300
 
3031
3301
struct fuse *fuse_new_compat25(int fd, struct fuse_args *args,