SlideShare une entreprise Scribd logo
1  sur  71
Télécharger pour lire hors ligne
Desenvolvendo Sistemas de
       Arquivos no FUSE



Nível:         Intermediário

Pré-requisitos: familiaridade com a linguagem C
                conceitos de sistemas de arquivos
Desenvolvendo Sistemas de
      Arquivos no FUSE


    http://fuse.sourceforge.net/
               Miklos Szeredi



Luis Otávio de Colla Furquim (luisfurquim@gmail.com)
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
    Arquivos no FUSE
Desenvolvendo Sistemas de
        Arquivos no FUSE
                             getattr
          open                                  opendir
         release             statfs
                                                readdir
          read                                 releasedir

          write          symlink

                                       mkdir
unlink
                 chmod                 rmdir
Desenvolvendo Sistemas de
       Arquivos no FUSE
● Processar linha de comando
● Inicializar variáveis / hardware

● Inicializar o sistema de
arquivos (efetivar a montagem)

● Finalizar o programa
Desenvolvendo Sistemas de
       Arquivos no FUSE
● Processar linha de comando
● Inicializar variáveis / hardware

● Inicializar o sistema de
arquivos (efetivar a montagem)

● Finalizar o programa
Desenvolvendo Sistemas de
         Arquivos no FUSE
Inicializar o sistema de arquivos
                  fuse.h
  fuse_main(argc, argv, &my_oper, NULL);
●argc, argv: opções do FUSE
●my_oper: funções que tratam o FS
●NULL: dados opcionais
●Bloqueia o programa
●Entra em modo DAEMON
 ●Perde stdin, stdout, stderr (debug via log)
 ●Funções de my_oper iniciam threads (exceto
 se a opção -s for definida)
Desenvolvendo Sistemas de
            Arquivos no FUSE
                               DEBUG
unique: 15, opcode: GETATTR (3), nodeid: 1, insize: 56
 unique: 15, error: 0 (Success), outsize: 112
unique: 16, opcode: GETXATTR (22), nodeid: 1, insize: 65
 unique: 16, error: -38 (Function not implemented), outsize: 16
unique: 17, opcode: OPENDIR (27), nodeid: 1, insize: 48
 unique: 17, error: 0 (Success), outsize: 32
unique: 18, opcode: READDIR (28), nodeid: 1, insize: 80
 unique: 18, error: 0 (Success), outsize: 616
unique: 19, opcode: LOOKUP (1), nodeid: 1, insize: 48
LOOKUP /Maildir
 NODEID: 2
 unique: 19, error: 0 (Success), outsize: 136
Desenvolvendo Sistemas de
            Arquivos no FUSE
unique: 20, opcode: LOOKUP (1), nodeid: 1, insize: 45
LOOKUP /logs
 NODEID: 3
 unique: 20, error: 0 (Success), outsize: 136
unique: 27, opcode: READDIR (28), nodeid: 1, insize: 80
 unique: 27, error: 0 (Success), outsize: 16
unique: 28, opcode: RELEASEDIR (29), nodeid: 1, insize: 64
 unique: 28, error: 0 (Success), outsize: 16
Desenvolvendo Sistemas de
     Arquivos no FUSE
Processar linha de comando
       mount [options] device mountpoint

   sshfs [user@]host:[dir] mountpoint [options]
Desenvolvendo Sistemas de
     Arquivos no FUSE
Processar linha de comando
       mount [options] device mountpoint

   sshfs [user@]host:[dir] mountpoint [options]
Desenvolvendo Sistemas de
             Arquivos no FUSE
     Processar linha de comando
                       mount [options] device mountpoint

                 sshfs [user@]host:[dir] mountpoint [options]

              Específicas                                  Gerais (FUSE)
                                                  -o allow_other
    -p PORT
                                                       allow access to other users
        equivalent to ’-o port=PORT’
    -C   equivalent to ’-o compression=yes’       -o allow_root
                                                       allow access to root
    -1   equivalent to ’-o ssh_protocol=1’
    -o reconnect                                  -o nonempty
         reconnect to server                          allow mounts over non-empty file/dir
    -o sshfs_sync                                 -o default_permissions enable
         synchronous writes                   permission checking by kernel
    -o no_readahead
        synchronous reads (no speculative
readahead)
Desenvolvendo Sistemas de
             Arquivos no FUSE
      Processar linha de comando
                             fuse_opt.h
myfs <mountpoint> <myfs_option> [-o <fuse_option1>[,...[,<fuse_optionN>]]]

   struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
   int i;

   for(i = 0; i < argc; i++) {
         if (i == 2) {
                myparameter = argv[i];
        } else {
                fuse_opt_add_arg(&args, argv[i]);
       }
   }
   fuse_main(args.argc, args.argv, my_oper, NULL);
Desenvolvendo Sistemas de
             Arquivos no FUSE
      Processar linha de comando
char *myparameter;
static int myfs_opt_proc(void *data, const char *arg, int key,
                                   struct fuse_args *outargs)
{
     if (key == FUSE_OPT_KEY_NONOPT && myparameter == NULL) {
           myparameter = strdup(arg);
           return 0;
     }
     return 1;
}

int main(int argc, char *argv[])
{
    struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
    fuse_opt_parse(&args, NULL, NULL, myfs_opt_proc);
    fuse_main(args.argc, args.argv, my_oper, NULL);
}
Desenvolvendo Sistemas de
             Arquivos no FUSE
      Processar linha de comando
char *myparameter;
static int myfs_opt_proc(void *data, const char *arg, int key,
                                   struct fuse_args *outargs)
{
     if (key == FUSE_OPT_KEY_NONOPT && myparameter == NULL) {
           myparameter = strdup(arg);
           return 0;
     }
     return 1;
}

