nfs-ganesha 1.4
|
00001 /* 00002 FUSE: Filesystem in Userspace 00003 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> 00004 00005 This program can be distributed under the terms of the GNU GPL. 00006 See the file COPYING. 00007 00008 gcc -Wall `pkg-config fuse --cflags --libs` -lulockmgr fusexmp_fh.c -o fusexmp_fh 00009 */ 00010 00011 #define FUSE_USE_VERSION 26 00012 00013 #ifdef HAVE_CONFIG_H 00014 #include <config.h> 00015 #endif 00016 00017 #ifdef _SOLARIS 00018 #include "solaris_port.h" 00019 #endif 00020 00021 #include <ganesha_fuse_wrap.h> 00022 /*#include <ulockmgr.h> */ 00023 #include <stdio.h> 00024 #include <string.h> 00025 #include <unistd.h> 00026 #include <fcntl.h> 00027 #include <dirent.h> 00028 #include <errno.h> 00029 #include <sys/time.h> 00030 #ifdef HAVE_SETXATTR 00031 #include <sys/xattr.h> 00032 #endif 00033 00034 static int xmp_getattr(const char *path, struct stat *stbuf) 00035 { 00036 int res; 00037 00038 res = lstat(path, stbuf); 00039 if(res == -1) 00040 return -errno; 00041 00042 #ifdef _FULL_DEBUG 00043 printf("inode=%llu\n", (unsigned long long)stbuf->st_ino); 00044 #endif 00045 00046 return 0; 00047 } 00048 00049 static int xmp_fgetattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi) 00050 { 00051 int res; 00052 00053 (void)path; 00054 00055 res = fstat(fi->fh, stbuf); 00056 if(res == -1) 00057 return -errno; 00058 00059 return 0; 00060 } 00061 00062 static int xmp_access(const char *path, int mask) 00063 { 00064 int res; 00065 00066 res = access(path, mask); 00067 if(res == -1) 00068 return -errno; 00069 00070 return 0; 00071 } 00072 00073 static int xmp_readlink(const char *path, char *buf, size_t size) 00074 { 00075 int res; 00076 00077 res = readlink(path, buf, size - 1); 00078 if(res == -1) 00079 return -errno; 00080 00081 buf[res] = '\0'; 00082 return 0; 00083 } 00084 00085 static int xmp_opendir(const char *path, struct fuse_file_info *fi) 00086 { 00087 DIR *dp = opendir(path); 00088 if(dp == NULL) 00089 return -errno; 00090 00091 fi->fh = (unsigned long)dp; 00092 return 0; 00093 } 00094 00095 static inline DIR *get_dirp(struct fuse_file_info *fi) 00096 { 00097 return (DIR *) (uintptr_t) fi->fh; 00098 } 00099 00100 static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, 00101 off_t offset, struct fuse_file_info *fi) 00102 { 00103 DIR *dp = get_dirp(fi); 00104 struct dirent *de; 00105 00106 (void)path; 00107 seekdir(dp, offset); 00108 while((de = readdir(dp)) != NULL) 00109 { 00110 /*struct stat st; 00111 memset(&st, 0, sizeof(st)); 00112 st.st_ino = de->d_ino; 00113 st.st_mode = de->d_type << 12; */ 00114 if(filler(buf, de->d_name, NULL, telldir(dp))) 00115 break; 00116 } 00117 00118 return 0; 00119 } 00120 00121 static int xmp_releasedir(const char *path, struct fuse_file_info *fi) 00122 { 00123 DIR *dp = get_dirp(fi); 00124 (void)path; 00125 closedir(dp); 00126 return 0; 00127 } 00128 00129 static int xmp_mknod(const char *path, mode_t mode, dev_t rdev) 00130 { 00131 int res; 00132 00133 if(S_ISFIFO(mode)) 00134 res = mkfifo(path, mode); 00135 else 00136 res = mknod(path, mode, rdev); 00137 if(res == -1) 00138 return -errno; 00139 00140 return 0; 00141 } 00142 00143 static int xmp_mkdir(const char *path, mode_t mode) 00144 { 00145 int res; 00146 00147 res = mkdir(path, mode); 00148 if(res == -1) 00149 return -errno; 00150 00151 return 0; 00152 } 00153 00154 static int xmp_unlink(const char *path) 00155 { 00156 int res; 00157 00158 res = unlink(path); 00159 if(res == -1) 00160 return -errno; 00161 00162 return 0; 00163 } 00164 00165 static int xmp_rmdir(const char *path) 00166 { 00167 int res; 00168 00169 res = rmdir(path); 00170 if(res == -1) 00171 return -errno; 00172 00173 return 0; 00174 } 00175 00176 static int xmp_symlink(const char *from, const char *to) 00177 { 00178 int res; 00179 00180 res = symlink(from, to); 00181 if(res == -1) 00182 return -errno; 00183 00184 return 0; 00185 } 00186 00187 static int xmp_rename(const char *from, const char *to) 00188 { 00189 int res; 00190 00191 res = rename(from, to); 00192 if(res == -1) 00193 return -errno; 00194 00195 return 0; 00196 } 00197 00198 static int xmp_link(const char *from, const char *to) 00199 { 00200 int res; 00201 00202 res = link(from, to); 00203 if(res == -1) 00204 return -errno; 00205 00206 return 0; 00207 } 00208 00209 static int xmp_chmod(const char *path, mode_t mode) 00210 { 00211 int res; 00212 00213 res = chmod(path, mode); 00214 if(res == -1) 00215 return -errno; 00216 00217 return 0; 00218 } 00219 00220 static int xmp_chown(const char *path, uid_t uid, gid_t gid) 00221 { 00222 int res; 00223 00224 res = lchown(path, uid, gid); 00225 if(res == -1) 00226 return -errno; 00227 00228 return 0; 00229 } 00230 00231 static int xmp_truncate(const char *path, off_t size) 00232 { 00233 int res; 00234 00235 res = truncate(path, size); 00236 if(res == -1) 00237 return -errno; 00238 00239 return 0; 00240 } 00241 00242 static int xmp_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) 00243 { 00244 int res; 00245 00246 (void)path; 00247 00248 res = ftruncate(fi->fh, size); 00249 if(res == -1) 00250 return -errno; 00251 00252 return 0; 00253 } 00254 00255 static int xmp_utimens(const char *path, const struct timespec ts[2]) 00256 { 00257 int res; 00258 struct timeval tv[2]; 00259 00260 tv[0].tv_sec = ts[0].tv_sec; 00261 tv[0].tv_usec = ts[0].tv_nsec / 1000; 00262 tv[1].tv_sec = ts[1].tv_sec; 00263 tv[1].tv_usec = ts[1].tv_nsec / 1000; 00264 00265 res = utimes(path, tv); 00266 if(res == -1) 00267 return -errno; 00268 00269 return 0; 00270 } 00271 00272 static int xmp_create(const char *path, mode_t mode, struct fuse_file_info *fi) 00273 { 00274 int fd; 00275 00276 fd = open(path, fi->flags, mode); 00277 if(fd == -1) 00278 return -errno; 00279 00280 fi->fh = fd; 00281 return 0; 00282 } 00283 00284 static int xmp_open(const char *path, struct fuse_file_info *fi) 00285 { 00286 int fd; 00287 00288 fd = open(path, fi->flags); 00289 if(fd == -1) 00290 return -errno; 00291 00292 fi->fh = fd; 00293 return 0; 00294 } 00295 00296 static int xmp_read(const char *path, char *buf, size_t size, off_t offset, 00297 struct fuse_file_info *fi) 00298 { 00299 int res; 00300 00301 (void)path; 00302 res = pread(fi->fh, buf, size, offset); 00303 if(res == -1) 00304 res = -errno; 00305 00306 return res; 00307 } 00308 00309 static int xmp_write(const char *path, const char *buf, size_t size, 00310 off_t offset, struct fuse_file_info *fi) 00311 { 00312 int res; 00313 00314 (void)path; 00315 res = pwrite(fi->fh, buf, size, offset); 00316 if(res == -1) 00317 res = -errno; 00318 00319 return res; 00320 } 00321 00322 static int xmp_statfs(const char *path, struct statvfs *stbuf) 00323 { 00324 int res; 00325 00326 res = statvfs(path, stbuf); 00327 if(res == -1) 00328 return -errno; 00329 00330 return 0; 00331 } 00332 00333 static int xmp_flush(const char *path, struct fuse_file_info *fi) 00334 { 00335 int res; 00336 00337 (void)path; 00338 /* This is called from every close on an open file, so call the 00339 close on the underlying filesystem. But since flush may be 00340 called multiple times for an open file, this must not really 00341 close the file. This is important if used on a network 00342 filesystem like NFS which flush the data/metadata on close() */ 00343 res = close(dup(fi->fh)); 00344 if(res == -1) 00345 return -errno; 00346 00347 return 0; 00348 } 00349 00350 static int xmp_release(const char *path, struct fuse_file_info *fi) 00351 { 00352 (void)path; 00353 close(fi->fh); 00354 00355 return 0; 00356 } 00357 00358 static int xmp_fsync(const char *path, int isdatasync, struct fuse_file_info *fi) 00359 { 00360 int res; 00361 (void)path; 00362 00363 #ifndef HAVE_FDATASYNC 00364 (void)isdatasync; 00365 #else 00366 if(isdatasync) 00367 res = fdatasync(fi->fh); 00368 else 00369 #endif 00370 res = fsync(fi->fh); 00371 if(res == -1) 00372 return -errno; 00373 00374 return 0; 00375 } 00376 00377 #ifdef HAVE_SETXATTR 00378 /* xattr operations are optional and can safely be left unimplemented */ 00379 static int xmp_setxattr(const char *path, const char *name, const char *value, 00380 size_t size, int flags) 00381 { 00382 int res = lsetxattr(path, name, value, size, flags); 00383 if(res == -1) 00384 return -errno; 00385 return 0; 00386 } 00387 00388 static int xmp_getxattr(const char *path, const char *name, char *value, size_t size) 00389 { 00390 int res = lgetxattr(path, name, value, size); 00391 if(res == -1) 00392 return -errno; 00393 return res; 00394 } 00395 00396 static int xmp_listxattr(const char *path, char *list, size_t size) 00397 { 00398 int res = llistxattr(path, list, size); 00399 if(res == -1) 00400 return -errno; 00401 return res; 00402 } 00403 00404 static int xmp_removexattr(const char *path, const char *name) 00405 { 00406 int res = lremovexattr(path, name); 00407 if(res == -1) 00408 return -errno; 00409 return 0; 00410 } 00411 #endif /* HAVE_SETXATTR */ 00412 00413 static int xmp_lock(const char *path, struct fuse_file_info *fi, int cmd, 00414 struct flock *lock) 00415 { 00416 (void)path; 00417 00418 #if 0 00419 return ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner, sizeof(fi->lock_owner)); 00420 #else 00421 return 0; 00422 #endif 00423 00424 } 00425 00426 static struct fuse_operations xmp_oper = { 00427 .getattr = xmp_getattr, 00428 .fgetattr = xmp_fgetattr, 00429 .access = xmp_access, 00430 .readlink = xmp_readlink, 00431 .opendir = xmp_opendir, 00432 .readdir = xmp_readdir, 00433 .releasedir = xmp_releasedir, 00434 .mknod = xmp_mknod, 00435 .mkdir = xmp_mkdir, 00436 .symlink = xmp_symlink, 00437 .unlink = xmp_unlink, 00438 .rmdir = xmp_rmdir, 00439 .rename = xmp_rename, 00440 .link = xmp_link, 00441 .chmod = xmp_chmod, 00442 .chown = xmp_chown, 00443 .truncate = xmp_truncate, 00444 .ftruncate = xmp_ftruncate, 00445 .utimens = xmp_utimens, 00446 .create = xmp_create, 00447 .open = xmp_open, 00448 .read = xmp_read, 00449 .write = xmp_write, 00450 .statfs = xmp_statfs, 00451 .flush = xmp_flush, 00452 .release = xmp_release, 00453 .fsync = xmp_fsync, 00454 #ifdef HAVE_SETXATTR 00455 .setxattr = xmp_setxattr, 00456 .getxattr = xmp_getxattr, 00457 .listxattr = xmp_listxattr, 00458 .removexattr = xmp_removexattr, 00459 #endif 00460 .lock = xmp_lock, 00461 }; 00462 00463 int main(int argc, char *argv[]) 00464 { 00465 umask(0); 00466 return fuse_main(argc, argv, &xmp_oper, NULL); 00467 }