[2/2] fs/fuse kio_pcs: pass the file handle for FUSE_SETATTR request

Submitted by Pavel Butsykin on June 7, 2018, 2:40 p.m.

Details

Message ID 20180607144012.22213-3-pbutsykin@virtuozzo.com
State New
Series "fuse_kdirect: fsync hungs after unlink fixes"
Headers show

Commit Message

Pavel Butsykin June 7, 2018, 2:40 p.m.
Add to pass the file handle (if it is) for FUSE_SETATTR request inside
submit_size_grow().

Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
---
 fs/fuse/file.c                     | 5 +++--
 fs/fuse/fuse_i.h                   | 4 ++++
 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 8 ++++++++
 3 files changed, 15 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index ddfb41af54ec..9ae260a10490 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1137,6 +1137,7 @@  void fuse_release_ff(struct inode *inode, struct fuse_file *ff)
 		}
 	}
 }
+EXPORT_SYMBOL_GPL(fuse_release_ff);
 
 static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
 {
@@ -1997,8 +1998,7 @@  static void fuse_writepage_end(struct fuse_conn *fc, struct fuse_req *req)
 	fuse_writepage_free(fc, req);
 }
 
-static struct fuse_file *fuse_write_file(struct fuse_conn *fc,
-					 struct fuse_inode *fi)
+struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi)
 {
 	struct fuse_file *ff = NULL;
 
@@ -2011,6 +2011,7 @@  static struct fuse_file *fuse_write_file(struct fuse_conn *fc,
 
 	return ff;
 }
+EXPORT_SYMBOL_GPL(fuse_write_file);
 
 static int tree_insert(struct rb_root *root, struct fuse_req *ins_req)
 {
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 939835f585b1..20295250070a 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -1091,4 +1091,8 @@  void fuse_stat_account(struct fuse_conn * fc, int op, ktime_t val);
 int fuse_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
 		__u64 start, __u64 len);
 
+struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi);
+
+void fuse_release_ff(struct inode *inode, struct fuse_file *ff);
+
 #endif /* _FS_FUSE_I_H */
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index 1a6776f7977a..4f8b0133ca5b 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -608,6 +608,7 @@  void ireq_destroy(struct pcs_int_request *ireq)
 static int submit_size_grow(struct inode *inode, unsigned long long size)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
+	struct fuse_file *ff;
 	struct fuse_setattr_in inarg;
 	struct fuse_attr_out outarg;
 	struct fuse_req *req;
@@ -630,6 +631,11 @@  static int submit_size_grow(struct inode *inode, unsigned long long size)
 	inarg.valid |= FATTR_SIZE;
 	inarg.size = size;
 
+	ff = fuse_write_file(fc, get_fuse_inode(inode));
+	if (ff) {
+		inarg.valid |= FATTR_FH;
+		inarg.fh = ff->fh;
+	}
 	req->io_inode = inode;
 	req->in.h.opcode = FUSE_SETATTR;
 	req->in.h.nodeid = get_node_id(inode);
@@ -641,7 +647,9 @@  static int submit_size_grow(struct inode *inode, unsigned long long size)
 	req->out.args[0].value = &outarg;
 
 	fuse_request_send(fc, req);
+
 	err = req->out.h.error;
+	fuse_release_ff(inode, ff);
 	fuse_put_request(fc, req);
 
 	return err;

Comments

Kirill Tkhai June 8, 2018, 3:13 p.m.
On 07.06.2018 17:40, Pavel Butsykin wrote:
> Add to pass the file handle (if it is) for FUSE_SETATTR request inside
> submit_size_grow().
> 
> Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
> ---
>  fs/fuse/file.c                     | 5 +++--
>  fs/fuse/fuse_i.h                   | 4 ++++
>  fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 8 ++++++++
>  3 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/fuse/file.c b/fs/fuse/file.c
> index ddfb41af54ec..9ae260a10490 100644
> --- a/fs/fuse/file.c
> +++ b/fs/fuse/file.c
> @@ -1137,6 +1137,7 @@ void fuse_release_ff(struct inode *inode, struct fuse_file *ff)
>  		}
>  	}
>  }
> +EXPORT_SYMBOL_GPL(fuse_release_ff);

I'd make fuse-related actions like this in a separate patch. So we have one patch
about generic fuse and one patch about kio. Then we will be more productive on
doing rebase on new kernel.
  
>  static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
>  {
> @@ -1997,8 +1998,7 @@ static void fuse_writepage_end(struct fuse_conn *fc, struct fuse_req *req)
>  	fuse_writepage_free(fc, req);
>  }
>  
> -static struct fuse_file *fuse_write_file(struct fuse_conn *fc,
> -					 struct fuse_inode *fi)
> +struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi)
>  {
>  	struct fuse_file *ff = NULL;
>  
> @@ -2011,6 +2011,7 @@ static struct fuse_file *fuse_write_file(struct fuse_conn *fc,
>  
>  	return ff;
>  }
> +EXPORT_SYMBOL_GPL(fuse_write_file);
>  
>  static int tree_insert(struct rb_root *root, struct fuse_req *ins_req)
>  {
> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
> index 939835f585b1..20295250070a 100644
> --- a/fs/fuse/fuse_i.h
> +++ b/fs/fuse/fuse_i.h
> @@ -1091,4 +1091,8 @@ void fuse_stat_account(struct fuse_conn * fc, int op, ktime_t val);
>  int fuse_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
>  		__u64 start, __u64 len);
>  
> +struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi);
> +
> +void fuse_release_ff(struct inode *inode, struct fuse_file *ff);
> +
>  #endif /* _FS_FUSE_I_H */
> diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
> index 1a6776f7977a..4f8b0133ca5b 100644
> --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
> +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
> @@ -608,6 +608,7 @@ void ireq_destroy(struct pcs_int_request *ireq)
>  static int submit_size_grow(struct inode *inode, unsigned long long size)
>  {
>  	struct fuse_conn *fc = get_fuse_conn(inode);
> +	struct fuse_file *ff;
>  	struct fuse_setattr_in inarg;
>  	struct fuse_attr_out outarg;
>  	struct fuse_req *req;
> @@ -630,6 +631,11 @@ static int submit_size_grow(struct inode *inode, unsigned long long size)
>  	inarg.valid |= FATTR_SIZE;
>  	inarg.size = size;
>  
> +	ff = fuse_write_file(fc, get_fuse_inode(inode));
> +	if (ff) {
> +		inarg.valid |= FATTR_FH;
> +		inarg.fh = ff->fh;
> +	}
>  	req->io_inode = inode;
>  	req->in.h.opcode = FUSE_SETATTR;
>  	req->in.h.nodeid = get_node_id(inode);
> @@ -641,7 +647,9 @@ static int submit_size_grow(struct inode *inode, unsigned long long size)
>  	req->out.args[0].value = &outarg;
>  
>  	fuse_request_send(fc, req);
> +
>  	err = req->out.h.error;
> +	fuse_release_ff(inode, ff);
>  	fuse_put_request(fc, req);
>  
>  	return err;
>