Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'fuse-fixes-6.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

Pull fuse fixes from Miklos Szeredi:

- Fix two bugs in the new passthrough mode

- Fix a statx bug introduced in v6.6

- Fix code documentation

* tag 'fuse-fixes-6.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
cuse: add kernel-doc comments to cuse_process_init_reply()
fuse: fix leaked ENOSYS error on first statx call
fuse: fix parallel dio write on file open in passthrough mode
fuse: fix wrong ff->iomode state changes from parallel dio write

+58 -27
+4
fs/fuse/cuse.c
··· 310 310 /** 311 311 * cuse_process_init_reply - finish initializing CUSE channel 312 312 * 313 + * @fm: The fuse mount information containing the CUSE connection. 314 + * @args: The arguments passed to the init reply. 315 + * @error: The error code signifying if any error occurred during the process. 316 + * 313 317 * This function creates the character device and sets up all the 314 318 * required data structures for it. Please read the comment at the 315 319 * top of this file for high level overview.
+1
fs/fuse/dir.c
··· 1321 1321 err = fuse_do_statx(inode, file, stat); 1322 1322 if (err == -ENOSYS) { 1323 1323 fc->no_statx = 1; 1324 + err = 0; 1324 1325 goto retry; 1325 1326 } 1326 1327 } else {
+7 -5
fs/fuse/file.c
··· 1362 1362 bool *exclusive) 1363 1363 { 1364 1364 struct inode *inode = file_inode(iocb->ki_filp); 1365 - struct fuse_file *ff = iocb->ki_filp->private_data; 1365 + struct fuse_inode *fi = get_fuse_inode(inode); 1366 1366 1367 1367 *exclusive = fuse_dio_wr_exclusive_lock(iocb, from); 1368 1368 if (*exclusive) { ··· 1377 1377 * have raced, so check it again. 1378 1378 */ 1379 1379 if (fuse_io_past_eof(iocb, from) || 1380 - fuse_file_uncached_io_start(inode, ff, NULL) != 0) { 1380 + fuse_inode_uncached_io_start(fi, NULL) != 0) { 1381 1381 inode_unlock_shared(inode); 1382 1382 inode_lock(inode); 1383 1383 *exclusive = true; ··· 1388 1388 static void fuse_dio_unlock(struct kiocb *iocb, bool exclusive) 1389 1389 { 1390 1390 struct inode *inode = file_inode(iocb->ki_filp); 1391 - struct fuse_file *ff = iocb->ki_filp->private_data; 1391 + struct fuse_inode *fi = get_fuse_inode(inode); 1392 1392 1393 1393 if (exclusive) { 1394 1394 inode_unlock(inode); 1395 1395 } else { 1396 1396 /* Allow opens in caching mode after last parallel dio end */ 1397 - fuse_file_uncached_io_end(inode, ff); 1397 + fuse_inode_uncached_io_end(fi); 1398 1398 inode_unlock_shared(inode); 1399 1399 } 1400 1400 } ··· 2574 2574 * First mmap of direct_io file enters caching inode io mode. 2575 2575 * Also waits for parallel dio writers to go into serial mode 2576 2576 * (exclusive instead of shared lock). 2577 + * After first mmap, the inode stays in caching io mode until 2578 + * the direct_io file release. 2577 2579 */ 2578 - rc = fuse_file_cached_io_start(inode, ff); 2580 + rc = fuse_file_cached_io_open(inode, ff); 2579 2581 if (rc) 2580 2582 return rc; 2581 2583 }
+4 -3
fs/fuse/fuse_i.h
··· 1394 1394 struct dentry *dentry, struct fileattr *fa); 1395 1395 1396 1396 /* iomode.c */ 1397 - int fuse_file_cached_io_start(struct inode *inode, struct fuse_file *ff); 1398 - int fuse_file_uncached_io_start(struct inode *inode, struct fuse_file *ff, struct fuse_backing *fb); 1399 - void fuse_file_uncached_io_end(struct inode *inode, struct fuse_file *ff); 1397 + int fuse_file_cached_io_open(struct inode *inode, struct fuse_file *ff); 1398 + int fuse_inode_uncached_io_start(struct fuse_inode *fi, 1399 + struct fuse_backing *fb); 1400 + void fuse_inode_uncached_io_end(struct fuse_inode *fi); 1400 1401 1401 1402 int fuse_file_io_open(struct file *file, struct inode *inode); 1402 1403 void fuse_file_io_release(struct fuse_file *ff, struct inode *inode);
+1
fs/fuse/inode.c
··· 175 175 } 176 176 } 177 177 if (S_ISREG(inode->i_mode) && !fuse_is_bad(inode)) { 178 + WARN_ON(fi->iocachectr != 0); 178 179 WARN_ON(!list_empty(&fi->write_files)); 179 180 WARN_ON(!list_empty(&fi->queued_writes)); 180 181 }
+41 -19
fs/fuse/iomode.c
··· 21 21 } 22 22 23 23 /* 24 - * Start cached io mode. 24 + * Called on cached file open() and on first mmap() of direct_io file. 25 + * Takes cached_io inode mode reference to be dropped on file release. 25 26 * 26 27 * Blocks new parallel dio writes and waits for the in-progress parallel dio 27 28 * writes to complete. 28 29 */ 29 - int fuse_file_cached_io_start(struct inode *inode, struct fuse_file *ff) 30 + int fuse_file_cached_io_open(struct inode *inode, struct fuse_file *ff) 30 31 { 31 32 struct fuse_inode *fi = get_fuse_inode(inode); 32 33 ··· 68 67 return 0; 69 68 } 70 69 71 - static void fuse_file_cached_io_end(struct inode *inode, struct fuse_file *ff) 70 + static void fuse_file_cached_io_release(struct fuse_file *ff, 71 + struct fuse_inode *fi) 72 72 { 73 - struct fuse_inode *fi = get_fuse_inode(inode); 74 - 75 73 spin_lock(&fi->lock); 76 74 WARN_ON(fi->iocachectr <= 0); 77 75 WARN_ON(ff->iomode != IOM_CACHED); ··· 82 82 } 83 83 84 84 /* Start strictly uncached io mode where cache access is not allowed */ 85 - int fuse_file_uncached_io_start(struct inode *inode, struct fuse_file *ff, struct fuse_backing *fb) 85 + int fuse_inode_uncached_io_start(struct fuse_inode *fi, struct fuse_backing *fb) 86 86 { 87 - struct fuse_inode *fi = get_fuse_inode(inode); 88 87 struct fuse_backing *oldfb; 89 88 int err = 0; 90 89 91 90 spin_lock(&fi->lock); 92 91 /* deny conflicting backing files on same fuse inode */ 93 92 oldfb = fuse_inode_backing(fi); 94 - if (oldfb && oldfb != fb) { 93 + if (fb && oldfb && oldfb != fb) { 95 94 err = -EBUSY; 96 95 goto unlock; 97 96 } ··· 98 99 err = -ETXTBSY; 99 100 goto unlock; 100 101 } 101 - WARN_ON(ff->iomode != IOM_NONE); 102 102 fi->iocachectr--; 103 - ff->iomode = IOM_UNCACHED; 104 103 105 104 /* fuse inode holds a single refcount of backing file */ 106 - if (!oldfb) { 105 + if (fb && !oldfb) { 107 106 oldfb = fuse_inode_backing_set(fi, fb); 108 107 WARN_ON_ONCE(oldfb != NULL); 109 108 } else { ··· 112 115 return err; 113 116 } 114 117 115 - void fuse_file_uncached_io_end(struct inode *inode, struct fuse_file *ff) 118 + /* Takes uncached_io inode mode reference to be dropped on file release */ 119 + static int fuse_file_uncached_io_open(struct inode *inode, 120 + struct fuse_file *ff, 121 + struct fuse_backing *fb) 116 122 { 117 123 struct fuse_inode *fi = get_fuse_inode(inode); 124 + int err; 125 + 126 + err = fuse_inode_uncached_io_start(fi, fb); 127 + if (err) 128 + return err; 129 + 130 + WARN_ON(ff->iomode != IOM_NONE); 131 + ff->iomode = IOM_UNCACHED; 132 + return 0; 133 + } 134 + 135 + void fuse_inode_uncached_io_end(struct fuse_inode *fi) 136 + { 118 137 struct fuse_backing *oldfb = NULL; 119 138 120 139 spin_lock(&fi->lock); 121 140 WARN_ON(fi->iocachectr >= 0); 122 - WARN_ON(ff->iomode != IOM_UNCACHED); 123 - ff->iomode = IOM_NONE; 124 141 fi->iocachectr++; 125 142 if (!fi->iocachectr) { 126 143 wake_up(&fi->direct_io_waitq); ··· 143 132 spin_unlock(&fi->lock); 144 133 if (oldfb) 145 134 fuse_backing_put(oldfb); 135 + } 136 + 137 + /* Drop uncached_io reference from passthrough open */ 138 + static void fuse_file_uncached_io_release(struct fuse_file *ff, 139 + struct fuse_inode *fi) 140 + { 141 + WARN_ON(ff->iomode != IOM_UNCACHED); 142 + ff->iomode = IOM_NONE; 143 + fuse_inode_uncached_io_end(fi); 146 144 } 147 145 148 146 /* ··· 183 163 return PTR_ERR(fb); 184 164 185 165 /* First passthrough file open denies caching inode io mode */ 186 - err = fuse_file_uncached_io_start(inode, ff, fb); 166 + err = fuse_file_uncached_io_open(inode, ff, fb); 187 167 if (!err) 188 168 return 0; 189 169 ··· 236 216 if (ff->open_flags & FOPEN_PASSTHROUGH) 237 217 err = fuse_file_passthrough_open(inode, file); 238 218 else 239 - err = fuse_file_cached_io_start(inode, ff); 219 + err = fuse_file_cached_io_open(inode, ff); 240 220 if (err) 241 221 goto fail; 242 222 ··· 256 236 /* No more pending io and no new io possible to inode via open/mmapped file */ 257 237 void fuse_file_io_release(struct fuse_file *ff, struct inode *inode) 258 238 { 239 + struct fuse_inode *fi = get_fuse_inode(inode); 240 + 259 241 /* 260 - * Last parallel dio close allows caching inode io mode. 242 + * Last passthrough file close allows caching inode io mode. 261 243 * Last caching file close exits caching inode io mode. 262 244 */ 263 245 switch (ff->iomode) { ··· 267 245 /* Nothing to do */ 268 246 break; 269 247 case IOM_UNCACHED: 270 - fuse_file_uncached_io_end(inode, ff); 248 + fuse_file_uncached_io_release(ff, fi); 271 249 break; 272 250 case IOM_CACHED: 273 - fuse_file_cached_io_end(inode, ff); 251 + fuse_file_cached_io_release(ff, fi); 274 252 break; 275 253 } 276 254 }