Commit 051732bcbe3cff3fea04dc9042266562fe8b0859

Authored by Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
  fuse: check size of FUSE_NOTIFY_INVAL_ENTRY message
  fuse: mark pages accessed when written to
  fuse: delete dead .write_begin and .write_end aops
  fuse: fix flock
  fuse: fix non-ANSI void function notation

Showing 5 changed files Side-by-side Diff

... ... @@ -1358,6 +1358,10 @@
1358 1358 if (outarg.namelen > FUSE_NAME_MAX)
1359 1359 goto err;
1360 1360  
  1361 + err = -EINVAL;
  1362 + if (size != sizeof(outarg) + outarg.namelen + 1)
  1363 + goto err;
  1364 +
1361 1365 name.name = buf;
1362 1366 name.len = outarg.namelen;
1363 1367 err = fuse_copy_one(cs, buf, outarg.namelen + 1);
... ... @@ -14,6 +14,7 @@
14 14 #include <linux/sched.h>
15 15 #include <linux/module.h>
16 16 #include <linux/compat.h>
  17 +#include <linux/swap.h>
17 18  
18 19 static const struct file_operations fuse_direct_io_file_operations;
19 20  
... ... @@ -245,6 +246,12 @@
245 246 req = ff->reserved_req;
246 247 fuse_prepare_release(ff, file->f_flags, opcode);
247 248  
  249 + if (ff->flock) {
  250 + struct fuse_release_in *inarg = &req->misc.release.in;
  251 + inarg->release_flags |= FUSE_RELEASE_FLOCK_UNLOCK;
  252 + inarg->lock_owner = fuse_lock_owner_id(ff->fc,
  253 + (fl_owner_t) file);
  254 + }
248 255 /* Hold vfsmount and dentry until release is finished */
249 256 path_get(&file->f_path);
250 257 req->misc.release.path = file->f_path;
... ... @@ -755,18 +762,6 @@
755 762 return req->misc.write.out.size;
756 763 }
757 764  
758   -static int fuse_write_begin(struct file *file, struct address_space *mapping,
759   - loff_t pos, unsigned len, unsigned flags,
760   - struct page **pagep, void **fsdata)
761   -{
762   - pgoff_t index = pos >> PAGE_CACHE_SHIFT;
763   -
764   - *pagep = grab_cache_page_write_begin(mapping, index, flags);
765   - if (!*pagep)
766   - return -ENOMEM;
767   - return 0;
768   -}
769   -
770 765 void fuse_write_update_size(struct inode *inode, loff_t pos)
771 766 {
772 767 struct fuse_conn *fc = get_fuse_conn(inode);
... ... @@ -779,62 +774,6 @@
779 774 spin_unlock(&fc->lock);
780 775 }
781 776  
782   -static int fuse_buffered_write(struct file *file, struct inode *inode,
783   - loff_t pos, unsigned count, struct page *page)
784   -{
785   - int err;
786   - size_t nres;
787   - struct fuse_conn *fc = get_fuse_conn(inode);
788   - unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
789   - struct fuse_req *req;
790   -
791   - if (is_bad_inode(inode))
792   - return -EIO;
793   -
794   - /*
795   - * Make sure writepages on the same page are not mixed up with
796   - * plain writes.
797   - */
798   - fuse_wait_on_page_writeback(inode, page->index);
799   -
800   - req = fuse_get_req(fc);
801   - if (IS_ERR(req))
802   - return PTR_ERR(req);
803   -
804   - req->in.argpages = 1;
805   - req->num_pages = 1;
806   - req->pages[0] = page;
807   - req->page_offset = offset;
808   - nres = fuse_send_write(req, file, pos, count, NULL);
809   - err = req->out.h.error;
810   - fuse_put_request(fc, req);
811   - if (!err && !nres)
812   - err = -EIO;
813   - if (!err) {
814   - pos += nres;
815   - fuse_write_update_size(inode, pos);
816   - if (count == PAGE_CACHE_SIZE)
817   - SetPageUptodate(page);
818   - }
819   - fuse_invalidate_attr(inode);
820   - return err ? err : nres;
821   -}
822   -
823   -static int fuse_write_end(struct file *file, struct address_space *mapping,
824   - loff_t pos, unsigned len, unsigned copied,
825   - struct page *page, void *fsdata)
826   -{
827   - struct inode *inode = mapping->host;
828   - int res = 0;
829   -
830   - if (copied)
831   - res = fuse_buffered_write(file, inode, pos, copied, page);
832   -
833   - unlock_page(page);
834   - page_cache_release(page);
835   - return res;
836   -}
837   -
838 777 static size_t fuse_send_write_pages(struct fuse_req *req, struct file *file,
839 778 struct inode *inode, loff_t pos,
840 779 size_t count)
... ... @@ -908,6 +847,8 @@
908 847 pagefault_enable();
909 848 flush_dcache_page(page);
910 849  
  850 + mark_page_accessed(page);
  851 +
