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