fuse_impls_readdir.c
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:4k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. #include "fuse_dfs.h"
  19. #include "fuse_impls.h"
  20. #include "fuse_stat_struct.h"
  21. #include "fuse_connect.h"
  22. int dfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
  23.                        off_t offset, struct fuse_file_info *fi)
  24. {
  25.   TRACE1("readdir",path)
  26.   (void) offset;
  27.   (void) fi;
  28.   // retrieve dfs specific data
  29.   dfs_context *dfs = (dfs_context*)fuse_get_context()->private_data;
  30.   // check params and the context var
  31.   assert(dfs);
  32.   assert(path);
  33.   assert(buf);
  34.   int path_len = strlen(path);
  35.   hdfsFS userFS;
  36.   // if not connected, try to connect and fail out if we can't.
  37.   if ((userFS = doConnectAsUser(dfs->nn_hostname,dfs->nn_port))== NULL) {
  38.     syslog(LOG_ERR, "ERROR: could not connect to dfs %s:%dn", __FILE__, __LINE__);
  39.     return -EIO;
  40.   }
  41.   // call dfs to read the dir
  42.   int numEntries = 0;
  43.   hdfsFileInfo *info = hdfsListDirectory(userFS,path,&numEntries);
  44.   userFS = NULL;
  45.   // NULL means either the directory doesn't exist or maybe IO error.
  46.   if (NULL == info) {
  47.     return -ENOENT;
  48.   }
  49.   int i ;
  50.   for (i = 0; i < numEntries; i++) {
  51.     // check the info[i] struct
  52.     if (NULL == info[i].mName) {
  53.       syslog(LOG_ERR,"ERROR: for <%s> info[%d].mName==NULL %s:%d", path, i, __FILE__,__LINE__);
  54.       continue;
  55.     }
  56.     struct stat st;
  57.     fill_stat_structure(&info[i], &st);
  58.     // hack city: todo fix the below to something nicer and more maintainable but
  59.     // with good performance
  60.     // strip off the path but be careful if the path is solely '/'
  61.     // NOTE - this API started returning filenames as full dfs uris
  62.     const char *const str = info[i].mName + dfs->dfs_uri_len + path_len + ((path_len == 1 && *path == '/') ? 0 : 1);
  63.     // pack this entry into the fuse buffer
  64.     int res = 0;
  65.     if ((res = filler(buf,str,&st,0)) != 0) {
  66.       syslog(LOG_ERR, "ERROR: readdir filling the buffer %d %s:%dn",res, __FILE__, __LINE__);
  67.     }
  68.   }
  69.   // insert '.' and '..'
  70.   const char *const dots [] = { ".",".."};
  71.   for (i = 0 ; i < 2 ; i++)
  72.     {
  73.       struct stat st;
  74.       memset(&st, 0, sizeof(struct stat));
  75.       // set to 0 to indicate not supported for directory because we cannot (efficiently) get this info for every subdirectory
  76.       st.st_nlink =  0;
  77.       // setup stat size and acl meta data
  78.       st.st_size    = 512;
  79.       st.st_blksize = 512;
  80.       st.st_blocks  =  1;
  81.       st.st_mode    = (S_IFDIR | 0777);
  82.       st.st_uid     = default_id;
  83.       st.st_gid     = default_id;
  84.       // todo fix below times
  85.       st.st_atime   = 0;
  86.       st.st_mtime   = 0;
  87.       st.st_ctime   = 0;
  88.       const char *const str = dots[i];
  89.       // flatten the info using fuse's function into a buffer
  90.       int res = 0;
  91.       if ((res = filler(buf,str,&st,0)) != 0) {
  92.         syslog(LOG_ERR, "ERROR: readdir filling the buffer %d %s:%d", res, __FILE__, __LINE__);
  93.       }
  94.     }
  95.   // free the info pointers
  96.   hdfsFreeFileInfo(info,numEntries);
  97.   return 0;
  98. }