• 沒有找到結果。

CONCLUSIONS AND FUTURE WORK

在文檔中 中 中 (頁 46-69)

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, };

在文檔中 中 中 (頁 46-69)

相關文件