Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82547981 authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Linus Torvalds
Browse files

[PATCH] FUSE: add fsync operation for directories



This patch adds a new FSYNCDIR request, which is sent when fsync is called
on directories.  This operation is available in libfuse 2.3-pre1 or
greater.

Signed-off-by: default avatarMiklos Szeredi <miklos@szeredi.hu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b36c31ba
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -617,6 +617,12 @@ static int fuse_dir_release(struct inode *inode, struct file *file)
	return fuse_release_common(inode, file, 1);
}

static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
{
	/* nfsd can call this with no file */
	return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
}

static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr)
{
	unsigned ivalid = iattr->ia_valid;
@@ -934,6 +940,7 @@ static struct file_operations fuse_dir_operations = {
	.readdir	= fuse_readdir,
	.open		= fuse_dir_open,
	.release	= fuse_dir_release,
	.fsync		= fuse_dir_fsync,
};

static struct inode_operations fuse_common_inode_operations = {
+13 −4
Original line number Diff line number Diff line
@@ -156,7 +156,8 @@ static int fuse_flush(struct file *file)
	return err;
}

static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
		      int isdir)
{
	struct inode *inode = de->d_inode;
	struct fuse_conn *fc = get_fuse_conn(inode);
@@ -165,7 +166,7 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
	struct fuse_fsync_in inarg;
	int err;

	if (fc->no_fsync)
	if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
		return 0;

	req = fuse_get_request(fc);
@@ -175,7 +176,7 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
	memset(&inarg, 0, sizeof(inarg));
	inarg.fh = ff->fh;
	inarg.fsync_flags = datasync ? 1 : 0;
	req->in.h.opcode = FUSE_FSYNC;
	req->in.h.opcode = isdir ? FUSE_FSYNCDIR : FUSE_FSYNC;
	req->in.h.nodeid = get_node_id(inode);
	req->inode = inode;
	req->file = file;
@@ -186,12 +187,20 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
	err = req->out.h.error;
	fuse_put_request(fc, req);
	if (err == -ENOSYS) {
		if (isdir)
			fc->no_fsyncdir = 1;
		else
			fc->no_fsync = 1;
		err = 0;
	}
	return err;
}

static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
{
	return fuse_fsync_common(file, de, datasync, 0);
}

size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
			     struct inode *inode, loff_t pos, size_t count,
			     int isdir)
+9 −0
Original line number Diff line number Diff line
@@ -248,6 +248,9 @@ struct fuse_conn {
	/** Is fsync not implemented by fs? */
	unsigned no_fsync : 1;

	/** Is fsyncdir not implemented by fs? */
	unsigned no_fsyncdir : 1;

	/** Is flush not implemented by fs? */
	unsigned no_flush : 1;

@@ -339,6 +342,12 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir);
 */
int fuse_release_common(struct inode *inode, struct file *file, int isdir);

/**
 * Send FSYNC or FSYNCDIR request
 */
int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
		      int isdir);

/**
 * Initialise file operations on a regular file
 */
+2 −1
Original line number Diff line number Diff line
@@ -99,7 +99,8 @@ enum fuse_opcode {
	FUSE_INIT          = 26,
	FUSE_OPENDIR       = 27,
	FUSE_READDIR       = 28,
	FUSE_RELEASEDIR    = 29
	FUSE_RELEASEDIR    = 29,
	FUSE_FSYNCDIR      = 30
};

/* Conservative buffer size for the client */