aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fuse/dir.c7
-rw-r--r--fs/fuse/file.c17
-rw-r--r--fs/fuse/fuse_i.h9
-rw-r--r--include/linux/fuse.h3
4 files changed, 31 insertions, 5 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 9b43fd46aaad..73792d65b6cf 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -617,6 +617,12 @@ static int fuse_dir_release(struct inode *inode, struct file *file)
617 return fuse_release_common(inode, file, 1); 617 return fuse_release_common(inode, file, 1);
618} 618}
619 619
620static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
621{
622 /* nfsd can call this with no file */
623 return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
624}
625
620static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr) 626static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr)
621{ 627{
622 unsigned ivalid = iattr->ia_valid; 628 unsigned ivalid = iattr->ia_valid;
@@ -934,6 +940,7 @@ static struct file_operations fuse_dir_operations = {
934 .readdir = fuse_readdir, 940 .readdir = fuse_readdir,
935 .open = fuse_dir_open, 941 .open = fuse_dir_open,
936 .release = fuse_dir_release, 942 .release = fuse_dir_release,
943 .fsync = fuse_dir_fsync,
937}; 944};
938 945
939static struct inode_operations fuse_common_inode_operations = { 946static struct inode_operations fuse_common_inode_operations = {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 6dcae74ce7fa..e225f8c0b267 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -156,7 +156,8 @@ static int fuse_flush(struct file *file)
156 return err; 156 return err;
157} 157}
158 158
159static int fuse_fsync(struct file *file, struct dentry *de, int datasync) 159int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
160 int isdir)
160{ 161{
161 struct inode *inode = de->d_inode; 162 struct inode *inode = de->d_inode;
162 struct fuse_conn *fc = get_fuse_conn(inode); 163 struct fuse_conn *fc = get_fuse_conn(inode);
@@ -165,7 +166,7 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
165 struct fuse_fsync_in inarg; 166 struct fuse_fsync_in inarg;
166 int err; 167 int err;
167 168
168 if (fc->no_fsync) 169 if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
169 return 0; 170 return 0;
170 171
171 req = fuse_get_request(fc); 172 req = fuse_get_request(fc);
@@ -175,7 +176,7 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
175 memset(&inarg, 0, sizeof(inarg)); 176 memset(&inarg, 0, sizeof(inarg));
176 inarg.fh = ff->fh; 177 inarg.fh = ff->fh;
177 inarg.fsync_flags = datasync ? 1 : 0; 178 inarg.fsync_flags = datasync ? 1 : 0;
178 req->in.h.opcode = FUSE_FSYNC; 179 req->in.h.opcode = isdir ? FUSE_FSYNCDIR : FUSE_FSYNC;
179 req->in.h.nodeid = get_node_id(inode); 180 req->in.h.nodeid = get_node_id(inode);
180 req->inode = inode; 181 req->inode = inode;
181 req->file = file; 182 req->file = file;
@@ -186,12 +187,20 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
186 err = req->out.h.error; 187 err = req->out.h.error;
187 fuse_put_request(fc, req); 188 fuse_put_request(fc, req);
188 if (err == -ENOSYS) { 189 if (err == -ENOSYS) {
189 fc->no_fsync = 1; 190 if (isdir)
191 fc->no_fsyncdir = 1;
192 else
193 fc->no_fsync = 1;
190 err = 0; 194 err = 0;
191 } 195 }
192 return err; 196 return err;
193} 197}
194 198
199static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
200{
201 return fuse_fsync_common(file, de, datasync, 0);
202}
203
195size_t fuse_send_read_common(struct fuse_req *req, struct file *file, 204size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
196 struct inode *inode, loff_t pos, size_t count, 205 struct inode *inode, loff_t pos, size_t count,
197 int isdir) 206 int isdir)
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 84849601363e..d7647289d8a1 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -248,6 +248,9 @@ struct fuse_conn {
248 /** Is fsync not implemented by fs? */ 248 /** Is fsync not implemented by fs? */
249 unsigned no_fsync : 1; 249 unsigned no_fsync : 1;
250 250
251 /** Is fsyncdir not implemented by fs? */
252 unsigned no_fsyncdir : 1;
253
251 /** Is flush not implemented by fs? */ 254 /** Is flush not implemented by fs? */
252 unsigned no_flush : 1; 255 unsigned no_flush : 1;
253 256
@@ -340,6 +343,12 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir);
340int fuse_release_common(struct inode *inode, struct file *file, int isdir); 343int fuse_release_common(struct inode *inode, struct file *file, int isdir);
341 344
342/** 345/**
346 * Send FSYNC or FSYNCDIR request
347 */
348int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
349 int isdir);
350
351/**
343 * Initialise file operations on a regular file 352 * Initialise file operations on a regular file
344 */ 353 */
345void fuse_init_file_inode(struct inode *inode); 354void fuse_init_file_inode(struct inode *inode);
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index c65124a213a1..acbeb96a3353 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -99,7 +99,8 @@ enum fuse_opcode {
99 FUSE_INIT = 26, 99 FUSE_INIT = 26,
100 FUSE_OPENDIR = 27, 100 FUSE_OPENDIR = 27,
101 FUSE_READDIR = 28, 101 FUSE_READDIR = 28,
102 FUSE_RELEASEDIR = 29 102 FUSE_RELEASEDIR = 29,
103 FUSE_FSYNCDIR = 30
103}; 104};
104 105
105/* Conservative buffer size for the client */ 106/* Conservative buffer size for the client */