int main(int argc, char *argv[])
{
    struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
    fuse_opt_parse(&args, NULL, NULL, myfs_opt_proc);
    fuse_opt_add_arg(&args, "-oallow_other");
    fuse_main(args.argc, args.argv, my_oper, NULL);
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
              Funções Callback
getattr          rmdir           write
fgetattr         rename          statfs
access           link            flush
readlink         chmod           release
opendir          chown           fsync
readdir          truncate        setxattr
releasedir       ftruncate       getxattr
mknod            utimens         listxattr
mkdir            create          removexattr
symlink          open            lock
unlink           read
Desenvolvendo Sistemas de
             Arquivos no FUSE

static struct fuse_operations xmp_oper = {
     .getattr    = my_getattr,
     .access      = my_access,
     .readlink   = my_readlink,
     .opendir     = my_opendir,
     .readdir    = my_readdir,

     .
     .
     .
};
Desenvolvendo Sistemas de
            Arquivos no FUSE
         Ferramentas de apoio aos callbacks
struct fuse_context :
     uid_t uid – Id do usuário do processo chamador
     gid_t gid – Id do grupo do processo chamador
     pid_t pid – Id do processo chamador
     void *private_data – Dados do filesystem

struct fuse_context *fuse_get_context(void); Informações do contexto

struct fuse_file_info:
     int flags – modo de abertura de arquivo (open/release)
     uint64_t fh – file handle, se inicializado em open, estará disponível
                  nas demais operações sobre arquivos abertos
     uint64_t lock_owner – Id do dono do lock (lock e flush)
Desenvolvendo Sistemas de
          Arquivos no FUSE
                        Padrões
path – Inicia com '/', mas é relativo ao mountpoint.
Exemplo:
root@darkstar # myfs /foo
root@darkstar # ls /foo/bar
path = ”/bar”


errno – Retornar –errno (MENOS errno)
Exemplo:
if ((size=read( ... )<0) {
   return( –errno);
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
                        Funções Callback
Inicialização e término do sistema de arquivos
static void *my_init(struct fuse_conn_info *conn)
{
   // inicialização de variáveis, threads, etc
   // uma conexão com um banco mysql, por exemplo
   myconn = mysql_init ( NULL );
   mysql_real_connect (myconn ,"localhost","user", ...);
   return(&myconn);
}

static int my_destroy(void *myconn)
{
  mysql_close(*myconn);
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Atributos do sistema de arquivos
static int my_statfs(const char *path, struct statvfs *stbuf)
{
     int res;
     res = statvfs(path, stbuf);
     if (res == -1)
           return -errno;
     return 0;
}
Desenvolvendo Sistemas de
               Arquivos no FUSE
static int my_statfs(const char *path, struct statvfs *stbuf)
{
    ...
    MYSQL **conn = fuse_get_context()->private_data;
    sprintf(qry,"SELECT MAX_DATA_LENGTH/512, DATA_FREE/512 "
      "FROM INFORMATION_SCHEMA.PARTITIONS "
      "WHERE TABLE_NAME='files' AND TABLE_SCHEMA='myfs'");
    mysql_query(*myconn,qry);
    res = mysql_store_result(*myconn);
    if (row = mysql_fetch_row(res)) {
       memset(&attr,0,sizeof(struct statvfs));
       stbuf->f_bsize    = 512;
       stbuf->f_frsize   = 512;
       stbuf->f_blocks = row[0];
       stbuf->f_bfree    = row[1];
       ...
       return (0);
    } else {
       return (-EIO);
    }
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Atributos (uid/gid, datas, permissões, etc) do arquivo
static int my_getattr(const char *path, struct stat *stbuf)
{
     int res;
     res = lstat(path, stbuf);
     if (res == -1) return -errno;
     return 0;
}
static int my_fgetattr(const char *path, struct stat *stbuf,
                struct fuse_file_info *fi)
{
     int res;
     (void) path;
     res = fstat(fi->fh, stbuf);
     if (res == -1) return -errno;
     return 0;
}
Desenvolvendo Sistemas de
             Arquivos no FUSE
static int my_getattr(const char *path, struct stat *stbuf) {
  MYSQL_RES *res; MYSQL_ROW row;
  MYSQL *conn = (MYSQL *) fuse_get_context()->private_data;
  sprintf(qry,"select uid, gid, mode, ctime, mtime, atime, size ”
               ”from files where path='%s'",path);
  mysql_query(conn,qry);
  res = mysql_store_result(conn);
  if (row = mysql_fetch_row(res)) {
     memset(&attr,0,sizeof(struct stat));
     stbuf->st_uid        = row[0];
     stbuf->st_gid        = row[1];
     stbuf->st_mode       = row[2];
     stbuf->st_ctime      = row[3];
     stbuf->st_mtime      = row[4];
     stbuf->st_atime      = row[5];
     stbuf->st_size       = row[6];
  } else {
     return (-ENOENT);
  }
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Listagem de diretórios


static int my_opendir(const char *path, struct fuse_file_info *fi)
{
    DIR *dp = opendir(path);
    if (dp == NULL)
         return -errno;


    fi->fh = (unsigned long) dp;
    return 0;
}
Desenvolvendo Sistemas de
             Arquivos no FUSE
#define get_dirp(f) ((DIR *) (uintptr_t) f->fh)
static int my_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
              off_t offset, struct fuse_file_info *fi)
{
     DIR *dp = get_dirp(fi); struct dirent *de; struct stat st;
     seekdir(dp, offset);
     while ((de = readdir(dp)) != NULL) {
          memset(&st, 0, sizeof(st));
          st.st_ino = de->d_ino;
          st.st_mode = de->d_type << 12;
          if (filler(buf, de->d_name, &st, telldir(dp)))
                 break;
     }
     return 0;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
static int my_releasedir(const char *path, struct fuse_file_info *fi)
{
     DIR *dp = get_dirp(fi);
     (void) path;
     closedir(dp);
     return 0;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
-rw-r--r-- 1 root root 299 2008-09-12 11:08 a.out.h
-rw-r--r-- 1 root root 5365 2008-09-12 11:08 byteswap.h
-rw-r--r-- 1 root root 4881 2008-09-12 11:07 cmathcalls.h
-rw-r--r-- 1 root root 20634 2008-09-12 11:08 confname.h
-rw-r--r-- 1 root root 1609 2008-09-12 11:08 dirent.h
-rw-r--r-- 1 root root 2593 2008-09-12 11:08 dlfcn.h
-rw-r--r-- 1 root root 426 2008-09-12 11:09 elfclass.h
-rw-r--r-- 1 root root 170 2008-09-12 11:08 endian.h
-rw-r--r-- 1 root root 3275 2008-09-12 11:08 environments.h
-rw-r--r-- 1 root root 2129 2008-09-12 11:07 errno.h
-rw-r--r-- 1 root root 2762 2008-09-12 11:08 error.h
-rw-r--r-- 1 root root 5607 2008-09-12 11:08 fcntl2.h
-rw-r--r-- 1 root root 9258 2008-09-12 11:08 fcntl.h
-rw-r--r-- 1 root root 3064 2008-09-12 11:07 fenv.h
-rw-r--r-- 1 root root 190 2008-09-12 11:07 fenvinline.h
-rw-r--r-- 1 root root 1901 2008-09-12 11:07 huge_valf.h
Desenvolvendo Sistemas de
            Arquivos no FUSE
-rw-r--r-- 1 root root 299 2008-09-12 11:08 a.out.h
-rw-r--r-- 1 root root 5365 2008-09-12 11:08 byteswap.h
-rw-r--r-- 1 root root 4881 2008-09-12 11:07 cmathcalls.h
-rw-r--r-- 1 root root 20634 2008-09-12 11:08 confname.h
-rw-r--r-- 1 root root 1609 2008-09-12 11:08 dirent.h
-rw-r--r-- 1 root root 2593 2008-09-12 11:08 dlfcn.h
-rw-r--r-- 1 root root 426 2008-09-12 11:09 elfclass.h
-rw-r--r-- 1 root root 170 2008-09-12 11:08 endian.h
-rw-r--r-- 1 root root 3275 2008-09-12 11:08 environments.h
-rw-r--r-- 1 root root 2129 2008-09-12 11:07 errno.h
-rw-r--r-- 1 root root 2762 2008-09-12 11:08 error.h
-rw-r--r-- 1 root root 5607 2008-09-12 11:08 fcntl2.h
-rw-r--r-- 1 root root 9258 2008-09-12 11:08 fcntl.h
-rw-r--r-- 1 root root 3064 2008-09-12 11:07 fenv.h
-rw-r--r-- 1 root root 190 2008-09-12 11:07 fenvinline.h
-rw-r--r-- 1 root root 1901 2008-09-12 11:07 huge_valf.h
Desenvolvendo Sistemas de
            Arquivos no FUSE
-rw-r--r-- 1 root root 299 2008-09-12 11:08 a.out.h
-rw-r--r-- 1 root root 5365 2008-09-12 11:08 byteswap.h
-rw-r--r-- 1 root root 4881 2008-09-12 11:07 cmathcalls.h
-rw-r--r-- 1 root root 20634 2008-09-12 11:08 confname.h
-rw-r--r-- 1 root root 1609 2008-09-12 11:08 dirent.h
-rw-r--r-- 1 root root 2593 2008-09-12 11:08 dlfcn.h
-rw-r--r-- 1 root root 426 2008-09-12 11:09 elfclass.h
-rw-r--r-- 1 root root 170 2008-09-12 11:08 endian.h
-rw-r--r-- 1 root root 3275 2008-09-12 11:08 environments.h
-rw-r--r-- 1 root root 2129 2008-09-12 11:07 errno.h
-rw-r--r-- 1 root root 2762 2008-09-12 11:08 error.h
-rw-r--r-- 1 root root 5607 2008-09-12 11:08 fcntl2.h
-rw-r--r-- 1 root root 9258 2008-09-12 11:08 fcntl.h
-rw-r--r-- 1 root root 3064 2008-09-12 11:07 fenv.h
-rw-r--r-- 1 root root 190 2008-09-12 11:07 fenvinline.h
-rw-r--r-- 1 root root 1901 2008-09-12 11:07 huge_valf.h
Desenvolvendo Sistemas de
            Arquivos no FUSE
-rw-r--r-- 1 root root 5365 2008-09-12 11:08 byteswap.h
-rw-r--r-- 1 root root 4881 2008-09-12 11:07 cmathcalls.h
-rw-r--r-- 1 root root 20634 2008-09-12 11:08 confname.h
-rw-r--r-- 1 root root 1609 2008-09-12 11:08 dirent.h
-rw-r--r-- 1 root root 2593 2008-09-12 11:08 dlfcn.h
-rw-r--r-- 1 root root 426 2008-09-12 11:09 elfclass.h
-rw-r--r-- 1 root root 170 2008-09-12 11:08 endian.h
-rw-r--r-- 1 root root 3275 2008-09-12 11:08 environments.h
-rw-r--r-- 1 root root 2129 2008-09-12 11:07 errno.h
-rw-r--r-- 1 root root 2762 2008-09-12 11:08 error.h
-rw-r--r-- 1 root root 5607 2008-09-12 11:08 fcntl2.h
-rw-r--r-- 1 root root 9258 2008-09-12 11:08 fcntl.h
-rw-r--r-- 1 root root 3064 2008-09-12 11:07 fenv.h
-rw-r--r-- 1 root root 190 2008-09-12 11:07 fenvinline.h
-rw-r--r-- 1 root root 1901 2008-09-12 11:07 huge_valf.h
Desenvolvendo Sistemas de
              Arquivos no FUSE
Criação de arquivos – MÉTODO OPCIONAL
static int my_create(const char *path, mode_t mode, struct fuse_file_info *fi)
{
     int fd = open(path, fi->flags, mode);
     if (fd == -1)
           return -errno;
     fi->fh = fd; // prover um descritor de arquivos é OPCIONAL
     return 0;
}
Flags
O_EXCL - Falha se o arquivo já existir
O_NONBLOCK - Evita que bloqueie por um "longo" tempo
O_NOLINK - Se for link simbólico, abre o link (não o arquivo)
O_TRUNC - Trunca o arquivo
O_SHLOCK (BSD) - Obtem shared lock
O_EXLOCK (BSD) - Obtem lock exclusivo
Desenvolvendo Sistemas de
           Arquivos no FUSE
Cria (sem abrir) um arquivo
static int my_mknod(const char *path, mode_t mode, dev_t rdev)
{
     int res;

    if (S_ISFIFO(mode))
          res = mkfifo(path, mode);
    else
          res = mknod(path, mode, rdev);
    if (res == -1)
          return -errno;

    return 0;
}
Desenvolvendo Sistemas de
           Arquivos no FUSE
Abre arquivo existente (não cria arquivos)
static int my_open(const char *path, struct fuse_file_info *fi)
{
     int fd = open(path, fi->flags); // sem mode
     if (fd == -1)
           return -errno;

    fi->fh = fd; // fornecer um file handle é OPCIONAL
    return 0;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Lê dados de um arquivo
static int my_read(const char *path, char *buf, size_t size, off_t offset,
              struct fuse_file_info *fi)
{
     int res;

    (void) path;
    res = pread(fi->fh, buf, size, offset);
    if (res == -1)
          res = -errno;

    return res;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Grava dados num arquivo
static int my_write(const char *path, const char *buf, size_t size,
              off_t offset, struct fuse_file_info *fi)
{
     int res;

    (void) path;
    res = pwrite(fi->fh, buf, size, offset);
    if (res == -1)
          res = -errno;

    return res;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Fecha arquivo / libera recursos
static int my_release(const char *path, struct fuse_file_info *fi)
{
     (void) path;
     close(fi->fh);

    return 0;
}

OBS: Só é chamado uma vez por arquivo aberto, se a aplicação duplicou
     o descritor de arquivo (dup, fork, ...) release é chamado quando a
     aplicação chamar close para o último descritor aberto.
Desenvolvendo Sistemas de
            Arquivos no FUSE
Lê o conteúdo de um link simbólico
static int my_readlink(const char *path, char *buf, size_t size)
{
     int res = readlink(path, buf, size - 1);
     if (res == -1)
           return -errno;

    buf[res] = '0';
    return 0;
}

OBS: readlink da libc copia string sem '0' para o buf e retorna a
  quantidade de caracteres lidos, o callback do FUSE exige o terminador
  na string e o valor de retorno é -errno.
Desenvolvendo Sistemas de
            Arquivos no FUSE
Cria symlink/hardlink
static int my_symlink(const char *from, const char *to)
{
     int res = symlink(from, to);
     if (res == -1)
           return -errno;
     return 0;
}
static int my_link(const char *from, const char *to)
{
     int res = link(from, to);
     if (res == -1)
           return -errno;
     return 0;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Remove (deleta) um arquivo
static int my_unlink(const char *path)
{
     int res;

    res = unlink(path);
    if (res == -1)
          return -errno;

    return 0;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Renomeia/Move um arquivo
static int my_rename(const char *from, const char *to)
{
     int res;

    res = rename(from, to);
    if (res == -1)
          return -errno;

    return 0;
}

OBS: from e to sempre estão em myfs
Desenvolvendo Sistemas de
            Arquivos no FUSE
Muda atributos dos arquivo
static int my_chmod(const char *path, mode_t mode)
{
     int res = chmod(path, mode);
     if (res == -1)
           return -errno;
     return 0;
}

static int my_chown(const char *path, uid_t uid, gid_t gid)
{
     int res = lchown(path, uid, gid);
     if (res == -1)
           return -errno;
     return 0;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Muda atributos de data/hora com precisão de nanosegundos
static int my_utimens(const char *path, const struct timespec ts[2])
{
     int res;
     struct timeval tv[2];

    tv[0].tv_sec = ts[0].tv_sec;
    tv[0].tv_usec = ts[0].tv_nsec / 1000;
    tv[1].tv_sec = ts[1].tv_sec;
    tv[1].tv_usec = ts[1].tv_nsec / 1000;

    res = utimes(path, tv);
    if (res == -1)
          return -errno;
    return 0;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Cria/deleta diretório
static int my_mkdir(const char *path, mode_t mode)
{
     int res = mkdir(path, mode);
     if (res == -1)
           return -errno;
     return 0;
}

static int my_rmdir(const char *path)
{
     int res = rmdir(path);
     if (res == -1)
           return -errno;
     return 0;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Verifica se é possível fazer o acesso, especificado em mask, ao arquivo
static int my_access(const char *path, int mask)
{
     int res;

    res = access(path, mask);
    if (res == -1)
          return -errno;

    return 0;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Modifica o tamanho de um arquivo pelo nome ou pelo file handle
static int my_truncate(const char *path, off_t size)
{
     int res = truncate(path, size);
     if (res == -1)
           return -errno;
     return 0;
}
static int my_ftruncate(const char *path, off_t size,
                 struct fuse_file_info *fi)
{
     int res = ftruncate(fi->fh, size);
     if (res == -1)
           return -errno;
     return 0;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Grava atributo extendido
static int my_setxattr(const char *path, const char *name, const char *value,
                size_t size, int flags)
{
      int res = lsetxattr(path, name, value, size, flags);
      if (res == -1)
            return -errno;
      return 0;
}
Desenvolvendo Sistemas de
             Arquivos no FUSE
Lê/lista atributos extendidos
static int my_getxattr(const char *path, const char *name, char *value,
                size_t size)
{
     int res = lgetxattr(path, name, value, size);
     if (res == -1)
           return -errno;
     return res;
}
static int my_listxattr(const char *path, char *list, size_t size)
{
     int res = llistxattr(path, list, size);
     if (res == -1)
           return -errno;
     return res;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Remove atributo extendido
static int my_removexattr(const char *path, const char *name)
{
     int res = lremovexattr(path, name);
     if (res == -1)
           return -errno;
     return 0;
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Gerencia trava de arquivo, segundo o padrão POSIX
static int my_lock(const char *path, struct fuse_file_info *fi, int cmd,
             struct flock *lock)
{
     (void) path;

    return ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner,
               sizeof(fi->lock_owner));
}
Desenvolvendo Sistemas de
            Arquivos no FUSE
Sincroniza dados em memória com o meio de armazenamento
static int my_fsync(const char *path, int datasync, struct fuse_file_info *fi)
{
     (void) path;
     (void) datasync;
     (void) fi;

    return (0);
}

OBS: Se datasync = = zero, deve sincronizar dados e meta-dados
     Se datasync != zero, deve sincronizar somente dados
Desenvolvendo Sistemas de
            Arquivos no FUSE
Sincroniza dados em memória com o meio de armazenamento
static int my_flush(const char *path, struct fuse_file_info *fi)
{
     (void) path;
     (void) fi;

    return (0);
}

OBS: Não é chamado quando a aplicação chama fsync.
     Só é chamado quando a aplicação chama close.
     Pode haver mais de um close por arquivo (dup, fork, ...)
     Não há garantia de que seja chamado sequer uma vez.
Desenvolvendo Sistemas de
            Arquivos no FUSE
    int fuseargc = 5;
    char *fuseargv[6];
    fuseargv[0] = "sohofs";
    fuseargv[1] = "-f";
    fuseargv[2] = "/tmp/fuse";
    fuseargv[3] = "-o";
    fuseargv[4] = "allow_other,nonempty";
    fuseargv[5] = NULL;
    return (fuse_main(fuseargc, fuseargv, &my_ops, NULL));

it reports the error "Access is denied" when I try to copy a new file
into the share folder through SAMBA.

Try to run in debug mode:
fuseargv[4] = "allow_other,nonempty,debug";
And check what is happening when samba calls access/getattr.
Desenvolvendo Sistemas de
            Arquivos no FUSE
unique: 2, opcode: GETATTR (3), nodeid: 1, insize: 40
 unique: 2, error: 0 (Success), outsize: 112
WRITE[6] 4096 bytes to 0
 unique: 128, error: -28 (No space left on device), outsize: 16
unique: 129, opcode: WRITE (16), nodeid: 9, insize: 4160
WRITE[6] 4096 bytes to 0
 unique: 129, error: -28 (No space left on device), outsize: 16
unique: 130, opcode: WRITE (16), nodeid: 9, insize: 4160
WRITE[6] 4096 bytes to 0
 unique: 130, error: -28 (No space left on device), outsize: 16

But there are actually free space on the the device, so what are the
  potential issues.


So, the problem is with the statfs callback function. This function is
responsible to tell the system the info about the filesystem and this
includes the space in it.

Contenu connexe

Tendances

Comandos Básicos Linux
Comandos Básicos LinuxComandos Básicos Linux
Comandos Básicos Linux
SoftD Abreu
 
Sistemas Operacionais - Gnu/Linux Montando e Desmontando Sistemas de Arquivos
Sistemas Operacionais - Gnu/Linux Montando e Desmontando Sistemas de ArquivosSistemas Operacionais - Gnu/Linux Montando e Desmontando Sistemas de Arquivos
Sistemas Operacionais - Gnu/Linux Montando e Desmontando Sistemas de Arquivos
Luiz Arthur
 
Debian 6: Instalação e Hardening
Debian 6: Instalação e HardeningDebian 6: Instalação e Hardening
Debian 6: Instalação e Hardening
Bruna Griebeler
 
SegurançA BáSica Do Apache
SegurançA BáSica Do ApacheSegurançA BáSica Do Apache
SegurançA BáSica Do Apache
Felipe Santos
 
Guia com mais de 500 comandos do linux explicados computeiro da depressão
Guia com mais de 500 comandos do linux explicados   computeiro da depressãoGuia com mais de 500 comandos do linux explicados   computeiro da depressão
Guia com mais de 500 comandos do linux explicados computeiro da depressão
Jesser Martins Medeiros
 
Apache2+PHP5+PostgreSQL no Linux
Apache2+PHP5+PostgreSQL no LinuxApache2+PHP5+PostgreSQL no Linux
Apache2+PHP5+PostgreSQL no Linux
Victor Eloy
 
Linux comandos gerais e servidores de rede
Linux   comandos gerais e servidores de redeLinux   comandos gerais e servidores de rede
Linux comandos gerais e servidores de rede
fernandao777
 
Cap1 exercicios comandos linux resolucao part i
Cap1 exercicios comandos linux   resolucao part iCap1 exercicios comandos linux   resolucao part i
Cap1 exercicios comandos linux resolucao part i
portal_Do_estudante
 

Tendances (20)

Comandos Básicos Linux
Comandos Básicos LinuxComandos Básicos Linux
Comandos Básicos Linux
 
Sistemas Operacionais - Gnu/Linux Montando e Desmontando Sistemas de Arquivos
Sistemas Operacionais - Gnu/Linux Montando e Desmontando Sistemas de ArquivosSistemas Operacionais - Gnu/Linux Montando e Desmontando Sistemas de Arquivos
Sistemas Operacionais - Gnu/Linux Montando e Desmontando Sistemas de Arquivos
 
Shell Scipt - Comandos
Shell Scipt - ComandosShell Scipt - Comandos
Shell Scipt - Comandos
 
Linux - Shell e Comandos Básicos
Linux - Shell e Comandos BásicosLinux - Shell e Comandos Básicos
Linux - Shell e Comandos Básicos
 
Debian 6: Instalação e Hardening
Debian 6: Instalação e HardeningDebian 6: Instalação e Hardening
Debian 6: Instalação e Hardening
 
Introdução ao Linux - aula 03 e 04
Introdução ao Linux - aula 03 e 04Introdução ao Linux - aula 03 e 04
Introdução ao Linux - aula 03 e 04
 
SegurançA BáSica Do Apache
SegurançA BáSica Do ApacheSegurançA BáSica Do Apache
SegurançA BáSica Do Apache
 
Ubuntu 8.04 LTS 2008
Ubuntu 8.04 LTS 2008Ubuntu 8.04 LTS 2008
Ubuntu 8.04 LTS 2008
 
Guia com mais de 500 comandos do linux explicados computeiro da depressão
Guia com mais de 500 comandos do linux explicados   computeiro da depressãoGuia com mais de 500 comandos do linux explicados   computeiro da depressão
Guia com mais de 500 comandos do linux explicados computeiro da depressão
 
Linux - Permissões, Usuários, Grupos e Quotas
Linux - Permissões, Usuários, Grupos e QuotasLinux - Permissões, Usuários, Grupos e Quotas
Linux - Permissões, Usuários, Grupos e Quotas
 
Aula 06 comandos linux
Aula 06   comandos linuxAula 06   comandos linux
Aula 06 comandos linux
 
Apache2+PHP5+PostgreSQL no Linux
Apache2+PHP5+PostgreSQL no LinuxApache2+PHP5+PostgreSQL no Linux
Apache2+PHP5+PostgreSQL no Linux
 
So trabalho
So trabalhoSo trabalho
So trabalho
 
O Que é Shell (bash)
O Que é Shell (bash)O Que é Shell (bash)
O Que é Shell (bash)
 
Linux comandos gerais e servidores de rede
Linux   comandos gerais e servidores de redeLinux   comandos gerais e servidores de rede
Linux comandos gerais e servidores de rede
 
Comandos do linux
Comandos do linuxComandos do linux
Comandos do linux
 
Apache proxy
Apache proxyApache proxy
Apache proxy
 
01 notações iniciais
01   notações iniciais01   notações iniciais
01 notações iniciais
 
Cap1 exercicios comandos linux resolucao part i
Cap1 exercicios comandos linux   resolucao part iCap1 exercicios comandos linux   resolucao part i
Cap1 exercicios comandos linux resolucao part i
 
Resumo LPIC-1 101
Resumo LPIC-1 101Resumo LPIC-1 101
Resumo LPIC-1 101
 

Similaire à Desenvolvendo Sistemas de Arquivos no FUSE - Luis Otávio de Colla Furquim

PHPSC Conference 2010 - Desenvolvimento de Extensões PECL
PHPSC Conference 2010 - Desenvolvimento de Extensões PECLPHPSC Conference 2010 - Desenvolvimento de Extensões PECL
PHPSC Conference 2010 - Desenvolvimento de Extensões PECL
Erick Belluci Tedeschi
 
55 New Things in Java 7 - Brazil
55 New Things in Java 7 - Brazil55 New Things in Java 7 - Brazil
55 New Things in Java 7 - Brazil
Stephen Chin
 
Apostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em LinuxApostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em Linux
eliezer
 
Apostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em LinuxApostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em Linux
guest7a481e8
 

Similaire à Desenvolvendo Sistemas de Arquivos no FUSE - Luis Otávio de Colla Furquim (20)

PHPSC Conference 2010 - Desenvolvimento de Extensões PECL
PHPSC Conference 2010 - Desenvolvimento de Extensões PECLPHPSC Conference 2010 - Desenvolvimento de Extensões PECL
PHPSC Conference 2010 - Desenvolvimento de Extensões PECL
 
Dev Ext PHP
Dev Ext PHPDev Ext PHP
Dev Ext PHP
 
IntroduçãO Ao Linux
IntroduçãO Ao LinuxIntroduçãO Ao Linux
IntroduçãO Ao Linux
 
Desenvolvimento de Extensões PECL
Desenvolvimento de Extensões PECLDesenvolvimento de Extensões PECL
Desenvolvimento de Extensões PECL
 
Desenvolvendo Extensões PECL
Desenvolvendo Extensões PECLDesenvolvendo Extensões PECL
Desenvolvendo Extensões PECL
 
Arquivos de Inicialização do Linux
Arquivos de Inicialização do LinuxArquivos de Inicialização do Linux
Arquivos de Inicialização do Linux
 
Customizando Slackware
Customizando SlackwareCustomizando Slackware
Customizando Slackware
 
Sapo Sessions PHP
Sapo Sessions PHPSapo Sessions PHP
Sapo Sessions PHP
 
55 New Things in Java 7 - Brazil
55 New Things in Java 7 - Brazil55 New Things in Java 7 - Brazil
55 New Things in Java 7 - Brazil
 
Apostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em LinuxApostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em Linux
 
Apostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em LinuxApostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em Linux
 
Apostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em LinuxApostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em Linux
 
Instalação do asterisk
Instalação do asteriskInstalação do asterisk
Instalação do asterisk
 
PHP e Redis
PHP e RedisPHP e Redis
PHP e Redis
 
Aula - Comandos Linux - Parte 1
Aula - Comandos Linux - Parte 1Aula - Comandos Linux - Parte 1
Aula - Comandos Linux - Parte 1
 
Comandos Linux Parte 1
Comandos Linux Parte 1Comandos Linux Parte 1
Comandos Linux Parte 1
 
PHP like a super hero
PHP like a super heroPHP like a super hero
PHP like a super hero
 
TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...
TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...
TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...
 
Palestra Elasticsearch - The Developers Conference - Floripa - 2017
Palestra Elasticsearch - The Developers Conference - Floripa - 2017Palestra Elasticsearch - The Developers Conference - Floripa - 2017
Palestra Elasticsearch - The Developers Conference - Floripa - 2017
 
I Workshop de Redes do Iespes
I Workshop de Redes do IespesI Workshop de Redes do Iespes
I Workshop de Redes do Iespes
 

Plus de Tchelinux

Bikeshedding - Márcio Josué Ramos Torres - Tchelinux 2019 Rio Grande
Bikeshedding - Márcio Josué Ramos Torres - Tchelinux 2019 Rio GrandeBikeshedding - Márcio Josué Ramos Torres - Tchelinux 2019 Rio Grande
Bikeshedding - Márcio Josué Ramos Torres - Tchelinux 2019 Rio Grande
Tchelinux
 
A tecnologia no futuro e nas mãos de quem ela estará - Jaqueline Trevizan, Ne...
A tecnologia no futuro e nas mãos de quem ela estará - Jaqueline Trevizan, Ne...A tecnologia no futuro e nas mãos de quem ela estará - Jaqueline Trevizan, Ne...
A tecnologia no futuro e nas mãos de quem ela estará - Jaqueline Trevizan, Ne...
Tchelinux
 

Plus de Tchelinux (20)

Do Zero ao YouTube em menos de 10 softwares livres - Vinícius Alves Hax - Tch...
Do Zero ao YouTube em menos de 10 softwares livres - Vinícius Alves Hax - Tch...Do Zero ao YouTube em menos de 10 softwares livres - Vinícius Alves Hax - Tch...
Do Zero ao YouTube em menos de 10 softwares livres - Vinícius Alves Hax - Tch...
 
Insegurança na Internet - Diego Luiz Silva da Costa - Tchelinux 2019 Rio Grande
Insegurança na Internet - Diego Luiz Silva da Costa - Tchelinux 2019 Rio GrandeInsegurança na Internet - Diego Luiz Silva da Costa - Tchelinux 2019 Rio Grande
Insegurança na Internet - Diego Luiz Silva da Costa - Tchelinux 2019 Rio Grande
 
Explorando Editores de Texto Open Source - Gabriel Prestes Ritta - Tchelinux ...
Explorando Editores de Texto Open Source - Gabriel Prestes Ritta - Tchelinux ...Explorando Editores de Texto Open Source - Gabriel Prestes Ritta - Tchelinux ...
Explorando Editores de Texto Open Source - Gabriel Prestes Ritta - Tchelinux ...
 
Desenvolvendo Jogos com PyGame - Jerônimo Medina Madruga - Tchelinux 2019 Rio...
Desenvolvendo Jogos com PyGame - Jerônimo Medina Madruga - Tchelinux 2019 Rio...Desenvolvendo Jogos com PyGame - Jerônimo Medina Madruga - Tchelinux 2019 Rio...
Desenvolvendo Jogos com PyGame - Jerônimo Medina Madruga - Tchelinux 2019 Rio...
 
Me formei. E agora? - Matheus Cezar - Tchelinux 2019 Rio Grande
Me formei. E agora? - Matheus Cezar - Tchelinux 2019 Rio GrandeMe formei. E agora? - Matheus Cezar - Tchelinux 2019 Rio Grande
Me formei. E agora? - Matheus Cezar - Tchelinux 2019 Rio Grande
 
APIs, REST e RESTful: O que os programadores precisam saber? - Marcos Echevar...
APIs, REST e RESTful: O que os programadores precisam saber? - Marcos Echevar...APIs, REST e RESTful: O que os programadores precisam saber? - Marcos Echevar...
APIs, REST e RESTful: O que os programadores precisam saber? - Marcos Echevar...
 
Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...
Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...
Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...
 
WebRTC: Comunicação aberta em tempo real - Nelson Dutra Junior - Tchelinux 20...
WebRTC: Comunicação aberta em tempo real - Nelson Dutra Junior - Tchelinux 20...WebRTC: Comunicação aberta em tempo real - Nelson Dutra Junior - Tchelinux 20...
WebRTC: Comunicação aberta em tempo real - Nelson Dutra Junior - Tchelinux 20...
 
Introdução à programação funcional com Clojure - Victor Hechel Colares - Tche...
Introdução à programação funcional com Clojure - Victor Hechel Colares - Tche...Introdução à programação funcional com Clojure - Victor Hechel Colares - Tche...
Introdução à programação funcional com Clojure - Victor Hechel Colares - Tche...
 
Construindo um Data Warehouse - Vítor Resing Plentz - Tchelinux 2019 Rio Grande
Construindo um Data Warehouse - Vítor Resing Plentz - Tchelinux 2019 Rio GrandeConstruindo um Data Warehouse - Vítor Resing Plentz - Tchelinux 2019 Rio Grande
Construindo um Data Warehouse - Vítor Resing Plentz - Tchelinux 2019 Rio Grande
 
Bikeshedding - Márcio Josué Ramos Torres - Tchelinux 2019 Rio Grande
Bikeshedding - Márcio Josué Ramos Torres - Tchelinux 2019 Rio GrandeBikeshedding - Márcio Josué Ramos Torres - Tchelinux 2019 Rio Grande
Bikeshedding - Márcio Josué Ramos Torres - Tchelinux 2019 Rio Grande
 
Produção de textos com Latex - Samuel Francisco Ferrigo - Tchelinux Caxias do...
Produção de textos com Latex - Samuel Francisco Ferrigo - Tchelinux Caxias do...Produção de textos com Latex - Samuel Francisco Ferrigo - Tchelinux Caxias do...
Produção de textos com Latex - Samuel Francisco Ferrigo - Tchelinux Caxias do...
 
A tecnologia no futuro e nas mãos de quem ela estará - Jaqueline Trevizan, Ne...
A tecnologia no futuro e nas mãos de quem ela estará - Jaqueline Trevizan, Ne...A tecnologia no futuro e nas mãos de quem ela estará - Jaqueline Trevizan, Ne...
A tecnologia no futuro e nas mãos de quem ela estará - Jaqueline Trevizan, Ne...
 
oVirt uma solução de virtualização distribuída opensource - Daniel Lara - Tch...
oVirt uma solução de virtualização distribuída opensource - Daniel Lara - Tch...oVirt uma solução de virtualização distribuída opensource - Daniel Lara - Tch...
oVirt uma solução de virtualização distribuída opensource - Daniel Lara - Tch...
 
Sistemas Embarcados e Buildroot - Renato Severo - Tchelinux Caxias do Sul 2019
Sistemas Embarcados e Buildroot - Renato Severo - Tchelinux Caxias do Sul 2019Sistemas Embarcados e Buildroot - Renato Severo - Tchelinux Caxias do Sul 2019
Sistemas Embarcados e Buildroot - Renato Severo - Tchelinux Caxias do Sul 2019
 
Com que ônibus eu vou? Uma gentil introdução ao Python.
Com que ônibus eu vou? Uma gentil introdução ao Python.Com que ônibus eu vou? Uma gentil introdução ao Python.
Com que ônibus eu vou? Uma gentil introdução ao Python.
 
O TCC... um dia ele chega! (The beautiful and easy LaTeX way.
O TCC... um dia ele chega! (The beautiful and easy LaTeX way.O TCC... um dia ele chega! (The beautiful and easy LaTeX way.
O TCC... um dia ele chega! (The beautiful and easy LaTeX way.
 
Não deixe para testar depois o que você pode testar antes.
Não deixe para testar depois o que você pode testar antes. Não deixe para testar depois o que você pode testar antes.
Não deixe para testar depois o que você pode testar antes.
 
Desenvolvendo jogos com pygame
Desenvolvendo jogos com pygameDesenvolvendo jogos com pygame
Desenvolvendo jogos com pygame
 
Essa câmera faz fotos muito boas, né?
Essa câmera faz fotos muito boas, né?Essa câmera faz fotos muito boas, né?
Essa câmera faz fotos muito boas, né?
 

Dernier

Assessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdfAssessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdf
Natalia Granato
 

Dernier (6)

ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docxATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
 
Boas práticas de programação com Object Calisthenics
Boas práticas de programação com Object CalisthenicsBoas práticas de programação com Object Calisthenics
Boas práticas de programação com Object Calisthenics
 
Assessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdfAssessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdf
 
Padrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemploPadrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemplo
 
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docxATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
 
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docxATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
 

Desenvolvendo Sistemas de Arquivos no FUSE - Luis Otávio de Colla Furquim

  • 1. Desenvolvendo Sistemas de Arquivos no FUSE Nível: Intermediário Pré-requisitos: familiaridade com a linguagem C conceitos de sistemas de arquivos
  • 2. Desenvolvendo Sistemas de Arquivos no FUSE http://fuse.sourceforge.net/ Miklos Szeredi Luis Otávio de Colla Furquim (luisfurquim@gmail.com)
  • 3. Desenvolvendo Sistemas de Arquivos no FUSE
  • 4. Desenvolvendo Sistemas de Arquivos no FUSE
  • 5. Desenvolvendo Sistemas de Arquivos no FUSE
  • 6. Desenvolvendo Sistemas de Arquivos no FUSE
  • 7. Desenvolvendo Sistemas de Arquivos no FUSE
  • 8. Desenvolvendo Sistemas de Arquivos no FUSE
  • 9. Desenvolvendo Sistemas de Arquivos no FUSE
  • 10. Desenvolvendo Sistemas de Arquivos no FUSE
  • 11. Desenvolvendo Sistemas de Arquivos no FUSE
  • 12. Desenvolvendo Sistemas de Arquivos no FUSE
  • 13. Desenvolvendo Sistemas de Arquivos no FUSE
  • 14. Desenvolvendo Sistemas de Arquivos no FUSE
  • 15. Desenvolvendo Sistemas de Arquivos no FUSE
  • 16. Desenvolvendo Sistemas de Arquivos no FUSE
  • 17. Desenvolvendo Sistemas de Arquivos no FUSE
  • 18. Desenvolvendo Sistemas de Arquivos no FUSE
  • 19. Desenvolvendo Sistemas de Arquivos no FUSE
  • 20. Desenvolvendo Sistemas de Arquivos no FUSE
  • 21. Desenvolvendo Sistemas de Arquivos no FUSE getattr open opendir release statfs readdir read releasedir write symlink mkdir unlink chmod rmdir
  • 22. Desenvolvendo Sistemas de Arquivos no FUSE ● Processar linha de comando ● Inicializar variáveis / hardware ● Inicializar o sistema de arquivos (efetivar a montagem) ● Finalizar o programa
  • 23. Desenvolvendo Sistemas de Arquivos no FUSE ● Processar linha de comando ● Inicializar variáveis / hardware ● Inicializar o sistema de arquivos (efetivar a montagem) ● Finalizar o programa
  • 24. Desenvolvendo Sistemas de Arquivos no FUSE Inicializar o sistema de arquivos fuse.h fuse_main(argc, argv, &my_oper, NULL); ●argc, argv: opções do FUSE ●my_oper: funções que tratam o FS ●NULL: dados opcionais ●Bloqueia o programa ●Entra em modo DAEMON ●Perde stdin, stdout, stderr (debug via log) ●Funções de my_oper iniciam threads (exceto se a opção -s for definida)
  • 25. Desenvolvendo Sistemas de Arquivos no FUSE DEBUG unique: 15, opcode: GETATTR (3), nodeid: 1, insize: 56 unique: 15, error: 0 (Success), outsize: 112 unique: 16, opcode: GETXATTR (22), nodeid: 1, insize: 65 unique: 16, error: -38 (Function not implemented), outsize: 16 unique: 17, opcode: OPENDIR (27), nodeid: 1, insize: 48 unique: 17, error: 0 (Success), outsize: 32 unique: 18, opcode: READDIR (28), nodeid: 1, insize: 80 unique: 18, error: 0 (Success), outsize: 616 unique: 19, opcode: LOOKUP (1), nodeid: 1, insize: 48 LOOKUP /Maildir NODEID: 2 unique: 19, error: 0 (Success), outsize: 136
  • 26. Desenvolvendo Sistemas de Arquivos no FUSE unique: 20, opcode: LOOKUP (1), nodeid: 1, insize: 45 LOOKUP /logs NODEID: 3 unique: 20, error: 0 (Success), outsize: 136 unique: 27, opcode: READDIR (28), nodeid: 1, insize: 80 unique: 27, error: 0 (Success), outsize: 16 unique: 28, opcode: RELEASEDIR (29), nodeid: 1, insize: 64 unique: 28, error: 0 (Success), outsize: 16
  • 27. Desenvolvendo Sistemas de Arquivos no FUSE Processar linha de comando mount [options] device mountpoint sshfs [user@]host:[dir] mountpoint [options]
  • 28. Desenvolvendo Sistemas de Arquivos no FUSE Processar linha de comando mount [options] device mountpoint sshfs [user@]host:[dir] mountpoint [options]
  • 29. Desenvolvendo Sistemas de Arquivos no FUSE Processar linha de comando mount [options] device mountpoint sshfs [user@]host:[dir] mountpoint [options] Específicas Gerais (FUSE) -o allow_other -p PORT allow access to other users equivalent to ’-o port=PORT’ -C equivalent to ’-o compression=yes’ -o allow_root allow access to root -1 equivalent to ’-o ssh_protocol=1’ -o reconnect -o nonempty reconnect to server allow mounts over non-empty file/dir -o sshfs_sync -o default_permissions enable synchronous writes permission checking by kernel -o no_readahead synchronous reads (no speculative readahead)
  • 30. Desenvolvendo Sistemas de Arquivos no FUSE Processar linha de comando fuse_opt.h myfs <mountpoint> <myfs_option> [-o <fuse_option1>[,...[,<fuse_optionN>]]] struct fuse_args args = FUSE_ARGS_INIT(0, NULL); int i; for(i = 0; i < argc; i++) { if (i == 2) { myparameter = argv[i]; } else { fuse_opt_add_arg(&args, argv[i]); } } fuse_main(args.argc, args.argv, my_oper, NULL);
  • 31. Desenvolvendo Sistemas de Arquivos no FUSE Processar linha de comando char *myparameter; static int myfs_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) { if (key == FUSE_OPT_KEY_NONOPT && myparameter == NULL) { myparameter = strdup(arg); return 0; } return 1; } int main(int argc, char *argv[]) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); fuse_opt_parse(&args, NULL, NULL, myfs_opt_proc); fuse_main(args.argc, args.argv, my_oper, NULL); }
  • 32. Desenvolvendo Sistemas de Arquivos no FUSE Processar linha de comando char *myparameter; static int myfs_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) { if (key == FUSE_OPT_KEY_NONOPT && myparameter == NULL) { myparameter = strdup(arg); return 0; } return 1; } int main(int argc, char *argv[]) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); fuse_opt_parse(&args, NULL, NULL, myfs_opt_proc); fuse_opt_add_arg(&args, "-oallow_other"); fuse_main(args.argc, args.argv, my_oper, NULL); }
  • 33. Desenvolvendo Sistemas de Arquivos no FUSE Funções Callback getattr rmdir write fgetattr rename statfs access link flush readlink chmod release opendir chown fsync readdir truncate setxattr releasedir ftruncate getxattr mknod utimens listxattr mkdir create removexattr symlink open lock unlink read
  • 34. Desenvolvendo Sistemas de Arquivos no FUSE static struct fuse_operations xmp_oper = { .getattr = my_getattr, .access = my_access, .readlink = my_readlink, .opendir = my_opendir, .readdir = my_readdir, . . . };
  • 35. Desenvolvendo Sistemas de Arquivos no FUSE Ferramentas de apoio aos callbacks struct fuse_context : uid_t uid – Id do usuário do processo chamador gid_t gid – Id do grupo do processo chamador pid_t pid – Id do processo chamador void *private_data – Dados do filesystem struct fuse_context *fuse_get_context(void); Informações do contexto struct fuse_file_info: int flags – modo de abertura de arquivo (open/release) uint64_t fh – file handle, se inicializado em open, estará disponível nas demais operações sobre arquivos abertos uint64_t lock_owner – Id do dono do lock (lock e flush)
  • 36. Desenvolvendo Sistemas de Arquivos no FUSE Padrões path – Inicia com '/', mas é relativo ao mountpoint. Exemplo: root@darkstar # myfs /foo root@darkstar # ls /foo/bar path = ”/bar” errno – Retornar –errno (MENOS errno) Exemplo: if ((size=read( ... )<0) { return( –errno); }
  • 37. Desenvolvendo Sistemas de Arquivos no FUSE Funções Callback Inicialização e término do sistema de arquivos static void *my_init(struct fuse_conn_info *conn) { // inicialização de variáveis, threads, etc // uma conexão com um banco mysql, por exemplo myconn = mysql_init ( NULL ); mysql_real_connect (myconn ,"localhost","user", ...); return(&myconn); } static int my_destroy(void *myconn) { mysql_close(*myconn); }
  • 38. Desenvolvendo Sistemas de Arquivos no FUSE Atributos do sistema de arquivos static int my_statfs(const char *path, struct statvfs *stbuf) { int res; res = statvfs(path, stbuf); if (res == -1) return -errno; return 0; }
  • 39. Desenvolvendo Sistemas de Arquivos no FUSE static int my_statfs(const char *path, struct statvfs *stbuf) { ... MYSQL **conn = fuse_get_context()->private_data; sprintf(qry,"SELECT MAX_DATA_LENGTH/512, DATA_FREE/512 " "FROM INFORMATION_SCHEMA.PARTITIONS " "WHERE TABLE_NAME='files' AND TABLE_SCHEMA='myfs'"); mysql_query(*myconn,qry); res = mysql_store_result(*myconn); if (row = mysql_fetch_row(res)) { memset(&attr,0,sizeof(struct statvfs)); stbuf->f_bsize = 512; stbuf->f_frsize = 512; stbuf->f_blocks = row[0]; stbuf->f_bfree = row[1]; ... return (0); } else { return (-EIO); } }
  • 40. Desenvolvendo Sistemas de Arquivos no FUSE Atributos (uid/gid, datas, permissões, etc) do arquivo static int my_getattr(const char *path, struct stat *stbuf) { int res; res = lstat(path, stbuf); if (res == -1) return -errno; return 0; } static int my_fgetattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi) { int res; (void) path; res = fstat(fi->fh, stbuf); if (res == -1) return -errno; return 0; }
  • 41. Desenvolvendo Sistemas de Arquivos no FUSE static int my_getattr(const char *path, struct stat *stbuf) { MYSQL_RES *res; MYSQL_ROW row; MYSQL *conn = (MYSQL *) fuse_get_context()->private_data; sprintf(qry,"select uid, gid, mode, ctime, mtime, atime, size ” ”from files where path='%s'",path); mysql_query(conn,qry); res = mysql_store_result(conn); if (row = mysql_fetch_row(res)) { memset(&attr,0,sizeof(struct stat)); stbuf->st_uid = row[0]; stbuf->st_gid = row[1]; stbuf->st_mode = row[2]; stbuf->st_ctime = row[3]; stbuf->st_mtime = row[4]; stbuf->st_atime = row[5]; stbuf->st_size = row[6]; } else { return (-ENOENT); } }
  • 42. Desenvolvendo Sistemas de Arquivos no FUSE Listagem de diretórios static int my_opendir(const char *path, struct fuse_file_info *fi) { DIR *dp = opendir(path); if (dp == NULL) return -errno; fi->fh = (unsigned long) dp; return 0; }
  • 43. Desenvolvendo Sistemas de Arquivos no FUSE #define get_dirp(f) ((DIR *) (uintptr_t) f->fh) static int my_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { DIR *dp = get_dirp(fi); struct dirent *de; struct stat st; seekdir(dp, offset); while ((de = readdir(dp)) != NULL) { memset(&st, 0, sizeof(st)); st.st_ino = de->d_ino; st.st_mode = de->d_type << 12; if (filler(buf, de->d_name, &st, telldir(dp))) break; } return 0; }
  • 44. Desenvolvendo Sistemas de Arquivos no FUSE static int my_releasedir(const char *path, struct fuse_file_info *fi) { DIR *dp = get_dirp(fi); (void) path; closedir(dp); return 0; }
  • 45. Desenvolvendo Sistemas de Arquivos no FUSE -rw-r--r-- 1 root root 299 2008-09-12 11:08 a.out.h -rw-r--r-- 1 root root 5365 2008-09-12 11:08 byteswap.h -rw-r--r-- 1 root root 4881 2008-09-12 11:07 cmathcalls.h -rw-r--r-- 1 root root 20634 2008-09-12 11:08 confname.h -rw-r--r-- 1 root root 1609 2008-09-12 11:08 dirent.h -rw-r--r-- 1 root root 2593 2008-09-12 11:08 dlfcn.h -rw-r--r-- 1 root root 426 2008-09-12 11:09 elfclass.h -rw-r--r-- 1 root root 170 2008-09-12 11:08 endian.h -rw-r--r-- 1 root root 3275 2008-09-12 11:08 environments.h -rw-r--r-- 1 root root 2129 2008-09-12 11:07 errno.h -rw-r--r-- 1 root root 2762 2008-09-12 11:08 error.h -rw-r--r-- 1 root root 5607 2008-09-12 11:08 fcntl2.h -rw-r--r-- 1 root root 9258 2008-09-12 11:08 fcntl.h -rw-r--r-- 1 root root 3064 2008-09-12 11:07 fenv.h -rw-r--r-- 1 root root 190 2008-09-12 11:07 fenvinline.h -rw-r--r-- 1 root root 1901 2008-09-12 11:07 huge_valf.h
  • 46. Desenvolvendo Sistemas de Arquivos no FUSE -rw-r--r-- 1 root root 299 2008-09-12 11:08 a.out.h -rw-r--r-- 1 root root 5365 2008-09-12 11:08 byteswap.h -rw-r--r-- 1 root root 4881 2008-09-12 11:07 cmathcalls.h -rw-r--r-- 1 root root 20634 2008-09-12 11:08 confname.h -rw-r--r-- 1 root root 1609 2008-09-12 11:08 dirent.h -rw-r--r-- 1 root root 2593 2008-09-12 11:08 dlfcn.h -rw-r--r-- 1 root root 426 2008-09-12 11:09 elfclass.h -rw-r--r-- 1 root root 170 2008-09-12 11:08 endian.h -rw-r--r-- 1 root root 3275 2008-09-12 11:08 environments.h -rw-r--r-- 1 root root 2129 2008-09-12 11:07 errno.h -rw-r--r-- 1 root root 2762 2008-09-12 11:08 error.h -rw-r--r-- 1 root root 5607 2008-09-12 11:08 fcntl2.h -rw-r--r-- 1 root root 9258 2008-09-12 11:08 fcntl.h -rw-r--r-- 1 root root 3064 2008-09-12 11:07 fenv.h -rw-r--r-- 1 root root 190 2008-09-12 11:07 fenvinline.h -rw-r--r-- 1 root root 1901 2008-09-12 11:07 huge_valf.h
  • 47. Desenvolvendo Sistemas de Arquivos no FUSE -rw-r--r-- 1 root root 299 2008-09-12 11:08 a.out.h -rw-r--r-- 1 root root 5365 2008-09-12 11:08 byteswap.h -rw-r--r-- 1 root root 4881 2008-09-12 11:07 cmathcalls.h -rw-r--r-- 1 root root 20634 2008-09-12 11:08 confname.h -rw-r--r-- 1 root root 1609 2008-09-12 11:08 dirent.h -rw-r--r-- 1 root root 2593 2008-09-12 11:08 dlfcn.h -rw-r--r-- 1 root root 426 2008-09-12 11:09 elfclass.h -rw-r--r-- 1 root root 170 2008-09-12 11:08 endian.h -rw-r--r-- 1 root root 3275 2008-09-12 11:08 environments.h -rw-r--r-- 1 root root 2129 2008-09-12 11:07 errno.h -rw-r--r-- 1 root root 2762 2008-09-12 11:08 error.h -rw-r--r-- 1 root root 5607 2008-09-12 11:08 fcntl2.h -rw-r--r-- 1 root root 9258 2008-09-12 11:08 fcntl.h -rw-r--r-- 1 root root 3064 2008-09-12 11:07 fenv.h -rw-r--r-- 1 root root 190 2008-09-12 11:07 fenvinline.h -rw-r--r-- 1 root root 1901 2008-09-12 11:07 huge_valf.h
  • 48. Desenvolvendo Sistemas de Arquivos no FUSE -rw-r--r-- 1 root root 5365 2008-09-12 11:08 byteswap.h -rw-r--r-- 1 root root 4881 2008-09-12 11:07 cmathcalls.h -rw-r--r-- 1 root root 20634 2008-09-12 11:08 confname.h -rw-r--r-- 1 root root 1609 2008-09-12 11:08 dirent.h -rw-r--r-- 1 root root 2593 2008-09-12 11:08 dlfcn.h -rw-r--r-- 1 root root 426 2008-09-12 11:09 elfclass.h -rw-r--r-- 1 root root 170 2008-09-12 11:08 endian.h -rw-r--r-- 1 root root 3275 2008-09-12 11:08 environments.h -rw-r--r-- 1 root root 2129 2008-09-12 11:07 errno.h -rw-r--r-- 1 root root 2762 2008-09-12 11:08 error.h -rw-r--r-- 1 root root 5607 2008-09-12 11:08 fcntl2.h -rw-r--r-- 1 root root 9258 2008-09-12 11:08 fcntl.h -rw-r--r-- 1 root root 3064 2008-09-12 11:07 fenv.h -rw-r--r-- 1 root root 190 2008-09-12 11:07 fenvinline.h -rw-r--r-- 1 root root 1901 2008-09-12 11:07 huge_valf.h
  • 49. Desenvolvendo Sistemas de Arquivos no FUSE Criação de arquivos – MÉTODO OPCIONAL static int my_create(const char *path, mode_t mode, struct fuse_file_info *fi) { int fd = open(path, fi->flags, mode); if (fd == -1) return -errno; fi->fh = fd; // prover um descritor de arquivos é OPCIONAL return 0; } Flags O_EXCL - Falha se o arquivo já existir O_NONBLOCK - Evita que bloqueie por um "longo" tempo O_NOLINK - Se for link simbólico, abre o link (não o arquivo) O_TRUNC - Trunca o arquivo O_SHLOCK (BSD) - Obtem shared lock O_EXLOCK (BSD) - Obtem lock exclusivo
  • 50. Desenvolvendo Sistemas de Arquivos no FUSE Cria (sem abrir) um arquivo static int my_mknod(const char *path, mode_t mode, dev_t rdev) { int res; if (S_ISFIFO(mode)) res = mkfifo(path, mode); else res = mknod(path, mode, rdev); if (res == -1) return -errno; return 0; }
  • 51. Desenvolvendo Sistemas de Arquivos no FUSE Abre arquivo existente (não cria arquivos) static int my_open(const char *path, struct fuse_file_info *fi) { int fd = open(path, fi->flags); // sem mode if (fd == -1) return -errno; fi->fh = fd; // fornecer um file handle é OPCIONAL return 0; }
  • 52. Desenvolvendo Sistemas de Arquivos no FUSE Lê dados de um arquivo static int my_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int res; (void) path; res = pread(fi->fh, buf, size, offset); if (res == -1) res = -errno; return res; }
  • 53. Desenvolvendo Sistemas de Arquivos no FUSE Grava dados num arquivo static int my_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int res; (void) path; res = pwrite(fi->fh, buf, size, offset); if (res == -1) res = -errno; return res; }
  • 54. Desenvolvendo Sistemas de Arquivos no FUSE Fecha arquivo / libera recursos static int my_release(const char *path, struct fuse_file_info *fi) { (void) path; close(fi->fh); return 0; } OBS: Só é chamado uma vez por arquivo aberto, se a aplicação duplicou o descritor de arquivo (dup, fork, ...) release é chamado quando a aplicação chamar close para o último descritor aberto.
  • 55. Desenvolvendo Sistemas de Arquivos no FUSE Lê o conteúdo de um link simbólico static int my_readlink(const char *path, char *buf, size_t size) { int res = readlink(path, buf, size - 1); if (res == -1) return -errno; buf[res] = '0'; return 0; } OBS: readlink da libc copia string sem '0' para o buf e retorna a quantidade de caracteres lidos, o callback do FUSE exige o terminador na string e o valor de retorno é -errno.
  • 56. Desenvolvendo Sistemas de Arquivos no FUSE Cria symlink/hardlink static int my_symlink(const char *from, const char *to) { int res = symlink(from, to); if (res == -1) return -errno; return 0; } static int my_link(const char *from, const char *to) { int res = link(from, to); if (res == -1) return -errno; return 0; }
  • 57. Desenvolvendo Sistemas de Arquivos no FUSE Remove (deleta) um arquivo static int my_unlink(const char *path) { int res; res = unlink(path); if (res == -1) return -errno; return 0; }
  • 58. Desenvolvendo Sistemas de Arquivos no FUSE Renomeia/Move um arquivo static int my_rename(const char *from, const char *to) { int res; res = rename(from, to); if (res == -1) return -errno; return 0; } OBS: from e to sempre estão em myfs
  • 59. Desenvolvendo Sistemas de Arquivos no FUSE Muda atributos dos arquivo static int my_chmod(const char *path, mode_t mode) { int res = chmod(path, mode); if (res == -1) return -errno; return 0; } static int my_chown(const char *path, uid_t uid, gid_t gid) { int res = lchown(path, uid, gid); if (res == -1) return -errno; return 0; }
  • 60. Desenvolvendo Sistemas de Arquivos no FUSE Muda atributos de data/hora com precisão de nanosegundos static int my_utimens(const char *path, const struct timespec ts[2]) { int res; struct timeval tv[2]; tv[0].tv_sec = ts[0].tv_sec; tv[0].tv_usec = ts[0].tv_nsec / 1000; tv[1].tv_sec = ts[1].tv_sec; tv[1].tv_usec = ts[1].tv_nsec / 1000; res = utimes(path, tv); if (res == -1) return -errno; return 0; }
  • 61. Desenvolvendo Sistemas de Arquivos no FUSE Cria/deleta diretório static int my_mkdir(const char *path, mode_t mode) { int res = mkdir(path, mode); if (res == -1) return -errno; return 0; } static int my_rmdir(const char *path) { int res = rmdir(path); if (res == -1) return -errno; return 0; }
  • 62. Desenvolvendo Sistemas de Arquivos no FUSE Verifica se é possível fazer o acesso, especificado em mask, ao arquivo static int my_access(const char *path, int mask) { int res; res = access(path, mask); if (res == -1) return -errno; return 0; }
  • 63. Desenvolvendo Sistemas de Arquivos no FUSE Modifica o tamanho de um arquivo pelo nome ou pelo file handle static int my_truncate(const char *path, off_t size) { int res = truncate(path, size); if (res == -1) return -errno; return 0; } static int my_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) { int res = ftruncate(fi->fh, size); if (res == -1) return -errno; return 0; }
  • 64. Desenvolvendo Sistemas de Arquivos no FUSE Grava atributo extendido static int my_setxattr(const char *path, const char *name, const char *value, size_t size, int flags) { int res = lsetxattr(path, name, value, size, flags); if (res == -1) return -errno; return 0; }
  • 65. Desenvolvendo Sistemas de Arquivos no FUSE Lê/lista atributos extendidos static int my_getxattr(const char *path, const char *name, char *value, size_t size) { int res = lgetxattr(path, name, value, size); if (res == -1) return -errno; return res; } static int my_listxattr(const char *path, char *list, size_t size) { int res = llistxattr(path, list, size); if (res == -1) return -errno; return res; }
  • 66. Desenvolvendo Sistemas de Arquivos no FUSE Remove atributo extendido static int my_removexattr(const char *path, const char *name) { int res = lremovexattr(path, name); if (res == -1) return -errno; return 0; }
  • 67. Desenvolvendo Sistemas de Arquivos no FUSE Gerencia trava de arquivo, segundo o padrão POSIX static int my_lock(const char *path, struct fuse_file_info *fi, int cmd, struct flock *lock) { (void) path; return ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner, sizeof(fi->lock_owner)); }
  • 68. Desenvolvendo Sistemas de Arquivos no FUSE Sincroniza dados em memória com o meio de armazenamento static int my_fsync(const char *path, int datasync, struct fuse_file_info *fi) { (void) path; (void) datasync; (void) fi; return (0); } OBS: Se datasync = = zero, deve sincronizar dados e meta-dados Se datasync != zero, deve sincronizar somente dados
  • 69. Desenvolvendo Sistemas de Arquivos no FUSE Sincroniza dados em memória com o meio de armazenamento static int my_flush(const char *path, struct fuse_file_info *fi) { (void) path; (void) fi; return (0); } OBS: Não é chamado quando a aplicação chama fsync. Só é chamado quando a aplicação chama close. Pode haver mais de um close por arquivo (dup, fork, ...) Não há garantia de que seja chamado sequer uma vez.
  • 70. Desenvolvendo Sistemas de Arquivos no FUSE int fuseargc = 5; char *fuseargv[6]; fuseargv[0] = "sohofs"; fuseargv[1] = "-f"; fuseargv[2] = "/tmp/fuse"; fuseargv[3] = "-o"; fuseargv[4] = "allow_other,nonempty"; fuseargv[5] = NULL; return (fuse_main(fuseargc, fuseargv, &my_ops, NULL)); it reports the error "Access is denied" when I try to copy a new file into the share folder through SAMBA. Try to run in debug mode: fuseargv[4] = "allow_other,nonempty,debug"; And check what is happening when samba calls access/getattr.
  • 71. Desenvolvendo Sistemas de Arquivos no FUSE unique: 2, opcode: GETATTR (3), nodeid: 1, insize: 40 unique: 2, error: 0 (Success), outsize: 112 WRITE[6] 4096 bytes to 0 unique: 128, error: -28 (No space left on device), outsize: 16 unique: 129, opcode: WRITE (16), nodeid: 9, insize: 4160 WRITE[6] 4096 bytes to 0 unique: 129, error: -28 (No space left on device), outsize: 16 unique: 130, opcode: WRITE (16), nodeid: 9, insize: 4160 WRITE[6] 4096 bytes to 0 unique: 130, error: -28 (No space left on device), outsize: 16 But there are actually free space on the the device, so what are the potential issues. So, the problem is with the statfs callback function. This function is responsible to tell the system the info about the filesystem and this includes the space in it.