nfs-ganesha 1.4

fusexmp_fh.c

Go to the documentation of this file.
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 }