~ubuntu-branches/ubuntu/vivid/aufs/vivid

« back to all changes in this revision

Viewing changes to sample/uloop/libuloop.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2007-12-15 23:32:51 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20071215233251-2vgs2lmg8mai5d9e
Tags: 0+20071211-1ubuntu1
* Merge from debian unstable (LP: #175705), remaining changes:
  - Fix for Ubuntu Kernels (updated)
* patches/01_vserver.dpatch: Removed
* patches/06_ubuntu.dpatch: Added (update of ubuntu patch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * aufs sample -- ULOOP driver
 
3
 *
 
4
 * Copyright (C) 2007 Junjiro Okajima
 
5
 *
 
6
 * This program, aufs is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 */
 
20
 
 
21
/* $Id: libuloop.c,v 1.2 2007/11/26 01:35:40 sfjro Exp $ */
 
22
 
 
23
#include <linux/uloop.h>
 
24
 
 
25
#include <sys/ioctl.h>
 
26
#include <sys/stat.h>
 
27
#include <sys/types.h>
 
28
 
 
29
#include <assert.h>
 
30
#include <errno.h>
 
31
#include <fcntl.h>
 
32
#include <limits.h>
 
33
#include <signal.h>
 
34
#include <stdio.h>
 
35
#include <string.h>
 
36
#include <unistd.h>
 
37
 
 
38
static struct uloop g_uloop;
 
39
const struct uloop *uloop = &g_uloop;
 
40
 
 
41
/* ---------------------------------------------------------------------- */
 
42
 
 
43
#define Dbg(fmt, args...) fprintf(stderr, "%s:%d:" fmt, \
 
44
        __func__, __LINE__, ##args)
 
45
#define DbgErr(e) if (e) Dbg("err %d\n", e)
 
46
 
 
47
/* ---------------------------------------------------------------------- */
 
48
 
 
49
int ulo_loop(int sig, ulo_cb_t store, void *arg)
 
50
{
 
51
        int err;
 
52
        pid_t pid;
 
53
        static sigset_t sigset;
 
54
        union ulo_ctl ctl;
 
55
 
 
56
        pid = getpid();
 
57
        err = sigemptyset(&sigset);
 
58
        if (!err)
 
59
                err = sigaddset(&sigset, sig);
 
60
        if (!err)
 
61
                err = sigprocmask(SIG_BLOCK, &sigset, NULL);
 
62
 
 
63
        while (!err) {
 
64
                ctl.ready.signum = sig;
 
65
                ctl.ready.pid = pid;
 
66
                //Dbg("ready\n");
 
67
                err = ioctl(g_uloop.fd[ULO_DEV], ULOCTL_READY, &ctl);
 
68
                DbgErr(err);
 
69
                if (!err)
 
70
                        err = sigwaitinfo(&sigset, NULL);
 
71
                //DbgErr(err);
 
72
                if (err == sig)
 
73
                        err = ioctl(g_uloop.fd[ULO_DEV], ULOCTL_RCVREQ, &ctl);
 
74
                DbgErr(err);
 
75
                if (!err)
 
76
                        err = store(ctl.rcvreq.start, ctl.rcvreq.size, arg);
 
77
                if (!err) {
 
78
                        ctl.sndres.start = ctl.rcvreq.start;
 
79
                        ctl.sndres.size = ctl.rcvreq.size;
 
80
                        err = ioctl(g_uloop.fd[ULO_DEV], ULOCTL_SNDRES, &ctl);
 
81
                        DbgErr(err);
 
82
                }
 
83
        }
 
84
 
 
85
        return err;
 
86
}
 
87
 
 
88
/* ---------------------------------------------------------------------- */
 
89
 
 
90
static int ulo_create_size(char *path, unsigned long long size)
 
91
{
 
92
        int fd, err;
 
93
        off_t off;
 
94
        ssize_t sz;
 
95
        struct stat st;
 
96
 
 
97
        err = 0;
 
98
        st.st_size = 0;
 
99
        fd = open(path, O_RDWR | O_CREAT, 0644);
 
100
        if (fd < 0)
 
101
                return fd;
 
102
        err = fstat(fd, &st);
 
103
        if (err)
 
104
                return err;
 
105
        if (st.st_size == size)
 
106
                return fd; /* success */
 
107
 
 
108
        off = lseek(fd, size - 1, SEEK_SET);
 
109
        if (off == -1)
 
110
                return -1;
 
111
        sz = write(fd, "\0", 1);
 
112
        if (sz != 1)
 
113
                return -1;
 
114
        return fd; /* success */
 
115
}
 
116
 
 
117
static int ulo_init_loop(char *dev_path, int dev_flags, char *cache_path)
 
118
{
 
119
        int err;
 
120
        struct loop_info64 loinfo64;
 
121
        union ulo_ctl ctl;
 
122
 
 
123
        err = open(dev_path, dev_flags);
 
124
        if (err < 0)
 
125
                goto out;
 
126
        g_uloop.fd[ULO_DEV] = err;
 
127
 
 
128
        err = ioctl(g_uloop.fd[ULO_DEV], LOOP_SET_FD, g_uloop.fd[ULO_CACHE]);
 
129
        if (err)
 
130
                goto out;
 
131
 
 
132
        memset(&loinfo64, 0, sizeof(loinfo64));
 
133
        strncpy((void *)(loinfo64.lo_file_name), cache_path, LO_NAME_SIZE);
 
134
        loinfo64.lo_encrypt_type = LOOP_FILTER_ULOOP;
 
135
        //strncpy((void *)(loinfo64.lo_crypt_name), "ulttp", LO_NAME_SIZE);
 
136
        //loinfo64.lo_sizelimit = cache_size;
 
137
        err = ioctl(g_uloop.fd[ULO_DEV], LOOP_SET_STATUS64, &loinfo64);
 
138
        if (err)
 
139
                goto out_loop;
 
140
 
 
141
        ctl.setbmp.fd = g_uloop.fd[ULO_BITMAP];
 
142
        ctl.setbmp.pagesize = g_uloop.pagesize;
 
143
        err = ioctl(g_uloop.fd[ULO_DEV], ULOCTL_SETBMP, &ctl);
 
144
        if (!err) {
 
145
#if 0
 
146
                Dbg("{%d, %d, %d}, pgae %d, tgt %Lu, cache %Lu\n",
 
147
                    uloop->fd[0], uloop->fd[1], uloop->fd[2],
 
148
                    uloop->pagesize, uloop->tgt_size, uloop->cache_size);
 
149
#endif
 
150
                return 0;
 
151
        }
 
152
        DbgErr(err);
 
153
 
 
154
 out_loop:
 
155
        ioctl(g_uloop.fd[ULO_DEV], LOOP_CLR_FD, g_uloop.fd[ULO_CACHE]);
 
156
 out:
 
157
        return err;
 
158
}
 
159
 
 
160
int ulo_init(struct ulo_init *init)
 
161
{
 
162
        int err;
 
163
        unsigned long long mod, sz;
 
164
 
 
165
#if 0
 
166
        err = EINVAL;
 
167
        int i;
 
168
        for (i = 0; i < ULO_Last; i++)
 
169
                if (!init->path[i])
 
170
                        goto out;
 
171
        if (init->size == -1)
 
172
                goto out;
 
173
#endif
 
174
 
 
175
        g_uloop.cache_size = init->size;
 
176
        g_uloop.tgt_size = init->size;
 
177
 
 
178
        g_uloop.pagesize = sysconf(_SC_PAGESIZE);
 
179
        assert(g_uloop.pagesize > 0);
 
180
 
 
181
        err = EINVAL;
 
182
        mod = g_uloop.cache_size % g_uloop.pagesize;
 
183
        if (mod)
 
184
                g_uloop.cache_size += g_uloop.pagesize - mod;
 
185
        if (g_uloop.cache_size % g_uloop.pagesize)
 
186
                goto out;
 
187
        g_uloop.fd[ULO_CACHE] = ulo_create_size(init->path[ULO_CACHE],
 
188
                                                g_uloop.cache_size);
 
189
        err = g_uloop.fd[ULO_CACHE];
 
190
        if (g_uloop.fd[ULO_CACHE] < 0)
 
191
                goto out;
 
192
 
 
193
        sz = g_uloop.cache_size;
 
194
        sz /= g_uloop.pagesize;
 
195
        sz /= CHAR_BIT;
 
196
        if (sz < g_uloop.pagesize)
 
197
                sz = g_uloop.pagesize;
 
198
        else {
 
199
                mod = sz % g_uloop.pagesize;
 
200
                if (mod)
 
201
                        sz += g_uloop.pagesize - mod;
 
202
        }
 
203
        err = EINVAL;
 
204
        if (sz % g_uloop.pagesize)
 
205
                goto out;
 
206
        g_uloop.fd[ULO_BITMAP] = ulo_create_size(init->path[ULO_BITMAP], sz);
 
207
        err = g_uloop.fd[ULO_BITMAP];
 
208
        if (g_uloop.fd[ULO_BITMAP] < 0)
 
209
                goto out;
 
210
 
 
211
        err = ulo_init_loop(init->path[ULO_DEV], init->dev_flags,
 
212
                            init->path[ULO_CACHE]);
 
213
        if (!err)
 
214
                return 0;
 
215
 out:
 
216
        return err;
 
217
}