[Gluster-devel] The quota xlator V0.1 against tla636

Anand Avati avati at zresearch.com
Mon Jan 21 00:55:43 UTC 2008


Angel,
 Thanks for kickstarting :) Some comments -

1. Storing stat from pre_unlink_stat_cbk into frame->local is not right
since.

2. Instead of having a pre_unlink_stat and then subtracting (after fixing
the storage of stat), why not have a post_unlink_statfs() ? That sounds a
lot neater implementation. It also guards against hardlinks getting wrongly
calculated twice. You can also improve the performance by pipelining unlink
and statfs one after another without waiting for the callback from the other
(the order of two stack_winds from the same thread will guarantee the same
order of execution at posix (if they both are headed towards the same
storage/posix) unless the calls are a mix of file/non-file (in this case
both are non-file, so order is guaranteed).

3. it would also be convinient if you 'unimplement' the remaining fops which
are copied from trace.

4. do you have any thoughts on per-user or per-dir? If so I would like to
discuss as we are discussing internally with a few algos for doing the most
efficient per-dir quota.

thanks,
avati

2008/1/20, Angel <clist at uah.es>:
>
> Hi, all
>
> I just send you my QUOTA xlator, it is still VERY ALPHA code, but yet
> usefull to allow devs and people
> comment and report on funcionality, errors, coding guidelines and so.
>
> Quota is a dirty hack over trace and need a lot cleaning :-) but patch
> compiles cleanly againt tla636
>
> It offers still very limited functionality:
>         - Check limits and reports limited values from stats mops to upper
> schedulers.
>         - Cheks limits and reports limited values on statsvfs fops (for
> "df " command)
>         - Check limits on writes, reporting ENOSPC on hitting max-size
> writes
>         - Checks on unliks computing recovered space.
>
> Include docs at /doc/examples/quota.vol
>
>
>
> Any comments is welcome
>
> First Hint:
>   Possible race condiction as quota modifies struct stat *buf from
> posix-storage as it traverses *_cbk functions
>
> Kind Regards,
> --
> ------------------------------------------------
> Clist UAH Angel Alvarez
> ------------------------------------------------
>
> diff -pruN glusterfs-tla636/configure.ac glusterfs-tla636-quota-xlator-0.1
> /configure.ac
> --- glusterfs-tla636/configure.ac       2008-01-16 17:19:48.290785081+0100
> +++ glusterfs-tla636-quota-xlator-0.1/configure.ac      2008-01-16 22:43:
> 06.896248606 +0100
> @@ -64,6 +64,8 @@ AC_CONFIG_FILES([Makefile
>                 xlators/features/fixed-id/src/Makefile
>                 xlators/features/trash/Makefile
>                 xlators/features/trash/src/Makefile
> +               xlators/features/quota/Makefile
> +               xlators/features/quota/src/Makefile
>                 xlators/encryption/Makefile
>                 xlators/encryption/rot-13/Makefile
>                 xlators/encryption/rot-13/src/Makefile
> diff -pruN glusterfs-tla636/doc/examples/quota.vol
> glusterfs-tla636-quota-xlator-0.1/doc/examples/quota.vol
> --- glusterfs-tla636/doc/examples/quota.vol     1970-01-01 01:00:
> 00.000000000 +0100
> +++ glusterfs-tla636-quota-xlator-0.1/doc/examples/quota.vol    2008-01-19
> 22:27:50.234951911 +0100
> @@ -0,0 +1,21 @@
> +volume brick
> +  type storage/posix                   # POSIX FS translator
> +  option directory /home/export        # Export this directory
> +end-volume
> +
> +### 'Quota' feature should be added on the server side (as posix volume
> as subvolume) where it can be used to limit max usage,
> +on the underlaying block device.
> +volume quota
> +  type features/quota
> +  subvolumes brick
> +  option max-size 50M   # Limit underlaying volume to 50MB of space
> +  option enforce-level  # Limit upper schedulers or limit all oprations
> (CURRENTLY NOT IMPLEMENTED)
> +end-volume
> +
> +volume server
> +  type protocol/server
> +  subvolumes quota brick
> +  option transport-type tcp/server
> +  option auth.ip.brick.allow 192.168.* # Allow access to "brick" volume
> +  option auth.ip.quota.allow 192.168.* # Allow access to "quota" volume
> (exporting 50MB disk space)
> +end-volume
> diff -pruN glusterfs-tla636/doc/translator-option.txt
> glusterfs-tla636-quota-xlator-0.1/doc/translator-option.txt
> --- glusterfs-tla636/doc/translator-option.txt  2008-01-16 17:19:
> 48.790813576 +0100
> +++ glusterfs-tla636-quota-xlator-0.1/doc/translator-option.txt 2008-01-19
> 22:22:12.215689291 +0100
> @@ -151,6 +151,10 @@
>       option fixed-uid <n> [if not set, not used]
>       option fixed-gid <n> [if not set, not used]
>
> +# features/quota:
> +     option max-size <n>  [if not set, not used ]
> +     option enforce-level [0|1] (1)
> +
> # features/filter:
>   - NO OPTIONS
>
> diff -pruN glusterfs-tla636/xlators/features/Makefile.am
> glusterfs-tla636-quota-xlator-0.1/xlators/features/Makefile.am
> --- glusterfs-tla636/xlators/features/Makefile.am       2008-01-16 17:19:
> 52.291013041 +0100
> +++ glusterfs-tla636-quota-xlator-0.1/xlators/features/Makefile.am      2008-01-16
> 22:24:35.832932716 +0100
> @@ -1 +1 @@
> -SUBDIRS = filter fixed-id posix-locks trash
> +SUBDIRS = filter fixed-id posix-locks trash quota
> diff -pruN glusterfs-tla636/xlators/features/quota/Makefile.am
> glusterfs-tla636-quota-xlator-0.1/xlators/features/quota/Makefile.am
> --- glusterfs-tla636/xlators/features/quota/Makefile.am 1970-01-01 01:00:
> 00.000000000 +0100
> +++ glusterfs-tla636-quota-xlator-0.1/xlators/features/quota/Makefile.am        2008-01-16
> 17:19:51.000000000 +0100
> @@ -0,0 +1 @@
> +SUBDIRS = src
> diff -pruN glusterfs-tla636/xlators/features/quota/src/Makefile.am
> glusterfs-tla636-quota-xlator-0.1/xlators/features/quota/src/Makefile.am
> --- glusterfs-tla636/xlators/features/quota/src/Makefile.am     1970-01-01
> 01:00:00.000000000 +0100
> +++ glusterfs-tla636-quota-xlator-0.1/xlators/features/quota/src/Makefile.am    2008-01-16
> 22:59:55.453723021 +0100
> @@ -0,0 +1,11 @@
> +
> +xlator_PROGRAMS = quota.so
> +xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/quota
> +
> +quota_so_SOURCES = quota.c
> +
> +AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall
> -D$(GF_HOST_OS)\
> +       -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles
> +
> +CLEANFILES = *~
> +
> diff -pruN glusterfs-tla636/xlators/features/quota/src/quota.c
> glusterfs-tla636-quota-xlator-0.1/xlators/features/quota/src/quota.c
> --- glusterfs-tla636/xlators/features/quota/src/quota.c 1970-01-01 01:00:
> 00.000000000 +0100
> +++ glusterfs-tla636-quota-xlator-0.1/xlators/features/quota/src/quota.c        2008-01-19
> 22:14:30.689388405 +0100
> @@ -0,0 +1,2011 @@
> +/*
> +   Copyright (c) 2006, 2007 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/>.
> +*/
> +
> +/**
> + * xlators/features/quota :
> + *    This translator imposes quota over file operations
> + *    mostly based on trace xlator :-).
> + *    Derive initially by Angel Alvarez clist at uah.es
> + */
> +
> +#include <time.h>
> +#include <errno.h>
> +#include "glusterfs.h"
> +#include "xlator.h"
> +#include "defaults.h"
> +
> +
> +#define ERR_EINVAL_NORETURN(cond)                \
> +do                                               \
> +  {                                             \
> +    if ((cond))                                         \
> +      {                                                 \
> +       gf_log ("ERROR",                         \
> +               GF_LOG_ERROR,                    \
> +               "%s: %s: (%s) is true",          \
> +               __FILE__, __FUNCTION__, #cond);  \
> +      }                                          \
> +  } while (0)
> +
> +extern int32_t errno;
> +
> +#define _FORMAT_WARN(domain, log_level, format, args...)  printf
> ("__DEBUG__" format, ##args);
> +
> +struct quota_private {
> +  int32_t debug_flag;
> +  int64_t storage_size;
> +  int64_t disk_usage;
> +  int64_t free_disk;
> +};
> +
> +struct {
> +  const char *name;
> +  int enabled;
> +} fop_names[] = {{"stat", 1},
> +                {"readlink", 1},
> +                {"mknod", 1},
> +                {"mkdir", 1},
> +                {"unlink", 1},
> +                {"rmdir", 0},
> +                {"symlink", 0},
> +                {"rename", 0},
> +                {"link", 0},
> +                {"chmod", 0},
> +                {"chown", 0},
> +                {"truncate", 0},
> +                {"open", 0},
> +                {"read", 0},
> +                {"write", 1},
> +                {"statfs", 1},
> +                {"flush", 0},
> +                {"close", 0},
> +                {"fsync", 0},
> +                {"setxattr", 0},
> +                {"getxattr", 0},
> +                {"removexattr", 0},
> +                {"opendir", 0},
> +                {"getdents", 0},
> +                {"closedir", 0},
> +                {"fsyncdir", 0},
> +                {"access", 0},
> +                {"create", 0},
> +                {"ftruncate", 0},
> +                {"fstat", 0},
> +                {"lk", 0},
> +                {"utimens", 0},
> +                {"fchmod", 0},
> +                {"fchown", 0},
> +                {"lookup", 0},
> +                {"forget", 0},
> +                {"setdents", 0},
> +                {"rmelem", 0},
> +                {"incver", 0},
> +                {"readdir", 0},};
> +
> +void
> +quota_add (xlator_t *this,
> +           int64_t quantity)
> +{
> +  struct quota_private *private = NULL;
> +
> +  if (this) {
> +    gf_log (this->name,
> +           GF_LOG_WARNING,
> +           "QUOTA add (%d)",
> +            quantity);
> +    private = this->private;
> +    private->disk_usage += quantity;
> +    if ( private->disk_usage > private->storage_size ) {
> +      private->free_disk = 0;
> +      } else {
> +      private->free_disk = private->storage_size - private->disk_usage;
> +    }
> +  }
> +}
> +
> +void
> +quota_sub (xlator_t *this,
> +           int64_t quantity)
> +{
> +  struct quota_private *private = NULL;
> +
> +  if (this) {
> +    gf_log (this->name,
> +           GF_LOG_WARNING,
> +           "QUOTA sub (%d)",
> +            quantity);
> +    private = this->private;
> +    private->disk_usage -= quantity;
> +    if ( private->disk_usage < 0 ) {
> +      private->free_disk = private->storage_size;
> +      } else {
> +      private->free_disk = private->storage_size - private->disk_usage;
> +    }
> +  }
> +}
> +
> +int64_t
> +quota_check (xlator_t *this)
> +{
> +    return ((struct quota_private *)this->private)->free_disk;
> +}
> +
> +void
> +quota_alter_statvfs (xlator_t *this,
> +                     struct statvfs *buf)
> +{
> +  struct quota_private *private = NULL;
> +
> +  private = this->private;
> +
> +  // set filesystem max blocks
> +  if ( buf->f_blocks > (private->storage_size / buf->f_frsize) )
> buf->f_blocks = (private->storage_size / buf->f_frsize);
> +  // set filesystem free blocks for users
> +  buf->f_bfree = private->free_disk / buf->f_frsize;
> +  // FIXME: set filesystem free blocks for root
> +  buf->f_bavail = private->free_disk / buf->f_frsize;
> +
> +}
> +
> +static int32_t
> +quota_writev_cbk (call_frame_t *frame,
> +                 void *cookie,
> +                 xlator_t *this,
> +                 int32_t op_ret,
> +                 int32_t op_errno,
> +                 struct stat *buf)
> +{
> +  int64_t disk_size = quota_check(this);
> +
> +  ERR_EINVAL_NORETURN (!this);
> +
> +  // Record bytes written on success
> +  if ( op_ret > 0 ) {
> +    quota_add( this, op_ret );
> +  }
> +  // If quota is over return error
> +  if ( disk_size == 0 ) {
> +    op_ret  = -1;
> +    op_errno = ENOSPC;
> +    gf_log (this->name,
> +           GF_LOG_WARNING,
> +           "No space available! (*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  STACK_UNWIND (frame, op_ret, op_errno, buf);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_writev (call_frame_t *frame,
> +             xlator_t *this,
> +             fd_t *fd,
> +             struct iovec *vector,
> +             int32_t count,
> +             off_t offset)
> +{
> +  ERR_EINVAL_NORETURN (!this || !fd || !vector || (count < 1));
> +
> +  STACK_WIND (frame,
> +              quota_writev_cbk,
> +              FIRST_CHILD(this),
> +              FIRST_CHILD(this)->fops->writev,
> +              fd, vector, count,offset);
> +  return 0;
> +}
> +
> +
> +static int32_t
> +quota_unlink_cbk (call_frame_t *frame,
> +                 void *cookie,
> +                 xlator_t *this,
> +                 int32_t op_ret,
> +                 int32_t op_errno)
> +{
> +  struct stat *buf = NULL;
> +
> +  ERR_EINVAL_NORETURN (!this );
> +  buf = frame->local;
> +  if (op_ret >= 0) {
> +    quota_sub(this,buf->st_size); // unlink completed account bytes freed
> +  } else {
> +    // unlik failed? can not account bytes freed
> +    gf_log (this->name,
> +           GF_LOG_WARNING,
> +           "unlink failed! (*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  // free fame->local
> +  frame->local = NULL;
> +  // return to caller
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_pre_unlink_stat_cbk (call_frame_t *frame,
> +               void *cookie,
> +               xlator_t *this,
> +               int32_t op_ret,
> +               int32_t op_errno,
> +               struct stat *buf)
> +{
> +  loc_t *loc = NULL;
> +
> +  ERR_EINVAL_NORETURN (!this);
> +  // Recover loc info from frame (stored by unlink)
> +  loc = frame->local;
> +  //pass buf on frame->local to unlink_cbk
> +  frame->local=buf;
> +  STACK_WIND (frame,
> +             quota_unlink_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->unlink,
> +             loc);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_unlink (call_frame_t *frame,
> +             xlator_t *this,
> +             loc_t *loc)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc);
> +
> +  gf_log (this->name,
> +         GF_LOG_WARNING,
> +         " Unlink request path=%s, inode=%p ",
> +         loc->path, loc->inode);
> +  // store loc on frame->local to preserve it
> +  frame->local=loc;
> +  // Call stat to figure out how many bytes will be freed
> +  // Place pre_unlink_stat_cbk on return
> +  STACK_WIND (frame,
> +             quota_pre_unlink_stat_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->stat,
> +             loc);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_statfs_cbk (call_frame_t *frame,
> +                 void *cookie,
> +                 xlator_t *this,
> +                 int32_t op_ret,
> +                 int32_t op_errno,
> +                 struct statvfs *buf)
> +{
> +
> +  ERR_EINVAL_NORETURN (!this);
> +
> +  if ( op_ret >= 0 ) {
> +    quota_alter_statvfs (this, buf);
> +  }
> +  STACK_UNWIND (frame, op_ret, op_errno, buf);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_statfs (call_frame_t *frame,
> +             xlator_t *this,
> +             loc_t *loc)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc);
> +  STACK_WIND (frame,
> +             quota_statfs_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->statfs,
> +             loc);
> +  return 0;
> +}
> +
> +
> +
>
> +//#####################################################################################################################
> +
> +static int32_t
> +quota_fstat_cbk (call_frame_t *frame,
> +                void *cookie,
> +                xlator_t *this,
> +                int32_t op_ret,
> +                int32_t op_errno,
> +                struct stat *buf)
> +{
> +  char atime_buf[256], mtime_buf[256], ctime_buf[256];
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_FSTAT].enabled) {
> +  if (op_ret >= 0) {
> +    strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_atime));
> +    strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_mtime));
> +    strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_ctime));
> +
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d, *buf=%p {st_dev=%lld,
> st_ino=%lld, st_mode=%d, st_nlink=%d, st_uid=%d, st_gid=%d, st_rdev=%llx,
> st_size=%lld, st_blksize=%ld, st_blocks=%lld, st_atime=%s, st_mtime=%s,
> st_ctime=%s})",
> +           this, op_ret, op_errno, buf, buf->st_dev, buf->st_ino,
> buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, buf->st_rdev,
> buf->st_size, buf->st_blksize, buf->st_blocks, atime_buf, mtime_buf,
> ctime_buf);
> +  } else {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, buf);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_fstat (call_frame_t *frame,
> +            xlator_t *this,
> +            fd_t *fd)
> +{
> +  ERR_EINVAL_NORETURN (!this || !fd);
> +
> +  if (fop_names[GF_FOP_FSTAT].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, *fd=%p)",
> +         this, fd);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_fstat_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->fstat,
> +             fd);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_create_cbk (call_frame_t *frame,
> +                 void *cookie,
> +                 xlator_t *this,
> +                 int32_t op_ret,
> +                 int32_t op_errno,
> +                 fd_t *fd,
> +                 inode_t *inode,
> +                 struct stat *buf)
> +{
> +  char atime_buf[256], mtime_buf[256], ctime_buf[256];
> +  ERR_EINVAL_NORETURN (!this);
> +
> +  if (fop_names[GF_FOP_CREATE].enabled) {
> +    if (op_ret >= 0) {
> +      strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_atime));
> +      strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_mtime));
> +      strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_ctime));
> +
> +      gf_log (this->name, GF_LOG_DEBUG,
> +           "(*this=%s, op_ret=%d, op_errno=%d, fd=%p, inode=%p), *buf=%p
> {st_dev=%lld, st_ino=%lld, st_mode=%d, st_nlink=%d, st_uid=%d, st_gid=%d,
> st_rdev=%llx, st_size=%lld, st_blksize=%ld, st_blocks=%lld, st_atime=%s,
> st_mtime=%s, st_ctime=%s})",
> +           this->name, op_ret, op_errno, fd, inode, buf, buf->st_dev,
> buf->st_ino, buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid,
> buf->st_rdev, buf->st_size, buf->st_blksize, buf->st_blocks, atime_buf,
> mtime_buf, ctime_buf);
> +  } else {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, fd, inode, buf);
> +  return 0;
> +}
> +static int32_t
> +quota_create (call_frame_t *frame,
> +             xlator_t *this,
> +             loc_t *loc,
> +             int32_t flags,
> +             mode_t mode,
> +             fd_t *fd)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc->path);
> +
> +  if (fop_names[GF_FOP_CREATE].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, loc=%p {path=%s, inode=%p}, flags=0%o mode=0%o)",
> +         this, loc, loc->path, loc->inode, flags, mode);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_create_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->create,
> +             loc,
> +             flags,
> +             mode,
> +             fd);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_open_cbk (call_frame_t *frame,
> +               void *cookie,
> +               xlator_t *this,
> +               int32_t op_ret,
> +               int32_t op_errno,
> +               fd_t *fd)
> +{
> +  ERR_EINVAL_NORETURN (!this);
> +
> +  if (fop_names[GF_FOP_OPEN].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d, *fd=%p)",
> +         this, op_ret, op_errno, fd);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, fd);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_open (call_frame_t *frame,
> +           xlator_t *this,
> +           loc_t *loc,
> +           int32_t flags,
> +           fd_t *fd)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc);
> +
> +  if (fop_names[GF_FOP_OPEN].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, loc=%p {path=%s, inode=%p}, flags=%d, fd=%p)",
> +         this, loc, loc->path, loc->inode, flags, fd);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_open_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->open,
> +             loc,
> +             flags,
> +             fd);
> +  return 0;
> +}
> +
> +
> +
> +
> +static int32_t
> +quota_readv_cbk (call_frame_t *frame,
> +                void *cookie,
> +                xlator_t *this,
> +                int32_t op_ret,
> +                int32_t op_errno,
> +                struct iovec *vector,
> +                int32_t count,
> +                struct stat *buf)
> +{
> +  char atime_buf[256], mtime_buf[256], ctime_buf[256];
> +  ERR_EINVAL_NORETURN (!this);
> +
> +  if (fop_names[GF_FOP_READ].enabled) {
> +
> +  if (op_ret >= 0) {
> +    strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_atime));
> +    strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_mtime));
> +    strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_ctime));
> +
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d, *buf=%p {st_dev=%lld,
> st_ino=%lld, st_mode=%d, st_nlink=%d, st_uid=%d, st_gid=%d, st_rdev=%llx,
> st_size=%lld, st_blksize=%ld, st_blocks=%lld, st_atime=%s, st_mtime=%s,
> st_ctime=%s})",
> +           this, op_ret, op_errno, buf, buf->st_dev, buf->st_ino,
> buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, buf->st_rdev,
> buf->st_size, buf->st_blksize, buf->st_blocks, atime_buf, mtime_buf,
> ctime_buf);
> +  } else {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, vector, count, buf);
> +  return 0;
> +}
> +
> +
> +
> +static int32_t
> +quota_getdents_cbk (call_frame_t *frame,
> +                   void *cookie,
> +                   xlator_t *this,
> +                   int32_t op_ret,
> +                   int32_t op_errno,
> +                   dir_entry_t *entries,
> +                   int32_t count)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_GETDENTS].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d, count=%d)",
> +         this, op_ret, op_errno, count);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, entries, count);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_fsync_cbk (call_frame_t *frame,
> +                void *cookie,
> +                xlator_t *this,
> +                int32_t op_ret,
> +                int32_t op_errno)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_FSYNC].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d)",
> +         this, op_ret, op_errno);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_rename_cbk (call_frame_t *frame,
> +                 void *cookie,
> +                 xlator_t *this,
> +                 int32_t op_ret,
> +                 int32_t op_errno,
> +                 struct stat *buf)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_RENAME].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d, buf=%p)",
> +         this, op_ret, op_errno, buf);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, buf);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_readlink_cbk (call_frame_t *frame,
> +                   void *cookie,
> +                   xlator_t *this,
> +                   int32_t op_ret,
> +                   int32_t op_errno,
> +                   const char *buf)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_READLINK].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d, buf=%s)",
> +         this, op_ret, op_errno, buf);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, buf);
> +  return 0;
> +}
> +
> +int32_t
> +quota_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)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_LOOKUP].enabled) {
> +  if (op_ret >= 0) {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "callid: %lld (*this=%p, op_ret=%d, op_errno=%d, inode=%p,
> *buf=%p {st_dev=%lld, st_ino=%lld, st_mode=%d, st_nlink=%d, st_uid=%d,
> st_gid=%d, st_rdev=%llx, st_size=%lld, st_blksize=%ld, st_blocks=%lld})",
> +           (long long) frame->root->unique, this, op_ret, op_errno,
> inode, buf, buf->st_dev, buf->st_ino, buf->st_mode, buf->st_nlink,
> buf->st_uid, buf->st_gid, buf->st_rdev, buf->st_size, buf->st_blksize,
> buf->st_blocks);
> +  } else {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, inode, buf, xattr);
> +  return 0;
> +}
> +
> +int32_t
> +quota_forget_cbk (call_frame_t *frame,
> +                 void *cookie,
> +                 xlator_t *this,
> +                 int32_t op_ret,
> +                 int32_t op_errno)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_FORGET].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d)",
> +         this, op_ret, op_errno);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_symlink_cbk (call_frame_t *frame,
> +                  void *cookie,
> +                  xlator_t *this,
> +                  int32_t op_ret,
> +                  int32_t op_errno,
> +                  inode_t *inode,
> +                  struct stat *buf)
> +{
> +  char atime_buf[256], mtime_buf[256], ctime_buf[256];
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_SYMLINK].enabled) {
> +  if (op_ret >= 0) {
> +    strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_atime));
> +    strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_mtime));
> +    strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_ctime));
> +
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d, inode=%p, *buf=%p
> {st_dev=%lld, st_ino=%lld, st_mode=%d, st_nlink=%d, st_uid=%d, st_gid=%d,
> st_rdev=%llx, st_size=%lld, st_blksize=%ld, st_blocks=%lld, st_atime=%s,
> st_mtime=%s, st_ctime=%s})",
> +           this, op_ret, op_errno, inode, buf, buf->st_dev, buf->st_ino,
> buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, buf->st_rdev,
> buf->st_size, buf->st_blksize, buf->st_blocks, atime_buf, mtime_buf,
> ctime_buf);
> +  } else {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_mknod_cbk (call_frame_t *frame,
> +                void *cookie,
> +                xlator_t *this,
> +                int32_t op_ret,
> +                int32_t op_errno,
> +                inode_t *inode,
> +                struct stat *buf)
> +{
> +  char atime_buf[256], mtime_buf[256], ctime_buf[256];
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_MKNOD].enabled) {
> +  if (op_ret >= 0) {
> +    strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_atime));
> +    strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_mtime));
> +    strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_ctime));
> +
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d, inode=%p, *buf=%p
> {st_dev=%lld, st_ino=%lld, st_mode=%d, st_nlink=%d, st_uid=%d, st_gid=%d,
> st_rdev=%llx, st_size=%lld, st_blksize=%ld, st_blocks=%lld, st_atime=%s,
> st_mtime=%s, st_ctime=%s})",
> +           this, op_ret, op_errno, inode, buf, buf->st_dev, buf->st_ino,
> buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, buf->st_rdev,
> buf->st_size, buf->st_blksize, buf->st_blocks, atime_buf, mtime_buf,
> ctime_buf);
> +  } else {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
> +  return 0;
> +}
> +
> +
> +static int32_t
> +quota_mkdir_cbk (call_frame_t *frame,
> +                void *cookie,
> +                xlator_t *this,
> +                int32_t op_ret,
> +                int32_t op_errno,
> +                inode_t *inode,
> +                struct stat *buf)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_MKDIR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d, inode=%p",
> +         this, op_ret, op_errno, inode);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_link_cbk (call_frame_t *frame,
> +               void *cookie,
> +               xlator_t *this,
> +               int32_t op_ret,
> +               int32_t op_errno,
> +               inode_t *inode,
> +               struct stat *buf)
> +{
> +  char atime_buf[256], mtime_buf[256], ctime_buf[256];
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_LINK].enabled) {
> +  if (op_ret >= 0) {
> +    strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_atime));
> +    strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_mtime));
> +    strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_ctime));
> +
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d, inode=%p, *buf=%p
> {st_dev=%lld, st_ino=%lld, st_mode=%d, st_nlink=%d, st_uid=%d, st_gid=%d,
> st_rdev=%llx, st_size=%lld, st_blksize=%ld, st_blocks=%lld, st_atime=%s,
> st_mtime=%s, st_ctime=%s})",
> +           this, op_ret, op_errno, inode, buf, buf->st_dev, buf->st_ino,
> buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, buf->st_rdev,
> buf->st_size, buf->st_blksize, buf->st_blocks, atime_buf, mtime_buf,
> ctime_buf);
> +  } else {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_flush_cbk (call_frame_t *frame,
> +                void *cookie,
> +                xlator_t *this,
> +                int32_t op_ret,
> +                int32_t op_errno)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_FLUSH].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d)",
> +         this, op_ret, op_errno);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_close_cbk (call_frame_t *frame,
> +                void *cookie,
> +                xlator_t *this,
> +                int32_t op_ret,
> +                int32_t op_errno)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_CLOSE].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d)",
> +         this, op_ret, op_errno);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_opendir_cbk (call_frame_t *frame,
> +                  void *cookie,
> +                  xlator_t *this,
> +                  int32_t op_ret,
> +                  int32_t op_errno,
> +                  fd_t *fd)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_OPENDIR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d, fd=%p)",
> +         this, op_ret, op_errno, fd);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, fd);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_rmdir_cbk (call_frame_t *frame,
> +                void *cookie,
> +                xlator_t *this,
> +                int32_t op_ret,
> +                int32_t op_errno)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_RMDIR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d)",
> +         this, op_ret, op_errno);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_truncate_cbk (call_frame_t *frame,
> +                   void *cookie,
> +                   xlator_t *this,
> +                   int32_t op_ret,
> +                   int32_t op_errno,
> +                   struct stat *buf)
> +{
> +  char atime_buf[256], mtime_buf[256], ctime_buf[256];
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_TRUNCATE].enabled) {
> +  if (op_ret >= 0) {
> +    strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_atime));
> +    strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_mtime));
> +    strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_ctime));
> +
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d, *buf=%p {st_dev=%lld,
> st_ino=%lld, st_mode=%d, st_nlink=%d, st_uid=%d, st_gid=%d, st_rdev=%llx,
> st_size=%lld, st_blksize=%ld, st_blocks=%lld, st_atime=%s, st_mtime=%s,
> st_ctime=%s})",
> +           this, op_ret, op_errno, buf, buf->st_dev, buf->st_ino,
> buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, buf->st_rdev,
> buf->st_size, buf->st_blksize, buf->st_blocks, atime_buf, mtime_buf,
> ctime_buf);
> +  } else {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, buf);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_utimens_cbk (call_frame_t *frame,
> +                  void *cookie,
> +                  xlator_t *this,
> +                  int32_t op_ret,
> +                  int32_t op_errno,
> +                  struct stat *buf)
> +{
> +  char atime_buf[256], mtime_buf[256], ctime_buf[256];
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_UTIMENS].enabled) {
> +  if (op_ret >= 0) {
> +    strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_atime));
> +    strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_mtime));
> +    strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_ctime));
> +
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d, *buf=%p {st_dev=%lld,
> st_ino=%lld, st_mode=%d, st_nlink=%d, st_uid=%d, st_gid=%d, st_rdev=%llx,
> st_size=%lld, st_blksize=%ld, st_blocks=%lld, st_atime=%s, st_mtime=%s,
> st_ctime=%s})",
> +           this, op_ret, op_errno, buf, buf->st_dev, buf->st_ino,
> buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, buf->st_rdev,
> buf->st_size, buf->st_blksize, buf->st_blocks, atime_buf, mtime_buf,
> ctime_buf);
> +  } else {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, buf);
> +  return 0;
> +}
> +
> +
> +static int32_t
> +quota_setxattr_cbk (call_frame_t *frame,
> +                   void *cookie,
> +                   xlator_t *this,
> +                   int32_t op_ret,
> +                   int32_t op_errno)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_SETXATTR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d)",
> +         this, op_ret, op_errno);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_getxattr_cbk (call_frame_t *frame,
> +                   void *cookie,
> +                   xlator_t *this,
> +                   int32_t op_ret,
> +                   int32_t op_errno,
> +                   dict_t *dict)
> +{
> +  ERR_EINVAL_NORETURN (!this || !dict);
> +
> +  if (fop_names[GF_FOP_GETXATTR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d, dict=%p)",
> +         this, op_ret, op_errno, dict);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, dict);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_removexattr_cbk (call_frame_t *frame,
> +                      void *cookie,
> +                      xlator_t *this,
> +                      int32_t op_ret,
> +                      int32_t op_errno)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_REMOVEXATTR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d)",
> +         this, op_ret, op_errno);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_closedir_cbk (call_frame_t *frame,
> +                   void *cookie,
> +                   xlator_t *this,
> +                   int32_t op_ret,
> +                   int32_t op_errno)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_CLOSEDIR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d)",
> +         this, op_ret, op_errno);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_fsyncdir_cbk (call_frame_t *frame,
> +                   void *cookie,
> +                   xlator_t *this,
> +                   int32_t op_ret,
> +                   int32_t op_errno)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_FSYNCDIR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d)",
> +         this, op_ret, op_errno);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_access_cbk (call_frame_t *frame,
> +                 void *cookie,
> +                 xlator_t *this,
> +                 int32_t op_ret,
> +                 int32_t op_errno)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_ACCESS].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, op_ret=%d, op_errno=%d)",
> +         this, op_ret, op_errno);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_ftruncate_cbk (call_frame_t *frame,
> +                    void *cookie,
> +                    xlator_t *this,
> +                    int32_t op_ret,
> +                    int32_t op_errno,
> +                    struct stat *buf)
> +{
> +  char atime_buf[256], mtime_buf[256], ctime_buf[256];
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_FTRUNCATE].enabled) {
> +  if (op_ret >= 0) {
> +    strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_atime));
> +    strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_mtime));
> +    strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime
> (&buf->st_ctime));
> +
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d, *buf=%p {st_dev=%lld,
> st_ino=%lld, st_mode=%d, st_nlink=%d, st_uid=%d, st_gid=%d, st_rdev=%llx,
> st_size=%lld, st_blksize=%ld, st_blocks=%lld, st_atime=%s, st_mtime=%s,
> st_ctime=%s})",
> +           this, op_ret, op_errno, buf, buf->st_dev, buf->st_ino,
> buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, buf->st_rdev,
> buf->st_size, buf->st_blksize, buf->st_blocks, atime_buf, mtime_buf,
> ctime_buf);
> +  } else {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, buf);
> +  return 0;
> +}
> +
> +
> +static int32_t
> +quota_lk_cbk (call_frame_t *frame,
> +             void *cookie,
> +             xlator_t *this,
> +             int32_t op_ret,
> +             int32_t op_errno,
> +             struct flock *lock)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_LK].enabled) {
> +  if (op_ret >= 0) {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d, *lock=%p {l_type=%d,
> l_whence=%d, l_start=%lld, l_len=%lld, l_pid=%ld})",
> +           this, op_ret, op_errno, lock,
> +           lock->l_type, lock->l_whence, lock->l_start, lock->l_len,
> lock->l_pid);
> +  } else {
> +    gf_log (this->name,
> +           GF_LOG_DEBUG,
> +           "(*this=%p, op_ret=%d, op_errno=%d)",
> +           this, op_ret, op_errno);
> +  }
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno, lock);
> +  return 0;
> +}
> +
> +
> +static int32_t
> +quota_setdents_cbk (call_frame_t *frame,
> +                   void *cookie,
> +                   xlator_t *this,
> +                   int32_t op_ret,
> +                   int32_t op_errno)
> +{
> +  ERR_EINVAL_NORETURN (!this );
> +
> +  if (fop_names[GF_FOP_SETDENTS].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "*this=%p, op_ret=%d, op_errno=%d",
> +         this, op_ret, op_errno);
> +  }
> +
> +  STACK_UNWIND (frame, op_ret, op_errno);
> +  return 0;
> +}
> +
> +int32_t
> +quota_lookup (call_frame_t *frame,
> +             xlator_t *this,
> +             loc_t *loc,
> +             int32_t need_xattr)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc);
> +
> +  if (fop_names[GF_FOP_LOOKUP].enabled) {
> +  gf_log (this->name, GF_LOG_DEBUG,
> +         "callid: %lld (*this=%p, loc=%p {path=%s, inode=%p} )",
> +         (long long) frame->root->unique, this, loc, loc->path,
> +         loc->inode, need_xattr);
> +  }
> +
> +  STACK_WIND (frame, quota_lookup_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->lookup,
> +             loc, need_xattr);
> +
> +  return 0;
> +}
> +
> +static int32_t
> +quota_forget (call_frame_t *frame,
> +             xlator_t *this,
> +             inode_t *inode)
> +{
> +  ERR_EINVAL_NORETURN (!this || !inode);
> +
> +  if (fop_names[GF_FOP_FORGET].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "callid: %lld (*this=%p, inode=%p})",
> +         (long long) frame->root->unique, this, inode);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_forget_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->forget,
> +             inode);
> +
> +  return 0;
> +}
> +
> +
> +static int32_t
> +quota_readlink (call_frame_t *frame,
> +               xlator_t *this,
> +               loc_t *loc,
> +               size_t size)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc || (size < 1));
> +  if (fop_names[GF_FOP_READLINK].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, loc=%p {path=%s, inode=%p}, size=%d)",
> +         this, loc, loc->path, loc->inode, size);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_readlink_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->readlink,
> +             loc,
> +             size);
> +
> +  return 0;
> +}
> +
> +static int32_t
> +quota_mknod (call_frame_t *frame,
> +            xlator_t *this,
> +            loc_t *loc,
> +            mode_t mode,
> +            dev_t dev)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc->path);
> +
> +  if (fop_names[GF_FOP_MKNOD].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, loc=%p {path=%s, inode=%p}, mode=%d, dev=%lld)",
> +         this, loc, loc->path, loc->inode, mode, dev);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_mknod_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->mknod,
> +             loc,
> +             mode,
> +             dev);
> +
> +  return 0;
> +}
> +
> +static int32_t
> +quota_mkdir (call_frame_t *frame,
> +            xlator_t *this,
> +            loc_t *loc,
> +            mode_t mode)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc->path);
> +
> +  if (fop_names[GF_FOP_MKDIR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, path=%s, loc=%p {path=%s, inode=%p}, mode=%d)",
> +         this, loc->path, loc, loc->inode, mode);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_mkdir_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->mkdir,
> +             loc,
> +             mode);
> +  return 0;
> +}
> +
> +
> +static int32_t
> +quota_rmdir (call_frame_t *frame,
> +            xlator_t *this,
> +            loc_t *loc)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc);
> +
> +  if (fop_names[GF_FOP_RMDIR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, loc=%p {path=%s, inode=%p})",
> +         this, loc, loc->path, loc->inode);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_rmdir_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->rmdir,
> +             loc);
> +
> +  return 0;
> +}
> +
> +static int32_t
> +quota_symlink (call_frame_t *frame,
> +              xlator_t *this,
> +              const char *linkpath,
> +              loc_t *loc)
> +{
> +  ERR_EINVAL_NORETURN (!this || !linkpath || !loc->path);
> +
> +  if (fop_names[GF_FOP_SYMLINK].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, linkpath=%s, loc=%p {path=%s, inode=%p})",
> +         this, linkpath, loc, loc->path, loc->inode);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_symlink_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->symlink,
> +             linkpath,
> +             loc);
> +
> +  return 0;
> +}
> +
> +static int32_t
> +quota_rename (call_frame_t *frame,
> +             xlator_t *this,
> +             loc_t *oldloc,
> +             loc_t *newloc)
> +{
> +  ERR_EINVAL_NORETURN (!this || !oldloc || !newloc);
> +
> +  if (fop_names[GF_FOP_RENAME].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, oldloc=%p{path=%s, inode=%p, ino=%ld},
> newloc=%p{path=%s, inode=%p, ino=%ld})",
> +         this, oldloc, oldloc->path, oldloc->inode, oldloc->ino, newloc,
> newloc->path, newloc->inode, newloc->ino);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_rename_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->rename,
> +             oldloc,
> +             newloc);
> +
> +  return 0;
> +}
> +
> +static int32_t
> +quota_link (call_frame_t *frame,
> +           xlator_t *this,
> +           loc_t *loc,
> +           const char *newpath)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc || !newpath);
> +
> +  if (fop_names[GF_FOP_LINK].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, loc=%p {path=%s, inode=%p}, newpath=%s)",
> +         this, loc, loc->path, loc->inode, newpath);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_link_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->link,
> +             loc,
> +             newpath);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_truncate (call_frame_t *frame,
> +               xlator_t *this,
> +               loc_t *loc,
> +               off_t offset)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc);
> +
> +  if (fop_names[GF_FOP_TRUNCATE].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, loc=%p {path=%s, inode=%p}, offset=%lld)",
> +         this, loc, loc->path, loc->inode, offset);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_truncate_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->truncate,
> +             loc,
> +             offset);
> +
> +  return 0;
> +}
> +
> +static int32_t
> +quota_utimens (call_frame_t *frame,
> +              xlator_t *this,
> +              loc_t *loc,
> +              struct timespec tv[2])
> +{
> +  char actime_str[256];
> +  char modtime_str[256];
> +
> +  ERR_EINVAL_NORETURN (!this || !loc || !tv);
> +
> +  if (fop_names[GF_FOP_UTIMENS].enabled) {
> +  strftime (actime_str, 256, "[%b %d %H:%M:%S]", localtime
> (&tv[0].tv_sec));
> +  strftime (modtime_str, 256, "[%b %d %H:%M:%S]", localtime
> (&tv[1].tv_sec));
> +
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, loc=%p {path=%s, inode=%p}, *tv=%p {actime=%s,
> modtime=%s})",
> +         this, loc, loc->path, loc->inode, tv, actime_str, modtime_str);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_utimens_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->utimens,
> +             loc,
> +             tv);
> +
> +  return 0;
> +}
> +
> +
> +
> +static int32_t
> +quota_readv (call_frame_t *frame,
> +            xlator_t *this,
> +            fd_t *fd,
> +            size_t size,
> +            off_t offset)
> +{
> +  ERR_EINVAL_NORETURN (!this || !fd || (size < 1));
> +
> +  if (fop_names[GF_FOP_READ].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, *fd=%p, size=%d, offset=%lld)",
> +         this, fd, size, offset);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_readv_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->readv,
> +             fd,
> +             size,
> +             offset);
> +  return 0;
> +}
> +
> +
> +
> +static int32_t
> +quota_flush (call_frame_t *frame,
> +            xlator_t *this,
> +            fd_t *fd)
> +{
> +  ERR_EINVAL_NORETURN (!this || !fd);
> +
> +  if (fop_names[GF_FOP_FLUSH].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, *fd=%p)",
> +         this, fd);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_flush_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->flush,
> +             fd);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_close (call_frame_t *frame,
> +            xlator_t *this,
> +            fd_t *fd)
> +{
> +  ERR_EINVAL_NORETURN (!this || !fd);
> +
> +  if (fop_names[GF_FOP_CLOSE].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, *fd=%p)",
> +         this, fd);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_close_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->close,
> +             fd);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_fsync (call_frame_t *frame,
> +            xlator_t *this,
> +            fd_t *fd,
> +            int32_t flags)
> +{
> +  ERR_EINVAL_NORETURN (!this || !fd);
> +
> +  if (fop_names[GF_FOP_FSYNC].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, flags=%d, *fd=%p)",
> +         this, flags, fd);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_fsync_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->fsync,
> +             fd,
> +             flags);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_setxattr (call_frame_t *frame,
> +               xlator_t *this,
> +               loc_t *loc,
> +               dict_t *dict,
> +               int32_t flags)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc || !dict);
> +
> +  if (fop_names[GF_FOP_SETXATTR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, loc=%p {path=%s, inode=%p}, dict=%p, flags=%d)",
> +         this, loc, loc->path, loc->inode, dict, flags);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_setxattr_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->setxattr,
> +             loc,
> +             dict,
> +             flags);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_getxattr (call_frame_t *frame,
> +               xlator_t *this,
> +               loc_t *loc)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc);
> +
> +  if (fop_names[GF_FOP_GETXATTR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, loc=%p {path=%s, inode=%p})",
> +         this, loc, loc->path, loc->inode);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_getxattr_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->getxattr,
> +             loc);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_removexattr (call_frame_t *frame,
> +                  xlator_t *this,
> +                  loc_t *loc,
> +                  const char *name)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc || !name);
> +
> +  if (fop_names[GF_FOP_REMOVEXATTR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, loc=%p {path=%s, inode=%p}, name=%s)",
> +         this, loc, loc->path, loc->inode, name);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_removexattr_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->removexattr,
> +             loc,
> +             name);
> +
> +  return 0;
> +}
> +
> +static int32_t
> +quota_opendir (call_frame_t *frame,
> +              xlator_t *this,
> +              loc_t *loc,
> +              fd_t *fd)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc );
> +
> +  if (fop_names[GF_FOP_OPENDIR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "callid: %lld (*this=%p, loc=%p {path=%s, inode=%p}, fd=%p)",
> +         (long long) frame->root->unique, this, loc, loc->path,
> loc->inode, fd);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_opendir_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->opendir,
> +             loc,
> +             fd);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_getdents (call_frame_t *frame,
> +               xlator_t *this,
> +               fd_t *fd,
> +               size_t size,
> +               off_t offset,
> +               int32_t flag)
> +{
> +  ERR_EINVAL_NORETURN (!this || !fd);
> +
> +  if (fop_names[GF_FOP_GETDENTS].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "callid: %lld (*this=%p, fd=%p, size=%d, offset=%lld,
> flag=0x%x)",
> +         (long long) frame->root->unique, this, fd, size, offset, flag);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_getdents_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->getdents,
> +             fd,
> +             size,
> +             offset,
> +             flag);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_closedir (call_frame_t *frame,
> +               xlator_t *this,
> +               fd_t *fd)
> +{
> +  ERR_EINVAL_NORETURN (!this || !fd);
> +
> +  if (fop_names[GF_FOP_CLOSEDIR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "callid: %lld (*this=%p, *fd=%p)",
> +         (long long) frame->root->unique, this, fd);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_closedir_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->closedir,
> +             fd);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_fsyncdir (call_frame_t *frame,
> +               xlator_t *this,
> +               fd_t *fd,
> +               int32_t datasync)
> +{
> +  ERR_EINVAL_NORETURN (!this || !fd);
> +
> +  if (fop_names[GF_FOP_FSYNCDIR].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, datasync=%d, *fd=%p)",
> +         this, datasync, fd);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_fsyncdir_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->fsyncdir,
> +             fd,
> +             datasync);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_access (call_frame_t *frame,
> +             xlator_t *this,
> +             loc_t *loc,
> +             int32_t mask)
> +{
> +  ERR_EINVAL_NORETURN (!this || !loc);
> +
> +  if (fop_names[GF_FOP_ACCESS].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, *loc=%p {path=%s, inode=%p}, mask=%d)",
> +         this, loc, loc->path, loc->inode, mask);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_access_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->access,
> +             loc,
> +             mask);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_ftruncate (call_frame_t *frame,
> +                xlator_t *this,
> +                fd_t *fd,
> +                off_t offset)
> +{
> +  ERR_EINVAL_NORETURN (!this || !fd);
> +
> +  if (fop_names[GF_FOP_FTRUNCATE].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, offset=%lld, *fd=%p)",
> +         this, offset, fd);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_ftruncate_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->ftruncate,
> +             fd,
> +             offset);
> +
> +  return 0;
> +}
> +
> +static int32_t
> +quota_lk (call_frame_t *frame,
> +         xlator_t *this,
> +         fd_t *fd,
> +         int32_t cmd,
> +         struct flock *lock)
> +{
> +  ERR_EINVAL_NORETURN (!this || !fd);
> +
> +  if (fop_names[GF_FOP_LK].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, *fd=%p, cmd=%d, lock=%p {l_type=%d, l_whence=%d,
> l_start=%lld, l_len=%lld, l_pid=%ld})",
> +         this, fd, cmd, lock,
> +         lock->l_type, lock->l_whence, lock->l_start, lock->l_len,
> lock->l_pid);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_lk_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->lk,
> +             fd,
> +             cmd,
> +             lock);
> +  return 0;
> +}
> +
> +int32_t
> +quota_setdents (call_frame_t *frame,
> +               xlator_t *this,
> +               fd_t *fd,
> +               int32_t flags,
> +               dir_entry_t *entries,
> +               int32_t count)
> +{
> +  if (fop_names[GF_FOP_SETDENTS].enabled) {
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "(*this=%p, *fd=%p, flags=%d, entries=%p count=%d",
> +         this, fd, flags, entries, count);
> +  }
> +
> +  STACK_WIND (frame,
> +             quota_setdents_cbk,
> +             FIRST_CHILD(this),
> +             FIRST_CHILD(this)->fops->setdents,
> +             fd,
> +             flags,
> +             entries,
> +             count);
> +  return 0;
> +}
> +
> +int32_t
> +notify (xlator_t *this,
> +       int32_t event,
> +       void *data,
> +       ...)
> +{
> +  struct quota_private *private = NULL;
> +
> +  private = this->private;
> +
> +  if (!private)
> +    return 0;
> +
> +  switch (event) {
> +    case GF_EVENT_CHILD_UP:
> +    {
> +      gf_log (this->name,
> +             GF_LOG_WARNING,
> +             "Notify Event CHILD_UP (%d)\n", event);
> +      default_notify (this, event, data);
> +    }
> +    break;
> +    case GF_EVENT_CHILD_DOWN:
> +    {
> +      gf_log (this->name,
> +             GF_LOG_WARNING,
> +              "Notify Event CHILD_DOWN (%d)\n", event);
> +      default_notify (this, event, data);
> +    }
> +    break;
> +    default:
> +    {
> +      default_notify (this, event, data);
> +    }
> +  }
> +
> +  return 0;
> +}
> +
> +int32_t
> +init (xlator_t *this)
> +{
> +
> +void
> +gf_log_xlator (xlator_t *this) {
> +    int32_t len;
> +    char *buf;
> +
> +    if (!this)
> +      return;
> +
> +    len = dict_serialized_length (this->options);
> +    buf = alloca (len);
> +    dict_serialize (this->options, buf);
> +
> +    gf_log (this->name,
> +           GF_LOG_WARNING,
> +           "init name=%s, next=%s, parent=%s ",
> +           this->name, this->next->name, this->parent->name);
> +}
> +
> +  dict_t *options = this->options;
> +
> +  struct quota_private *private = calloc (1, sizeof (*private));
> +
> +  if (!this)
> +    return -1;
> +  if (!this->children) {
> +    gf_log (this->name,
> +           GF_LOG_ERROR,
> +           "quota translator requires one subvolume");
> +    return -1;
> +  }
> +
> +  if (this->children->next) {
> +    gf_log (this->name,
> +           GF_LOG_ERROR,
> +           "quota translator does not support more than one sub-volume");
> +    return -1;
> +  }
> +  // If parameter "max-size" is set init vars
> +  if (dict_get (this->options, "max-size")) {
> +    private->storage_size = gf_str_to_long_long (data_to_str (dict_get
> (this->options,"max-size")));
> +    private->disk_usage   = 0;
> +    private->free_disk    = private->storage_size;
> +
> +    gf_log (this->name, GF_LOG_DEBUG,
> +            "Max filesystem size reported = %s",
> +            dict_get (this->options,"max-size"));
> +  } else {
> +    private->storage_size = 0;
> +  }
> +
> +  //gf_log_set_loglevel (GF_LOG_DEBUG);
> +
> +
> +  gf_log_xlator(this);
> +
> +  /* Set this translator's inode table pointer to child node's pointer.
> */
> +  this->itable = FIRST_CHILD (this)->itable;
> +
> +  this->private = (void *)private;
> +
> +
> +  return 0;
> +}
> +
> +
> +void
> +fini (xlator_t *this)
> +{
> +  if (!this)
> +    return;
> +
> +
> +  /* Free up the dictionary options */
> +  dict_destroy (FIRST_CHILD(this)->options);
> +
> +  gf_log (this->name,
> +         GF_LOG_DEBUG,
> +         "quota translator unloaded");
> +  return;
> +}
> +
> +struct xlator_fops fops = {
> +  //.stat        = quota_stat,
> +  .readlink    = quota_readlink,
> +  .mknod       = quota_mknod,
> +  .mkdir       = quota_mkdir,
> +  .unlink      = quota_unlink,
> +  .rmdir       = quota_rmdir,
> +  .symlink     = quota_symlink,
> +  .rename      = quota_rename,
> +  .link        = quota_link,
> +  //.chmod       = quota_chmod,
> +  //.chown       = quota_chown,
> +  .truncate    = quota_truncate,
> +  .utimens     = quota_utimens,
> +  .open        = quota_open,
> +  .readv       = quota_readv,
> +  .writev      = quota_writev,
> +  .statfs      = quota_statfs,
> +  .flush       = quota_flush,
> +  .close       = quota_close,
> +  .fsync       = quota_fsync,
> +  .setxattr    = quota_setxattr,
> +  .getxattr    = quota_getxattr,
> +  .removexattr = quota_removexattr,
> +  .opendir     = quota_opendir,
> +  //.readdir     = quota_readdir, FIXME: implement quota_readdir
> +  .closedir    = quota_closedir,
> +  .fsyncdir    = quota_fsyncdir,
> +  .access      = quota_access,
> +  .ftruncate   = quota_ftruncate,
> +  .fstat       = quota_fstat,
> +  .create      = quota_create,
> +  //.fchown      = quota_fchown,
> +  //.fchmod      = quota_fchmod,
> +  .lk          = quota_lk,
> +  .lookup      = quota_lookup,
> +  .forget      = quota_forget,
> +  .setdents    = quota_setdents,
> +  .getdents    = quota_getdents,
> +};
> +
> +static int32_t
> +quota_stats_cbk (call_frame_t *frame,
> +                void *cookie,
> +                xlator_t *this,
> +                int32_t op_ret,
> +                int32_t op_errno,
> +                struct xlator_stats *stats)
> +{
> +  struct quota_private *private = NULL;
> +
> +
> +  private = this->private;
> +
> +  // Here we control space available to upper modules
> +  if (private->storage_size > 0) {
> +    // Show original values
> +    gf_log (this->name,
> +            GF_LOG_WARNING,
> +           "quota_stats_cbk (Limiting storage in stats_cbk)\n");
> +    printf ("Pre Limit: %lld Total: %lld Free: %lld Used: %lld \n",
> +           private->storage_size,
> +           stats->total_disk_size,
> +           stats->free_disk,
> +           stats->disk_usage);
> +    // Alter values for enforce limitation
> +    stats->total_disk_size = private->storage_size;
> +    stats->free_disk       = private->free_disk;
> +    stats->disk_usage      = private->disk_usage;
> +
> +    printf ("Post Limit: %lld Total: %lld Free: %lld Used: %lld \n",
> +           private->storage_size,
> +           stats->total_disk_size,
> +           stats->free_disk,
> +           stats->disk_usage);
> +  }
> +  STACK_UNWIND (frame, op_ret, op_errno, stats);
> +  return 0;
> +}
> +
> +static int32_t
> +quota_stats (call_frame_t *frame,
> +            xlator_t *this,
> +            int32_t flags)
> +{
> +  ERR_EINVAL_NORETURN (!this);
> +
> +  {
> +    gf_log (this->name, GF_LOG_DEBUG, "quota_stats (*this=%p,
> flags=%d\n", this, flags);
> +
> +    STACK_WIND (frame,
> +               quota_stats_cbk,
> +               FIRST_CHILD(this),
> +               FIRST_CHILD(this)->mops->stats,
> +               flags);
> +  }
> +  return 0;
> +}
> +
> +struct xlator_mops mops = {
> +  .stats = quota_stats
> +};
>
>
> _______________________________________________
> Gluster-devel mailing list
> Gluster-devel at nongnu.org
> http://lists.nongnu.org/mailman/listinfo/gluster-devel
>



-- 
If I traveled to the end of the rainbow
As Dame Fortune did intend,
Murphy would be there to tell me
The pot's at the other end.



More information about the Gluster-devel mailing list