911 852 if (!tmp) {
912 853 unlock_page(page);
913 854 page_cache_release(page);
914 855  
915 856  
... ... @@ -1559,11 +1500,14 @@
1559 1500 struct fuse_conn *fc = get_fuse_conn(inode);
1560 1501 int err;
1561 1502  
1562   - if (fc->no_lock) {
  1503 + if (fc->no_flock) {
1563 1504 err = flock_lock_file_wait(file, fl);
1564 1505 } else {
  1506 + struct fuse_file *ff = file->private_data;
  1507 +
1565 1508 /* emulate flock with POSIX locks */
1566 1509 fl->fl_owner = (fl_owner_t) file;
  1510 + ff->flock = true;
1567 1511 err = fuse_setlk(file, fl, 1);
1568 1512 }
1569 1513  
... ... @@ -2201,8 +2145,6 @@
2201 2145 .readpage = fuse_readpage,
2202 2146 .writepage = fuse_writepage,
2203 2147 .launder_page = fuse_launder_page,
2204   - .write_begin = fuse_write_begin,
2205   - .write_end = fuse_write_end,
2206 2148 .readpages = fuse_readpages,
2207 2149 .set_page_dirty = __set_page_dirty_nobuffers,
2208 2150 .bmap = fuse_bmap,
... ... @@ -135,6 +135,9 @@
135 135  
136 136 /** Wait queue head for poll */
137 137 wait_queue_head_t poll_wait;
  138 +
  139 + /** Has flock been performed on this file? */
  140 + bool flock:1;
138 141 };
139 142  
140 143 /** One input argument of a request */
... ... @@ -448,7 +451,7 @@
448 451 /** Is removexattr not implemented by fs? */
449 452 unsigned no_removexattr:1;
450 453  
451   - /** Are file locking primitives not implemented by fs? */
  454 + /** Are posix file locking primitives not implemented by fs? */
452 455 unsigned no_lock:1;
453 456  
454 457 /** Is access not implemented by fs? */
... ... @@ -471,6 +474,9 @@
471 474  
472 475 /** Don't apply umask to creation modes */
473 476 unsigned dont_mask:1;
  477 +
  478 + /** Are BSD file locking primitives not implemented by fs? */
  479 + unsigned no_flock:1;
474 480  
475 481 /** The number of requests waiting for completion */
476 482 atomic_t num_waiting;
... ... @@ -71,7 +71,7 @@
71 71 unsigned blksize;
72 72 };
73 73  
74   -struct fuse_forget_link *fuse_alloc_forget()
  74 +struct fuse_forget_link *fuse_alloc_forget(void)
75 75 {
76 76 return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL);
77 77 }
... ... @@ -809,6 +809,10 @@
809 809 fc->async_read = 1;
810 810 if (!(arg->flags & FUSE_POSIX_LOCKS))
811 811 fc->no_lock = 1;
  812 + if (arg->minor >= 17) {
  813 + if (!(arg->flags & FUSE_FLOCK_LOCKS))
  814 + fc->no_flock = 1;
  815 + }
812 816 if (arg->flags & FUSE_ATOMIC_O_TRUNC)
813 817 fc->atomic_o_trunc = 1;
814 818 if (arg->minor >= 9) {
... ... @@ -823,6 +827,7 @@
823 827 } else {
824 828 ra_pages = fc->max_read / PAGE_CACHE_SIZE;
825 829 fc->no_lock = 1;
  830 + fc->no_flock = 1;
826 831 }
827 832  
828 833 fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages);
... ... @@ -843,7 +848,8 @@
843 848 arg->minor = FUSE_KERNEL_MINOR_VERSION;
844 849 arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
845 850 arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
846   - FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK;
  851 + FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
  852 + FUSE_FLOCK_LOCKS;
847 853 req->in.h.opcode = FUSE_INIT;
848 854 req->in.numargs = 1;
849 855 req->in.args[0].size = sizeof(*arg);
include/linux/fuse.h
... ... @@ -47,6 +47,9 @@
47 47 * - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct
48 48 * fuse_ioctl_iovec' instead of ambiguous 'struct iovec'
49 49 * - add FUSE_IOCTL_32BIT flag
  50 + *
  51 + * 7.17
  52 + * - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK
50 53 */
51 54  
52 55 #ifndef _LINUX_FUSE_H
... ... @@ -78,7 +81,7 @@
78 81 #define FUSE_KERNEL_VERSION 7
79 82  
80 83 /** Minor version number of this interface */
81   -#define FUSE_KERNEL_MINOR_VERSION 16
  84 +#define FUSE_KERNEL_MINOR_VERSION 17
82 85  
83 86 /** The node ID of the root inode */
84 87 #define FUSE_ROOT_ID 1
85 88  
... ... @@ -153,8 +156,10 @@
153 156 /**
154 157 * INIT request/reply flags
155 158 *
  159 + * FUSE_POSIX_LOCKS: remote locking for POSIX file locks
156 160 * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
157 161 * FUSE_DONT_MASK: don't apply umask to file mode on create operations
  162 + * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
158 163 */
159 164 #define FUSE_ASYNC_READ (1 << 0)
160 165 #define FUSE_POSIX_LOCKS (1 << 1)
... ... @@ -163,6 +168,7 @@
163 168 #define FUSE_EXPORT_SUPPORT (1 << 4)
164 169 #define FUSE_BIG_WRITES (1 << 5)
165 170 #define FUSE_DONT_MASK (1 << 6)
  171 +#define FUSE_FLOCK_LOCKS (1 << 10)
166 172  
167 173 /**
168 174 * CUSE INIT request/reply flags
... ... @@ -175,6 +181,7 @@
175 181 * Release flags
176 182 */
177 183 #define FUSE_RELEASE_FLUSH (1 << 0)
  184 +#define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1)
178 185  
179 186 /**
180 187 * Getattr flags