./kernel/Linux/modbin/*.o
./kernel/Linux/modbin/prepmod-tmp-dir
./kernel/Linux/2.4/makefile
- ./kernel/Linux/2.5/makefile
+ ./kernel/Linux/2.6/makefile
./debian/changelog
)],
"ChangeLog"=>"ChangeLog.captive",
AC_INIT(AUTHORS)
AM_CONFIG_HEADER(config.h)
AC_CANONICAL_SYSTEM
-VERSION_BASE=0.9.6
-VERSION_EXT=captive6
+VERSION_BASE=0.9.7
+VERSION_EXT=captive7cvs
AC_SUBST(VERSION_BASE)
AC_SUBST(VERSION_EXT)
AM_INIT_AUTOMAKE(lufs,$VERSION_BASE$VERSION_EXT)
CXX=false
])
-OS_DIR=Linux
+ dnl Checking os
+ AC_MSG_CHECKING(OS)
+ OS_DIR=`uname -s`
+ if test ! -d kernel/$OS_DIR
+ then
+ AC_MSG_ERROR($OS_DIR - not supported!)
+ else
+ AC_MSG_RESULT($OS_DIR)
+ fi
+fi
AC_SUBST(OS_DIR)
dnl options
kernel/Makefile \
kernel/Linux/Makefile \
kernel/Linux/2.4/Makefile \
- kernel/Linux/2.5/Makefile \
+ kernel/Linux/2.6/Makefile \
kernel/Linux/modbin/Makefile \
include/Makefile \
docs/Makefile \
kernel/Linux/prepmod \
debian/changelog \
kernel/Linux/2.4/makefile \
- kernel/Linux/2.5/makefile \
+ kernel/Linux/2.6/makefile \
)
echo "###############################################################################"
AM_CXXFLAGS:= -O2 -Wall -DSSHPROG=\"@SSHPROG@\" @DEBUG_FLAGS@
INCLUDES=-I../ @all_includes@
-lib_LTLIBRARIES=liblufs-sshfs.la
+lib_LTLIBRARIES = liblufs-sshfs.la
noinst_HEADERS=sshfs.h sftplib.h
liblufs_sshfs_la_SOURCES=sshfs.cpp sftplib.cpp
basedir=$(datadir)/lufs
src24dir=$(basedir)/2.4
-src25dir=$(basedir)/2.5
+src26dir=$(basedir)/2.6
src24_HEADERS = lufs/proto.h
-src25_HEADERS = lufs/proto.h
+src26_HEADERS = lufs/proto.h
+++ /dev/null
- ifdef KERNELRELEASE
- include $(SUBDIRS)/makefile
- else
-
-basedir=$(datadir)/lufs
-src25dir=$(basedir)/2.5
-
-src25= \
- lufs.h proc.h \
- proc.c inode.c dir.c file.c symlink.c
-
-src25_DATA= \
- lufs.h proc.h \
- proc.c inode.c dir.c file.c symlink.c \
- makefile
-
-install-data-hook:
- rm -f $(DESTDIR)$(src25dir)/Makefile
- mv -f $(DESTDIR)$(src25dir)/makefile $(DESTDIR)$(src25dir)/Makefile
-
-EXTRA_DIST=$(src25) makefile.in
-
- endif
+++ /dev/null
-/*
- * dir.c
- * Copyright (C) 2002 Florin Malita <mali@go.ro>
- *
- * This file is part of LUFS, a free userspace filesystem implementation.
- * See http://lufs.sourceforge.net/ for updates.
- *
- * LUFS 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.
- *
- * LUFS 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
- */
-
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/socket.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#include <linux/smp_lock.h>
-
-#include "lufs.h"
-#include "proc.h"
-
-
-extern struct inode* lu_iget(struct super_block*, struct lufs_fattr*);
-extern int lufs_notify_change(struct dentry*, struct iattr*);
-
-static int lu_readdir(struct file*, void*, filldir_t);
-
-static struct dentry *lu_lookup(struct inode*, struct dentry*, struct nameidata *);
-static int lu_mkdir(struct inode*, struct dentry*, int);
-static int lu_create(struct inode*, struct dentry*, int, struct nameidata *);
-static int lu_rmdir(struct inode*, struct dentry*);
-static int lu_rename(struct inode*, struct dentry*, struct inode*, struct dentry*);
-static int lu_unlink(struct inode*, struct dentry*);
-static int lu_link(struct dentry*, struct inode*, struct dentry*);
-static int lu_symlink(struct inode*, struct dentry*, const char*);
-
-struct file_operations lu_dir_operations = {
- .read = generic_read_dir,
- .readdir = lu_readdir,
-};
-
-struct inode_operations lu_dir_inode_operations = {
- .create = lu_create,
- .lookup = lu_lookup,
- .link = lu_link,
- .unlink = lu_unlink,
- .symlink = lu_symlink,
- .mkdir = lu_mkdir,
- .rmdir = lu_rmdir,
- .rename = lu_rename,
- .setattr = lufs_notify_change,
-};
-
-static int lu_lookup_validate(struct dentry *dentry, struct nameidata *nd)
-{
- struct inode *inode = dentry->d_inode;
- unsigned long age = jiffies - dentry->d_time;
- int res;
-
- TRACE("in\n");
-
- res = (age <= LU_MAXAGE);
- TRACE("age: %lu, valid: %d\n", age, res);
-
- if(!res)
- res = (lu_revalidate_inode(dentry) == 0);
-
-
- if(inode){
- lock_kernel();
-
- if(is_bad_inode(inode))
- res = 0;
- unlock_kernel();
- }else
- TRACE("no inode?!\n");
-
- TRACE("out(res=%d)\n", res);
-
- return res;
-}
-
-static int lu_delete_dentry(struct dentry *dentry)
-{
-
- TRACE("in\n");
- if(dentry->d_inode && is_bad_inode(dentry->d_inode)){
- WARN("bad inode, unhashing \n");
- return 1;
- }
-
- TRACE("out\n");
- return 0;
-}
-
-struct dentry_operations lufs_dentry_operations = {
- .d_revalidate = lu_lookup_validate,
- .d_delete = lu_delete_dentry,
-};
-
-static int lu_readdir(struct file *f, void *dirent, filldir_t filldir)
-{
- int res = -1;
- char *c;
- struct qstr qname;
- unsigned long ino;
- struct iovec siov[2], riov;
- struct server_slot *slot;
- unsigned short offset;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(f->f_dentry->d_sb))) == NULL)
- return -ERESTARTSYS;
-
- if(lu_getname(f->f_dentry, slot->s_buf, LU_MAXDATA) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- TRACE("reading %s, offset %u...\n", slot->s_buf, (unsigned)f->f_pos);
- res = 0;
-
- switch((unsigned int)f->f_pos){
-
- case 0:
- if(filldir(dirent, ".", 1, 0, f->f_dentry->d_inode->i_ino, DT_DIR) < 0)
- goto out;
- f->f_pos++;
-
- case 1:
- if(filldir(dirent, "..", 2, 1, f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
- goto out;
- f->f_pos++;
-
- default:
- offset = f->f_pos;
- siov[0].iov_base = &offset;
- siov[0].iov_len = sizeof(unsigned short);
- siov[1].iov_base = slot->s_buf;
- siov[1].iov_len = strlen(slot->s_buf) + 1;
- riov.iov_base = slot->s_buf;
- riov.iov_len = LU_MAXDATA;
-
- if((res = lu_execute(GET_INFO(f->f_dentry->d_inode->i_sb), slot, PTYPE_READDIR, siov, 2, &riov, 1)) < 0){
- WARN("could not read directory content!\n");
- if(res == -ERESTARTSYS)
- res = -EINTR;
- goto out;
- }
- if(PIS_ERROR(res)){
- WARN("server failure!\n");
- res = PERROR(res);
- goto out;
- }
- for(qname.name = slot->s_buf, c = strchr(slot->s_buf, '\n'); c != NULL; qname.name = c+1, c = strchr(c+1, '\n')){
- *c = 0;
- TRACE("direntry: %s.\n", qname.name);
- qname.len = strlen(qname.name);
- if((ino = find_inode_number(f->f_dentry, &qname)) == 0)
- ino = iunique(f->f_dentry->d_sb, 2);
- if(filldir(dirent, qname.name, qname.len, f->f_pos, ino, DT_UNKNOWN) < 0)
- break;
- f->f_pos++;
- }
- }
-
- TRACE("out\n");
- out:
- lu_putslot(slot);
- return res;
-}
-
-static struct dentry* lu_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
-{
- int res;
- struct lufs_fattr fattr;
- struct iovec siov, riov;
- struct inode *inode;
- struct server_slot *slot;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(dir->i_sb))) == NULL)
- return ERR_PTR(-ERESTARTSYS);
-
- if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- TRACE("looking up %s\n", slot->s_buf);
-
- siov.iov_base = slot->s_buf;
- siov.iov_len = strlen(slot->s_buf) + 1;
- riov.iov_base = &fattr;
- riov.iov_len = sizeof(struct lufs_fattr);
-
- if((res = lu_execute(GET_INFO(dir->i_sb), slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("File not found...\n");
- dentry->d_op = &lufs_dentry_operations;
- dentry->d_time = jiffies;
- d_add(dentry, NULL);
- lu_putslot(slot);
- return NULL;
- }
-
- lu_fixattrs(GET_INFO(dir->i_sb), &fattr);
-
- if(dentry == dentry->d_parent)
- fattr.f_ino = 2;
- else
- fattr.f_ino = iunique(dentry->d_sb, 2);
-
- if((inode = lu_iget(dir->i_sb, &fattr))){
- dentry->d_op = &lufs_dentry_operations;
- dentry->d_time = jiffies;
- d_add(dentry, inode);
- }
- res = 0;
-
- out:
- lu_putslot(slot);
-
- TRACE("out\n");
- return ERR_PTR(res);
-}
-
-static int lu_instantiate(struct dentry *dentry, char *name, struct server_slot *slot)
-{
- int res;
- struct lufs_fattr fattr;
- struct iovec siov, riov;
- struct inode *inode;
-
- TRACE("in\n");
-
- TRACE("instantiating %s\n", name);
-
- siov.iov_base = name;
- siov.iov_len = strlen(name) + 1;
- riov.iov_base = &fattr;
- riov.iov_len = sizeof(struct lufs_fattr);
-
- if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("File not found...\n");
- res = PERROR(res);
- goto out;
- }
-
- lu_fixattrs(GET_INFO(dentry->d_sb), &fattr);
-
- fattr.f_ino = iunique(dentry->d_sb, 2);
- inode = lu_iget(dentry->d_sb, &fattr);
-
- if(!inode){
- res = -EACCES;
- goto out;
- }
-
- d_instantiate(dentry, inode);
- res = 0;
-
- out:
- TRACE("out\n");
- return res;
-}
-
-static int lu_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-{
- int res;
- struct server_slot *slot;
- struct iovec iov[2];
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
- return -ERESTARTSYS;
-
- if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- iov[0].iov_base = &mode;
- iov[0].iov_len = sizeof(mode);
- iov[1].iov_base = slot->s_buf;
- iov[1].iov_len = strlen(slot->s_buf) + 1;
-
- if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_MKDIR, iov, 2, NULL, 0)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("Could not create directory.\n");
- res = PERROR(res);
- goto out;
- }
-
- res = lu_instantiate(dentry, slot->s_buf, slot);
-
- out:
- lu_putslot(slot);
-
- TRACE("out\n");
- return res;
-}
-
-static int lu_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
-{
- int res;
- struct server_slot *slot;
- struct iovec iov[2];
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
- return -ERESTARTSYS;
-
- if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- iov[0].iov_base = &mode;
- iov[0].iov_len = sizeof(mode);
- iov[1].iov_base = slot->s_buf;
- iov[1].iov_len = strlen(slot->s_buf) + 1;
-
- if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_CREATE, iov, 2, NULL, 0)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("Could not create file.\n");
- res = PERROR(res);
- goto out;
- }
-
- res = lu_instantiate(dentry, slot->s_buf, slot);
-
- out:
- lu_putslot(slot);
-
- TRACE("out\n");
- return res;
-}
-
-static int lu_rmdir(struct inode *dir, struct dentry *dentry)
-{
- int res;
- struct server_slot *slot;
- struct iovec iov;
-
- if(!d_unhashed(dentry))
- return -EBUSY;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
- return -ERESTARTSYS;
-
- if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
- WARN("lu_getname failed!");
- goto out;
- }
-
- iov.iov_base = slot->s_buf;
- iov.iov_len = strlen(slot->s_buf) + 1;
-
- if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_RMDIR, &iov, 1, NULL, 0)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("rmdir failed!\n");
- res = PERROR(res);
- goto out;
- }
- res = 0;
-
- out:
- lu_putslot(slot);
-
- TRACE("out\n");
- return res;
-}
-
-static int lu_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
-{
- struct server_slot *slot;
- int res;
- struct iovec iov[2];
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(old_dentry->d_sb))) == NULL)
- return -ERESTARTSYS;
-
- if((res = lu_getname(old_dentry, slot->s_buf, LU_MAXPATHLEN)) < 0 ||
- (res = lu_getname(new_dentry, &(slot->s_buf[LU_MAXPATHLEN]), LU_MAXPATHLEN)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- iov[0].iov_base = slot->s_buf;
- iov[0].iov_len = strlen(slot->s_buf) + 1;
- iov[1].iov_base = &(slot->s_buf[LU_MAXPATHLEN]);
- iov[1].iov_len = strlen(&(slot->s_buf[LU_MAXPATHLEN])) + 1;
-
- if((res = lu_execute(GET_INFO(old_dentry->d_sb), slot, PTYPE_RENAME, iov, 2, NULL, 0)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("rename failed!\n");
- res = PERROR(res);
- goto out;
- }
- res = 0;
-
- out:
- lu_putslot(slot);
-
- TRACE("out\n");
- return res;
-}
-
-static int lu_unlink(struct inode *dir, struct dentry *dentry)
-{
- int res;
- struct server_slot *slot;
- struct iovec iov;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
- return -ERESTARTSYS;
-
- if((res = lu_getname(dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){
- WARN("lu_getname failed!");
- goto out;
- }
-
- iov.iov_base = slot->s_buf;
- iov.iov_len = strlen(slot->s_buf) + 1;
-
- if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_UNLINK, &iov, 1, NULL, 0)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("unlink failed!\n");
- res = PERROR(res);
- goto out;
- }
- res = 0;
-
- out:
- lu_putslot(slot);
-
- TRACE("out\n");
- return res;
-}
-
-
-static int lu_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
-{
- int res;
- struct server_slot *slot;
- struct iovec iov[2];
-
- TRACE("in\n");
-
- if(S_ISDIR(old_dentry->d_inode->i_mode))
- return -EPERM;
-
- if(!(slot = lu_getslot(GET_INFO(old_dentry->d_sb))))
- return -ERESTARTSYS;
-
- if((res = lu_getname(old_dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- if((res = lu_getname(dentry, &slot->s_buf[LU_MAXPATHLEN], LU_MAXPATHLEN)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- iov[0].iov_base = slot->s_buf;
- iov[0].iov_len = strlen(slot->s_buf) + 1;
- iov[1].iov_base = &slot->s_buf[LU_MAXPATHLEN];
- iov[1].iov_len = strlen(&slot->s_buf[LU_MAXPATHLEN]) + 1;
-
- d_drop(dentry);
-
- if((res = lu_execute(GET_INFO(old_dentry->d_sb), slot, PTYPE_LINK, iov, 2, NULL, 0)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("link failed!\n");
- res = PERROR(res);
- goto out;
- }
-
- res = 0;
-
- out:
- lu_putslot(slot);
- TRACE("out\n");
- return res;
-}
-
-static int lu_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
-{
- int res;
- struct server_slot *slot;
- struct iovec iov[2];
-
- TRACE("in\n");
- TRACE("symlink: %s\n", symname);
-
- if(strlen(symname) > LU_MAXPATHLEN - 1)
- return -ENAMETOOLONG;
-
- if(!(slot = lu_getslot(GET_INFO(dentry->d_sb))))
- return -ERESTARTSYS;
-
- if((res = lu_getname(dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- TRACE("fname: %s\n", slot->s_buf);
-
- strcpy(&slot->s_buf[LU_MAXPATHLEN], symname);
-
- iov[0].iov_base = slot->s_buf;
- iov[0].iov_len = strlen(slot->s_buf) + 1;
- iov[1].iov_base = &slot->s_buf[LU_MAXPATHLEN];
- iov[1].iov_len = strlen(&slot->s_buf[LU_MAXPATHLEN]) + 1;
-
- d_drop(dentry);
-
- if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_SYMLINK, iov, 2, NULL, 0)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("symlink failed!\n");
- res = PERROR(res);
- goto out;
- }
-
- res = 0;
-
- out:
- lu_putslot(slot);
- TRACE("out\n");
- return res;
-}
-
-
-
+++ /dev/null
-/*
- * file.c
- * Copyright (C) 2002 Florin Malita <mali@go.ro>
- *
- * This file is part of LUFS, a free userspace filesystem implementation.
- * See http://lufs.sourceforge.net/ for updates.
- *
- * LUFS 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.
- *
- * LUFS 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
- */
-
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-#include <linux/socket.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#include <linux/smp_lock.h>
-
-#include "lufs.h"
-#include "proc.h"
-
-extern int lufs_notify_change(struct dentry*, struct iattr*);
-extern int lu_revalidate_inode(struct dentry*);
-
-static int lu_file_open(struct inode *inode, struct file *file)
-{
- int res, gres;
- struct server_slot *slot;
- struct iovec iov[2];
- unsigned flags;
-
- TRACE("in\n");
-
- if((gres = generic_file_open(inode, file)) < 0)
- return gres;
-
- TRACE("f_mode: %u, i_mode: %u\n", file->f_mode, inode->i_mode);
- TRACE("f_flags: %u, i_flags: %u\n", file->f_flags, inode->i_flags);
-
- if((slot = lu_getslot(GET_INFO(file->f_dentry->d_sb))) == NULL)
- return gres;
-
- if((res = lu_getname(file->f_dentry, slot->s_buf, LU_MAXDATA)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- flags = file->f_flags & O_ACCMODE;
- iov[0].iov_base = &flags;
- iov[0].iov_len = sizeof(flags);
- iov[1].iov_base = slot->s_buf;
- iov[1].iov_len = strlen(slot->s_buf) + 1;
-
- lu_execute(GET_INFO(file->f_dentry->d_sb), slot, PTYPE_OPEN, iov, 2, NULL, 0);
-
-out:
- lu_putslot(slot);
-
- TRACE("out\n");
- return gres;
-}
-
-static int lu_file_release(struct inode *inode, struct file *file)
-{
- int res;
- struct server_slot *slot;
- struct iovec iov;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(file->f_dentry->d_sb))) == NULL)
- return -ERESTARTSYS;
-
- if((res = lu_getname(file->f_dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- iov.iov_base = slot->s_buf;
- iov.iov_len = strlen(slot->s_buf) + 1;
-
- if((res = lu_execute(GET_INFO(file->f_dentry->d_sb), slot, PTYPE_RELEASE, &iov, 1, NULL, 0)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("release failed\n");
- res = PERROR(res);
- goto out;
- }
-
- res = 0;
-
-out:
- lu_putslot(slot);
-
- TRACE("out\n");
- return res;
-}
-
-static int lu_file_readpage(struct file *f, struct page *p)
-{
- int res;
- struct iovec siov[3], riov;
- long long offset;
- unsigned long count;
- struct server_slot *slot;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(f->f_dentry->d_sb))) == NULL)
- return -ERESTARTSYS;
-
- get_page(p);
-
- if((res = lu_getname(f->f_dentry, slot->s_buf, LU_MAXDATA)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- offset = p->index << PAGE_CACHE_SHIFT;
- count = PAGE_SIZE;
-
- siov[0].iov_base = &offset;
- siov[0].iov_len = sizeof(offset);
- siov[1].iov_base = &count;
- siov[1].iov_len = sizeof(count);
- siov[2].iov_base = slot->s_buf;
- siov[2].iov_len = strlen(slot->s_buf) + 1;
-
- riov.iov_base = page_address(p);
- riov.iov_len = count;
-
- if((res = lu_execute(GET_INFO(f->f_dentry->d_sb), slot, PTYPE_READ, siov, 3, &riov, 1)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("read failed\n");
- res = PERROR(res);
- goto out;
- }
-
- flush_dcache_page(p);
- SetPageUptodate(p);
- res = 0;
-
- out:
- lu_putslot(slot);
- unlock_page(p);
- put_page(p);
-
- TRACE("out\n");
- return res;
-}
-
-static int lu_file_writepage(struct page *p, struct writeback_control *wbc)
-{
- TRACE("in\n");
-
- TRACE("out\n");
- return -1;
-}
-
-static int lu_file_preparewrite(struct file *f, struct page *p, unsigned offset, unsigned to)
-{
- TRACE("in\n");
-
- TRACE("out\n");
-
- return 0;
-}
-
-static int lu_file_commitwrite(struct file *f, struct page *p, unsigned offset, unsigned to)
-{
- int res;
- struct server_slot *slot;
- struct iovec iov[4];
- char *buf;
- long long off;
- unsigned long cnt;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(f->f_dentry->d_sb))) == NULL)
- return -ERESTARTSYS;
-
- if((res = lu_getname(f->f_dentry, slot->s_buf, LU_MAXDATA)) < 0){
- WARN("lu_getname failed!\n");
- goto out2;
- }
-
- lock_kernel();
-
- buf = kmap(p) + offset;
- cnt = to - offset;
- off = offset + (((long long)p->index) << PAGE_CACHE_SHIFT);
-
- iov[0].iov_base = &off;
- iov[0].iov_len = sizeof(off);
- iov[1].iov_base = &cnt;
- iov[1].iov_len = sizeof(cnt);
- iov[2].iov_base = slot->s_buf;
- iov[2].iov_len = strlen(slot->s_buf) + 1;
- iov[3].iov_base = buf;
- iov[3].iov_len = cnt;
-
- TRACE("write %s, offset %Ld, count %d\n", slot->s_buf, off, (int)cnt);
-
- if((res = lu_execute(GET_INFO(f->f_dentry->d_sb), slot, PTYPE_WRITE, iov, 4, NULL, 0)) < 0)
- goto out1;
-
-
- if(PIS_ERROR(res)){
- TRACE("write failed\n");
- res = PERROR(res);
- goto out1;
- }
-
- f->f_dentry->d_inode->i_mtime = f->f_dentry->d_inode->i_atime = CURRENT_TIME;
- if(off + cnt > f->f_dentry->d_inode->i_size)
- f->f_dentry->d_inode->i_size = off + cnt;
-
- res = cnt;
-
- out1:
- kunmap(p);
- unlock_kernel();
- out2:
- lu_putslot(slot);
- TRACE("out\n");
- return res;
-}
-
-static int lu_file_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
-{
- struct dentry *dentry = filp->f_dentry;
- int res;
-
- TRACE("in\n");
-
- if(!(res = lu_revalidate_inode(dentry)))
- res = generic_file_read(filp, buf, count, ppos);
-
- TRACE("out\n");
-
- return res;
-}
-
-static int lu_file_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct dentry *dentry = filp->f_dentry;
- int res;
-
- TRACE("in\n");
-
- if(!(res = lu_revalidate_inode(dentry)))
- res = generic_file_mmap(filp, vma);
-
- TRACE("out\n");
-
- return res;
-}
-
-static ssize_t lu_file_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
-{
- struct dentry *dentry = filp->f_dentry;
- ssize_t res;
-
- TRACE("in\n");
-
- if(!(res = lu_revalidate_inode(dentry)) && (count > 0))
- res = generic_file_write(filp, buf, count, ppos);
-
- TRACE("out\n");
-
- return res;
-}
-
-static int lu_file_fsync(struct file *filp, struct dentry *dentryp, int datasync)
-{
- return 0;
-}
-
-struct file_operations lu_file_operations = {
- .llseek = generic_file_llseek,
- .read = lu_file_read,
- .write = lu_file_write,
- .mmap = lu_file_mmap,
- .open = lu_file_open,
- .release = lu_file_release,
- .fsync = lu_file_fsync,
-};
-
-struct inode_operations lu_file_inode_operations = {
- .setattr = lufs_notify_change,
-};
-
-struct address_space_operations lu_file_aops = {
- .readpage = lu_file_readpage,
- .writepage = lu_file_writepage,
- .prepare_write = lu_file_preparewrite,
- .commit_write = lu_file_commitwrite,
-};
-
-
-
+++ /dev/null
-/*
- * inode.c
- * Copyright (C) 2002-2003 Florin Malita <mali@go.ro>
- *
- * This file is part of LUFS, a free userspace filesystem implementation.
- * See http://lufs.sourceforge.net/ for updates.
- *
- * LUFS 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.
- *
- * LUFS 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
- */
-
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/smp_lock.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/socket.h>
-#include <linux/string.h>
-#include <linux/vfs.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include "lufs.h"
-#include "proc.h"
-
-MODULE_AUTHOR("Florin Malita <mali@go.ro>");
-MODULE_DESCRIPTION("Linux Userland Filesystem");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
-
-extern struct file_operations lu_dir_operations, lu_file_operations;
-extern struct inode_operations lu_dir_inode_operations, lu_file_inode_operations, lu_symlink_inode_operations;
-extern struct address_space_operations lu_file_aops;
-extern struct dentry_operations lufs_dentry_operations;
-
-static void lu_delete_inode(struct inode*);
-static void lu_put_super(struct super_block*);
-static int lu_statfs(struct super_block*, struct kstatfs*);
-
-static struct super_operations lu_sops = {
- .drop_inode = generic_delete_inode,
- .delete_inode = lu_delete_inode,
- .put_super = lu_put_super,
- .statfs = lu_statfs,
-};
-
-
-/*
- * Ignore unknown options, they're probably for the userspace daemon.
- */
-static void parse_options(struct lufs_sb_info *server, char *opts)
-{
- char *p, *q;
- int len;
-
- if(!opts)
- return;
-
- len = strlen(opts);
-
- while((p = strsep(&opts, ","))){
- if(strncmp(p, "server_socket=", 14) == 0){
- if(strlen(p+14) > UNIX_PATH_MAX)
- goto ugly_opts;
- strcpy(server->server_socket, p+14);
- TRACE("server_socket: %s\n", server->server_socket);
- }else
- if(strncmp(p, "uid=", 4) == 0){
- if(current->uid)
- ERROR("only root can use uid option!\n");
- else{
- if(strlen(p+4) > 5)
- goto ugly_opts;
- q = p + 4;
- server->config.uid = simple_strtoul(q, &q, 0);
- TRACE("uid: %d\n", server->config.uid);
- }
- }else
- if(strncmp(p, "gid=", 4) == 0){
- if(current->uid)
- ERROR("only root can use gid option!\n");
- else{
- if(strlen(p+4) > 5)
- goto ugly_opts;
- q = p + 4;
- server->config.gid = simple_strtoul(q, &q, 0);
- TRACE("gid: %d\n", server->config.gid);
- }
- }else
- if(strncmp(p, "fmask=", 6) == 0){
- if(strlen(p + 6) > 3)
- goto ugly_opts;
- q = p + 6;
- server->config.fmode = (((q[0] - '0') << 6) + ((q[1] - '0') << 3) + (q[2] - '0')) & (S_IRWXU | S_IRWXG | S_IRWXO);
- TRACE("fmode: %d\n", server->config.fmode);
- }else
- if(strncmp(p, "dmask=", 6) == 0){
- if(strlen(p + 6) > 3)
- goto ugly_opts;
- q = p + 6;
- server->config.dmode = (((q[0] - '0') << 6) + ((q[1] - '0') << 3) + (q[2] - '0')) & (S_IRWXU | S_IRWXG | S_IRWXO);
- TRACE("dmode: %d\n", server->config.dmode);
- }else
- if(strncmp(p, "root=", 5) == 0){
- if(strlen(p+5) >= UNIX_PATH_MAX - 1)
- goto ugly_opts;
- strcpy(server->root, p+5);
- server->rootlen = strlen(server->root);
-
- if(server->root[server->rootlen - 1] == '/'){
- server->root[server->rootlen - 1] = 0;
- server->rootlen--;
- }
-
- TRACE("remote root: %s, len: %u\n", server->root, server->rootlen);
- }else
- if(strncmp(p, "channels=", 9) == 0){
- if(strlen(p+9) > 5)
- goto ugly_opts;
- q = p + 9;
- server->config.channels = simple_strtoul(q, &q, 0);
-
- TRACE("channels: %u\n", server->config.channels);
- }else
- if(strncmp(p, "own_fs", 6) == 0){
- server->config.own_fs = 1;
- TRACE("forcing ownership\n");
- }else
- if(strncmp(p, "server_pid=", 11) == 0){
- if(strlen(p+11) > 7)
- goto ugly_opts;
- q = p + 11;
- server->server_pid = simple_strtoul(q, &q, 0);
-
- TRACE("server_pid: %u\n", server->server_pid);
- }
- }
-
- return;
-
- ugly_opts:
- WARN("evil options!\n");
-}
-
-/*
- * Fill in inode attributes.
- * Ivalidate the page_cache pages if the inode has been modified.
- */
-static void set_inode_attr(struct inode *inode, struct lufs_fattr *fattr)
-{
- time_t last_time = inode->i_mtime.tv_sec;
- loff_t last_sz = inode->i_size;
-
- TRACE("in\n");
-
- inode->i_mode = fattr->f_mode;
- inode->i_nlink = fattr->f_nlink;
- inode->i_uid = fattr->f_uid;
- inode->i_gid = fattr->f_gid;
- inode->i_ctime.tv_sec = fattr->f_ctime;
- inode->i_mtime.tv_sec = fattr->f_mtime;
- inode->i_atime.tv_sec = fattr->f_atime;
- inode->i_blksize = fattr->f_blksize;
- inode->i_blocks = fattr->f_blocks;
- inode->i_size = fattr->f_size;
-
- if(inode->i_mtime.tv_sec != last_time || inode->i_size != last_sz){
- TRACE("inode changed...\n");
- if(!S_ISDIR(inode->i_mode))
- invalidate_inode_pages(inode->i_mapping);
- }
-
- TRACE("out\n");
-}
-
-static int lu_do_stat(struct dentry *dentry, struct lufs_fattr *fattr)
-{
- struct server_slot *slot;
- struct iovec siov, riov;
- int res;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
- return -ERESTARTSYS;
-
- if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- TRACE("stating %s...\n", slot->s_buf);
-
- siov.iov_base = slot->s_buf;
- siov.iov_len = strlen(slot->s_buf) + 1;
- riov.iov_base = fattr;
- riov.iov_len = sizeof(struct lufs_fattr);
-
- if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- WARN("stat failed!\n");
- res = PERROR(res);
- goto out;
- }
-
- lu_fixattrs(GET_INFO(dentry->d_sb), fattr);
-
- res = 0;
-
- out:
- TRACE("out\n");
- lu_putslot(slot);
- return res;
-}
-
-/*
- * Reload inode attributes.
- */
-static int lu_refresh_inode(struct dentry *dentry)
-{
- struct inode *inode = dentry->d_inode;
- struct lufs_fattr fattr;
- int res;
-
- TRACE("in\n");
-
- if((res = lu_do_stat(dentry, &fattr)) < 0)
- return res;
-
- dentry->d_time = jiffies;
-
- if(!inode)
- return 0;
-
- if((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT))
- set_inode_attr(inode, &fattr);
- else{
- WARN("inode changed mode, %x to %x\n", inode->i_mode, (unsigned int)fattr.f_mode);
- TRACE("oops!\n");
-
- fattr.f_mode = inode->i_mode;
- make_bad_inode(inode);
- inode->i_mode = fattr.f_mode;
-
- if(!S_ISDIR(inode->i_mode))
- invalidate_inode_pages(inode->i_mapping);
-
- return -EIO;
- }
-
- TRACE("out\n");
- return 0;
-}
-
-int lu_revalidate_inode(struct dentry *dentry)
-{
- int res = 0;
-
- TRACE("in\n");
-
- lock_kernel();
-
- if(time_before(jiffies, dentry->d_time + LU_MAXAGE))
- goto out;
-
- res = lu_refresh_inode(dentry);
-
- out:
- TRACE("out\n");
- unlock_kernel();
- return res;
-}
-
-int lufs_notify_change(struct dentry *dentry, struct iattr *iattr)
-{
- struct server_slot *slot;
- struct iovec iov[2];
- struct lufs_fattr fattr;
- int res;
-
- TRACE("in\n");
-
- if((res = lu_do_stat(dentry, &fattr)) < 0)
- return res;
-
- if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
- return -ERESTARTSYS;
-
- if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- if(iattr->ia_valid & ATTR_MODE)
- fattr.f_mode = iattr->ia_mode;
- if(iattr->ia_valid & ATTR_UID)
- fattr.f_uid = iattr->ia_uid;
- if(iattr->ia_valid & ATTR_GID)
- fattr.f_gid = iattr->ia_gid;
- if(iattr->ia_valid & ATTR_SIZE)
- fattr.f_size = iattr->ia_size;
- if(iattr->ia_valid & ATTR_ATIME)
- fattr.f_atime= iattr->ia_atime.tv_sec;
- if(iattr->ia_valid & ATTR_MTIME)
- fattr.f_mtime= iattr->ia_mtime.tv_sec;
- if(iattr->ia_valid & ATTR_CTIME)
- fattr.f_ctime= iattr->ia_ctime.tv_sec;
-
- iov[0].iov_base = &fattr;
- iov[0].iov_len = sizeof(struct lufs_fattr);
- iov[1].iov_base = slot->s_buf;
- iov[1].iov_len = strlen(slot->s_buf) + 1;
-
- if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_SETATTR, iov, 2, NULL, 0)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- WARN("setattr failed!\n");
- res = PERROR(res);
- goto out;
- }
-
- res = 0;
-
- lu_refresh_inode(dentry);
-
- out:
- TRACE("out\n");
- lu_putslot(slot);
- return res;
-}
-
-/*
- * We always create a new inode here.
- */
-struct inode* lu_iget(struct super_block *sb, struct lufs_fattr *fattr)
-{
- struct inode *res;
-
- TRACE("in\n");
-
- res = new_inode(sb);
- if(!res)
- return NULL;
- res->i_ino = fattr->f_ino;
- set_inode_attr(res, fattr);
-
- if(S_ISDIR(res->i_mode)){
- TRACE("it's a dir.\n");
- res->i_op = &lu_dir_inode_operations;
- res->i_fop = &lu_dir_operations;
- }else if(S_ISLNK(res->i_mode)){
- TRACE("it's a link.\n");
- res->i_op = &lu_symlink_inode_operations;
- }else{
- TRACE("it's a file.\n");
- res->i_op = &lu_file_inode_operations;
- res->i_fop = &lu_file_operations;
- res->i_data.a_ops = &lu_file_aops;
- }
-
- insert_inode_hash(res);
- return res;
-}
-
-static int lu_statfs(struct super_block *sb, struct kstatfs *attr)
-{
- int res;
- struct iovec riov;
- struct server_slot *slot;
- struct lufs_sbattr sbattr;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(sb))) == NULL)
- return -ERESTARTSYS;
-
- riov.iov_base = &sbattr;
- riov.iov_len = sizeof(sbattr);
-
- if((res = lu_execute(GET_INFO(sb), slot, PTYPE_STATFS, NULL, 0, &riov, 1)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- WARN("statfs failed\n");
- res = PERROR(res);
- goto out;
- }
-
- attr->f_type = LU_MAGIC;
- attr->f_bsize = LU_BLOCKSIZE;
- attr->f_blocks = sbattr.sb_bytes / LU_BLOCKSIZE;
- attr->f_bfree = sbattr.sb_bytes_free / LU_BLOCKSIZE;
- attr->f_bavail = sbattr.sb_bytes_available / LU_BLOCKSIZE;
- attr->f_files = sbattr.sb_files;
- attr->f_ffree = sbattr.sb_ffree;
- attr->f_namelen = 0xFF;
-
- res = 0;
-
- out:
- TRACE("out\n");
- lu_putslot(slot);
- return res;
-}
-
-static void lu_put_super(struct super_block *sb)
-{
- struct siginfo info;
-
- TRACE("in\n");
-
- info.si_signo = SIGUSR1;
- info.si_errno = 0;
- info.si_code = SI_USER;
- info.si_pid = current->pid;
- info.si_uid = current->uid;
-
- /* notify the daemon that we're going bye-bye */
- kill_proc_info(SIGUSR1, &info, GET_INFO(sb)->server_pid);
-
- lu_empty_slots(GET_INFO(sb));
- kfree(GET_INFO(sb));
- TRACE("out\n");
-}
-
-static void lu_delete_inode(struct inode *in)
-{
- TRACE("in\n");
- clear_inode(in);
- TRACE("out\n");
-}
-
-static int lu_fill_super(struct super_block *sb, void *opts, int silent)
-{
- struct lufs_sb_info *info;
- struct server_slot *slot;
- struct lufs_fattr root_attr;
- struct inode *root_inode;
-
- int i;
-
- TRACE("in\n");
-
- if(!opts){
- ERROR("need some options here!\n");
- goto out;
- }
-
- if((info = (struct lufs_sb_info*)kmalloc(sizeof(struct lufs_sb_info), GFP_KERNEL)) == NULL){
- ERROR("kmalloc error!\n");
- goto out;
- }
- memset(info, 0, sizeof(struct lufs_sb_info));
- info->lock = RW_LOCK_UNLOCKED;
- INIT_LIST_HEAD(&info->slots);
-
- info->config.uid = current->uid;
- info->config.gid = current->gid;
- info->config.channels = LU_NRSLOTS;
-
- parse_options(info, opts);
-
- if(!info->server_socket[0]){
- ERROR("no server_socket specified!\n");
- goto out_info;
- }
-
- for(i = 0; i < info->config.channels; i++){
- if((slot = kmalloc(sizeof(struct server_slot), GFP_KERNEL)) == NULL){
- ERROR("kmalloc error!\n");
- goto out_slots;
- }
- memset(slot, 0, sizeof(struct server_slot));
- init_MUTEX(&slot->s_lock);
- if((slot->s_buf = kmalloc(LU_MAXDATA, GFP_KERNEL)) == NULL){
- ERROR("kmalloc error!\n");
- goto out_slots;
- }
- list_add(&slot->s_list, &info->slots);
- }
-
- sb->s_fs_info = info;
- sb->s_blocksize = LU_BLOCKSIZE;
- sb->s_blocksize_bits = LU_BLOCKSIZEBITS;
- sb->s_magic = LU_MAGIC;
- sb->s_op = &lu_sops;
- sb->s_flags = 0;
- sb->s_maxbytes = ((((long long)1) << 32) << LU_BLOCKSIZEBITS) - 1;
- TRACE("sb->s_maxbytes=%Ld\n",sb->s_maxbytes);
-
- lu_lookup_root(info, &root_attr);
- root_inode = lu_iget(sb, &root_attr);
- if(!root_inode)
- goto out_slots;
- sb->s_root = d_alloc_root(root_inode);
- if(!sb->s_root)
- goto out_slots;
-
- sb->s_root->d_op = &lufs_dentry_operations;
- sb->s_root->d_time = jiffies;
-
- TRACE("mount succeded: %s\n", info->server_socket);
- return 0;
-
- out_slots:
- lu_empty_slots(info);
- out_info:
- kfree(info);
- out:
- ERROR("mount failed!\n");
- return -EINVAL;
-}
-
-static struct super_block *lu_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
-{
- return get_sb_nodev(fs_type, flags, data, lu_fill_super);
-}
-
-static struct file_system_type lu_fs_type = {
- .owner = THIS_MODULE,
- .name = "lufs",
- .get_sb = lu_get_sb,
- .kill_sb = kill_anon_super,
-};
-
-static int __init lu_init(void)
-{
- VERBOSE("UserLand File System\n");
- VERBOSE("Copyright (c) 2002, Florin Malita\n");
- return register_filesystem(&lu_fs_type);
-}
-
-static void __exit lu_release(void)
-{
- VERBOSE("Unregistering lufs...\n");
- unregister_filesystem(&lu_fs_type);
-}
-
-module_init(lu_init);
-module_exit(lu_release);
+++ /dev/null
-/*
- * lufs.h
- * Copyright (C) 2002 Florin Malita <mali@go.ro>
- *
- * This file is part of LUFS, a free userspace filesystem implementation.
- * See http://lufs.sourceforge.net/ for updates.
- *
- * LUFS 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.
- *
- * LUFS 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
- */
-
-#ifndef _LUFS_H_
-#define _LUFS_H_
-
-#include <linux/list.h>
-#include <linux/un.h>
-#include <linux/spinlock.h>
-
-#include "proto.h"
-
-#undef TRACE
-#undef WARN
-#undef VERBOSE
-#undef ERROR
-
-#ifdef LUFS_DEBUG
-#define TRACE(x...) do { printk(KERN_INFO "(%s) - ", __func__); printk(x); } while(0)
-#define WARN(x...) do { printk(KERN_ERR "(%s) - ", __func__); printk(x); } while(0)
-#else
-#define TRACE(x...) do {} while(0)
-#define WARN(x...) do {} while(0)
-#endif
-
-#ifdef LUFS_VERBOSE
-#define VERBOSE(x...) do { printk(KERN_INFO "(%s) - ", __func__); printk(x); } while(0)
-#else
-#define VERBOSE(x...) do {} while(0)
-#endif
-
-#define ERROR(x...) do { printk(KERN_ERR "(%s) - ", __func__); printk(x); } while(0)
-
-#define GET_INFO(sb) ((struct lufs_sb_info*)sb->s_fs_info)
-
-#define LU_MAXPATHLEN 1024
-#define LU_MAXTRIES 10
-#define LU_MAXIOVEC 5
-#define LU_NRSLOTS 3
-#define LU_MAGIC 0xfade
-#define LU_MAXAGE HZ*5
-
-#define LU_DEF_UID 2
-#define LU_DEF_GID 2
-
-#define LU_BLOCKSIZE 512
-#define LU_BLOCKSIZEBITS 9
-
-struct lufs_config{
- __kernel_uid_t uid;
- __kernel_gid_t gid;
- __kernel_mode_t fmode;
- __kernel_mode_t dmode;
- unsigned channels;
- int own_fs;
-};
-
-struct lufs_sb_info{
- struct list_head slots;
- struct lufs_config config;
- rwlock_t lock;
- char server_socket[UNIX_PATH_MAX];
- pid_t server_pid;
- char root[UNIX_PATH_MAX];
- unsigned rootlen;
-};
-
-#endif
+++ /dev/null
-/*
- * proc.c
- * Copyright (C) 2002 Florin Malita <mali@go.ro>
- *
- * This file is part of LUFS, a free userspace filesystem implementation.
- * See http://lufs.sourceforge.net/ for updates.
- *
- * LUFS 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.
- *
- * LUFS 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
- */
-
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/socket.h>
-#include <linux/un.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/smp_lock.h>
-#include <linux/net.h>
-#include <linux/vfs.h>
-#include <linux/mount.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include "lufs.h"
-#include "proc.h"
-
-static int sock_send(struct socket *sock, struct iovec *iov, int len)
-{
- struct msghdr msg = {
- .msg_name = NULL,
- .msg_namelen = 0,
- .msg_iov = iov,
- .msg_iovlen = len,
- .msg_control = NULL,
- .msg_controllen = 0,
- .msg_flags = 0
- };
- int res, i, size;
- mm_segment_t fs;
-
- for(i = 0, size = 0; i < len; i++)
- size += iov[i].iov_len;
-
- fs = get_fs();
- set_fs(get_ds());
- res = sock_sendmsg(sock, &msg, size);
- set_fs(fs);
-
- return res;
-}
-
-static int sock_recv(struct socket *sock, struct iovec *iov, int len, int rsize, unsigned flags)
-{
- struct msghdr msg = {
- .msg_flags = flags,
- .msg_name = NULL,
- .msg_namelen = 0,
- .msg_iov = iov,
- .msg_iovlen = len,
- .msg_control = NULL,
- .msg_controllen = 0
- };
- mm_segment_t fs;
- int res, i, size;
-
- for(i = 0, size = 0; i < len; i++)
- size += iov[i].iov_len;
-
- if(size < rsize){
- VERBOSE("Trying to overflow old me?! Truncating...\n");
- rsize = size;
- }
-
- fs = get_fs();
- set_fs(get_ds());
- res = sock_recvmsg(sock, &msg, rsize, flags);
- set_fs(fs);
-
- return res;
-}
-
-static int sock_connect(char *path, struct socket **s)
-{
- struct sockaddr_un addr;
- int res;
-
- if(strlen(path) > UNIX_PATH_MAX - 1){
- WARN("unix domain path too long: %s", path);
- return -1;
- }
-
- addr.sun_family = AF_UNIX;
- strcpy(addr.sun_path, path);
-
- if((res = sock_create(PF_UNIX, SOCK_STREAM, 0, s)) < 0){
- WARN("failed to create a unix domain socket!\n");
- return res;
- }
-
- if((res = (*s)->ops->connect(*s, (struct sockaddr*)&addr, sizeof(addr), 0)) < 0){
- WARN("failed to connect the socket: %d!\n", res);
- return res;
- }
- return 0;
-}
-
-static int slot_reconnect(struct lufs_sb_info *info, struct server_slot *slot)
-{
- int res = 0, tries = 0;
-
- if(slot->s_sock){
- TRACE("closing socket.\n");
- sock_release(slot->s_sock);
- slot->s_sock = NULL;
- }
-
- while(tries++ < LU_MAXTRIES && (res = sock_connect(info->server_socket, &slot->s_sock)) < 0){
- TRACE("retrying...\n");
- sock_release(slot->s_sock);
- slot->s_sock = NULL;
- }
-
- if(res >= 0){
- TRACE("successfully reconnected.\n");
- }
-
- return res;
-}
-
-void lu_empty_slots(struct lufs_sb_info *info)
-{
- struct server_slot *slot;
-
- while(!list_empty(&info->slots)){
- slot = list_entry(info->slots.next, struct server_slot, s_list);
- if(slot->s_sock)
- sock_release(slot->s_sock);
- list_del(&slot->s_list);
- if(slot->s_buf)
- kfree(slot->s_buf);
- kfree(slot);
- }
-}
-
-static int do_execute(struct socket *sock, unsigned short cmd, unsigned short msglen, struct iovec *siov, unsigned short slen, struct iovec *riov, unsigned short rlen)
-{
- struct lu_msg msg;
- struct iovec iov;
- int res;
-
- TRACE("msg_len: %d\n", msglen);
-
- msg.msg_version = PVERSION;
- msg.msg_type = cmd;
- msg.msg_datalen = msglen;
- msg.msg_pid = current->pid;
-
- iov.iov_base = &msg;
- iov.iov_len = sizeof(struct lu_msg);
-
- if((res = sock_send(sock, &iov, 1)) < 0){
- WARN("sock_send failed!\n");
- return res;
- }
- if((res = sock_send(sock, siov, slen)) < 0){
- WARN("sock_send failed!\n");
- return res;
- }
-
- iov.iov_base = &msg;
- iov.iov_len = sizeof(struct lu_msg);
- if((res = sock_recv(sock, &iov, 1, sizeof(struct lu_msg), 0)) < 0){
- WARN("sock_recv failed!\n");
- return res;
- }
- if(res != sizeof(struct lu_msg)){
- WARN("Ayeeee, didn't read a whole header!\n");
- return -EBUSY;
- }
-
- if((msg.msg_datalen == 0))
- return msg.msg_type;
-
- if(riov == NULL){
- WARN("Unexpected data!!! Getting out of sync...\n");
- return -1;
- }
-
- if((res = sock_recv(sock, riov, rlen, msg.msg_datalen, 0)) < 0){
- WARN("sock_recv failed!\n");
- return res;
- }
-
- return msg.msg_type;
-}
-
-struct server_slot* lu_getslot(struct lufs_sb_info *info)
-{
- struct list_head *p, *nd_best = NULL;
- struct server_slot *slot;
- int gotlock = 0;
-
- /* Look for a slot used by this process before */
- read_lock(&info->lock);
- list_for_each(p, &info->slots)
- if(list_entry(p, struct server_slot, s_list)->s_lastpid == current->pid){
- TRACE("found a previous used slot for %u.\n", current->pid);
- if(down_trylock(&list_entry(p, struct server_slot, s_list)->s_lock) == 0){
- gotlock = 1;
- break;
- }
- TRACE("oops! I still hold the lock! forget this one...\n");
- }else
- if(!nd_best){
- nd_best = p;
- }
-
- /* if we couldn't find one, take the first not locked by us */
- if(p == &info->slots){
- if(!nd_best){
- ERROR("deadlock: all locks owned by us!\n");
- read_unlock(&info->lock);
- return NULL;
- }else
- p = nd_best;
-
- }
- read_unlock(&info->lock);
-
- slot = list_entry(p, struct server_slot, s_list);
-
- /* Get the lock on that slot */
- if(!gotlock)
- if(down_interruptible(&slot->s_lock))
- return NULL;
-
- slot->s_lastpid = current->pid;
-
- /* Move it to the tail */
- write_lock(&info->lock);
- list_del(p);
- list_add_tail(p, &info->slots);
- write_unlock(&info->lock);
-
- return slot;
-}
-
-void lu_putslot(struct server_slot *slot)
-{
- up(&slot->s_lock);
-}
-
-int lu_execute(struct lufs_sb_info *info, struct server_slot *slot, unsigned short cmd, struct iovec *siov, unsigned short slen, struct iovec *riov, unsigned short rlen)
-{
- int res, i, msglen;
- struct iovec bkup[LU_MAXIOVEC];
-
- for(i = 0, msglen = 0; i < slen; i++){
- bkup[i] = siov[i];
- msglen += siov[i].iov_len;
- }
-
- if(slot->s_sock == NULL){
- TRACE("slot not connected.\n");
- if((res = slot_reconnect(info, slot)) < 0){
- ERROR("failed to connect!\n");
- goto out;
- }
- }
-
- if((res = do_execute(slot->s_sock, cmd, msglen, siov, slen, riov, rlen)) < 0){
- TRACE("do_execute failed!\n");
-
- if(signal_pending(current) && (!sigismember(¤t->pending.signal, SIGPIPE))){
- TRACE("interrupted by a signal. disconnecting this slot...\n");
- sock_release(slot->s_sock);
- slot->s_sock = NULL;
- goto out;
- }
-
- if(sigismember(¤t->pending.signal, SIGPIPE)){
- TRACE("got a SIGPIPE\n");
- sigdelset(¤t->pending.signal, SIGPIPE);
- }
-
- if((res = slot_reconnect(info, slot)) < 0){
- ERROR("could't reconnect!\n");
- goto out;
- }
-
- for(i = 0; i < slen; i++)
- siov[i] = bkup[i];
-
- if((res = do_execute(slot->s_sock, cmd, msglen, siov, slen, riov, rlen)) < 0){
- ERROR("error executing command!\n");
- goto out;
- }
- }
-
- out:
- return res;
-}
-
-int lu_getname(struct dentry *d, char *name, int max)
-{
- int len = 0;
- struct dentry *p;
- struct lufs_sb_info *info = GET_INFO(d->d_sb);
-
- for(p = d; p != p->d_parent; p = p->d_parent)
- len += p->d_name.len + 1;
-
- TRACE("root: %s, rootlen: %d, namelen: %d\n", info->root, info->rootlen, len);
-
- if(len + info->rootlen > max)
- return -1;
-
- strcpy(name, info->root);
-
- if(len + info->rootlen == 0){
- strcat(name, "/");
- goto out;
- }
-
- len += info->rootlen;
-
- name[len] = 0;
- for(p = d; p != p->d_parent; p = p->d_parent){
- len -= p->d_name.len;
- strncpy(&(name[len]), p->d_name.name, p->d_name.len);
- name[--len] = '/';
- }
-
-out:
- TRACE("name resolved to %s\n", name);
- return 0;
-}
-
-int lu_getname_dumb(struct dentry *d, char *name, int max)
-{
- int len = 0;
- struct dentry *p;
-
- for(p = d; p != p->d_parent; p = p->d_parent)
- len += p->d_name.len + 1;
-
- if(len > max)
- return -1;
-
- if(len == 0){
- name[0] = '/';
- name[1] = 0;
- goto out;
- }
-
- name[len] = 0;
- for(p = d; p != p->d_parent; p = p->d_parent){
- len -= p->d_name.len;
- strncpy(&(name[len]), p->d_name.name, p->d_name.len);
- name[--len] = '/';
- }
-
-out:
- return 0;
-}
-
-static void init_root_dirent(struct lufs_sb_info *server, struct lufs_fattr *fattr)
-{
- memset(fattr, 0, sizeof(struct lufs_fattr));
- fattr->f_nlink = 1;
- fattr->f_uid = server->config.uid;
- fattr->f_gid = server->config.gid;
- fattr->f_blksize = 512;
- fattr->f_ino = 2;
- fattr->f_mtime = CURRENT_TIME.tv_sec;
- fattr->f_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH | S_IFDIR | server->config.dmode;
- fattr->f_size = 512;
- fattr->f_blocks = 1;
-}
-
-void lu_lookup_root(struct lufs_sb_info *server, struct lufs_fattr *fattr)
-{
- struct server_slot *slot;
- struct iovec siov, riov;
- int res;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(server)) == NULL){
- init_root_dirent(server, fattr);
- return;
- }
-
- if(server->rootlen)
- strcpy(slot->s_buf, server->root);
- else
- strcpy(slot->s_buf, "/");
-
- TRACE("stating root %s\n", slot->s_buf);
-
- siov.iov_base = slot->s_buf;
- siov.iov_len = strlen(slot->s_buf) + 1;
- riov.iov_base = fattr;
- riov.iov_len = sizeof(struct lufs_fattr);
-
- if((res = lu_execute(server, slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0){
- init_root_dirent(server, fattr);
- goto out;
- }
-
- if(PIS_ERROR(res)){
- WARN("stat failed!\n");
- init_root_dirent(server, fattr);
- goto out;
- }
-
- lu_fixattrs(server, fattr);
-
- fattr->f_ino = 2;
-
- out:
- TRACE("out\n");
- lu_putslot(slot);
-}
-
-void lu_fixattrs(struct lufs_sb_info *info, struct lufs_fattr *fattr)
-{
-
- fattr->f_blksize = LU_BLOCKSIZE;
-
- if(S_ISREG(fattr->f_mode) || S_ISDIR(fattr->f_mode))
- fattr->f_blocks = (fattr->f_size + LU_BLOCKSIZE - 1) / LU_BLOCKSIZE;
- else
- fattr->f_blocks = 0;
-
- if(info->config.own_fs){
-
- if(!fattr->f_uid)
- fattr->f_mode = (fattr->f_mode & ~S_IRWXU) | ((fattr->f_mode & S_IRWXO)*(S_IRWXU/S_IRWXO));
-
- if(!fattr->f_gid)
- fattr->f_mode = (fattr->f_mode & ~S_IRWXG) | ((fattr->f_mode & S_IRWXO)*(S_IRWXG/S_IRWXO));
-
- fattr->f_uid = info->config.uid;
- fattr->f_gid = info->config.gid;
-
- }else{
-
- if(fattr->f_uid)
- fattr->f_uid = info->config.uid;
- else
- fattr->f_uid = LU_DEF_UID;
-
- if(fattr->f_gid)
- fattr->f_gid = info->config.gid;
- else
- fattr->f_gid = LU_DEF_GID;
- }
-
- if(fattr->f_mode & S_IFDIR)
- fattr->f_mode |= info->config.dmode;
- else
- fattr->f_mode |= info->config.fmode;
-}
-
-void lu_xlate_symlink(char *link, char *target, char *buf)
-{
- int i;
- char *c1, *c2 = link;
-
- TRACE("translating %s->%s\n", link, target);
-
- for(c1 = strchr(link, '/'); c1 && !strncmp(link, target, c1 - link); c2 = c1, c1 = strchr(c1 + 1, '/'));
-
- TRACE("disjoint paths: %s, %s\n", c2, target + (c2 - link));
-
- for(i = 0, c1 = c2; (c1 = strchr(c1 + 1, '/')); i++);
-
- strcpy(buf, "./");
-
- for(; i > 0; i--)
- strcat(buf, "../");
-
- strcat(buf, target + (c2 - link) + 1);
-
- TRACE("absolute link resolved to %s\n", buf);
-
-}
-
+++ /dev/null
-/*
- * proc.h
- * Copyright (C) 2002 Florin Malita <mali@go.ro>
- *
- * This file is part of LUFS, a free userspace filesystem implementation.
- * See http://lufs.sourceforge.net/ for updates.
- *
- * LUFS 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.
- *
- * LUFS 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
- */
-
-#ifndef _LU_PROC_H_
-#define _LU_PROC_H_
-
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/socket.h>
-
-struct server_slot{
- struct socket *s_sock;
- struct semaphore s_lock;
- struct list_head s_list;
- pid_t s_lastpid;
- char *s_buf;
-};
-
-struct lufs_fattr;
-
-int lu_execute(struct lufs_sb_info*, struct server_slot*, unsigned short, struct iovec*, unsigned short, struct iovec*, unsigned short);
-void lu_empty_slots(struct lufs_sb_info*);
-int lu_getname(struct dentry*, char*, int);
-int lu_getname_dumb(struct dentry*, char*, int);
-struct server_slot* lu_getslot(struct lufs_sb_info*);
-void lu_putslot(struct server_slot*);
-int lu_revalidate_inode(struct dentry*);
-void lu_lookup_root(struct lufs_sb_info*, struct lufs_fattr*);
-void lu_fixattrs(struct lufs_sb_info*, struct lufs_fattr*);
-void lu_xlate_symlink(char*, char*, char*);
-
-#endif
+++ /dev/null
-/*
- * symlink.c
- * Copyright (C) 2002 Florin Malita <mali@go.ro>
- *
- * This file is part of LUFS, a free userspace filesystem implementation.
- * See http://lufs.sourceforge.net/ for updates.
- *
- * LUFS 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.
- *
- * LUFS 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
- */
-
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/socket.h>
-#include <linux/smp_lock.h>
-#include <linux/fs.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-
-#include "lufs.h"
-#include "proc.h"
-
-static char failed_link[] = "invalid";
-
-static int lu_readlink(struct dentry *dentry, char *buffer, int bufflen)
-{
- struct server_slot *slot;
- struct iovec siov, riov;
- int res;
- char *cc = failed_link;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
- return vfs_readlink(dentry, buffer, bufflen, cc);
-
- if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- siov.iov_base = slot->s_buf;
- siov.iov_len = strlen(slot->s_buf) + 1;
- riov.iov_base = &slot->s_buf[LU_MAXPATHLEN];
- riov.iov_len = LU_MAXPATHLEN;
-
- if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_READLINK, &siov, 1, &riov, 1)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("read_link failed.\n");
- res = PERROR(res);
- goto out;
- }
-
- cc = &slot->s_buf[LU_MAXPATHLEN];
-
- TRACE("response: %s\n", cc);
-
- if(*cc == '/'){
- if(GET_INFO(dentry->d_sb)->rootlen){
- if(strncmp(GET_INFO(dentry->d_sb)->root, cc, GET_INFO(dentry->d_sb)->rootlen)){
- WARN("symlink outside mounted root!");
- cc = failed_link;
- goto out;
- }
- cc += GET_INFO(dentry->d_sb)->rootlen;
- }
-
- lu_xlate_symlink(slot->s_buf, slot->s_buf + LU_MAXPATHLEN, slot->s_buf);
-
- cc = slot->s_buf;
-
- }
-
-
-
- out:
- res = vfs_readlink(dentry, buffer, bufflen, cc);
-
- lu_putslot(slot);
-
- TRACE("out\n");
- return res;
-}
-
-static int lu_followlink(struct dentry *dentry, struct nameidata *nd)
-{
- struct server_slot *slot;
- struct iovec siov, riov;
- int res;
- char *cc = failed_link;
- char *tmp;
-
- TRACE("in\n");
-
- if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
- return vfs_follow_link(nd, cc);
-
-
- if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
- WARN("lu_getname failed!\n");
- goto out;
- }
-
- siov.iov_base = slot->s_buf;
- siov.iov_len = strlen(slot->s_buf) + 1;
- riov.iov_base = &slot->s_buf[LU_MAXPATHLEN];
- riov.iov_len = LU_MAXPATHLEN;
-
- if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_READLINK, &siov, 1, &riov, 1)) < 0)
- goto out;
-
- if(PIS_ERROR(res)){
- TRACE("read_link failed.\n");
- res = PERROR(res);
- goto out;
- }
-
- cc = &slot->s_buf[LU_MAXPATHLEN];
-
- if(*cc == '/'){
- if(GET_INFO(dentry->d_sb)->rootlen){
- if(strncmp(GET_INFO(dentry->d_sb)->root, cc, GET_INFO(dentry->d_sb)->rootlen)){
- WARN("symlink outside mounted root!");
- cc = failed_link;
- goto out;
- }
- cc += GET_INFO(dentry->d_sb)->rootlen;
- }
-
- lu_xlate_symlink(slot->s_buf, slot->s_buf + LU_MAXPATHLEN, slot->s_buf);
-
- cc = slot->s_buf;
-
- }
-
- out:
-
- /* vfs_follow_link somehow manages to call lookup_validate, so we need to
- release the slot, in case it's the only one, otherwise lu_lookup will
- fail (avoid a deadlock). bad, bad vfs_follow_link! you break the overall
- beauty of no kmallocs... */
-
- if((tmp = kmalloc(strlen(cc) + 1, GFP_KERNEL)) == NULL){
- WARN("out of mem!\n");
- tmp = failed_link;
- }else
- strcpy(tmp, cc);
-
- lu_putslot(slot);
- res = vfs_follow_link(nd, tmp);
-
- if(tmp != failed_link)
- kfree(tmp);
-
- TRACE("out\n");
- return res;
-}
-
-struct inode_operations lu_symlink_inode_operations = {
- .readlink = lu_readlink,
- .follow_link = lu_followlink,
-};
-
-
-
-
-
static int lu_readdir(struct file*, void*, filldir_t);
-static struct dentry *lu_lookup(struct inode*, struct dentry*);
+static struct dentry *lu_lookup(struct inode*, struct dentry*, struct nameidata *);
static int lu_mkdir(struct inode*, struct dentry*, int);
-static int lu_create(struct inode*, struct dentry*, int);
+static int lu_create(struct inode*, struct dentry*, int, struct nameidata *);
static int lu_rmdir(struct inode*, struct dentry*);
static int lu_rename(struct inode*, struct dentry*, struct inode*, struct dentry*);
static int lu_unlink(struct inode*, struct dentry*);
.setattr = lufs_notify_change,
};
-static int lu_lookup_validate(struct dentry *dentry, int flags)
+static int lu_lookup_validate(struct dentry *dentry, struct nameidata *nd)
{
struct inode *inode = dentry->d_inode;
unsigned long age = jiffies - dentry->d_time;
return res;
}
-static struct dentry* lu_lookup(struct inode *dir, struct dentry *dentry)
+static struct dentry* lu_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
{
int res;
struct lufs_fattr fattr;
return res;
}
-static int lu_create(struct inode *dir, struct dentry *dentry, int mode)
+static int lu_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
{
int res;
struct server_slot *slot;
static void lu_delete_inode(struct inode*);
static void lu_put_super(struct super_block*);
-static int lu_statfs(struct super_block*, struct statfs*);
+static int lu_statfs(struct super_block*, struct kstatfs*);
static struct super_operations lu_sops = {
.drop_inode = generic_delete_inode,
return res;
}
-static int lu_statfs(struct super_block *sb, struct statfs *attr)
+static int lu_statfs(struct super_block *sb, struct kstatfs *attr)
{
+ int res;
+ struct iovec riov;
+ struct server_slot *slot;
+ struct lufs_sbattr sbattr;
+
TRACE("in\n");
+ if((slot = lu_getslot(GET_INFO(sb))) == NULL)
+ return -ERESTARTSYS;
+
+ riov.iov_base = &sbattr;
+ riov.iov_len = sizeof(sbattr);
+
+ if((res = lu_execute(GET_INFO(sb), slot, PTYPE_STATFS, NULL, 0, &riov, 1)) < 0)
+ goto out;
+
+ if(PIS_ERROR(res)){
+ WARN("statfs failed\n");
+ res = PERROR(res);
+ goto out;
+ }
+
attr->f_type = LU_MAGIC;
attr->f_bsize = LU_BLOCKSIZE;
- attr->f_blocks = 0;
- attr->f_namelen = LU_MAXPATHLEN;
- attr->f_files = -1;
- attr->f_bavail = -1;
+ attr->f_blocks = sbattr.sb_bytes / LU_BLOCKSIZE;
+ attr->f_bfree = sbattr.sb_bytes_free / LU_BLOCKSIZE;
+ attr->f_bavail = sbattr.sb_bytes_available / LU_BLOCKSIZE;
+ attr->f_files = sbattr.sb_files;
+ attr->f_ffree = sbattr.sb_ffree;
+ attr->f_namelen = 0xFF;
+
+ res = 0;
+ out:
TRACE("out\n");
- return 0;
+ lu_putslot(slot);
+ return res;
}
static void lu_put_super(struct super_block *sb)
return -EINVAL;
}
-static struct super_block *lu_get_sb(struct file_system_type *fs_type, int flags, char *dev_name, void *data)
+static struct super_block *lu_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
{
return get_sb_nodev(fs_type, flags, data, lu_fill_super);
}
#include <linux/un.h>
#include <linux/spinlock.h>
-#include "../../../include/lufs/proto.h"
+#include "proto.h"
#undef TRACE
#undef WARN
-SUBDIRS = 2.4 2.5 modbin
+SUBDIRS = 2.4 2.6 modbin
EXTRA_DIST=prepmod.in
$basedir=~s#\$\Q{prefix}\E#'@prefix@';#ge;
$vardir=~s#\$\Q{prefix}\E#'@prefix@';#ge;
$vardir="" if $vardir=~/^@/;
-sub srcdir { my($uname_r)=@_; $basedir."/".($uname_r lt "2.5" ? "2.4" : "2.5"); }
+sub srcdir { my($uname_r)=@_; $basedir."/".($uname_r lt "2.5" ? "2.4" : "2.6"); }
my $modbindir=$basedir."/modbin";
my @sources=qw(proc.c inode.c dir.c file.c symlink.c);
." ".$kdebug
." ".$kernel_gcc_args
." -I$kernel/include"
- ." -I$kernel/include/asm-i386/mach-default"; # gcc should not care if this 2.5 dir does not exist
+ ." -I$kernel/include/asm-i386/mach-default"; # gcc should not care if this 2.6 dir does not exist
my $config=_readfile "$kernel/.config","optional";
my $autoconf=_readfile "$kernel/include/linux/autoconf.h","optional";