~ubuntu-branches/ubuntu/maverick/fuse/maverick-proposed

« back to all changes in this revision

Viewing changes to lib/fuse_kern_chan.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2008-01-29 10:38:39 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20080129103839-kmz63d04pnttuuoc
Tags: 2.7.2-1ubuntu1
* Resynchronise with Debian. 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.
  - Create libfuse2-udeb and fuse-utils-udeb.
  - Copy /sbin/mount.fuse and the fuse kernel module into the initramfs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
    FUSE: Filesystem in Userspace
3
 
    Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
 
2
  FUSE: Filesystem in Userspace
 
3
  Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
4
4
 
5
 
    This program can be distributed under the terms of the GNU LGPLv2.
6
 
    See the file COPYING.LIB
 
5
  This program can be distributed under the terms of the GNU LGPLv2.
 
6
  See the file COPYING.LIB
7
7
*/
8
8
 
9
9
#include "fuse_lowlevel.h"
16
16
#include <assert.h>
17
17
 
18
18
static int fuse_kern_chan_receive(struct fuse_chan **chp, char *buf,
19
 
                                  size_t size)
 
19
                                  size_t size)
20
20
{
21
 
    struct fuse_chan *ch = *chp;
22
 
    int err;
23
 
    ssize_t res;
24
 
    struct fuse_session *se = fuse_chan_session(ch);
25
 
    assert(se != NULL);
26
 
 
27
 
 restart:
28
 
    res = read(fuse_chan_fd(ch), buf, size);
29
 
    err = errno;
30
 
 
31
 
    if (fuse_session_exited(se))
32
 
        return 0;
33
 
    if (res == -1) {
34
 
        /* ENOENT means the operation was interrupted, it's safe
35
 
           to restart */
36
 
        if (err == ENOENT)
37
 
            goto restart;
38
 
 
39
 
        if (err == ENODEV) {
40
 
            fuse_session_exit(se);
41
 
            return 0;
42
 
        }
43
 
        /* Errors occuring during normal operation: EINTR (read
44
 
           interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem
45
 
           umounted) */
46
 
        if (err != EINTR && err != EAGAIN)
47
 
            perror("fuse: reading device");
48
 
        return -err;
49
 
    }
50
 
    if ((size_t) res < sizeof(struct fuse_in_header)) {
51
 
        fprintf(stderr, "short read on fuse device\n");
52
 
        return -EIO;
53
 
    }
54
 
    return res;
 
21
        struct fuse_chan *ch = *chp;
 
22
        int err;
 
23
        ssize_t res;
 
24
        struct fuse_session *se = fuse_chan_session(ch);
 
25
        assert(se != NULL);
 
26
 
 
27
restart:
 
28
        res = read(fuse_chan_fd(ch), buf, size);
 
29
        err = errno;
 
30
 
 
31
        if (fuse_session_exited(se))
 
32
                return 0;
 
33
        if (res == -1) {
 
34
                /* ENOENT means the operation was interrupted, it's safe
 
35
                   to restart */
 
36
                if (err == ENOENT)
 
37
                        goto restart;
 
38
 
 
39
                if (err == ENODEV) {
 
40
                        fuse_session_exit(se);
 
41
                        return 0;
 
42
                }
 
43
                /* Errors occuring during normal operation: EINTR (read
 
44
                   interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem
 
45
                   umounted) */
 
46
                if (err != EINTR && err != EAGAIN)
 
47
                        perror("fuse: reading device");
 
48
                return -err;
 
49
        }
 
50
        if ((size_t) res < sizeof(struct fuse_in_header)) {
 
51
                fprintf(stderr, "short read on fuse device\n");
 
52
                return -EIO;
 
53
        }
 
54
        return res;
55
55
}
56
56
 
57
57
static int fuse_kern_chan_send(struct fuse_chan *ch, const struct iovec iov[],
58
 
                               size_t count)
 
58
                               size_t count)
59
59
{
60
 
    if (iov) {
61
 
        ssize_t res = writev(fuse_chan_fd(ch), iov, count);
62
 
        int err = errno;
63
 
 
64
 
        if (res == -1) {
65
 
            struct fuse_session *se = fuse_chan_session(ch);
66
 
 
67
 
            assert(se != NULL);
68
 
 
69
 
            /* ENOENT means the operation was interrupted */
70
 
            if (!fuse_session_exited(se) && err != ENOENT)
71
 
                perror("fuse: writing device");
72
 
            return -err;
73
 
        }
74
 
    }
75
 
    return 0;
 
60
        if (iov) {
 
61
                ssize_t res = writev(fuse_chan_fd(ch), iov, count);
 
62
                int err = errno;
 
63
 
 
64
                if (res == -1) {
 
65
                        struct fuse_session *se = fuse_chan_session(ch);
 
66
 
 
67
                        assert(se != NULL);
 
68
 
 
69
                        /* ENOENT means the operation was interrupted */
 
70
                        if (!fuse_session_exited(se) && err != ENOENT)
 
71
                                perror("fuse: writing device");
 
72
                        return -err;
 
73
                }
 
74
        }
 
75
        return 0;
76
76
}
77
77
 
78
78
static void fuse_kern_chan_destroy(struct fuse_chan *ch)
79
79
{
80
 
    close(fuse_chan_fd(ch));
 
80
        close(fuse_chan_fd(ch));
81
81
}
82
82
 
83
83
#define MIN_BUFSIZE 0x21000
84
84
 
85
85
struct fuse_chan *fuse_kern_chan_new(int fd)
86
86
{
87
 
    struct fuse_chan_ops op = {
88
 
        .receive = fuse_kern_chan_receive,
89
 
        .send = fuse_kern_chan_send,
90
 
        .destroy = fuse_kern_chan_destroy,
91
 
    };
92
 
    size_t bufsize = getpagesize() + 0x1000;
93
 
    bufsize = bufsize < MIN_BUFSIZE ? MIN_BUFSIZE : bufsize;
94
 
    return fuse_chan_new(&op, fd, bufsize, NULL);
 
87
        struct fuse_chan_ops op = {
 
88
                .receive = fuse_kern_chan_receive,
 
89
                .send = fuse_kern_chan_send,
 
90
                .destroy = fuse_kern_chan_destroy,
 
91
        };
 
92
        size_t bufsize = getpagesize() + 0x1000;
 
93
        bufsize = bufsize < MIN_BUFSIZE ? MIN_BUFSIZE : bufsize;
 
94
        return fuse_chan_new(&op, fd, bufsize, NULL);
95
95
}