VFS MODULES: hardlink_on_move & copy_on_write
Stefan Metzmacher
metze at metzemix.de
Thu Oct 9 13:29:17 GMT 2003
Hi,
I don't remember who was asking for harlink_on_move VFS module...
(please send me a note...)
Here're some vfs modules:
hardlink_on_move:
overloads the rename function with the link function
copy_on_write:
overloads the open function.
and test if the file as more than one harlink.
in this case the module creates a copy of the file and opens that copy.
PLEASE NOTE:
- this is note race free! And other problems can also happen.
- this is only an example that not handle every failure case! (I may
add that later)
- this module uses the SMB_VFS_NEXT_RENAME() function so, be careful
with multiple modules
(if you try to use hardlin_on_move together with copy_on_write use
this line in smb.conf:
vfs objects = hardlink_on_move copy_on_write
AND DON'T change the ORDER!!!)
Just copy the files to samba-3.0.0/examples/VFS/
cd samba-3.0.0/examples/VFS/
./autogen.sh
./configure
make
make install
will build and install the modules
Comments are welcome?
--
metze
-------------------------------------------
Stefan (metze) Metzmacher <metze at metzemix.de>
-------------- next part --------------
/*
* Copy On Write VFS Module
* Copyright (C) Stefan Metzmacher, 2003
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <includes.h>
#include "module_config.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
static int copy_on_write_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
{
int ret = -1;
SMB_STRUCT_STAT sbuf;
pstring tmpfname;
ZERO_STRUCT(sbuf);
switch (flags & O_ACCMODE) {
case O_RDONLY:
DEBUG(5,("want open: file[%s] for read\n",fname));
return SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);
break;
case O_WRONLY:
DEBUG(0,("want open: file[%s] for write\n",fname));
break;
case O_RDWR:
DEBUG(0,("want open: file[%s] for read/write\n",fname));
break;
default:
break;
}
ret = SMB_VFS_STAT(conn, fname, &sbuf);
if (ret != 0) {
DEBUG(5,("open: stat failed for [%s]\n",fname));
return SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);;
}
if (S_ISREG(sbuf.st_mode) && (sbuf.st_nlink > 1)) {
int in_fd;
int out_fd;
char buf[65536];
DEBUG(0,("need to copy on write: file[%s] links[%d]\n",fname,sbuf.st_nlink));
pstr_sprintf(tmpfname,"%s.copy_on_write_tmp",fname);
ret = SMB_VFS_NEXT_RENAME(handle, conn, fname, tmpfname);
if (ret != 0) {
DEBUG(0,("rename: file[%s]->file[%s] failed\n",fname,tmpfname));
return ret;
}
in_fd = open(tmpfname,O_RDONLY,0700);
out_fd = open(fname,O_WRONLY|O_CREAT,sbuf.st_mode);
while ((ret=read(in_fd,buf,sizeof(buf)))>0) {
DEBUGADD(0,("read: ret[%d]",ret));
if ((ret=write(out_fd,buf,ret))<=0) {
DEBUGADD(0,("write: ret[%d]\n",ret));
break;
}
DEBUGADD(0,("write: ret[%d]\n",ret));
//total +=ret;
}
close(in_fd);
close(out_fd);
if (ret <0) {
DEBUG(0,("transfer: file[%s]->file[%s] transfer failed ret[%d]\n",tmpfname,fname,ret));
return -1;
}
ret = SMB_VFS_UNLINK(conn, tmpfname);
if (ret != 0) {
DEBUG(0,("unlink: file[%s]failed\n",tmpfname));
return ret;
}
ZERO_STRUCT(sbuf);
ret = SMB_VFS_STAT(conn, fname, &sbuf);
if (ret != 0) {
DEBUG(5,("open: stat failed for [%s]\n",fname));
return SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);;
}
DEBUGADD(0,("after transfer: file[%s] links[%d]\n",fname,sbuf.st_nlink));
}
return SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);
}
/* VFS operations structure */
static vfs_op_tuple copy_on_write_ops[] = {
{SMB_VFS_OP(copy_on_write_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
NTSTATUS init_module(void)
{
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "copy_on_write", copy_on_write_ops);
}
-------------- next part --------------
/*
* Hardlink on Move VFS Module
* Copyright (C) Stefan Metzmacher, 2003
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <includes.h>
#include "module_config.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
static int hardlink_on_move_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname)
{
int ret = -1;
ret = SMB_VFS_LINK(conn, oldname, newname);
if (ret != 0) {
ret = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname);
}
return ret;
}
/* VFS operations structure */
static vfs_op_tuple hardlink_on_move_ops[] = {
{SMB_VFS_OP(hardlink_on_move_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
NTSTATUS init_module(void)
{
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "hardlink_on_move", hardlink_on_move_ops);
}
More information about the samba-technical
mailing list