⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io-cache.c

📁 分布式文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   Copyright (c) 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 "glusterfs.h"#include "logging.h"#include "dict.h"#include "xlator.h"#include "io-cache.h"#include <assert.h>#include <sys/time.h>static inline ioc_inode_t *ioc_inode_reupdate (ioc_inode_t *ioc_inode){  ioc_table_t *table = ioc_inode->table;  list_add_tail (&ioc_inode->inode_lru, &table->inode_lru[ioc_inode->weight]);    return ioc_inode;}static inline ioc_inode_t *ioc_get_inode (dict_t *dict,	       char *name){  ioc_inode_t *ioc_inode = NULL;  data_t *ioc_inode_data = dict_get (dict, name);  ioc_table_t *table = NULL;  if (ioc_inode_data) {    ioc_inode = data_to_ptr (ioc_inode_data);    table = ioc_inode->table;    ioc_table_lock (table);    if (list_empty (&ioc_inode->inode_lru)) {      ioc_inode = ioc_inode_reupdate (ioc_inode);    }    ioc_table_unlock (table);  }    return ioc_inode;}int32_tioc_inode_need_revalidate (ioc_inode_t *ioc_inode){  int8_t need_revalidate = 0;  struct timeval tv = {0,};  int32_t ret = -1;  ioc_table_t *table = ioc_inode->table;  ret = gettimeofday (&tv, NULL);  if (time_elapsed (&tv, &ioc_inode->tv) >= table->force_revalidate_timeout)    need_revalidate = 1;  return need_revalidate;}/* * __ioc_inode_flush - flush all the cached pages of the given inode * * @ioc_inode:  * * assumes lock is held */int32_t__ioc_inode_flush (ioc_inode_t *ioc_inode){  ioc_page_t *curr = NULL, *next = NULL;  int32_t destroy_size = 0;  int32_t ret = 0;  list_for_each_entry_safe (curr, next, &ioc_inode->pages, pages) {    ret = ioc_page_destroy (curr);        if (ret != -1)       destroy_size += ret;  }    return destroy_size;}voidioc_inode_flush (ioc_inode_t *ioc_inode){  int32_t destroy_size = 0;      ioc_inode_lock (ioc_inode);  destroy_size = __ioc_inode_flush (ioc_inode);  ioc_inode_unlock (ioc_inode);    if (destroy_size) {    ioc_table_lock (ioc_inode->table);    ioc_inode->table->cache_used -= destroy_size;    ioc_table_unlock (ioc_inode->table);  }  return;}/*  * ioc_utimens_cbk - *  * @frame: * @cookie: * @this: * @op_ret: * @op_errno: * @stbuf: * */int32_tioc_utimens_cbk (call_frame_t *frame,		 void *cookie,		 xlator_t *this,		 int32_t op_ret,		 int32_t op_errno,		 struct stat *stbuf){  STACK_UNWIND (frame, op_ret, op_errno, stbuf);  return 0;}/*  * ioc_utimens - *  * @frame: * @this: * @loc: * @tv: * */int32_tioc_utimens (call_frame_t *frame,	     xlator_t *this,	     loc_t *loc,	     struct timespec *tv){  ioc_inode_t *ioc_inode = ioc_get_inode (loc->inode->ctx, this->name);  if (ioc_inode)    ioc_inode_flush (ioc_inode);  STACK_WIND (frame, ioc_utimens_cbk,	      FIRST_CHILD (this),	      FIRST_CHILD (this)->fops->utimens,	      loc, tv);  return 0;}int32_tioc_lookup_cbk (call_frame_t *frame,		void *cookie,		xlator_t *this,		int32_t op_ret,		int32_t op_errno,		inode_t *inode,		struct stat *stbuf,		dict_t *dict){  ioc_inode_t *ioc_inode = NULL;  uint8_t cache_still_valid = 0;    if (op_ret == 0)    ioc_inode = ioc_get_inode (inode->ctx, this->name);  if (ioc_inode) {    cache_still_valid = ioc_cache_still_valid (ioc_inode, stbuf);        if (!cache_still_valid) {      ioc_inode_flush (ioc_inode);    }     /* update the time-stamp of revalidation */    gettimeofday (&ioc_inode->tv, NULL);  }    STACK_UNWIND (frame, op_ret, op_errno, inode, stbuf, dict);  return 0;}int32_t ioc_lookup (call_frame_t *frame,	    xlator_t *this,	    loc_t *loc,	    int32_t need_xattr){  STACK_WIND (frame,	      ioc_lookup_cbk,	      FIRST_CHILD (this),	      FIRST_CHILD (this)->fops->lookup,	      loc,	      need_xattr);  return 0;}/* * ioc_forget -  * * @frame: * @this: * @inode: * */int32_tioc_forget (call_frame_t *frame,	    xlator_t *this,	    inode_t *inode){  ioc_inode_t *ioc_inode = NULL;  ioc_inode = ioc_get_inode (inode->ctx, this->name);  if (ioc_inode)    ioc_inode_destroy (ioc_inode);	      return 0;}/*  * ioc_cache_validate_cbk -  * * @frame: * @cookie: * @this: * @op_ret: * @op_errno: * @buf * */int32_tioc_cache_validate_cbk (call_frame_t *frame,			void *cookie,			xlator_t *this,			int32_t op_ret,			int32_t op_errno,			struct stat *stbuf){  ioc_local_t *local = frame->local;  ioc_inode_t *ioc_inode = NULL;  size_t destroy_size = 0;  ioc_inode = local->inode;  if (op_ret == -1 || (op_ret >= 0 && !ioc_cache_still_valid(ioc_inode, stbuf))) {      gf_log (ioc_inode->table->xl->name, GF_LOG_DEBUG,	      "cache for inode(%p) is invalid. flushing all pages", ioc_inode);      ioc_inode_lock (ioc_inode);      destroy_size = __ioc_inode_flush (ioc_inode);      if (op_ret >= 0)	ioc_inode->mtime = stbuf->st_mtime;      ioc_inode_unlock (ioc_inode);  }  if (destroy_size) {    ioc_table_lock (ioc_inode->table);    ioc_inode->table->cache_used -= destroy_size;    ioc_table_unlock (ioc_inode->table);  }  if (op_ret < 0)    stbuf = NULL;    ioc_inode_lock (ioc_inode);  gettimeofday (&ioc_inode->tv, NULL);  ioc_inode_unlock (ioc_inode);  ioc_inode_wakeup (frame, ioc_inode, stbuf);    STACK_DESTROY (frame->root);  return 0;}/* * ioc_cache_validate - * * @frame: * @ioc_inode: * @fd: * */static int32_tioc_cache_validate (call_frame_t *frame,		    ioc_inode_t *ioc_inode,		    fd_t *fd,		    ioc_page_t *page){  char need_validate = 0;  ioc_waitq_t *waiter = calloc (1, sizeof (ioc_waitq_t));  call_frame_t *validate_frame = NULL;  ioc_inode_lock (ioc_inode);  if (!ioc_inode->waitq) {    need_validate = 1;  }  waiter->data = page;  waiter->next = ioc_inode->waitq;  ioc_inode->waitq = waiter;  ioc_inode_unlock (ioc_inode);    if (need_validate) {    ioc_local_t *validate_local = calloc (1, sizeof (ioc_local_t));    validate_frame = copy_frame (frame);    validate_local->fd = fd;    validate_local->inode = ioc_inode;    validate_frame->local = validate_local;        STACK_WIND (validate_frame,		ioc_cache_validate_cbk,		FIRST_CHILD (frame->this),		FIRST_CHILD (frame->this)->fops->fstat,		fd);  }  return 0;}static inline uint32_tis_match (const char *path,	  const char *pattern){  char *pathname = strdup (path);  int32_t ret = 0;  ret = fnmatch (pattern, path, FNM_NOESCAPE);    free (pathname);    return (ret == 0);}static uint32_tioc_get_priority (ioc_table_t *table, 		  const char *path){  uint32_t priority = 0;  struct ioc_priority *curr = NULL;    list_for_each_entry (curr, &table->priority_list, list) {    if (is_match (path, curr->pattern))       priority = curr->priority;  }  return priority;}/*  * ioc_open_cbk - open callback for io cache * * @frame: call frame * @cookie: * @this: * @op_ret: * @op_errno: * @fd: * */int32_tioc_open_cbk (call_frame_t *frame,	      void *cookie,	      xlator_t *this,	      int32_t op_ret,	      int32_t op_errno,	      fd_t *fd){  ioc_local_t *local = frame->local;  ioc_table_t *table = this->private;  ioc_inode_t *ioc_inode = NULL;  inode_t *inode = local->file_loc.inode;  uint32_t weight = 0;  const char *path = local->file_loc.path;  if (op_ret != -1) {    /* look for ioc_inode corresponding to this fd */    LOCK (&fd->inode->lock);    ioc_inode = ioc_get_inode (fd->inode->ctx, this->name);          if (!ioc_inode) {      /* this is the first time someone is opening this file */      /* assign weight */      weight = ioc_get_priority (table, path);       ioc_inode = ioc_inode_update (table, inode, weight);      dict_set (fd->inode->ctx, this->name, data_from_static_ptr (ioc_inode));    } else {      ioc_table_lock (ioc_inode->table);      list_move_tail (&ioc_inode->inode_lru,		      &table->inode_lru[ioc_inode->weight]);      ioc_table_unlock (ioc_inode->table);    }    UNLOCK (&fd->inode->lock);    /* If mandatory locking has been enabled on this file,       we disable caching on it */    if (((inode->st_mode & S_ISGID) && !(inode->st_mode & S_IXGRP))) {      dict_set (fd->ctx, this->name, data_from_uint32 (1));    }      /* If O_DIRECT open, we disable caching on it */    if ((local->flags & O_DIRECT)){      /* O_DIRECT is only for one fd, not the inode as a whole */      dict_set (fd->ctx, this->name, data_from_uint32 (1));    }  }  freee (local);  frame->local = NULL;  STACK_UNWIND (frame, op_ret, op_errno, fd);  return 0;}/* * ioc_create_cbk - create callback for io cache * * @frame: call frame * @cookie: * @this: * @op_ret: * @op_errno: * @fd: * @inode: * @buf: * */int32_tioc_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){  ioc_local_t *local = frame->local;  ioc_table_t *table = this->private;  ioc_inode_t *ioc_inode = NULL;  uint32_t weight = 0;  const char *path = local->file_loc.path;  if (op_ret != -1) {    {      /* assign weight */      weight = ioc_get_priority (table, path);      ioc_inode = ioc_inode_update (table, inode, weight);      LOCK (&fd->inode->lock);      dict_set (fd->inode->ctx, this->name, data_from_static_ptr (ioc_inode));      UNLOCK (&fd->inode->lock);    }    /* If mandatory locking has been enabled on this file,       we disable caching on it */    if ((inode->st_mode & S_ISGID) && 	!(inode->st_mode & S_IXGRP)) {      dict_set (fd->ctx, this->name, data_from_uint32 (1));    }    /* If O_DIRECT open, we disable caching on it */    if (local->flags & O_DIRECT){      /* O_DIRECT is only for one fd, not the inode as a whole */      dict_set (fd->ctx, this->name, data_from_uint32 (1));    }      }    frame->local = NULL;  freee (local);  STACK_UNWIND (frame, op_ret, op_errno, fd, inode, buf);  return 0;}/* * ioc_open - open fop for io cache * @frame: * @this: * @loc: * @flags: * */int32_tioc_open (call_frame_t *frame,	  xlator_t *this,	  loc_t *loc,	  int32_t flags,	  fd_t *fd){    ioc_local_t *local = calloc (1, sizeof (ioc_local_t));  local->flags = flags;  local->file_loc.path = loc->path;  local->file_loc.inode = loc->inode;    frame->local = local;    STACK_WIND (frame,	      ioc_open_cbk,	      FIRST_CHILD(this),	      FIRST_CHILD(this)->fops->open,	      loc,	      flags,	      fd);  return 0;}/* * ioc_create - create fop for io cache *  * @frame: * @this: * @pathname: * @flags: * @mode: * */int32_tioc_create (call_frame_t *frame,	    xlator_t *this,	    loc_t *loc,	    int32_t flags,	    mode_t mode,	    fd_t *fd){  ioc_local_t *local = calloc (1, sizeof (ioc_local_t));  local->flags = flags;  local->file_loc.path = loc->path;  frame->local = local;  STACK_WIND (frame, ioc_create_cbk,	      FIRST_CHILD(this),	      FIRST_CHILD(this)->fops->create,	      loc, flags, mode, fd);  return 0;}/* * ioc_close_cbk - close callback *  * @frame: * @cookie: * @this: * @op_ret: * @op_errno: * */int32_tioc_close_cbk (call_frame_t *frame,	       void *cookie,	       xlator_t *this,	       int32_t op_ret,	       int32_t op_errno){  STACK_UNWIND (frame, op_ret, op_errno);  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -