diff options
Diffstat (limited to 'xlators/features')
| -rw-r--r-- | xlators/features/trash/src/Makefile.am | 2 | ||||
| -rw-r--r-- | xlators/features/trash/src/trash.c | 722 | ||||
| -rw-r--r-- | xlators/features/trash/src/trash.h | 80 | 
3 files changed, 194 insertions, 610 deletions
diff --git a/xlators/features/trash/src/Makefile.am b/xlators/features/trash/src/Makefile.am index 52fced5247a..15998a56ec7 100644 --- a/xlators/features/trash/src/Makefile.am +++ b/xlators/features/trash/src/Makefile.am @@ -6,6 +6,8 @@ trash_la_LDFLAGS = -module -avoidversion  trash_la_SOURCES = trash.c  trash_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la  +noinst_HEADERS = trash.h +  AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\  	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) diff --git a/xlators/features/trash/src/trash.c b/xlators/features/trash/src/trash.c index b2de4cdbe50..98d0663279c 100644 --- a/xlators/features/trash/src/trash.c +++ b/xlators/features/trash/src/trash.c @@ -22,556 +22,7 @@  #include "config.h"  #endif - -#include "glusterfs.h" -#include "logging.h" -#include "dict.h" -#include "xlator.h" -#include "defaults.h" - -#include <libgen.h> - -/* TODO: currently it can work only above posix, no other translators  - *       between them. Not a good thing. Try making more reliable methods. - */ - -struct trash_struct { -	inode_t *inode; -	loc_t loc1; -	loc_t loc2; -	char origpath[ZR_PATH_MAX]; -	char newpath[ZR_PATH_MAX]; -	char oldpath[ZR_PATH_MAX]; // used only in case of rename -}; -typedef struct trash_struct trash_local_t; - -struct trash_priv { -	char trash_dir[ZR_PATH_MAX]; -}; -typedef struct trash_priv trash_private_t; - -int32_t -trash_unlink_rename_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 struct stat *buf, -                         struct stat *preoldparent, -                         struct stat *postoldparent, -                         struct stat *prenewparent, -                         struct stat *postnewparent); -int32_t -trash_rename_rename_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 struct stat *buf, -                         struct stat *preoldparent, -                         struct stat *postoldparent, -                         struct stat *prenewparent, -                         struct stat *postnewparent); - -/** - * trash_common_unwind_cbk - - */ -int32_t -trash_common_unwind_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -                         struct stat *preparent, -                         struct stat *postparent) -{ -	trash_local_t *local = frame->local; - -        if (!local) -                goto out; - -	if (local->loc1.path) -		loc_wipe (&local->loc1); -	 -	if (local->loc2.path) -		loc_wipe (&local->loc2); - - out: -	STACK_UNWIND (frame, op_ret, op_errno); -	return 0; -} - - -/** - * trash_rename_unwind_buf_cbk - - */ -int32_t -trash_rename_unwind_buf_cbk (call_frame_t *frame, -			     void *cookie, -			     xlator_t *this, -			     int32_t op_ret, -			     int32_t op_errno, -			     struct stat *buf, -                             struct stat *preoldparent, -                             struct stat *postoldparent, -                             struct stat *prenewparent, -                             struct stat *postnewparent) -{ -	trash_local_t *local = frame->local; - -        if (!local) -                goto out; - -	if (local->loc1.path) -		loc_wipe (&local->loc1); - -	if (local->loc2.path) -		loc_wipe (&local->loc2); - - out: -	STACK_UNWIND (frame, op_ret, op_errno, buf); -	return 0; -} - - -/** - * trash_common_unwind_buf_cbk - - */ -int32_t -trash_common_unwind_buf_cbk (call_frame_t *frame, -			     void *cookie, -			     xlator_t *this, -			     int32_t op_ret, -			     int32_t op_errno, -			     struct stat *buf) -{ -	trash_local_t *local = frame->local; - -        if (!local) -                goto out; - -	if (local->loc1.path) -		loc_wipe (&local->loc1); -	 -	if (local->loc2.path) -		loc_wipe (&local->loc2); - - out: -	STACK_UNWIND (frame, op_ret, op_errno, buf); -	return 0; -} - -int32_t -trash_mkdir_cbk (call_frame_t *frame, -		 void *cookie, -		 xlator_t *this, -		 int32_t op_ret, -		 int32_t op_errno, -		 inode_t *inode, -                 struct stat *stbuf, -                 struct stat *preparent, -                 struct stat *postparent) -{ -	trash_local_t *local = frame->local; -	char *tmp_str = strdup (local->newpath); -	int32_t count = 0; -	char *tmp_path = NULL; -	char *tmp_dirname = NULL; - -	if (op_ret == -1 && op_errno == ENOENT) { -		tmp_dirname = strchr (tmp_str, '/'); -		while (tmp_dirname) { -			count = tmp_dirname - tmp_str; -			if (count == 0) -				count = 1; -			tmp_path = CALLOC (1, count + 1); -			ERR_ABORT (tmp_path); -			memcpy (tmp_path, local->newpath, count); -			loc_t tmp_loc = { -				.inode = NULL, -				.path = tmp_path, -			}; - -			/* TODO:create the directory with proper permissions */ -			STACK_WIND_COOKIE (frame, -					   trash_mkdir_cbk, -					   tmp_path, -					   this->children->xlator, -					   this->children->xlator->fops->mkdir, -					   &tmp_loc, -					   0777); -			tmp_dirname = strchr (tmp_str + count + 1, '/'); -		} -		free (cookie); -		free (tmp_str); -		return 0; -	} -	char *dir_name = dirname (tmp_str); -	if (strcmp((char*)cookie, dir_name) == 0) { -		loc_t new_loc = { -			.inode = NULL, -			.path = local->newpath -		}; -		STACK_WIND (frame, -			    trash_unlink_rename_cbk, -			    this->children->xlator, -			    this->children->xlator->fops->rename, -			    &local->loc2, -			    &new_loc); - -	} -	free (cookie); /* strdup (dir_name) was sent here :) */ -	free (tmp_str); -	return 0; -} - -/** - * trash_unlink_rename_cbk - - */ -int32_t -trash_unlink_rename_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 struct stat *buf, -                         struct stat *preoldparent, -                         struct stat *postoldparent, -                         struct stat *prenewparent, -                         struct stat *postnewparent) -{ -	trash_local_t *local = frame->local; -	if (op_ret == -1 && op_errno == ENOENT) { -		/* check for the errno, if its ENOENT create directory and call -		 * rename later -		 */ -		char *tmp_str = strdup (local->newpath); -		char *dir_name = dirname (tmp_str); -		loc_t tmp_loc = { -			.inode = NULL, -			.path = dir_name, -		}; -		/* TODO: create the directory with proper permissions */ -		STACK_WIND_COOKIE (frame, -				   trash_mkdir_cbk, -				   strdup (dir_name), -				   this->children->xlator, -				   this->children->xlator->fops->mkdir, -				   &tmp_loc, -				   0777); -		free (tmp_str); -	} else if (op_ret == -1 && op_errno == ENOTDIR) { -		gf_log (this->name, GF_LOG_WARNING, -			"Target exists, cannot keep the copy, deleting"); -		STACK_WIND (frame, -			    trash_common_unwind_cbk, -			    this->children->xlator, -			    this->children->xlator->fops->unlink, -			    &local->loc2); -	} else if (op_ret == -1 && op_errno == EISDIR) { -		gf_log (this->name, GF_LOG_WARNING, -			"Target exists as a directory, cannot keep the copy, " -			"deleting"); -		STACK_WIND (frame, -			    trash_common_unwind_cbk, -			    this->children->xlator, -			    this->children->xlator->fops->unlink, -			    &local->loc2); -	} else { -		/* */ -		STACK_UNWIND (frame, 0, op_errno); -	} - -	return 0; -} - - -/** - * trash_unlink - - */ -int32_t -trash_unlink (call_frame_t *frame, -	      xlator_t *this, -	      loc_t *loc) -{ -	trash_private_t *priv = this->private; -	trash_local_t *local = NULL; -	time_t       utime = 0; -	struct tm   *tm = NULL; -	char         timestr[256]; - -	if (strncmp (loc->path, priv->trash_dir,  -		     strlen(priv->trash_dir)) == 0) { -		/* Trying to rename from the trash can dir, do the -		   actual unlink */ -		STACK_WIND (frame, -			    trash_common_unwind_cbk, -			    this->children->xlator, -			    this->children->xlator->fops->unlink, -			    loc); -	} else { -		local = CALLOC (1, sizeof (trash_local_t)); -		if (!local) { -			STACK_UNWIND (frame, -1, ENOMEM); -			return 0; -		} -		frame->local = local; -		 -		loc_copy (&local->loc2, loc); - -		strcpy (local->newpath, priv->trash_dir); -		strcat (local->newpath, loc->path); - -		utime = time (NULL); -		tm    = localtime (&utime); -		strftime (timestr, 256, ".%Y%m%d%H%M%S", tm);  -		strcat (local->newpath, timestr); - -		{ -			loc_t new_loc = { -				.inode = NULL, -				.path = local->newpath -			}; -			STACK_WIND (frame, -				    trash_unlink_rename_cbk, -				    this->children->xlator, -				    this->children->xlator->fops->rename, -				    loc, -				    &new_loc); -		} -	} -	return 0; -} - -/* */ -int32_t -trash_rename_mkdir_cbk (call_frame_t *frame, -			void *cookie, -			xlator_t *this, -			int32_t op_ret, -			int32_t op_errno, -			inode_t *inode, -                        struct stat *stbuf, -                        struct stat *preparent, -                        struct stat *postparent) -{ -	trash_local_t *local = frame->local; -	char *tmp_str = strdup (local->newpath); - -	if (op_ret == -1 && op_errno == ENOENT) { -		int32_t count = 0; -		char *tmp_path = NULL; -		char *tmp_dirname = strchr (tmp_str, '/'); - -		while (tmp_dirname) { -			count = tmp_dirname - tmp_str; -			if (count == 0) -				count = 1; -			tmp_path = CALLOC (1, count + 2); -			ERR_ABORT (tmp_path); -			memcpy (tmp_path, local->newpath, count); -			loc_t tmp_loc = { -				.inode = NULL, -				.path = tmp_path, -			}; - -			/* TODO:create the directory with proper permissions */ -			STACK_WIND_COOKIE (frame, -					   trash_rename_mkdir_cbk, -					   tmp_path, -					   this->children->xlator, -					   this->children->xlator->fops->mkdir, -					   &tmp_loc, -					   0777); -			tmp_dirname = strchr (tmp_str + count + 1, '/'); -		} -		free (cookie); -		free (tmp_str); -		return 0; -	} -	char *dir_name = dirname (tmp_str); -	if (strcmp((char*)cookie, dir_name) == 0) { -		loc_t new_loc = { -			.inode = NULL, -			.path = local->newpath -		}; -		STACK_WIND (frame, -			    trash_rename_rename_cbk, -			    this->children->xlator, -			    this->children->xlator->fops->rename, -			    &local->loc2, -			    &new_loc); - -	} -	free (cookie); /* strdup (dir_name) was sent here :) */ -	free (tmp_str); -	return 0; -} - - -/** - * trash_unlink_rename_cbk - - */ -int32_t -trash_rename_rename_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 struct stat *buf, -                         struct stat *preoldparent, -                         struct stat *postoldparent, -                         struct stat *prenewparent, -                         struct stat *postnewparent) -{ -	trash_local_t *local = frame->local; -	if (op_ret == -1 && op_errno == ENOENT) { -		/* check for the errno, if its ENOENT create directory and call -		 * rename later -		 */ -		char *tmp_str = strdup (local->newpath); -		char *dir_name = dirname (tmp_str); -		loc_t tmp_loc = { -			.inode = NULL, -			.path = dir_name, -		}; -		/* TODO: create the directory with proper permissions */ -		STACK_WIND_COOKIE (frame, -				   trash_rename_mkdir_cbk, -				   strdup (dir_name), -				   this->children->xlator, -				   this->children->xlator->fops->mkdir, -				   &tmp_loc, -				   0777); -		free (tmp_str); -		return 0; -	} else if (op_ret == -1 && op_errno == ENOTDIR) { -		gf_log (this->name, GF_LOG_WARNING, -			"Target exists, cannot keep the dest entry %s, " -			"renaming", -			local->loc2.path); -	} else if (op_ret == -1 && op_errno == EISDIR) { -		gf_log (this->name, GF_LOG_WARNING, -			"Target exists as a directory, cannot keep the " -			"copy %s, renaming", -			local->loc2.path); -	} -	loc_t new_loc = { -		.inode = NULL, -		.parent = local->loc2.parent, -		.path = local->loc2.path, -	}; -	STACK_WIND (frame, -		    trash_rename_unwind_buf_cbk, -		    this->children->xlator, -		    this->children->xlator->fops->rename, -		    &local->loc1, -		    &new_loc); - -	return 0; -} - -/** - * trash_rename_lookup_cbk - - */ -int32_t -trash_rename_lookup_cbk (call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 inode_t *inode, -			 struct stat *buf, -			 dict_t *xattr, -                         struct stat *postparent) -{ -	trash_local_t *local = frame->local; - -	if (op_ret == -1) { -		STACK_WIND (frame, -			    trash_rename_unwind_buf_cbk, -			    this->children->xlator, -			    this->children->xlator->fops->rename, -			    &local->loc1, -			    &local->loc2); -		return 0; -	} - -	loc_t oldloc = { -		.parent = local->loc2.parent, -		.inode = inode, -		.path = local->loc2.path, -	}; -	loc_t newloc = { -		.inode = NULL, -		.path = local->newpath -	}; -	STACK_WIND (frame, -		    trash_rename_rename_cbk, -		    this->children->xlator, -		    this->children->xlator->fops->rename, -		    &oldloc, -		    &newloc); - -	return 0; -} - - -/** - * trash_rename - - */ -int32_t -trash_rename (call_frame_t *frame, -	      xlator_t *this, -	      loc_t *oldloc, -	      loc_t *newloc) -{ -	trash_private_t *priv = this->private; -	trash_local_t *local = NULL; -	time_t       utime = 0; -	struct tm   *tm = NULL; -	char         timestr[256]; - -	if (strncmp (oldloc->path, priv->trash_dir,  -		     strlen(priv->trash_dir)) == 0) { -		/* Trying to rename from the trash can dir,  -		   do the actual rename */ -		STACK_WIND (frame, -			    trash_rename_unwind_buf_cbk, -			    this->children->xlator, -			    this->children->xlator->fops->rename, -			    oldloc, -			    newloc); -	} else { -		/* Trying to rename a regular file from GlusterFS */ -		local = CALLOC (1, sizeof (trash_local_t)); -		if (!local) { -			STACK_UNWIND (frame, -1, ENOMEM, NULL); -			return 0; -		} -		frame->local = local; -		loc_copy (&local->loc1, oldloc); -		loc_copy (&local->loc2, newloc); - -		strcpy (local->newpath, priv->trash_dir); -		strcat (local->newpath, newloc->path); - -		utime = time (NULL); -		tm    = localtime (&utime); -		strftime (timestr, 256, ".%Y%m%d%H%M%S", tm);  -		strcat (local->newpath, timestr); - -		/* Send a lookup call on newloc, to ensure we are not  -		   overwriting */ -		STACK_WIND (frame, -			    trash_rename_lookup_cbk, -			    this->children->xlator, -			    this->children->xlator->fops->lookup, -			    newloc, -			    0); -	} -	return 0; -} +#include "trash.h"  /**   * trash_init - @@ -579,70 +30,115 @@ trash_rename (call_frame_t *frame,  int32_t  init (xlator_t *this)  { -  	data_t *trash_dir = NULL; -	xlator_list_t *trav = NULL; -	trash_private_t *_priv = NULL; - -	/* Create .trashcan directory in init */ -	if (!this->children || this->children->next) { -		gf_log (this->name, GF_LOG_ERROR, -			"not configured with exactly one child. exiting"); -		return -1; -	} - -	if (!this->parents) { -		gf_log (this->name, GF_LOG_WARNING, -			"dangling volume. check volfile "); -	} - -	trav = this->children; -	while (trav->xlator->children) -		trav = trav->xlator->children; - -	if (strncmp ("storage/", trav->xlator->type, 8)) -	{ -		gf_log (this->name, GF_LOG_ERROR, -			"'trash' translator not loaded over storage " -			"translator, not a supported setup"); -		return -1; -	} - -	_priv = CALLOC (1, sizeof (*_priv)); -	ERR_ABORT (_priv); - -	trash_dir = dict_get (this->options, "trash-dir"); -	if (!trash_dir) { -		gf_log (this->name, GF_LOG_WARNING, -			"no option specified for 'trash-dir', " -			"using \"/.trashcan/\""); -		strcpy (_priv->trash_dir, "/.trashcan"); -	} else { -		/* Need a path with '/' as the first char, if not  -		   given, append it */ -		if (trash_dir->data[0] == '/') { -			strcpy (_priv->trash_dir, trash_dir->data); -		} else { -			strcpy (_priv->trash_dir, "/"); -			strcat (_priv->trash_dir, trash_dir->data); -		} -	} - -	this->private = (void *)_priv; -	return 0; +        int32_t                ret   = 0; +        data_t                *data  = NULL; +        trash_private_t       *_priv = NULL; +        trash_elim_pattern_t  *trav  = NULL; +        char                  *tmp_str = NULL; +        char                  *strtokptr = NULL; +        char                  *component = NULL; +        char                   trash_dir[PATH_MAX] = {0,}; + +        /* Create .trashcan directory in init */ +        if (!this->children || this->children->next) { +                gf_log (this->name, GF_LOG_ERROR, +                        "not configured with exactly one child. exiting"); +                return -1; +        } + +        if (!this->parents) { +                gf_log (this->name, GF_LOG_WARNING, +                        "dangling volume. check volfile "); +        } + +        _priv = CALLOC (1, sizeof (*_priv)); +        if (!_priv) { +                gf_log (this->name, GF_LOG_ERROR, "out of memory"); +                return -1; +        } + +        data = dict_get (this->options, "trash-dir"); +        if (!data) { +                gf_log (this->name, GF_LOG_NORMAL, +                        "no option specified for 'trash-dir', " +                        "using \"/.trashcan/\""); +                _priv->trash_dir = strdup ("/.trashcan"); +        } else { +                /* Need a path with '/' as the first char, if not +                   given, append it */ +                if (data->data[0] == '/') { +                        _priv->trash_dir = strdup (data->data); +                } else { +                        /* TODO: Make sure there is no ".." in the path */ +                        strcpy (trash_dir, "/"); +                        strcat (trash_dir, data->data); +                        _priv->trash_dir = strdup (trash_dir); +                } +        } + +        data = dict_get (this->options, "eliminate-pattern"); +        if (!data) { +                gf_log (this->name, GF_LOG_TRACE, +                        "no option specified for 'eliminate', using NULL"); +        } else { +                tmp_str = strdup (data->data); +                if (!tmp_str) { +                        gf_log (this->name, GF_LOG_DEBUG, "out of memory"); +                } + +                /*  Match Filename to option specified in eliminate. */ +                component = strtok_r (tmp_str, "|", &strtokptr); +                while (component) { +                        trav = CALLOC (1, sizeof (*trav)); +                        if (!trav) { +                                gf_log (this->name, GF_LOG_DEBUG, "out of memory"); +                        } +                        trav->pattern = component; +                        trav->next = _priv->eliminate; +                        _priv->eliminate = trav; + +                        component = strtok_r (NULL, "|", &strtokptr); +                } +        } + +        /* TODO: do gf_string2sizet () */ +        data = dict_get (this->options, "max-trashable-file-size"); +        if (!data) { +                gf_log (this->name, GF_LOG_DEBUG, +                        "no option specified for 'max-trashable-file-size', " +                        "using default = %lld MB", +                        GF_DEFAULT_MAX_FILE_SIZE / GF_UNIT_MB); +                _priv->max_trash_file_size = GF_DEFAULT_MAX_FILE_SIZE; +        } else { +                ret = gf_string2bytesize (data->data, +                                          &_priv->max_trash_file_size); +                if( _priv->max_trash_file_size > GF_ALLOWED_MAX_FILE_SIZE ) { +                        gf_log (this->name, GF_LOG_DEBUG, +                                "Size specified for max-size(in MB) is too " +                                "large so using 1GB as max-size (NOT IDEAL)"); +                        _priv->max_trash_file_size = GF_ALLOWED_MAX_FILE_SIZE; +                } +                gf_log (this->name, GF_LOG_DEBUG, "%"GF_PRI_SIZET" max-size", +                        _priv->max_trash_file_size); +        } + +        this->private = (void *)_priv; +        return 0;  }  void  fini (xlator_t *this)  { -	trash_private_t *priv = this->private; -	FREE (priv); -	return; -} +        trash_private_t *priv = NULL; + +        priv = this->private; +        if (priv) +                FREE (priv); +        return; +}  struct xlator_fops fops = { -	.unlink = trash_unlink, -	.rename = trash_rename,  };  struct xlator_mops mops = { @@ -653,8 +149,14 @@ struct xlator_cbks cbks = {  };  struct volume_options options[] = { -	{ .key  = { "trash-dir" },  -	  .type = GF_OPTION_TYPE_PATH  -	}, -	{ .key  = {NULL} }, +        { .key  = { "trash-directory" }, +          .type = GF_OPTION_TYPE_PATH, +        }, +        { .key  = { "eliminate-pattern" }, +          .type = GF_OPTION_TYPE_STR, +        }, +        { .key  = { "max-trashable-file-size" }, +          .type = GF_OPTION_TYPE_SIZET, +        }, +        { .key  = {NULL} },  }; diff --git a/xlators/features/trash/src/trash.h b/xlators/features/trash/src/trash.h new file mode 100644 index 00000000000..7f0e13085b1 --- /dev/null +++ b/xlators/features/trash/src/trash.h @@ -0,0 +1,80 @@ +/* +  Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +  This file is part of GlusterFS. + +  GlusterFS 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 3 of the License, +  or (at your option) any later version. + +  GlusterFS 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, see +  <http://www.gnu.org/licenses/>. +*/ + +#ifndef __TRASH_H__ +#define __TRASH_H__ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "glusterfs.h" +#include "logging.h" +#include "dict.h" +#include "xlator.h" +#include "defaults.h" +#include "inode.c" +#include "fnmatch.h" + +#include <libgen.h> + +#ifndef GF_BLOCK_READV_SIZE +#define GF_BLOCK_READV_SIZE      (128 * GF_UNIT_KB) +#endif + +#ifndef GF_DEFAULT_MAX_FILE_SIZE +#define GF_DEFAULT_MAX_FILE_SIZE (200 * GF_UNIT_MB) +#endif + +#ifndef GF_ALLOWED_MAX_FILE_SIZE +#define GF_ALLOWED_MAX_FILE_SIZE (1 * GF_UNIT_GB) +#endif + + +struct trash_struct { +        fd_t    *fd;         /* for the fd of existing file */ +        fd_t    *newfd;      /* for the newly created file */ +        loc_t    loc;        /* to store the location of the existing file */ +        loc_t    newloc;     /* to store the location for the new file */ +        size_t   fsize;      /* for keeping the size of existing file */ +        off_t    cur_offset; /* current offset for read and write ops */ +        off_t    fop_offset; +        char     origpath[PATH_MAX]; +        char     newpath[PATH_MAX]; +        int32_t  loop_count; +        struct stat preparent; +        struct stat postparent; +}; +typedef struct trash_struct trash_local_t; + +struct _trash_elim_pattern; +typedef struct _trash_elim_pattern { +        struct _trash_elim_pattern *next; +        char                       *pattern; +} trash_elim_pattern_t; + +struct trash_priv { +        char                 *trash_dir; +        trash_elim_pattern_t *eliminate; +        size_t                max_trash_file_size; +}; +typedef struct trash_priv trash_private_t; + +#endif /* __TRASH_H__ */  | 
