Back to index

avfs  1.0.1
Classes | Functions
filter.c File Reference
#include "filter.h"
#include "version.h"
#include "filtprog.h"
#include "filecache.h"
#include "cache.h"
#include "internal.h"
#include "oper.h"

Go to the source code of this file.

Classes

struct  filtid
struct  filtmod
struct  filtnode
struct  filtfile

Functions

static char ** filt_copy_prog (const char *prog[])
static void filt_free_prog (char **prog)
static int filt_lookup (ventry *ve, const char *name, void **newp)
static void filtnode_free (struct filtnode *nod)
static int filt_same_file (struct filtid *id, struct avstat *stbuf)
static int filt_unmodif_file (struct filtmod *mod, struct avstat *stbuf)
static void filt_id_set (struct filtid *id, struct avstat *stbuf)
static void filt_mod_set (struct filtmod *mod, struct avstat *stbuf)
static void filt_newnode (struct filtfile *ff, ventry *ve, vfile *vf, const char *key, struct avstat *buf)
static int filt_validate_file (struct filtnode *nod, ventry *ve, vfile *vf, struct avstat *buf, int iswrite)
static int filt_getfile (struct filtfile *ff, ventry *ve, vfile *vf, const char *key)
static int filt_get_baseflags (int flags, int *maybecrp)
static int filt_open_base (ventry *ve, int flags, avmode_t mode, vfile **vfp, int *bfresp)
static int filt_open_file (struct filtfile *ff, ventry *ve, int flags, avmode_t mode)
static int filt_open (ventry *ve, int flags, avmode_t mode, void **resp)
static avssize_t filt_read (vfile *vf, char *buf, avsize_t nbyte)
static avssize_t filt_write (vfile *vf, const char *buf, avsize_t nbyte)
static int filt_truncate (vfile *vf, avoff_t length)
static void filt_afterflush (vfile *vf, struct filtnode *nod)
static int filt_close (vfile *vf)
static int filt_getattr (vfile *vf, struct avstat *buf, int attrmask)
static int filt_setattr (vfile *vf, struct avstat *buf, int attrmask)
static int filt_access (ventry *ve, int amode)
static int filt_rename (ventry *ve, ventry *newve)
static int filt_unlink (ventry *ve)
static void filt_destroy (struct avfs *avfs)
int av_init_filt (struct vmodule *module, int version, const char *name, const char *prog[], const char *revprog[], struct ext_info *exts, struct avfs **resp)

Class Documentation

struct filtid

Definition at line 19 of file filter.c.

Class Members
avdev_t dev
avino_t ino
struct filtmod

Definition at line 24 of file filter.c.

Class Members
avtimestruc_t mtime
avoff_t size
struct filtnode

Definition at line 29 of file filter.c.

Collaboration diagram for filtnode:
Class Members
avino_t ino
avmutex lock
struct sfile * sf
vfile * vf
unsigned int writers
struct filtfile

Definition at line 39 of file filter.c.

Collaboration diagram for filtfile:
Class Members
struct cacheobj * cobj
int iswrite
struct filtnode * nod

Function Documentation

int av_init_filt ( struct vmodule module,
int  version,
const char *  name,
const char *  prog[],
const char *  revprog[],
struct ext_info exts,
struct avfs **  resp 
)

Definition at line 523 of file filter.c.

