Adds sym-link support to the loopback filesystem.
http://code.google.com/p/iphonedisk/source/detail?r=103
Modified:
/trunk/fs/fs_fuse.cc
/trunk/proto/fs.proto
/trunk/proto/fs_service.proto
/trunk/test/loopback_fs_service.cc
=======================================
--- /trunk/fs/fs_fuse.cc Sat Oct 9 22:35:38 2010
+++ /trunk/fs/fs_fuse.cc Sat Oct 9 23:28:21 2010
@@ -69,6 +69,22 @@
fill_stat(response.stat(), stbuf);
return 0;
}
+
+int fs_readlink(const char* path, char *buf, size_t bufsize) {
+ struct Context* context =
+ static_cast<struct Context*>(fuse_get_context()->private_data);
+ rpc::Rpc rpc;
+ proto::ReadLinkRequest request;
+ proto::ReadLinkResponse response;
+ request.mutable_header()->set_fs_id(context->fs_id);
+ request.set_path(path);
+ context->service->ReadLink(&rpc, &request, &response, g_null_callback);
+ if (rpc.Failed()) {
+ return -ENOENT;
+ }
+ strncpy(buf, response.destination().c_str(), bufsize);
+ return 0;
+}
int fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi) {
@@ -85,13 +101,7 @@
}
for (int i = 0; i < response.entry_size(); ++i) {
const proto::ReadDirResponse::Entry& entry = response.entry(i);
- struct stat stbuf;
- struct stat* stbuf_ptr = NULL;
- if (entry.has_stat()) {
- fill_stat(entry.stat(), &stbuf);
- stbuf_ptr = &stbuf;
- }
- if (filler(buf, entry.filename().c_str(), stbuf_ptr, 0) != 0) {
+ if (filler(buf, entry.filename().c_str(), NULL, 0) != 0) {
return -ENOENT;
}
}
@@ -274,6 +284,7 @@
fuse_op->init = fs_init;
fuse_op->destroy = fs_destroy;
fuse_op->getattr = fs_getattr;
+ fuse_op->readlink = fs_readlink;
fuse_op->readdir = fs_readdir;
fuse_op->open = fs_open;
fuse_op->create = fs_create;
=======================================
--- /trunk/proto/fs.proto Sat Oct 9 22:35:38 2010
+++ /trunk/proto/fs.proto Sat Oct 9 23:28:21 2010
@@ -26,6 +26,15 @@
message GetAttrResponse {
optional Stat stat = 1;
}
+
+message ReadLinkRequest {
+ required Header header = 1;
+ required string path = 2;
+}
+
+message ReadLinkResponse {
+ optional string destination = 1;
+}
message ReadDirRequest {
required Header header = 1;
=======================================
--- /trunk/proto/fs_service.proto Sat Mar 13 10:48:45 2010
+++ /trunk/proto/fs_service.proto Sat Oct 9 23:28:21 2010
@@ -8,6 +8,7 @@
service FsService {
rpc GetAttr (GetAttrRequest) returns (GetAttrResponse);
+ rpc ReadLink (ReadLinkRequest) returns (ReadLinkResponse);
rpc ReadDir (ReadDirRequest) returns (ReadDirResponse);
rpc Open (OpenRequest) returns (OpenResponse);
rpc Create (CreateRequest) returns (CreateResponse);
=======================================
--- /trunk/test/loopback_fs_service.cc Sat Oct 9 23:02:04 2010
+++ /trunk/test/loopback_fs_service.cc Sat Oct 9 23:28:21 2010
@@ -26,7 +26,7 @@
proto::GetAttrResponse* response,
Closure* done) {
struct stat stbuf;
- int res = stat(request->path().c_str(), &stbuf);
+ int res = lstat(request->path().c_str(), &stbuf);
if (res == -1) {
rpc->SetFailed(strerror(errno));
} else {
@@ -40,6 +40,21 @@
}
done->Run();
}
+
+ void ReadLink(RpcController* rpc,
+ const proto::ReadLinkRequest* request,
+ proto::ReadLinkResponse* response,
+ Closure* done) {
+ char destination[BUFSIZ];
+ ssize_t n = readlink(request->path().c_str(), destination, BUFSIZ);
+ if (n == -1) {
+ rpc->SetFailed(strerror(errno));
+ } else {
+ destination[n] = '\0';
+ response->set_destination(destination);
+ }
+ done->Run();
+ }
void ReadDir(RpcController* rpc,
const proto::ReadDirRequest* request,