+2005-02-28 Miklos Szeredi <miklos@szeredi.hu>
+
+ * libfuse: added opendir() operation. This can be used in case
+ permission checking in getdir() is too late. Thanks to Usarin
+ Heininga for pointing out this deficiency
+
+ * kernel: llseek() method for files and directories made explicit
+
+ * kernel: fixed inode leak in NFS export in case of nodeid
+ wrapping
+
2005-02-15 Miklos Szeredi <miklos@szeredi.hu>
* libfuse: clean up some unitialized memory found with valgrind
#define FUSE_MAJOR_VERSION 2
/** Minor version of FUSE library interface */
-#define FUSE_MINOR_VERSION 2
+#define FUSE_MINOR_VERSION 3
/* This interface uses 64 bit off_t */
#if _FILE_OFFSET_BITS != 64
/** Remove extended attributes */
int (*removexattr) (const char *, const char *);
+
+ /** Open direcory
+ *
+ * This method should check if the open operation is permitted for
+ * this directory. The fuse_file_info parameter is currently
+ * unused. This method is optional.
+ */
+ int (*opendir) (const char *, struct fuse_file_info *);
};
/** Extra context that may be needed by some filesystems
};
static struct file_operations fuse_dir_operations = {
+ .llseek = generic_file_llseek,
.read = generic_read_dir,
.readdir = fuse_readdir,
.open = fuse_dir_open,
#endif
static struct file_operations fuse_file_operations = {
+ .llseek = generic_file_llseek,
.read = fuse_file_read,
.write = fuse_file_write,
.mmap = fuse_file_mmap,
#ifdef KERNEL_2_6
static struct dentry *fuse_get_dentry(struct super_block *sb, void *vobjp)
{
+ int err;
__u32 *objp = vobjp;
unsigned long nodeid = objp[0];
__u32 generation = objp[1];
struct inode *inode;
struct dentry *entry;
+ err = -ESTALE;
if (nodeid == 0)
- return ERR_PTR(-ESTALE);
+ goto error;
inode = ilookup5(sb, nodeid, fuse_inode_eq, &nodeid);
- if (!inode || inode->i_generation != generation)
- return ERR_PTR(-ESTALE);
+ if (!inode)
+ goto error;
+ if (inode->i_generation != generation)
+ goto error_iput;
+ err = -ENOMEM;
entry = d_alloc_anon(inode);
- if (!entry) {
- iput(inode);
- return ERR_PTR(-ENOMEM);
- }
+ if (!entry)
+ goto error_iput;
return entry;
+
+ error_iput:
+ iput(inode);
+ error:
+ return ERR_PTR(err);
}
static int fuse_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
mount.c \
fuse_i.h
-libfuse_la_LDFLAGS = -lpthread -version-number 2:2:0 \
+libfuse_la_LDFLAGS = -lpthread -version-number 2:3:0 \
-Wl,--version-script,fuse_versionscript
EXTRA_DIST = fuse_versionscript
static struct fuse_context *(*fuse_getcontext)(void) = NULL;
-/* Compatibility with kernel ABI version 5.1 */
-struct fuse_getdir_out {
- __u32 fd;
-};
-
-#define FUSE_GETDIR 7
-
static const char *opname(enum fuse_opcode opcode)
{
switch (opcode) {
case FUSE_SETATTR: return "SETATTR";
case FUSE_READLINK: return "READLINK";
case FUSE_SYMLINK: return "SYMLINK";
- case FUSE_GETDIR: return "GETDIR";
case FUSE_MKNOD: return "MKNOD";
case FUSE_MKDIR: return "MKDIR";
case FUSE_UNLINK: return "UNLINK";
struct fuse_open_out outarg;
struct fuse_dirhandle *dh;
- (void) arg;
+ if (f->op.opendir) {
+ char *path;
+ res = -ENOENT;
+ path = get_path(f, in->nodeid);
+ if (path != NULL) {
+ struct fuse_file_info fi;
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = arg->flags;
+ res = f->op.opendir(path, &fi);
+ free(path);
+ }
+ if (res != 0) {
+ send_reply(f, in, res, NULL, 0);
+ return;
+ }
+ }
+
memset(&outarg, 0, sizeof(outarg));
res = -ENOMEM;
dh = (struct fuse_dirhandle *) malloc(sizeof(struct fuse_dirhandle));