diff options
| author | Vikas Gorur <vikas@zresearch.com> | 2009-02-18 17:36:07 +0530 | 
|---|---|---|
| committer | Vikas Gorur <vikas@zresearch.com> | 2009-02-18 17:36:07 +0530 | 
| commit | 77adf4cd648dce41f89469dd185deec6b6b53a0b (patch) | |
| tree | 02e155a5753b398ee572b45793f889b538efab6b /xlators/meta/src/tree.c | |
| parent | f3b2e6580e5663292ee113c741343c8a43ee133f (diff) | |
Added all files
Diffstat (limited to 'xlators/meta/src/tree.c')
| -rw-r--r-- | xlators/meta/src/tree.c | 176 | 
1 files changed, 176 insertions, 0 deletions
diff --git a/xlators/meta/src/tree.c b/xlators/meta/src/tree.c new file mode 100644 index 00000000000..ec88c42a084 --- /dev/null +++ b/xlators/meta/src/tree.c @@ -0,0 +1,176 @@ +/* +   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 _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <string.h> + +#include "glusterfs.h" +#include "xlator.h" + +#include "meta.h" + +static int +is_meta_path (const char *path) +{ +  while (*path == '/') +    path++; +  if (!strncmp (path, ".meta", strlen (".meta"))) +    return 1; +  return 0; +} + +struct stat * +new_stbuf (void) +{ +  static int next_inode = 0; +  struct stat *stbuf = CALLOC (1, sizeof (struct stat)); +   +  ERR_ABORT (stbuf); + +  stbuf->st_dev = 0; +  stbuf->st_ino = next_inode++; +  stbuf->st_mode = S_IRUSR | S_IRGRP | S_IROTH; +  stbuf->st_nlink = 1; +  stbuf->st_uid = 0; +  stbuf->st_gid = 0; +  stbuf->st_rdev = 0; +  stbuf->st_size = 0; +  stbuf->st_blksize = 0; +  stbuf->st_blocks = 0; +  stbuf->st_atime = time (NULL); +  stbuf->st_atim.tv_nsec = 0; +  stbuf->st_mtime = stbuf->st_atime; +  stbuf->st_mtim.tv_nsec = 0; +  stbuf->st_ctime = stbuf->st_ctime; +  stbuf->st_ctim.tv_nsec = 0; + +  return stbuf; +} + +/* find an entry among the siblings of an entry */ +static meta_dirent_t * +find_entry (meta_dirent_t *node, const char *dir) +{ +  meta_dirent_t *trav = node; +  while (trav) { +    if (!strcmp (trav->name, dir)) +      return trav; +    trav = trav->next; +  } +  return NULL; +} + +/* + * Return the meta_dirent_t corresponding to the pathname. + * + * If pathname does not exist in the meta tree, try to return + * its highest parent that does exist. The part of the + * pathname that is left over is returned in the value-result + * variable {remain}. + * For example, for "/.meta/xlators/brick1/view/foo/bar/baz", + * return the entry for "/.meta/xlators/brick1/view" + * and set remain to "/bar/baz" + */ + +meta_dirent_t * +lookup_meta_entry (meta_dirent_t *root, const char *path, +		   char **remain) +{ +  char *_path = strdup (path); + +  if (!is_meta_path (path)) +    return NULL; + +  meta_dirent_t *trav = root; +  char *dir = strtok (_path, "/"); +  dir = strtok (NULL, "/"); + +  while (dir) { +    meta_dirent_t *ntrav; +    ntrav = find_entry (trav->children, dir); +    if (!ntrav) { +      /* we have reached bottom of the meta tree.  +         Unknown dragons lie further below */ +      if (remain) { +	char *piece = dir; +	while (piece) { +	  char *tmp = *remain; +	  if (*remain) +	    asprintf (remain, "/%s/%s", *remain, piece); +	  else +	    asprintf (remain, "/%s", piece); +	  if (tmp) free (tmp); +	  piece = strtok (NULL, "/"); +	} +      } +      return trav; +    } +    dir = strtok (NULL, "/"); +    trav = ntrav; +  } + +  free (_path); +  return trav; +} + +meta_dirent_t * +insert_meta_entry (meta_dirent_t *root, const char *path, +		   int type, struct stat *stbuf, struct xlator_fops *fops) +{ +  if (!is_meta_path (path)) +    return NULL; +  char *slashpos = strrchr (path, '/'); +  char *dir = strndup (path, slashpos - path); +  meta_dirent_t *parent = lookup_meta_entry (root, dir, NULL); +  if (!dir) +    return NULL; + +  meta_dirent_t *new = CALLOC (1, sizeof (meta_dirent_t)); +  ERR_ABORT (new); +  new->name        = strdup (slashpos+1); +  new->type        = type; +  new->parent      = parent; +  new->next        = parent->children; +  parent->children = new; +  if (stbuf) +    new->stbuf     = stbuf; +  else  +    new->stbuf     = new_stbuf (); + +  new->stbuf->st_mode |= type; +  new->fops        = fops; +  return new; +} + +int main (void) +{ +  meta_dirent_t *root = CALLOC (1, sizeof (meta_dirent_t)); +  ERR_ABORT (root); +  root->name = strdup (".meta"); + +  insert_meta_entry (root, "/.meta/version", S_IFREG, NULL, NULL); +  return 0; +}  | 
