(四)Seafile FUSE 虚拟文件系统开发---功能1

(四)Seafile FUSE 虚拟文件系统开发---功能1

通过对源代码的阅读,现在终于可以进入对功能的开发了,在这周主要完成了第一个功能(列出文件的最后修改时间信息)开发。主要考虑到了以下3种情况:

 * 1. /user --> 用户目录

 * 2. /user/repo-id_name/ --> 仓库根目录

 * 3. /user/repo-id_name/repo_path --> 仓库内文件或者目录

下面对这三种情况逐个分析,并给出对应的实现。

1) 用户目录

对于用户目录的最后修改时间,我认为是该用户的创建时间。通过RPC获取从ccnet模块获取用户信息,进一步获取用户创建时间。

 

    emailuser = get_user_from_ccnet (client, user);
    if (!emailuser) {
        ccnet_rpc_client_free (client);
        return -ENOENT;
    }
	user_ctime = ccnet_email_user_get_ctime(emailuser);
    g_object_unref (emailuser);
    ccnet_rpc_client_free (client);

    stbuf->st_mode = S_IFDIR | 0755;
    stbuf->st_nlink = 2;
    stbuf->st_size = 4096;
	stbuf->st_mtime = user_ctime;

 

2) 仓库根目录和仓库内目录和文件

对于仓库根目录,因为每次commit对应一次更新,其最后的修改时间应该是对应最近的一次commit的时间。而在 getattr_repo 这个函数中,已经通过一系列的操作获取到了该仓库对应的最新一次commit信息,所以处理起来相对简单。而要获取仓库内的目录或文件的修改信息,则需要先获取到该目录或文件的Dirent ,在原系统中并没有对应的函数,所以需要自己重新实现。代码如下:

 

if (S_ISDIR(mode)) {  //如果是目录
        //此次省略若干代码
        dir = seaf_fs_manager_get_seafdir(seaf->fs_mgr,
                                          repo->store_id, repo->version, id);		   //此次省略若干代码
		if(strcmp(repo_path,"/") == 0){  //如果是仓库根目录
			//the dir is the root of the libary ,we obtain its last modify time from the infomation of last commit
			mtime = commit->ctime; //最后一次commit的时间及最后修改时间
		}else{
			//get dirent of the dir
			SeafDirent * dirent; 
            //通过路径获得其dirent 结构
            dirent = fuse_get_dirent_by_path(seaf->fs_mgr,	                                   
                                            repo->store_id, 
                                            repo->version,                                        
                                            commit->root_id,                                        
                                            repo_path);
            //新版本的 repo 格式,dirent 才包含最后修改时间
            if((dirent != NULL)&&(repo->version != 0))
			    stbuf->st_mtime = dirent->mtime; // 设置返回的 struct stat 结构
			seaf_dirent_free ((SeafDirent *)dirent); // 释放dirent数据结构
		}
		
       //此次省略若干代码
        stbuf->st_mtime = mtime; // 设置返回的 struct stat 结构
        seaf_dir_free (dir); // 释放dir数据结构
    } else if (S_ISREG(mode)) {  //如果是文件
        Seafile *file;
		SeafDirent * dirent;
        //此次省略若干代码
       //通过路径获得其dirent 结构
        dirent = fuse_get_dirent_by_path(seaf->fs_mgr,	                                   
                                        repo->store_id, 
                                        repo->version,                                        
                                        commit->root_id,                                        
                                        repo_path);
		if((dirent != NULL)&&(repo->version != 0))
			stbuf->st_mtime = dirent->mtime; // 设置返回的 struct stat 结构
			
		seaf_dirent_free ((SeafDirent *)dirent); // 释放dir数据结构
        seafile_unref (file); //减少引用计数
		
    } else {
        return -ENOENT;
		seaf_warning ("Unknown type.\n");
    }
 

fuse_get_dirent_by_path函数首先获得该文件或目录的上一级目录的dir结构,然后遍历该上级目录的dirent项,查找对应名称的dirent项 ,代码如下:

 

SeafDirent *
fuse_get_dirent_by_path (SeafFSManager *mgr,
                      const char *repo_id,
                      int version,
                      const char *root_id,
                      const char *path)
{
   //此处省略若干代码
   parent_dir  = g_path_get_dirname(path);//父目录
   file_name = g_path_get_basename(path);//文件名

   if(strcmp(parent_dir,".") == 0) 
   //若父目录为根目录,这直接获取该根目录结构
       dir = seaf_fs_manager_get_seafdir (mgr, repo_id, version, root_id);
   else
   //根据路径获取父目录结构
       dir = seaf_fs_manager_get_seafdir_by_path (mgr,
                                              repo_id, version,
                                              root_id,
                                              parent_dir, NULL);

   //此处省略若干代码
   //遍历该目录下的所有dirent,若找到该文件名对应的dirent则退出
   GList *p;
   for (p = dir->entries; p; p = p->next) {
       SeafDirent *d = p->data;
       int r = strcmp (d->name, file_name);
       if (r == 0) {
           dent = seaf_dirent_dup(d);
           break;
       }
   }

  //此处省略若干代码
   return dent;
}

 


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值