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 branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

Pull fuse fix from Miklos Szeredi:
"This makes sure userspace filesystems are not broken by the parallel
lookups and readdir feature"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
fuse: serialize dirops by default

+37 -2
+4
fs/fuse/dir.c
··· 341 341 struct dentry *newent; 342 342 bool outarg_valid = true; 343 343 344 + fuse_lock_inode(dir); 344 345 err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name, 345 346 &outarg, &inode); 347 + fuse_unlock_inode(dir); 346 348 if (err == -ENOENT) { 347 349 outarg_valid = false; 348 350 err = 0; ··· 1343 1341 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE, 1344 1342 FUSE_READDIR); 1345 1343 } 1344 + fuse_lock_inode(inode); 1346 1345 fuse_request_send(fc, req); 1346 + fuse_unlock_inode(inode); 1347 1347 nbytes = req->out.args[0].size; 1348 1348 err = req->out.h.error; 1349 1349 fuse_put_request(fc, req);
+9
fs/fuse/fuse_i.h
··· 110 110 111 111 /** Miscellaneous bits describing inode state */ 112 112 unsigned long state; 113 + 114 + /** Lock for serializing lookup and readdir for back compatibility*/ 115 + struct mutex mutex; 113 116 }; 114 117 115 118 /** FUSE inode state bits */ ··· 543 540 /** write-back cache policy (default is write-through) */ 544 541 unsigned writeback_cache:1; 545 542 543 + /** allow parallel lookups and readdir (default is serialized) */ 544 + unsigned parallel_dirops:1; 545 + 546 546 /* 547 547 * The following bitfields are only for optimization purposes 548 548 * and hence races in setting them will not cause malfunction ··· 961 955 struct file *file); 962 956 963 957 void fuse_set_initialized(struct fuse_conn *fc); 958 + 959 + void fuse_unlock_inode(struct inode *inode); 960 + void fuse_lock_inode(struct inode *inode); 964 961 965 962 #endif /* _FS_FUSE_I_H */
+18 -1
fs/fuse/inode.c
··· 97 97 INIT_LIST_HEAD(&fi->queued_writes); 98 98 INIT_LIST_HEAD(&fi->writepages); 99 99 init_waitqueue_head(&fi->page_waitq); 100 + mutex_init(&fi->mutex); 100 101 fi->forget = fuse_alloc_forget(); 101 102 if (!fi->forget) { 102 103 kmem_cache_free(fuse_inode_cachep, inode); ··· 118 117 struct fuse_inode *fi = get_fuse_inode(inode); 119 118 BUG_ON(!list_empty(&fi->write_files)); 120 119 BUG_ON(!list_empty(&fi->queued_writes)); 120 + mutex_destroy(&fi->mutex); 121 121 kfree(fi->forget); 122 122 call_rcu(&inode->i_rcu, fuse_i_callback); 123 123 } ··· 351 349 } 352 350 iput(inode); 353 351 return 0; 352 + } 353 + 354 + void fuse_lock_inode(struct inode *inode) 355 + { 356 + if (!get_fuse_conn(inode)->parallel_dirops) 357 + mutex_lock(&get_fuse_inode(inode)->mutex); 358 + } 359 + 360 + void fuse_unlock_inode(struct inode *inode) 361 + { 362 + if (!get_fuse_conn(inode)->parallel_dirops) 363 + mutex_unlock(&get_fuse_inode(inode)->mutex); 354 364 } 355 365 356 366 static void fuse_umount_begin(struct super_block *sb) ··· 912 898 fc->async_dio = 1; 913 899 if (arg->flags & FUSE_WRITEBACK_CACHE) 914 900 fc->writeback_cache = 1; 901 + if (arg->flags & FUSE_PARALLEL_DIROPS) 902 + fc->parallel_dirops = 1; 915 903 if (arg->time_gran && arg->time_gran <= 1000000000) 916 904 fc->sb->s_time_gran = arg->time_gran; 917 905 } else { ··· 944 928 FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ | 945 929 FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA | 946 930 FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO | 947 - FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT; 931 + FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT | 932 + FUSE_PARALLEL_DIROPS; 948 933 req->in.h.opcode = FUSE_INIT; 949 934 req->in.numargs = 1; 950 935 req->in.args[0].size = sizeof(*arg);
+6 -1
include/uapi/linux/fuse.h
··· 105 105 * 106 106 * 7.24 107 107 * - add FUSE_LSEEK for SEEK_HOLE and SEEK_DATA support 108 + * 109 + * 7.25 110 + * - add FUSE_PARALLEL_DIROPS 108 111 */ 109 112 110 113 #ifndef _LINUX_FUSE_H ··· 143 140 #define FUSE_KERNEL_VERSION 7 144 141 145 142 /** Minor version number of this interface */ 146 - #define FUSE_KERNEL_MINOR_VERSION 24 143 + #define FUSE_KERNEL_MINOR_VERSION 25 147 144 148 145 /** The node ID of the root inode */ 149 146 #define FUSE_ROOT_ID 1 ··· 237 234 * FUSE_ASYNC_DIO: asynchronous direct I/O submission 238 235 * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes 239 236 * FUSE_NO_OPEN_SUPPORT: kernel supports zero-message opens 237 + * FUSE_PARALLEL_DIROPS: allow parallel lookups and readdir 240 238 */ 241 239 #define FUSE_ASYNC_READ (1 << 0) 242 240 #define FUSE_POSIX_LOCKS (1 << 1) ··· 257 253 #define FUSE_ASYNC_DIO (1 << 15) 258 254 #define FUSE_WRITEBACK_CACHE (1 << 16) 259 255 #define FUSE_NO_OPEN_SUPPORT (1 << 17) 256 + #define FUSE_PARALLEL_DIROPS (1 << 18) 260 257 261 258 /** 262 259 * CUSE INIT request/reply flags