/************************************************************************** * Copyright (C) 2006 by Gustavo Padovan, Gustavo Scalet and * * Otávio Pontes * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* * Gustavo Fernando Padovan..ra061316 * Gustavo Serra Scalet......ra061358 * Otávio Busatto Pontes.....ra063462 */ #include #include #include #include #include #include #include #include "islenefs.h" extern int inode_number; /* Lembre-se que nao temos um disco! (Isso so complicaria as coisas, pois teriamos * que lidar com o sub-sistema de I/O. Entao teremos uma representacao bastante * simples da estrutura de arquivos: Uma lista duplamente ligada circular (para * aplicacoes reais, um hash seria muito mais adequado) contem em cada elemento * um indice (inode) e uma pagina para conteudo (ou seja: o tamanho maximo de um * arquivo nessa versao do islene fs eh de 4Kb. Nao ha subdiretorios */ const struct super_operations islenefs_ops = { .statfs = simple_statfs, .drop_inode = generic_delete_inode, }; /* criacao de um arquivo: sem misterio, sem segredo, apenas * alocar as estruturas, preencher, e retornar */ static int islenefs_create (struct inode *dir, struct dentry * dentry, int mode, struct nameidata *nd) { struct inode *inode; int err= -ENOSPC; mode |= S_IFREG; inode = islenefs_get_inode(dir->i_sb, mode); if (inode) { d_instantiate(dentry, inode); dget(dentry); inode->i_private = NULL; err = 0; } return err; } static int islenefs_unlink(struct inode * dir, struct dentry *dentry ) { struct inode * inode = dentry->d_inode; free_pages((unsigned long)(inode->i_private), get_order(inode->i_size)); inode->i_ctime = dir->i_ctime; inode_dec_link_count(inode); return 0; } /* * Função islenefs_link experimental */ static int islenefs_link(struct dentry * old_dentry, struct inode * dir, struct dentry * dentry) { struct inode * inode = old_dentry->d_inode; inode->i_ctime = CURRENT_TIME; inode_inc_link_count(inode); atomic_inc(&inode->i_count); d_instantiate(dentry,inode); dget(dentry); return 0; } static int islenefs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) { struct inode * inode; int error = - ENOSPC; inode = islenefs_get_inode(dir->i_sb, S_IFLNK | S_IRWXUGO); if (inode) { int l = strlen(symname)+1; error = page_symlink(inode, symname, l); if (!error) { if (dir->i_mode & S_ISGID) inode->i_gid = dir->i_gid; d_instantiate(dentry, inode); dget(dentry); dir->i_mtime = dir->i_ctime = CURRENT_TIME; } else iput(inode); } return error; } static int islenefs_mkdir(struct inode * dir, struct dentry *dentry, int mode) { struct inode * inode; mode |= S_IFDIR; inode = islenefs_get_inode(dir->i_sb, mode); if (inode) { if (dir->i_mode & S_ISGID) { inode->i_gid = dir->i_gid; if (S_ISDIR(mode)) inode->i_mode |= S_ISGID; } d_instantiate(dentry, inode); dget(dentry); dir->i_mtime = dir->i_ctime = CURRENT_TIME; inode->i_ino = ++inode_number; inc_nlink(dir); return 0; } return -ENOMEM; /* G: nah. Sistemas de arquivos em memoria nao retornam 'ENOSPC' -> ENOMEM? */ } const struct inode_operations islenefs_dir_inode_operations = { .create = islenefs_create, .lookup = simple_lookup, .unlink = islenefs_unlink, .link = islenefs_link, .symlink = islenefs_symlink, .mkdir = islenefs_mkdir, };