/* Copyright (c) 2010-2011 Gluster, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _NFS_FOPS_H_ #define _NFS_FOPS_H_ #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include "dict.h" #include "xlator.h" #include "iobuf.h" #include "call-stub.h" #include "stack.h" #include "nfs.h" #include "nfs-common.h" #include /* This structure used to communicate state between a fop and its callback. * The problem is, when we're calling a fop in the nfs op handler, the callback * is the NFS protocol's callback and we have to perform all GlusterFS * inode, inode table, fd_ts and fd table operations in the NFS callback. That * approach soon gets extremely complicated and confusing because, then we have * to try and separate in our heads which source lines in those callbacks are * required for serving the NFS op and which ones are needed for satisfying * GlusterFS requirements. This structure allows us avoid performing GlusterFS * state maintenance operations inside the fops layer itself. Now, before * we call the callback registered by the NFS operation, a hidden fops-layer * specific callback is called which performs the state maintenance and then * calls the NFS callback. * * These are allocated from a mem-pool stored in the nfs xlator's state. * i.e. struct nfs_state. * That is initiated in nfs_init_subvolumes in nfs.c. */ struct nfs_fop_local { /* The local sent along by the user of the fop. */ void *proglocal; /* The address of the callback supplied by the user. After our * callback is executed this one is called. * The exact cast destination of this pointer will depend on the * fop that is being called. */ void *progcbk; /* Used only for write requests. */ struct iobref *iobref; inode_t *parent; inode_t *newparent; inode_t *inode; /* Set to 1 by nfs-inodes layer, which uses this to decide whether to * link the newly allocated inode into the itable, in case the fop was * successful. */ int newinode; /* Used by nfs-fops layer in order to determine whether to funge the * ino in a dir's stbuf. This funging of root ino is needed to ensure * that the root ino remains 1 even when the NFS server has been * restarted. Note that in distribute, a fresh lookup and a revalidate * on the root inode returns two different inode numbers and this we * need to handle by ourself. */ int rootinode; /* This member is used to determine whether the new parent of a file * being renamed is the root directory. If yes, the ino is funged. */ int newrootinode; int newrootparentinode; /* Determines whether to funge the ino in the post and pre parent * stbufs for a file/dir where the parent directory could be the root * dir. Needed here because of the same reason as above. */ int rootparentinode; char path[NFS_NAME_MAX + 1]; char newpath[NFS_NAME_MAX + 1]; xlator_t *nfsx; dict_t *dictgfid; fd_t *fd; int cmd; struct gf_flock flock; }; extern struct nfs_fop_local * nfs_fop_local_init (xlator_t *xl); extern void nfs_fop_local_wipe (xlator_t *xl, struct nfs_fop_local *l); #define nfs_state(nfsxl) (nfsxl)->private #define nfs_fop_mempool(nfxl) (((struct nfs_state *)nfs_state(nfxl))->foppool) #define prog_data_to_nfl(nf,nflocal, fram, pcbk, plocal) \ do { \ nflocal = nfs_fop_local_init (nf); \ if (nflocal) { \ nflocal->proglocal = plocal; \ nflocal->progcbk = *VOID(&pcbk); \ nflocal->nfsx = nf; \ if (fram) \ ((call_frame_t *)fram)->local = nflocal;\ } \ } while (0) \ #define nfl_to_prog_data(nflocal, pcbk, fram) \ do { \ nflocal = fram->local; \ fram->local = nflocal->proglocal; \ pcbk = nflocal->progcbk; \ } while (0) \ #define nfs_fop_handle_local_init(fram,nfx, nfloc, cbck,prgloc,retval,lab) \ do { \ prog_data_to_nfl (nfx, nfloc, fram, cbck, prgloc); \ if (!nfloc) { \ gf_log (GF_NFS,GF_LOG_ERROR,"Failed to init local");\ retval = -ENOMEM; \ goto lab; \ } \ } while (0) \ extern int nfs_fop_fstat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, fop_stat_cbk_t cbk, void *local); extern int nfs_fop_readdirp (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *dirfd, size_t bufsize, off_t offset, fop_readdir_cbk_t cbk, void *local); extern int nfs_fop_lookup (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, fop_lookup_cbk_t cbk, void *local); extern int nfs_fop_create (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, int flags, mode_t mode, fd_t *fd, fop_create_cbk_t cbk, void *local); extern int nfs_fop_flush (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, fop_flush_cbk_t cbk, void *local); extern int nfs_fop_mkdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, mode_t mode, fop_mkdir_cbk_t cbk, void *local); extern int nfs_fop_truncate (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, off_t offset, fop_truncate_cbk_t cbk, void *local); extern int nfs_fop_read (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, size_t size, off_t offset, fop_readv_cbk_t cbk, void *local); extern int nfs_fop_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, int32_t datasync, fop_fsync_cbk_t cbk, void *local); extern int nfs_fop_write (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, struct iobref *srciobref, struct iovec *vector, int32_t count, off_t offset, fop_writev_cbk_t cbk, void *local); extern int nfs_fop_open (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, int32_t flags, fd_t *fd, fop_open_cbk_t cbk, void *local); extern int nfs_fop_rename (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc, loc_t *newloc, fop_rename_cbk_t cbk, void *local); extern int nfs_fop_link (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc, loc_t *newloc, fop_link_cbk_t cbk, void *local); extern int nfs_fop_unlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, fop_unlink_cbk_t cbk, void *local); extern int nfs_fop_rmdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, fop_rmdir_cbk_t cbk, void *local); extern int nfs_fop_mknod (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, mode_t mode, dev_t dev, fop_mknod_cbk_t cbk, void *local); extern int nfs_fop_readlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, size_t size, fop_readlink_cbk_t cbk, void *local); extern int nfs_fop_symlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, char *target, loc_t *pathloc, fop_symlink_cbk_t cbk, void *local); extern int nfs_fop_setattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, struct iatt *buf, int32_t valid, fop_setattr_cbk_t cbk, void *local); extern int nfs_fop_statfs (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, fop_statfs_cbk_t cbk, void *local); extern int nfs_fop_opendir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, fd_t *dirfd, fop_opendir_cbk_t cbk, void *local); extern int nfs_fop_stat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, fop_stat_cbk_t cbk, void *local); extern int nfs_fop_access (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, int32_t accesstest, fop_access_cbk_t cbk, void *local); extern int nfs_fop_lk (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, int cmd, struct gf_flock *flock, fop_lk_cbk_t cbk, void *local); extern int nfs_fop_getxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, char *name, dict_t *xdata, fop_getxattr_cbk_t cbk, void *local); extern int nfs_fop_setxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata, fop_setxattr_cbk_t cbk, void *local); #endif