2
* aufs sample -- ULOOP driver
4
* Copyright (C) 2007 Junjiro Okajima
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.
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.
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
21
/* $Id: libuloop.c,v 1.2 2007/11/26 01:35:40 sfjro Exp $ */
23
#include <linux/uloop.h>
25
#include <sys/ioctl.h>
27
#include <sys/types.h>
38
static struct uloop g_uloop;
39
const struct uloop *uloop = &g_uloop;
41
/* ---------------------------------------------------------------------- */
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)
47
/* ---------------------------------------------------------------------- */
49
int ulo_loop(int sig, ulo_cb_t store, void *arg)
53
static sigset_t sigset;
57
err = sigemptyset(&sigset);
59
err = sigaddset(&sigset, sig);
61
err = sigprocmask(SIG_BLOCK, &sigset, NULL);
64
ctl.ready.signum = sig;
67
err = ioctl(g_uloop.fd[ULO_DEV], ULOCTL_READY, &ctl);
70
err = sigwaitinfo(&sigset, NULL);
73
err = ioctl(g_uloop.fd[ULO_DEV], ULOCTL_RCVREQ, &ctl);
76
err = store(ctl.rcvreq.start, ctl.rcvreq.size, arg);
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);
88
/* ---------------------------------------------------------------------- */
90
static int ulo_create_size(char *path, unsigned long long size)
99
fd = open(path, O_RDWR | O_CREAT, 0644);
102
err = fstat(fd, &st);
105
if (st.st_size == size)
106
return fd; /* success */
108
off = lseek(fd, size - 1, SEEK_SET);
111
sz = write(fd, "\0", 1);
114
return fd; /* success */
117
static int ulo_init_loop(char *dev_path, int dev_flags, char *cache_path)
120
struct loop_info64 loinfo64;
123
err = open(dev_path, dev_flags);
126
g_uloop.fd[ULO_DEV] = err;
128
err = ioctl(g_uloop.fd[ULO_DEV], LOOP_SET_FD, g_uloop.fd[ULO_CACHE]);
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);
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);
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);
155
ioctl(g_uloop.fd[ULO_DEV], LOOP_CLR_FD, g_uloop.fd[ULO_CACHE]);
160
int ulo_init(struct ulo_init *init)
163
unsigned long long mod, sz;
168
for (i = 0; i < ULO_Last; i++)
171
if (init->size == -1)
175
g_uloop.cache_size = init->size;
176
g_uloop.tgt_size = init->size;
178
g_uloop.pagesize = sysconf(_SC_PAGESIZE);
179
assert(g_uloop.pagesize > 0);
182
mod = g_uloop.cache_size % g_uloop.pagesize;
184
g_uloop.cache_size += g_uloop.pagesize - mod;
185
if (g_uloop.cache_size % g_uloop.pagesize)
187
g_uloop.fd[ULO_CACHE] = ulo_create_size(init->path[ULO_CACHE],
189
err = g_uloop.fd[ULO_CACHE];
190
if (g_uloop.fd[ULO_CACHE] < 0)
193
sz = g_uloop.cache_size;
194
sz /= g_uloop.pagesize;
196
if (sz < g_uloop.pagesize)
197
sz = g_uloop.pagesize;
199
mod = sz % g_uloop.pagesize;
201
sz += g_uloop.pagesize - mod;
204
if (sz % g_uloop.pagesize)
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)
211
err = ulo_init_loop(init->path[ULO_DEV], init->dev_flags,
212
init->path[ULO_CACHE]);