References
[1] The DataGrid project, http://eu-datagrid.web.cern.ch
[2] Chaitanya Baru, Reagan Moore, Arcot Rajasekar, and Michael Wan. The SDSC storage resource broker. In Proceedings of IBM Centers for Advanced Studies Conference. IBM, 1998.
[3] A. Azagury, V. Dreizin, M. Factor, E. Henis, D. Naor, N. Rinetzky, O.
Rodeh, J. Satran, A. Tavory, and L. Yerushalmi. Towards an object store.
In The 20th IEEE Symposium on Mass Storage Systems,2003, pages 165–, 2003.
[4] Chin-Chen Chu, Ching-Hsien Hsu and Kai-Wen Lee, “SRBFS: A
User-Level Grid File System for Linux,” Proceedings of the 2nd Workshop on Grid Technology and Applications (WoGTA’05), pages 31-36, Dec.
2005.
[5] Chin-Chen Chu and Ching-Hsien Hsu, “Performance Evaluation of
Distributed SRB Server,” Proceedings of the 3rd Workshop on Grid Technology and Applications (WoGTA’06), pages 181-186, Dec. 2006 [6] N. Ali, M. Lauria. “SEMPLAR: High-Performance Remote Parallel I/O
over SRB”, 5th IEEE/ACM International Symposium on Cluster Computing and the Grid, Cardiff, UK, May 2005.
[7] John H. Howard. An overview of the andrew file system. In Proceedings of the USENIX Winter Conference, pages 23–26, Berkeley, CA, USA, Jan.
1988.
[8] B. Callaghan, B. Pawlowski, and P. Staubach. RFC 1813: NFS version 3 protocol specification, Jun. 1995.
[9] An Overview of DFS,
http://www.transarc.com/Library/documentation/dce/1.1/dfs_admin_gd_1.
html
[10] Grid File System Working Group (GFS-WG),
http://phase.hpcc.jp/ggf/gfs-rg/
[11] I. Foster and C. Kesselman. Globus: A metacomputing infrastructure toolkit. The International Journal of Supercomputer Applications and High Performance Computing, 11(2):115–128, 1997.
[12] O. Tatebe, Y. Morita, S. Matsuoka, N. Soda, and S. Sekiguchi. Grid datafarm architecture for petascale data intensive computing. In Proceedings of the 2nd IEEE/ACM International Symposium on Cluster Computing and the Grid (CCGrid 2002), pages 102–110, 2002
[13] Andrew S. Grimshaw, William A. Wulf, and the Legion team. The legion vision of a worldwide virtual computer. Communications of the ACM, 40(1):39–45, Jan. 1997.
[14] E. Nallipogu, F. Ozguner, and M. Lauria. Improving the Throughput of Remote Storage Access through Pipelining. In Proceedings of the Third International Workshop on Grid Computing, pages 305–316, 2002.
[15] K. Bell, A. Chien, and M. Lauria. A High-Performance Cluster Storage Server. In Proceedings of the 11th IEEE International Symposium on High Performance
[16] Osamu Tatebe, Grid Datafarm Architecture and Standardization of Grid File System, ISGC2004, Taipei, Jul. 2004.
[17] Linux Userland FileSystem, http://lufs.sourceforge.net/lufs
[18] White, B., M. Walker, M. Humphrey, and A. Grimshaw. LegionFS: A Secure and Scalable File System Supporting Cross-Domain
High-Performance Applications. In Proceedings of Supercomputing 2001, Denver, CO, Nov. 2001.
[19] M. Satyanarayanan et al. Coda. http://www.coda.cs.cmu.edu, 2004.
[20] J. Kistler and M. Satyanarayanan. Disconnected operation in the Coda file system. In Proc.13th Symposium on Operating Systems Principles, pages 213–225, Oct. 1991.
[21] S. Ghemawat, H. Gobioff, S.-T. Leung. The Google File System.Proceedings of the Nineteenth ACM Symposium on Operating Systems Principles, pages 29-43, 2003.
[22] A.J.Peters, P.Buncic, P.Saiz, AliEnFS - a Linux File System for the AliEn Grid Services, these proceedings, THAT005
[23] S. Susarla and J. Carter. DataStations: Ubiquitous transient storage for mobile users. Technical Report UUCS-03-024, University of Utah School of Computer Science, Nov. 2003.
[24] Sai Susarla; Carter, J., Flexible Consistency for Wide Area Peer Replication Distributed Computing Systems, 2005. ICDCS 2005.
Proceedings. 25th IEEE International Conference, pages 199 – 208, Jun.
2005.
[25] Filesystem in Userspace,. http://sourceforge.net/projects/avf
[26] M. P. I. Forum. MPI-2: Extensions to the Message-Passing Interface.
http://www.mpi-forum.org/docs/docs.html, 1997.
[27] R. Thakur, W. Gropp, and E. Lusk. An Abstract-Device Interface for Implementing Portable Parallel-I/O Interfaces. In Proceedings of the Sixth
Symposium on the Frontiers of Massively Parallel Computation, pages 180–187, 1996.
[28] ROMIO: A High-Performance, Portable MPI-IO Implementation.
http://www.mcs.anl.gov/romio
[29] PostgreSQL, http://pgcluster.projects.postgresql.org [30] PGCluster, http://pgcluster.projects.postgresql.org [31] High-Availability Linux project, http://linux-ha.org
[32] National Center For High-Performance Computing, http://www.nchc.org.tw
[33] EMC CLARiiON Disk Systems data sheet,
http://www.emc.com/products/systems/clariion_pdfs/C1075_cx_series_ds.pdf [34] Taiwan Advanced Research and Education Network,
http://www.twaren.net
[35] The Bonnie Benchmark, http://www.textuality.com/bonnie [36] Iozone filesystem benchmark., http://www.iozone.org
Appendix Source Code
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <srbClient.h>
#include <pthread.h>
#include <limits.h>
#include <time.h>
#include "scommands.h"
extern char mdasCollectionName[];
extern char mdasCollectionHome[];
extern char srbAuth[];
extern char srbHost[];
extern char srbPort[];
extern char mcatZone[];
extern char srbUser[];
extern char mdasCollectionName[];
extern char mdasCollectionHome[];
extern char defaultResource[];
extern char mdasDomainName[];
struct _file_stat{
char name[256];
struct stat atti;
}file_stat[1000];
/*
struct stat {
dev_t st_dev; // device
ino_t st_ino; // indoe
mode_t st_mode; // mode
nlink_t st_nlink; // number of link
uid_t st_uid; // user id
gid_t st_gid; // group id
dev_t st_rdev;
off_t st_off;
unsigned long st_blksize;
unsigned long st_blocks;
time_t st_atime; // last reading time
time_t st_mtime; // last modified time
time_t st_ctime; // last time of changing mode
};
*/
int file_stat_N=0;
char cache_dir_name[MAX_DATA_SIZE];
srbConn *conn;
FILE *fout;
char tmp_name[MAX_DATA_SIZE];
char tmp_col[MAX_DATA_SIZE];
char tmp_fname[MAX_DATA_SIZE];
unsigned int global_time=0;
// Query MCAT server
char qval[MAX_DCS_NUM][MAX_TOKEN];
int selval[MAX_DCS_NUM];
// Read Cache
#define MAX_SIZE 1024*128
#define MAX_NUM_BUF 100
struct RW_BUF{
unsigned char buf[MAX_SIZE];
char name[MAX_DATA_SIZE];
int fid;
int begin;
int end;
unsigned int time;
int is_last;
int dirty;
}RW_buf[MAX_NUM_BUF];
/* Mutex for locking the SRB context */
pthread_mutex_t ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
char *getAttributeColumn(mdasC_sql_result_struct*, int);
void cache_dir(char *path);
int cache_resource(char *path, int is_dir);
void init_rw_buf(int i){
RW_buf[i].name[0] = '\0';
RW_buf[i].fid = -1;
RW_buf[i].begin = -1;
RW_buf[i].end = -1;
RW_buf[i].time = 0;
RW_buf[i].is_last = 0;
RW_buf[i].dirty = 0;
}
/* not thread safe */
int flush_rw_buf(int i){
int size;
fprintf(fout, "flush_rw_buf :%d\n", i);
if(srbObjSeek(conn, RW_buf[i].fid, RW_buf[i].begin, SEEK_SET) < 0){
fprintf(fout, "flush_rw_buf :%s seek error\n", RW_buf[i].name);
srbObjClose(conn, RW_buf[i].fid);
pthread_mutex_unlock(&ctx_mutex);
return -errno;
}
size = RW_buf[i].end - RW_buf[i].begin;
if(srbObjWrite(conn, RW_buf[i].fid, RW_buf[i].buf, size) < 0 ){
fprintf(fout, "flush_rw_buf :%s, %d, %d write error\n", RW_buf[i].name, RW_buf[i].begin, size);
}
fprintf(fout, "flush_rw_buf :%s, %d, %d\n", RW_buf[i].name, RW_buf[i].begin, RW_buf[i].end);
init_rw_buf(i);
return 0;
}
/* thread safe */
int find_read_cache(int fid, int offset, int size){
int i;
for(i=0; i < MAX_NUM_BUF; i++){
if(fid == RW_buf[i].fid){
if((offset-RW_buf[i].begin) >= 0){
if((offset+size) <= RW_buf[i].end){
fprintf(fout, "find_read_cache :%d, %d\n", i, offset);
return i;
}else if(RW_buf[i].is_last){
fprintf(fout, "find_read_cache :%d, %d\n", i, offset);
return i;
} } } }
fprintf(fout, "find_read_cache : not found\n");
return -1;
}
/* thread safe */
int find_write_cache(int fid, int offset, int size){
int i;
for(i=0; i < MAX_NUM_BUF; i++){
if(fid == RW_buf[i].fid){
if(RW_buf[i].end == offset &&
(RW_buf[i].end+size) <= (RW_buf[i].begin+MAX_SIZE)){
fprintf(fout, "find_write_cache :%d, %d\n", i, offset);
return i;
} } }
return -1;
}
/* return the least recent unused buffer * thread safe
*/
int find_LRU(){
int i;
unsigned int lru_time=UINT_MAX;
int k=-1;
for(i=0; i < MAX_NUM_BUF; i++){
if(RW_buf[i].fid == -1){
RW_buf[i].time = global_time++;
fprintf(fout, "find_LRU :%d (new)\n", i);
return i;
}else{
if(RW_buf[i].time < lru_time){
lru_time = RW_buf[i].time;
k = i;
} } }
fprintf(fout, "find_LRU :%d\n", k);
return k;
}
/* flush dirty buffers * not thread safe
*/
int flush_dirty_cache(int fid){
int i;
int res=-1;
for(i=0; i < MAX_NUM_BUF; i++){
if(fid == RW_buf[i].fid && RW_buf[i].dirty){
flush_rw_buf(i);
res = 0;
} }
return res;
}
/* Split an absolute path into collection and file components.
* Calling function needs to malloc, bzero, and free collection and file.
*/
void split_path(char *absfile, char *collection, char *file){
int len;
char *tmpchar;
/* Split absfile into file and directory components */
if(!(tmpchar = strrchr(absfile, 0x2f))){
strcpy(file,absfile);
strcpy(collection[0], "/");
return;
}else{
strcpy(file,tmpchar + 1);
}
len = tmpchar - absfile;
if(len){
strncpy(collection, absfile, len);
collection[len] = '\0';
}else{
strcpy(collection, "/");
} }
time_t str_to_time_t(char *str){
struct tm st_tm;
strptime(str,"%Y-%m-%d-%H.%M.%S", &st_tm);
return mktime(&st_tm);
}
static int srb_getattr(const char *path, struct stat *stbuf) {
int i;
int res = 0;
memset(stbuf, 0, sizeof(struct stat));
if(strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
stbuf->st_size = 4096;
return res;
}
pthread_mutex_lock(&ctx_mutex);
for(i=0; i < file_stat_N; i++){
if(strcmp(path, file_stat[i].name)!=0) continue;
*stbuf = file_stat[i].atti;
pthread_mutex_unlock(&ctx_mutex);
return res;
}
split_path(path, tmp_col, tmp_fname);
if(strcmp(tmp_fname, "ls") == 0) res = -ENOENT;
if(strcmp(tmp_fname, "rm") == 0) res = -ENOENT;
if(strcmp(tmp_fname, "mkdir") == 0) res = -ENOENT;
if(res == -ENOENT){
pthread_mutex_unlock(&ctx_mutex);
return res;
}
fprintf (fout, "srb_getattr, cache_dir %s %s\n", tmp_col, cache_dir_name);
if(strcmp(path, cache_dir_name)==0){
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
stbuf->st_size = 4096;
pthread_mutex_unlock(&ctx_mutex);
return res;
}
fprintf (fout, "srb_getattr, %s\n", path);
sprintf(tmp_name, "%s%s", mdasCollectionHome, path);
if(tmp_name[strlen(tmp_name)-1]=='/') tmp_name[strlen(tmp_name)-1] = '\0';
res = srbObjStat(conn, MDAS_CATALOG, tmp_name, stbuf);
if(res < 0){
fprintf (fout, "srb_getattr, %s error \n", path);
res = -ENOENT;
}
pthread_mutex_unlock(&ctx_mutex);
return res;
}
static int srb_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler) {
int res=0;
filler(h, ".", 0, 0);
filler(h, "..", 0, 0);
pthread_mutex_lock(&ctx_mutex);
fprintf (fout, "read dir %s\n", path);
cache_dir(path);
for(i=0; i < file_stat_N; i++){
split_path(file_stat[i].name, tmp_col, tmp_fname);
fprintf (fout, "srb_getdir %s %s %s\n", path, tmp_col, tmp_fname);
if(strcmp(tmp_col, path)==0){
res = filler(h, tmp_fname, 0, 0);
if(res != 0) break;
} }
pthread_mutex_unlock(&ctx_mutex);
return res;
}
static int srb_open(const char *path, struct fuse_file_info *fi){
int res=0;
int fd;
int len;
pthread_mutex_lock(&ctx_mutex);
sprintf(tmp_name, "%s%s", mdasCollectionHome, path);
split_path(tmp_name, tmp_col, tmp_fname);
fprintf(fout, "srb_open :%s\n", path);
if((fd = srbObjOpen(conn, tmp_fname, fi->flags, tmp_col)) < 0){
fprintf(fout, "srb_open :%s error!\n", path);
res = -errno;
}else{
fi->fh = fd;
}
pthread_mutex_unlock(&ctx_mutex);
return res;
}
static int srb_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi){
int res=0;
int K;
K = find_read_cache(fi->fh, offset, size);
pthread_mutex_lock(&ctx_mutex);
if(K != -1){
RW_buf[K].time = global_time++;
if(RW_buf[K].end >= offset+size){
memcpy(buf, RW_buf[K].buf+offset-RW_buf[K].begin, size);
pthread_mutex_unlock(&ctx_mutex);
return size;
}else if(RW_buf[K].is_last){
memcpy(buf, RW_buf[K].buf+offset-RW_buf[K].begin, RW_buf[K].end-offset);
pthread_mutex_unlock(&ctx_mutex);
return RW_buf[K].end-offset;
} }
K = find_LRU();
if(RW_buf[K].dirty){
flush_rw_buf(K);
}
if(srbObjSeek(conn, fi->fh, offset, SEEK_SET) < 0){
fprintf(fout, "srb_read :%s seek error\n");
pthread_mutex_unlock(&ctx_mutex);
return -errno;
}
if((res = srbObjRead(conn, fi->fh, RW_buf[K].buf, MAX_SIZE)) < 0){
fprintf(fout, "srb_read :%s read error\n");
pthread_mutex_unlock(&ctx_mutex);
return -errno;
}
memcpy(buf, RW_buf[K].buf, size);
fprintf(fout, "srb_read :%s, offset:%d, size:%d, res: %d\n", path, offset, size, res);
RW_buf[K].fid = fi->fh;
strcpy(RW_buf[K].name, path);
RW_buf[K].is_last = (res != MAX_SIZE);
RW_buf[K].begin = offset;
RW_buf[K].end = offset + res;
RW_buf[K].dirty = 0;
RW_buf[K].time = global_time++;
pthread_mutex_unlock(&ctx_mutex);
return size;
}
static int srb_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi){
int K;
int res = 0;
pthread_mutex_lock(&ctx_mutex);
K = find_write_cache(fi->fh, offset, size);
// write to cache
if(K != -1){
memcpy(RW_buf[K].buf+RW_buf[K].end-RW_buf[K].begin, buf, size);
RW_buf[K].end += size;
RW_buf[K].time = global_time++;
RW_buf[K].dirty = 1;
pthread_mutex_unlock(&ctx_mutex);
return size;
}
K = find_LRU();
if(RW_buf[K].dirty){
flush_rw_buf(K);
}
strcpy(RW_buf[K].name, path);
memcpy(RW_buf[K].buf, buf, size);
RW_buf[K].fid = fi->fh;
RW_buf[K].begin = offset;
RW_buf[K].end = offset + size;
RW_buf[K].dirty = 1;
RW_buf[K].time = global_time++;
pthread_mutex_unlock(&ctx_mutex);
return size;
}
/** Create a file node *
* There is no create() operation, mknod() will be called for * creation of all non-directory, non-symlink nodes.
*/
static int srb_mknod(const char *path, mode_t mode, dev_t rddev){
static char datatype[] = "generic";
int res=0;
pthread_mutex_lock(&ctx_mutex);
fprintf(fout, "srb_mknod :%s\n", path);
sprintf(tmp_name, "%s%s", mdasCollectionHome, path);
split_path(tmp_name, tmp_col, tmp_fname);
if(srbObjCreate(conn, MDAS_CATALOG, tmp_fname, datatype, defaultResource, tmp_col, NULL, 0) < 0){
fprintf(fout, "srb_mknod :%s %s create error\n", tmp_col, tmp_fname);
res = -errno;
}
pthread_mutex_unlock(&ctx_mutex);
return res;
}
/** Create a directory */
static int srb_mkdir(const char *path, mode_t mode){
int res=0;
pthread_mutex_lock(&ctx_mutex);
sprintf(tmp_name, "%s%s", mdasCollectionHome, path);
split_path(tmp_name, tmp_col, tmp_fname);
if(srbCreateCollect(conn, MDAS_CATALOG, tmp_col, tmp_fname) < 0){
res = -errno;
}
pthread_mutex_unlock(&ctx_mutex);
return res;
}
/** Remove a file */
static int srb_unlink(const char *path){
int res=0;
pthread_mutex_lock(&ctx_mutex);
sprintf(tmp_name, "%s%s", mdasCollectionHome, path);
split_path(tmp_name, tmp_col, tmp_fname);
if(srbObjUnlink(conn, tmp_fname, tmp_col) < 0){
res = -errno;
}
pthread_mutex_unlock(&ctx_mutex);
return res;
}
/** Remove a directory */
static int srb_rmdir(const char *path){
int res=0;
pthread_mutex_lock(&ctx_mutex);
sprintf(tmp_name, "%s%s", mdasCollectionHome, path);
if(srbModifyCollect(conn, MDAS_CATALOG, tmp_name, "", "", "", D_DELETE_COLL) < 0){
res = -errno;
}
pthread_mutex_unlock(&ctx_mutex);
return res;
}
static int srb_release(const char *path, struct fuse_file_info *fi){
int K;
pthread_mutex_lock(&ctx_mutex);
fprintf(fout, "srb_release :%s\n", path);
flush_dirty_cache(fi->fh);
srbObjClose(conn, fi->fh);
pthread_mutex_unlock(&ctx_mutex);
return 0;
}
/** Change the permission bits of a file */
int srb_chmod(const char *path, mode_t mode){
printf("srb_chmod unimplement, %s, %d, %d\n", path, mode);
return 0;
}
/** Change the owner and group of a file */
int srb_chown(const char *path, uid_t uid, gid_t gid){
printf("srb_chown unimplement, %s, %d, %d\n", path, uid, gid);
return 0;
}
/** Change the size of a file */
int srb_truncate(const char *path, off_t offset){
if(offset==0){
if(srb_unlink(path) < 0) return -errno;
if(srb_mknod(path, 0, 0) < 0) return -errno;
}else{
printf("srb_truncate unimplement, %s, %d\n", path, offset);
} return 0;
}
/** Change the access and/or modification times of a file */
int srb_utime(const char *path, struct utimbuf *utime){
printf("srb_utime unimplement, %s\n", path);
return 0;
}
/* Initialize SRB connection. */
int srb_init(){
if(firstInitSrbClientEnv() < 0){
printf("Error Opening Client Environment File\n");
exit(1);
}
if(rewriteSrbClientEnvFile() < 0){
printf("Error Writing Client Environment File\n");
exit(1);
}
if(initSrbClientEnv() < 0){
printf("Error Opening Client Environment File\n");
exit(1);
}
pthread_mutex_lock(&ctx_mutex);
conn = srbConnect (NULL, NULL, NULL, NULL, NULL, NULL, NULL);
if(clStatus(conn) != CLI_CONNECTION_OK) { fprintf(fout,"Connection to srbMaster failed.\n");
fprintf(fout,"%s\n",clErrorMessage(conn));
srb_perror (2, clStatus(conn), "", SRB_RCMD_ACTION|SRB_LONG_MSG);
clFinish(conn);
pthread_mutex_unlock(&ctx_mutex);
exit(3);
}
fprintf (fout, "Connected to srbServer successfully\n");
pthread_mutex_unlock(&ctx_mutex);
return 1;
}
int cache_resource(char *path, int is_dir){
mdasC_sql_result_struct collResult;
char *query_result[100];
char *tmp;
int status;
int i, j, len;
int *query_list;
int query_N;
struct _file_stat *tmp_stat;
static int query_file[] = {DATA_NAME, SIZE, REPL_TIMESTAMP, DATA_ACCESS_PRIVILEGE};
static int query_dir[] = {DATA_GRP_NAME};
sprintf(tmp_name, "%s%s", mdasCollectionHome, path);
len = strlen(tmp_name);
if(tmp_name[len-1]=='/') tmp_name[len-1] = '\0';
memset(selval, 0,sizeof(selval));
if(is_dir){
sprintf(qval[PARENT_COLLECTION_NAME]," = '%s'", tmp_name);
strcpy(qval[COLLECTION_NAME],"");
query_list = query_dir;
query_N = sizeof(query_dir)/sizeof(int);
/*
sprintf(file_stat[file_stat_N].name, "%s", path);
file_stat[file_stat_N].atti.st_mode = S_IFDIR | 0755;
file_stat[file_stat_N].atti.st_nlink = 2;
file_stat[file_stat_N].atti.st_size = 4096;
file_stat_N++;
*/
}else{
sprintf(qval[COLLECTION_NAME]," = '%s'", tmp_name);
strcpy(qval[PARENT_COLLECTION_NAME],"");
query_list = query_file;
query_N = sizeof(query_file)/sizeof(int);
}
memset(selval, 0, MAX_DCS_NUM);
for(i=0; i < query_N; i++) selval[query_list[i]] = 1;
status = srbGetDataDirInfo(conn, MDAS_CATALOG, qval, selval, &collResult, 100);
if (status < 0) {
/* if (status == MCAT_INQUIRE_ERROR)
fprintf (fout, "%s: No such collection\n", tmp_name);
else
fprintf (fout, "MCAT query error\n");
*/
clearSqlResult(&collResult);
return status;
}
while(status == 0){
// retrieve the values for(i=0; i < query_N; i++)
query_result[i] = getAttributeColumn(&collResult, query_list[i]);
// print the result
for(i = 0; i < collResult.row_count; i++) { for(j=0; j < query_N; j++){
tmp = query_result[j];
tmp_stat = &file_stat[file_stat_N];
switch(query_list[j]){
case DATA_NAME:
if(strlen(path)==1 && path[0]=='/')
sprintf(tmp_stat->name, "%s%s", path, tmp);
else
sprintf(tmp_stat->name, "%s/%s", path, tmp);
tmp_stat->atti.st_mode = S_IFREG | 0444;
tmp_stat->atti.st_nlink = 1;
break;
case SIZE:
tmp_stat->atti.st_size = atol(tmp);
break;
case REPL_TIMESTAMP:
tmp_stat->atti.st_atime = str_to_time_t(tmp);
tmp_stat->atti.st_mtime = tmp_stat->atti.st_atime;
tmp_stat->atti.st_ctime = tmp_stat->atti.st_atime;
break;
case DATA_ACCESS_PRIVILEGE:
break;
case DATA_GRP_NAME:
if(strlen(mdasCollectionHome) > 1){
strcpy(tmp_stat->name, &tmp[strlen(mdasCollectionHome)]);
}else{
strcpy(tmp_stat->name, tmp);
}
tmp_stat->atti.st_mode = S_IFDIR | 0755;
tmp_stat->atti.st_nlink = 2;
tmp_stat->atti.st_size = 4096;
break;
default:
fprintf(stderr, "unexpected query result!\n");
break;
}
query_result[j] += MAX_DATA_SIZE;
}
file_stat_N++;
}
// if there are more rows retrieve them if(collResult.continuation_index >= 0){
clearSqlResult(&collResult);
status = srbGetMoreRows(conn, MDAS_CATALOG, collResult.continuation_index, &collResult, 100);
}else break;
}
clearSqlResult(&collResult);
return 1;
}
static struct fuse_operations srb_oper = { getattr: srb_getattr,
readlink: NULL, getdir: srb_getdir, mknod: srb_mknod, mkdir: srb_mkdir, symlink: NULL, unlink: srb_unlink, rmdir: srb_rmdir, rename: NULL, link: NULL, chmod: srb_chmod, chown: srb_chown, truncate: srb_truncate, utime: srb_utime, open: srb_open, read: srb_read, write: srb_write, statfs: NULL, release: srb_release, };