{
    int res;
    struct avfs *avfs;
    struct filtdata *filtdat;
    
    res = av_new_avfs(name, exts, version, AVF_NOLOCK, module, &avfs);
    if(res < 0)
        return res;

    AV_NEW(filtdat);
    filtdat->prog = filt_copy_prog(prog);
    filtdat->revprog = filt_copy_prog(revprog);

    avfs->data = filtdat;

    avfs->destroy  = filt_destroy;
    avfs->lookup   = filt_lookup;
    avfs->access   = filt_access;
    avfs->unlink   = filt_unlink;
    avfs->rename   = filt_rename;  
    avfs->open     = filt_open;
    avfs->close    = filt_close; 
    avfs->read     = filt_read;
    avfs->write    = filt_write;
    avfs->getattr  = filt_getattr;
    avfs->setattr  = filt_setattr;
    avfs->truncate = filt_truncate;

    av_add_avfs(avfs);
    
    *resp = avfs;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int filt_access ( ventry *  ve,
int  amode 
) [static]

Definition at line 499 of file filter.c.

{
    return av_access(ve->mnt->base, amode);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void filt_afterflush ( vfile *  vf,
struct filtnode nod 
) [static]

Definition at line 392 of file filter.c.

{
    int res;
    struct avstat stbuf;
    int attrmask = AVA_INO | AVA_DEV | AVA_SIZE | AVA_MTIME;
    avoff_t size = -1;
    vfile *bvf;

    res = av_fgetattr(nod->vf, &stbuf, AVA_SIZE);
    if(res == 0)
        size = stbuf.size;

    av_close(nod->vf);
    nod->vf = NULL;
    nod->mod.size = -1;

    res = av_open(vf->mnt->base, AVO_NOPERM, 0, &bvf);
    if(res < 0)
        return;

    res = av_fgetattr(bvf, &stbuf, attrmask);
    if(res == 0 && filt_same_file(&nod->id, &stbuf) && stbuf.size == size)
        filt_mod_set(&nod->mod, &stbuf);
        
    av_close(bvf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int filt_close ( vfile *  vf) [static]

Definition at line 419 of file filter.c.

{
    int res = 0;
    struct filtfile *ff = (struct filtfile *) vf->data;
    struct filtnode *nod = ff->nod;
    avoff_t du;

    AV_LOCK(nod->lock);
    if(ff->iswrite) {
        nod->writers --;

        if(nod->writers == 0) {
            res = av_sfile_flush(nod->sf);
            filt_afterflush(vf, nod);
        }
    }
    du = av_sfile_diskusage(nod->sf);
    if(du >= 0)
        av_cacheobj_setsize(ff->cobj, du);
    AV_UNLOCK(nod->lock);

    av_unref_obj(nod);
    av_unref_obj(ff->cobj);
    av_free(ff);

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char** filt_copy_prog ( const char *  prog[]) [static]

Definition at line 45 of file filter.c.

{
    int num;
    const char **curr;
    char **copyprog;
    int i;

    if(prog == NULL)
        return NULL;

    for(num = 0, curr = prog; *curr != NULL; curr++, num++);
    
    copyprog = (char **) av_malloc(sizeof(char *) * (num + 1));

    for(i = 0; i < num; i++)
        copyprog[i] = av_strdup(prog[i]);

    copyprog[i] = NULL;

    return copyprog;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void filt_destroy ( struct avfs avfs) [static]

Definition at line 514 of file filter.c.

{
    struct filtdata *filtdat = (struct filtdata *) avfs->data;

    filt_free_prog(filtdat->prog);
    filt_free_prog(filtdat->revprog);
    av_free(filtdat);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void filt_free_prog ( char **  prog) [static]

Definition at line 67 of file filter.c.

{
    if(prog != NULL) {
        char **curr;

        for(curr = prog; *curr != NULL; curr++)
            av_free(*curr);
        
        av_free(prog);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int filt_get_baseflags ( int  flags,
int *  maybecrp 
) [static]

Definition at line 227 of file filter.c.

{
    int baseflags;
    int maybecreat = 0;

    if(AV_ISWRITE(flags))
        baseflags = AVO_RDWR;
    else
        baseflags = AVO_RDONLY;
    
    if((flags & AVO_TRUNC) != 0)
        baseflags |= AVO_TRUNC;

    if((flags & AVO_CREAT) != 0) {
        if(flags & AVO_EXCL)
            baseflags = AVO_RDWR | AVO_CREAT | AVO_EXCL | AVO_TRUNC;
        else if(flags & AVO_TRUNC)
            baseflags = AVO_RDWR | AVO_CREAT | AVO_TRUNC;
        else
            maybecreat = 1;
    }

    *maybecrp = maybecreat;
    return baseflags;
}

Here is the caller graph for this function:

static int filt_getattr ( vfile *  vf,
struct avstat buf,
int  attrmask 
) [static]

Definition at line 447 of file filter.c.

{
    struct filtfile *ff = (struct filtfile *) vf->data;
    struct filtnode *nod = ff->nod;
    struct avstat origbuf;
    int res;
    avoff_t size = -1;
    avino_t ino;
    avtimestruc_t mtime;

    AV_LOCK(nod->lock);
    ino = nod->ino;
    res = av_fgetattr(nod->vf, &origbuf, AVA_ALL & ~AVA_SIZE);
    if(res == 0) { 
        size = av_sfile_size(nod->sf);
        if(size < 0)
            res = size;
    }
    if(nod->writers != 0)
        mtime = nod->mod.mtime;
    else
        mtime = origbuf.mtime;
    AV_UNLOCK(nod->lock);

    if(res < 0)
        return res;

    *buf = origbuf;
    buf->mode &= ~(07000);
    buf->blksize = 4096;
    buf->dev = vf->mnt->avfs->dev;
    buf->ino = ino;
    buf->size = size;
    buf->blocks = AV_BLOCKS(size);
    buf->mtime = mtime;
    
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int filt_getfile ( struct filtfile ff,
ventry *  ve,
vfile *  vf,
const char *  key 
) [static]

Definition at line 193 of file filter.c.

{
    int res;
    struct avstat buf;
    int attrmask = AVA_INO | AVA_DEV | AVA_SIZE | AVA_MTIME;

    res = av_fgetattr(vf, &buf, attrmask);
    if(res < 0)
        return res;

    ff->cobj = (struct cacheobj *) av_filecache_get(key);
    if(ff->cobj != NULL)
        ff->nod = (struct filtnode *) av_cacheobj_get(ff->cobj);

    if(ff->nod == NULL || !filt_same_file(&ff->nod->id, &buf)) {
        av_unref_obj(ff->nod);
        av_unref_obj(ff->cobj);
        filt_newnode(ff, ve, vf, key, &buf);
        return 0;
    }

    AV_LOCK(ff->nod->lock);
    res = filt_validate_file(ff->nod, ve, vf, &buf, ff->iswrite);
    if(res < 0) {
        AV_UNLOCK(ff->nod->lock);
        av_unref_obj(ff->nod);
        av_unref_obj(ff->cobj);
        return res;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void filt_id_set ( struct filtid id,
struct avstat stbuf 
) [static]

Definition at line 127 of file filter.c.

{
    id->ino = stbuf->ino;
    id->dev = stbuf->dev;
}

Here is the caller graph for this function:

static int filt_lookup ( ventry *  ve,
const char *  name,
void **  newp 
) [static]

Definition at line 79 of file filter.c.

{
    char *path = (char *) ve->data;
    
    if(path == NULL) {
        if(name[0] != '\0')
            return -ENOENT;
       if(ve->mnt->opts[0] != '\0')
            return -ENOENT;
        path = av_strdup(name);
    }
    else if(name == NULL) {
        av_free(path);
        path = NULL;
    }
    else 
        return -ENOENT;
    
    *newp = path;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void filt_mod_set ( struct filtmod mod,
struct avstat stbuf 
) [static]

Definition at line 133 of file filter.c.

{
    mod->size = stbuf->size;
    mod->mtime = stbuf->mtime;
}

Here is the caller graph for this function:

static void filt_newnode ( struct filtfile ff,
ventry *  ve,
vfile *  vf,
const char *  key,
struct avstat buf 
) [static]

Definition at line 140 of file filter.c.

{
    struct filtnode *nod;
    struct filtdata *filtdat = (struct filtdata *) ve->mnt->avfs->data;

    AV_NEW_OBJ(nod, filtnode_free);
    AV_INITLOCK(nod->lock);
    nod->vf = vf;
    nod->sf = av_filtprog_new(vf, filtdat);
    filt_id_set(&nod->id, buf);
    filt_mod_set(&nod->mod, buf);
    nod->ino = av_new_ino(ve->mnt->avfs);
    nod->writers = 0;

    AV_LOCK(nod->lock);

    ff->cobj = av_cacheobj_new(nod, key);
    ff->nod = nod;
    av_filecache_set(key, ff->cobj);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int filt_open ( ventry *  ve,
int  flags,
avmode_t  mode,
void **  resp 
) [static]

Definition at line 310 of file filter.c.

{
    int res;
    struct filtfile *ff;
    
    if(flags & AVO_DIRECTORY)
        return -ENOTDIR;

    AV_NEW(ff);
    ff->nod = NULL;
    ff->cobj = NULL;
    ff->iswrite = 0;

    res = filt_open_file(ff, ve, flags, mode);
    if(res < 0) {
        av_free(ff);
        return res;
    }

    *resp = ff;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int filt_open_base ( ventry *  ve,
int  flags,
avmode_t  mode,
vfile **  vfp,
int *  bfresp 
) [static]

Definition at line 253 of file filter.c.

{
    int res;
    int maybecreat;
    int baseflags;

    baseflags = filt_get_baseflags(flags, &maybecreat);

    res = av_open(ve->mnt->base, baseflags, mode, vfp);
    if(res == -ENOENT && maybecreat) {
        baseflags = AVO_RDWR | AVO_CREAT | AVO_TRUNC;
        res = av_open(ve->mnt->base, baseflags, mode, vfp);
    }

    *bfresp = baseflags;
    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int filt_open_file ( struct filtfile ff,
ventry *  ve,
int  flags,
avmode_t  mode 
) [static]

Definition at line 272 of file filter.c.

{
    int res;
    vfile *vf;
    char *key;
    int baseflags;
    
    res = filt_open_base(ve, flags, mode, &vf, &baseflags);
    if(res < 0)
        return res;

    res = av_filecache_getkey(ve, &key);
    if(res == 0) {
        if((baseflags & AVO_ACCMODE) == AVO_RDWR)
            ff->iswrite = 1;

        res = filt_getfile(ff, ve, vf, key);
        if(res == 0) {
            if((baseflags & AVO_TRUNC) != 0)
                av_sfile_truncate(ff->nod->sf, 0);

            if(ff->iswrite)
                ff->nod->writers ++;

            AV_UNLOCK(ff->nod->lock);
        }

        av_free(key);
    }
    if(res < 0) {
        av_close(vf);
        return res;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static avssize_t filt_read ( vfile *  vf,
char *  buf,
avsize_t  nbyte 
) [static]

Definition at line 334 of file filter.c.

{
    avssize_t res;
    struct filtfile *ff = (struct filtfile *) vf->data;
    struct filtnode *nod = ff->nod;
    
    AV_LOCK(nod->lock);
    res = av_sfile_pread(nod->sf, buf, nbyte, vf->ptr);
    AV_UNLOCK(nod->lock);

    if(res > 0)
        vf->ptr += res;

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int filt_rename ( ventry *  ve,
ventry *  newve 
) [static]

Definition at line 504 of file filter.c.

{
    return -EXDEV;
}

Here is the caller graph for this function:

static int filt_same_file ( struct filtid id,
struct avstat stbuf 
) [static]

Definition at line 110 of file filter.c.

{
    if(id->ino == stbuf->ino && id->dev == stbuf->dev)
        return 1;
    else
        return 0;
}

Here is the caller graph for this function:

static int filt_setattr ( vfile *  vf,
struct avstat buf,
int  attrmask 
) [static]

Definition at line 486 of file filter.c.

{
    int res;
    struct filtfile *ff = (struct filtfile *) vf->data;
    struct filtnode *nod = ff->nod;

    AV_LOCK(nod->lock);
    res = av_fsetattr(nod->vf, buf, attrmask);
    AV_UNLOCK(nod->lock);

    return res;    
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int filt_truncate ( vfile *  vf,
avoff_t  length 
) [static]

Definition at line 379 of file filter.c.

{
    int res;
    struct filtfile *ff = (struct filtfile *) vf->data;
    struct filtnode *nod = ff->nod;
    
    AV_LOCK(nod->lock);
    res = av_sfile_truncate(nod->sf, length);
    AV_UNLOCK(nod->lock);

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int filt_unlink ( ventry *  ve) [static]

Definition at line 509 of file filter.c.

{
    return av_unlink(ve->mnt->base);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int filt_unmodif_file ( struct filtmod mod,
struct avstat stbuf 
) [static]

Definition at line 118 of file filter.c.

{
    if(mod->size == stbuf->size && mod->mtime.sec == stbuf->mtime.sec &&
       mod->mtime.nsec == stbuf->mtime.nsec)
        return 1;
    else
        return 0;
}

Here is the caller graph for this function:

static int filt_validate_file ( struct filtnode nod,
ventry *  ve,
vfile *  vf,
struct avstat buf,
int  iswrite 
) [static]

Definition at line 162 of file filter.c.

{
    if(nod->writers == 0 && !filt_unmodif_file(&nod->mod, buf)) {
        struct filtdata *filtdat = (struct filtdata *) ve->mnt->avfs->data;
        
        av_unref_obj(nod->sf);
        av_close(nod->vf);
        nod->sf = av_filtprog_new(vf, filtdat);
        nod->vf = vf;
        filt_mod_set(&nod->mod, buf);
    }
    else if(nod->writers == 0 && iswrite) {
        avoff_t pos = av_lseek(nod->vf, 0, AVSEEK_CUR);

        if(pos > 0)
            pos = av_lseek(vf, pos, AVSEEK_SET);
        
        if(pos < 0)
            return pos;
        
        av_filtprog_change(nod->sf, vf);
        av_close(nod->vf);
        nod->vf = vf;
    }
    else
        av_close(vf);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static avssize_t filt_write ( vfile *  vf,
const char *  buf,
avsize_t  nbyte 
) [static]

Definition at line 350 of file filter.c.

{
    avssize_t res;
    struct filtfile *ff = (struct filtfile *) vf->data;
    struct filtnode *nod = ff->nod;
    
    AV_LOCK(nod->lock);
    if((vf->flags & AVO_APPEND) != 0) {
        avoff_t pos;

        pos = av_sfile_size(nod->sf);
        if(pos < 0) {
            AV_UNLOCK(nod->lock);
            return pos;
        }
        
        vf->ptr = pos;
    }
    res = av_sfile_pwrite(nod->sf, buf, nbyte, vf->ptr);
    if(res >= 0)
        av_curr_time(&nod->mod.mtime);
    AV_UNLOCK(nod->lock);
        
    if(res > 0)
        vf->ptr += res;

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void filtnode_free ( struct filtnode nod) [static]

Definition at line 102 of file filter.c.

{
    av_unref_obj(nod->sf);
    av_close(nod->vf);
    AV_FREELOCK(nod->lock)
}

Here is the call graph for this function:

Here is the caller graph for this function: