Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6ff958edbf39c014eb06b65ad25b736be08c4e63
Commit:     6ff958edbf39c014eb06b65ad25b736be08c4e63
Parent:     17637cbaba592076c221dc045ca78422b4af6290
Author:     Miklos Szeredi <[EMAIL PROTECTED]>
AuthorDate: Thu Oct 18 03:07:02 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Thu Oct 18 14:37:31 2007 -0700

    fuse: add atomic open+truncate support
    
    This patch allows fuse filesystems to implement open(..., O_TRUNC) as a 
single
    request, instead of separate truncate and open requests.
    
    Signed-off-by: Miklos Szeredi <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 fs/fuse/dir.c        |    3 +++
 fs/fuse/file.c       |    4 +++-
 fs/fuse/fuse_i.h     |    3 +++
 fs/fuse/inode.c      |    5 ++++-
 include/linux/fuse.h |    1 +
 5 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 537d38b..052327b 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1083,6 +1083,9 @@ static int fuse_do_setattr(struct dentry *entry, struct 
iattr *attr,
                        return err;
        }
 
+       if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc)
+               return 0;
+
        if (attr->ia_valid & ATTR_SIZE) {
                unsigned long limit;
                if (IS_SWAPFILE(inode))
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 4a28c3d..6726378 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -28,7 +28,9 @@ static int fuse_send_open(struct inode *inode, struct file 
*file, int isdir,
                return PTR_ERR(req);
 
        memset(&inarg, 0, sizeof(inarg));
-       inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+       inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
+       if (!fc->atomic_o_trunc)
+               inarg.flags &= ~O_TRUNC;
        req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
        req->in.h.nodeid = get_node_id(inode);
        req->in.numargs = 1;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index ffbcada..b24fc9b 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -320,6 +320,9 @@ struct fuse_conn {
        /** Do readpages asynchronously?  Only set in INIT */
        unsigned async_read : 1;
 
+       /** Do not send separate SETATTR request before open(O_TRUNC)  */
+       unsigned atomic_o_trunc : 1;
+
        /*
         * The following bitfields are only for optimization purposes
         * and hence races in setting them will not cause malfunction
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 6ef3973..3c13981 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -531,6 +531,8 @@ static void process_init_reply(struct fuse_conn *fc, struct 
fuse_req *req)
                                fc->async_read = 1;
                        if (!(arg->flags & FUSE_POSIX_LOCKS))
                                fc->no_lock = 1;
+                       if (arg->flags & FUSE_ATOMIC_O_TRUNC)
+                               fc->atomic_o_trunc = 1;
                } else {
                        ra_pages = fc->max_read / PAGE_CACHE_SIZE;
                        fc->no_lock = 1;
@@ -553,7 +555,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct 
fuse_req *req)
        arg->major = FUSE_KERNEL_VERSION;
        arg->minor = FUSE_KERNEL_MINOR_VERSION;
        arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
-       arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_FILE_OPS;
+       arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_FILE_OPS |
+               FUSE_ATOMIC_O_TRUNC;
        req->in.h.opcode = FUSE_INIT;
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(*arg);
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 43a77d7..4360470 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -101,6 +101,7 @@ struct fuse_file_lock {
 #define FUSE_ASYNC_READ                (1 << 0)
 #define FUSE_POSIX_LOCKS       (1 << 1)
 #define FUSE_FILE_OPS          (1 << 2)
+#define FUSE_ATOMIC_O_TRUNC    (1 << 3)
 
 /**
  * Release flags
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to