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

Pull fuse updates from Miklos Szeredi:

- Fix a regression introduced in 5.15

- Extend the size of the FUSE_INIT request to accommodate for more
flags. There's a slight possibility of a regression for obscure fuse
servers; if this happens, then more complexity will need to be added
to the protocol

- Allow the DAX property to be controlled by the server on a per-inode
basis in virtiofs

- Allow sending security context to the server when creating a file or
directory

* tag 'fuse-update-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
Documentation/filesystem/dax: DAX on virtiofs
fuse: mark inode DONT_CACHE when per inode DAX hint changes
fuse: negotiate per inode DAX in FUSE_INIT
fuse: enable per inode DAX
fuse: support per inode DAX in fuse protocol
fuse: make DAX mount option a tri-state
fuse: add fuse_should_enable_dax() helper
fuse: Pass correct lend value to filemap_write_and_wait_range()
fuse: send security context of inode on file
fuse: extend init flags

+294 -52
+18 -2
Documentation/filesystems/dax.rst
··· 23 23 size equal to your kernel's `PAGE_SIZE`, so you may need to specify a block 24 24 size when creating the filesystem. 25 25 26 - Currently 3 filesystems support `DAX`: ext2, ext4 and xfs. Enabling `DAX` on them 27 - is different. 26 + Currently 4 filesystems support `DAX`: ext2, ext4, xfs and virtiofs. 27 + Enabling `DAX` on them is different. 28 28 29 29 Enabling DAX on ext2 30 30 -------------------- ··· 166 166 Setting the `FS_XFLAG_DAX` flag (specifically or through inheritance) occurs even 167 167 if the underlying media does not support dax and/or the filesystem is 168 168 overridden with a mount option. 169 + 170 + 171 + Enabling DAX on virtiofs 172 + ---------------------------- 173 + The semantic of DAX on virtiofs is basically equal to that on ext4 and xfs, 174 + except that when '-o dax=inode' is specified, virtiofs client derives the hint 175 + whether DAX shall be enabled or not from virtiofs server through FUSE protocol, 176 + rather than the persistent `FS_XFLAG_DAX` flag. That is, whether DAX shall be 177 + enabled or not is completely determined by virtiofs server, while virtiofs 178 + server itself may deploy various algorithm making this decision, e.g. depending 179 + on the persistent `FS_XFLAG_DAX` flag on the host. 180 + 181 + It is still supported to set or clear persistent `FS_XFLAG_DAX` flag inside 182 + guest, but it is not guaranteed that DAX will be enabled or disabled for 183 + corresponding file then. Users inside guest still need to call statx(2) and 184 + check the statx flag `STATX_ATTR_DAX` to see if DAX is enabled for this file. 169 185 170 186 171 187 Implementation Tips for Block Driver Writers
+34 -2
fs/fuse/dax.c
··· 1279 1279 return ret; 1280 1280 } 1281 1281 1282 - int fuse_dax_conn_alloc(struct fuse_conn *fc, struct dax_device *dax_dev) 1282 + int fuse_dax_conn_alloc(struct fuse_conn *fc, enum fuse_dax_mode dax_mode, 1283 + struct dax_device *dax_dev) 1283 1284 { 1284 1285 struct fuse_conn_dax *fcd; 1285 1286 int err; 1287 + 1288 + fc->dax_mode = dax_mode; 1286 1289 1287 1290 if (!dax_dev) 1288 1291 return 0; ··· 1330 1327 .invalidatepage = noop_invalidatepage, 1331 1328 }; 1332 1329 1333 - void fuse_dax_inode_init(struct inode *inode) 1330 + static bool fuse_should_enable_dax(struct inode *inode, unsigned int flags) 1334 1331 { 1335 1332 struct fuse_conn *fc = get_fuse_conn(inode); 1333 + enum fuse_dax_mode dax_mode = fc->dax_mode; 1336 1334 1335 + if (dax_mode == FUSE_DAX_NEVER) 1336 + return false; 1337 + 1338 + /* 1339 + * fc->dax may be NULL in 'inode' mode when filesystem device doesn't 1340 + * support DAX, in which case it will silently fallback to 'never' mode. 1341 + */ 1337 1342 if (!fc->dax) 1343 + return false; 1344 + 1345 + if (dax_mode == FUSE_DAX_ALWAYS) 1346 + return true; 1347 + 1348 + /* dax_mode is FUSE_DAX_INODE* */ 1349 + return fc->inode_dax && (flags & FUSE_ATTR_DAX); 1350 + } 1351 + 1352 + void fuse_dax_inode_init(struct inode *inode, unsigned int flags) 1353 + { 1354 + if (!fuse_should_enable_dax(inode, flags)) 1338 1355 return; 1339 1356 1340 1357 inode->i_flags |= S_DAX; 1341 1358 inode->i_data.a_ops = &fuse_dax_file_aops; 1359 + } 1360 + 1361 + void fuse_dax_dontcache(struct inode *inode, unsigned int flags) 1362 + { 1363 + struct fuse_conn *fc = get_fuse_conn(inode); 1364 + 1365 + if (fuse_is_inode_dax_mode(fc->dax_mode) && 1366 + ((bool) IS_DAX(inode) != (bool) (flags & FUSE_ATTR_DAX))) 1367 + d_mark_dontcache(inode); 1342 1368 } 1343 1369 1344 1370 bool fuse_dax_check_alignment(struct fuse_conn *fc, unsigned int map_alignment)
+91
fs/fuse/dir.c
··· 17 17 #include <linux/xattr.h> 18 18 #include <linux/iversion.h> 19 19 #include <linux/posix_acl.h> 20 + #include <linux/security.h> 21 + #include <linux/types.h> 22 + #include <linux/kernel.h> 20 23 21 24 static void fuse_advise_use_readdirplus(struct inode *dir) 22 25 { ··· 459 456 return ERR_PTR(err); 460 457 } 461 458 459 + static int get_security_context(struct dentry *entry, umode_t mode, 460 + void **security_ctx, u32 *security_ctxlen) 461 + { 462 + struct fuse_secctx *fctx; 463 + struct fuse_secctx_header *header; 464 + void *ctx = NULL, *ptr; 465 + u32 ctxlen, total_len = sizeof(*header); 466 + int err, nr_ctx = 0; 467 + const char *name; 468 + size_t namelen; 469 + 470 + err = security_dentry_init_security(entry, mode, &entry->d_name, 471 + &name, &ctx, &ctxlen); 472 + if (err) { 473 + if (err != -EOPNOTSUPP) 474 + goto out_err; 475 + /* No LSM is supporting this security hook. Ignore error */ 476 + ctxlen = 0; 477 + ctx = NULL; 478 + } 479 + 480 + if (ctxlen) { 481 + nr_ctx = 1; 482 + namelen = strlen(name) + 1; 483 + err = -EIO; 484 + if (WARN_ON(namelen > XATTR_NAME_MAX + 1 || ctxlen > S32_MAX)) 485 + goto out_err; 486 + total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen + ctxlen); 487 + } 488 + 489 + err = -ENOMEM; 490 + header = ptr = kzalloc(total_len, GFP_KERNEL); 491 + if (!ptr) 492 + goto out_err; 493 + 494 + header->nr_secctx = nr_ctx; 495 + header->size = total_len; 496 + ptr += sizeof(*header); 497 + if (nr_ctx) { 498 + fctx = ptr; 499 + fctx->size = ctxlen; 500 + ptr += sizeof(*fctx); 501 + 502 + strcpy(ptr, name); 503 + ptr += namelen; 504 + 505 + memcpy(ptr, ctx, ctxlen); 506 + } 507 + *security_ctxlen = total_len; 508 + *security_ctx = header; 509 + err = 0; 510 + out_err: 511 + kfree(ctx); 512 + return err; 513 + } 514 + 462 515 /* 463 516 * Atomic create+open operation 464 517 * ··· 535 476 struct fuse_entry_out outentry; 536 477 struct fuse_inode *fi; 537 478 struct fuse_file *ff; 479 + void *security_ctx = NULL; 480 + u32 security_ctxlen; 538 481 539 482 /* Userspace expects S_IFREG in create mode */ 540 483 BUG_ON((mode & S_IFMT) != S_IFREG); ··· 578 517 args.out_args[0].value = &outentry; 579 518 args.out_args[1].size = sizeof(outopen); 580 519 args.out_args[1].value = &outopen; 520 + 521 + if (fm->fc->init_security) { 522 + err = get_security_context(entry, mode, &security_ctx, 523 + &security_ctxlen); 524 + if (err) 525 + goto out_put_forget_req; 526 + 527 + args.in_numargs = 3; 528 + args.in_args[2].size = security_ctxlen; 529 + args.in_args[2].value = security_ctx; 530 + } 531 + 581 532 err = fuse_simple_request(fm, &args); 533 + kfree(security_ctx); 582 534 if (err) 583 535 goto out_free_ff; 584 536 ··· 694 620 struct dentry *d; 695 621 int err; 696 622 struct fuse_forget_link *forget; 623 + void *security_ctx = NULL; 624 + u32 security_ctxlen; 697 625 698 626 if (fuse_is_bad(dir)) 699 627 return -EIO; ··· 709 633 args->out_numargs = 1; 710 634 args->out_args[0].size = sizeof(outarg); 711 635 args->out_args[0].value = &outarg; 636 + 637 + if (fm->fc->init_security && args->opcode != FUSE_LINK) { 638 + err = get_security_context(entry, mode, &security_ctx, 639 + &security_ctxlen); 640 + if (err) 641 + goto out_put_forget_req; 642 + 643 + BUG_ON(args->in_numargs != 2); 644 + 645 + args->in_numargs = 3; 646 + args->in_args[2].size = security_ctxlen; 647 + args->in_args[2].value = security_ctx; 648 + } 649 + 712 650 err = fuse_simple_request(fm, args); 651 + kfree(security_ctx); 713 652 if (err) 714 653 goto out_put_forget_req; 715 654
+3 -3
fs/fuse/file.c
··· 2910 2910 2911 2911 static int fuse_writeback_range(struct inode *inode, loff_t start, loff_t end) 2912 2912 { 2913 - int err = filemap_write_and_wait_range(inode->i_mapping, start, -1); 2913 + int err = filemap_write_and_wait_range(inode->i_mapping, start, LLONG_MAX); 2914 2914 2915 2915 if (!err) 2916 2916 fuse_sync_writes(inode); ··· 3169 3169 .write_end = fuse_write_end, 3170 3170 }; 3171 3171 3172 - void fuse_init_file_inode(struct inode *inode) 3172 + void fuse_init_file_inode(struct inode *inode, unsigned int flags) 3173 3173 { 3174 3174 struct fuse_inode *fi = get_fuse_inode(inode); 3175 3175 ··· 3183 3183 fi->writepages = RB_ROOT; 3184 3184 3185 3185 if (IS_ENABLED(CONFIG_FUSE_DAX)) 3186 - fuse_dax_inode_init(inode); 3186 + fuse_dax_inode_init(inode, flags); 3187 3187 }
+27 -4
fs/fuse/fuse_i.h
··· 480 480 struct list_head entry; 481 481 }; 482 482 483 + enum fuse_dax_mode { 484 + FUSE_DAX_INODE_DEFAULT, /* default */ 485 + FUSE_DAX_ALWAYS, /* "-o dax=always" */ 486 + FUSE_DAX_NEVER, /* "-o dax=never" */ 487 + FUSE_DAX_INODE_USER, /* "-o dax=inode" */ 488 + }; 489 + 490 + static inline bool fuse_is_inode_dax_mode(enum fuse_dax_mode mode) 491 + { 492 + return mode == FUSE_DAX_INODE_DEFAULT || mode == FUSE_DAX_INODE_USER; 493 + } 494 + 483 495 struct fuse_fs_context { 484 496 int fd; 485 497 struct file *file; ··· 509 497 bool no_control:1; 510 498 bool no_force_umount:1; 511 499 bool legacy_opts_show:1; 512 - bool dax:1; 500 + enum fuse_dax_mode dax_mode; 513 501 unsigned int max_read; 514 502 unsigned int blksize; 515 503 const char *subtype; ··· 777 765 /* Propagate syncfs() to server */ 778 766 unsigned int sync_fs:1; 779 767 768 + /* Initialize security xattrs when creating a new inode */ 769 + unsigned int init_security:1; 770 + 771 + /* Does the filesystem support per inode DAX? */ 772 + unsigned int inode_dax:1; 773 + 780 774 /** The number of requests waiting for completion */ 781 775 atomic_t num_waiting; 782 776 ··· 820 802 struct list_head devices; 821 803 822 804 #ifdef CONFIG_FUSE_DAX 805 + /* Dax mode */ 806 + enum fuse_dax_mode dax_mode; 807 + 823 808 /* Dax specific conn data, non-NULL if DAX is enabled */ 824 809 struct fuse_conn_dax *dax; 825 810 #endif ··· 1028 1007 /** 1029 1008 * Initialize file operations on a regular file 1030 1009 */ 1031 - void fuse_init_file_inode(struct inode *inode); 1010 + void fuse_init_file_inode(struct inode *inode, unsigned int flags); 1032 1011 1033 1012 /** 1034 1013 * Initialize inode operations on regular files and special files ··· 1290 1269 ssize_t fuse_dax_write_iter(struct kiocb *iocb, struct iov_iter *from); 1291 1270 int fuse_dax_mmap(struct file *file, struct vm_area_struct *vma); 1292 1271 int fuse_dax_break_layouts(struct inode *inode, u64 dmap_start, u64 dmap_end); 1293 - int fuse_dax_conn_alloc(struct fuse_conn *fc, struct dax_device *dax_dev); 1272 + int fuse_dax_conn_alloc(struct fuse_conn *fc, enum fuse_dax_mode mode, 1273 + struct dax_device *dax_dev); 1294 1274 void fuse_dax_conn_free(struct fuse_conn *fc); 1295 1275 bool fuse_dax_inode_alloc(struct super_block *sb, struct fuse_inode *fi); 1296 - void fuse_dax_inode_init(struct inode *inode); 1276 + void fuse_dax_inode_init(struct inode *inode, unsigned int flags); 1297 1277 void fuse_dax_inode_cleanup(struct inode *inode); 1278 + void fuse_dax_dontcache(struct inode *inode, unsigned int flags); 1298 1279 bool fuse_dax_check_alignment(struct fuse_conn *fc, unsigned int map_alignment); 1299 1280 void fuse_dax_cancel_work(struct fuse_conn *fc); 1300 1281
+55 -34
fs/fuse/inode.c
··· 301 301 if (inval) 302 302 invalidate_inode_pages2(inode->i_mapping); 303 303 } 304 + 305 + if (IS_ENABLED(CONFIG_FUSE_DAX)) 306 + fuse_dax_dontcache(inode, attr->flags); 304 307 } 305 308 306 309 static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr) ··· 316 313 inode->i_ctime.tv_nsec = attr->ctimensec; 317 314 if (S_ISREG(inode->i_mode)) { 318 315 fuse_init_common(inode); 319 - fuse_init_file_inode(inode); 316 + fuse_init_file_inode(inode, attr->flags); 320 317 } else if (S_ISDIR(inode->i_mode)) 321 318 fuse_init_dir(inode); 322 319 else if (S_ISLNK(inode->i_mode)) ··· 770 767 seq_printf(m, ",blksize=%lu", sb->s_blocksize); 771 768 } 772 769 #ifdef CONFIG_FUSE_DAX 773 - if (fc->dax) 774 - seq_puts(m, ",dax"); 770 + if (fc->dax_mode == FUSE_DAX_ALWAYS) 771 + seq_puts(m, ",dax=always"); 772 + else if (fc->dax_mode == FUSE_DAX_NEVER) 773 + seq_puts(m, ",dax=never"); 774 + else if (fc->dax_mode == FUSE_DAX_INODE_USER) 775 + seq_puts(m, ",dax=inode"); 775 776 #endif 776 777 777 778 return 0; ··· 1116 1109 process_init_limits(fc, arg); 1117 1110 1118 1111 if (arg->minor >= 6) { 1112 + u64 flags = arg->flags | (u64) arg->flags2 << 32; 1113 + 1119 1114 ra_pages = arg->max_readahead / PAGE_SIZE; 1120 - if (arg->flags & FUSE_ASYNC_READ) 1115 + if (flags & FUSE_ASYNC_READ) 1121 1116 fc->async_read = 1; 1122 - if (!(arg->flags & FUSE_POSIX_LOCKS)) 1117 + if (!(flags & FUSE_POSIX_LOCKS)) 1123 1118 fc->no_lock = 1; 1124 1119 if (arg->minor >= 17) { 1125 - if (!(arg->flags & FUSE_FLOCK_LOCKS)) 1120 + if (!(flags & FUSE_FLOCK_LOCKS)) 1126 1121 fc->no_flock = 1; 1127 1122 } else { 1128 - if (!(arg->flags & FUSE_POSIX_LOCKS)) 1123 + if (!(flags & FUSE_POSIX_LOCKS)) 1129 1124 fc->no_flock = 1; 1130 1125 } 1131 - if (arg->flags & FUSE_ATOMIC_O_TRUNC) 1126 + if (flags & FUSE_ATOMIC_O_TRUNC) 1132 1127 fc->atomic_o_trunc = 1; 1133 1128 if (arg->minor >= 9) { 1134 1129 /* LOOKUP has dependency on proto version */ 1135 - if (arg->flags & FUSE_EXPORT_SUPPORT) 1130 + if (flags & FUSE_EXPORT_SUPPORT) 1136 1131 fc->export_support = 1; 1137 1132 } 1138 - if (arg->flags & FUSE_BIG_WRITES) 1133 + if (flags & FUSE_BIG_WRITES) 1139 1134 fc->big_writes = 1; 1140 - if (arg->flags & FUSE_DONT_MASK) 1135 + if (flags & FUSE_DONT_MASK) 1141 1136 fc->dont_mask = 1; 1142 - if (arg->flags & FUSE_AUTO_INVAL_DATA) 1137 + if (flags & FUSE_AUTO_INVAL_DATA) 1143 1138 fc->auto_inval_data = 1; 1144 - else if (arg->flags & FUSE_EXPLICIT_INVAL_DATA) 1139 + else if (flags & FUSE_EXPLICIT_INVAL_DATA) 1145 1140 fc->explicit_inval_data = 1; 1146 - if (arg->flags & FUSE_DO_READDIRPLUS) { 1141 + if (flags & FUSE_DO_READDIRPLUS) { 1147 1142 fc->do_readdirplus = 1; 1148 - if (arg->flags & FUSE_READDIRPLUS_AUTO) 1143 + if (flags & FUSE_READDIRPLUS_AUTO) 1149 1144 fc->readdirplus_auto = 1; 1150 1145 } 1151 - if (arg->flags & FUSE_ASYNC_DIO) 1146 + if (flags & FUSE_ASYNC_DIO) 1152 1147 fc->async_dio = 1; 1153 - if (arg->flags & FUSE_WRITEBACK_CACHE) 1148 + if (flags & FUSE_WRITEBACK_CACHE) 1154 1149 fc->writeback_cache = 1; 1155 - if (arg->flags & FUSE_PARALLEL_DIROPS) 1150 + if (flags & FUSE_PARALLEL_DIROPS) 1156 1151 fc->parallel_dirops = 1; 1157 - if (arg->flags & FUSE_HANDLE_KILLPRIV) 1152 + if (flags & FUSE_HANDLE_KILLPRIV) 1158 1153 fc->handle_killpriv = 1; 1159 1154 if (arg->time_gran && arg->time_gran <= 1000000000) 1160 1155 fm->sb->s_time_gran = arg->time_gran; 1161 - if ((arg->flags & FUSE_POSIX_ACL)) { 1156 + if ((flags & FUSE_POSIX_ACL)) { 1162 1157 fc->default_permissions = 1; 1163 1158 fc->posix_acl = 1; 1164 1159 fm->sb->s_xattr = fuse_acl_xattr_handlers; 1165 1160 } 1166 - if (arg->flags & FUSE_CACHE_SYMLINKS) 1161 + if (flags & FUSE_CACHE_SYMLINKS) 1167 1162 fc->cache_symlinks = 1; 1168 - if (arg->flags & FUSE_ABORT_ERROR) 1163 + if (flags & FUSE_ABORT_ERROR) 1169 1164 fc->abort_err = 1; 1170 - if (arg->flags & FUSE_MAX_PAGES) { 1165 + if (flags & FUSE_MAX_PAGES) { 1171 1166 fc->max_pages = 1172 1167 min_t(unsigned int, fc->max_pages_limit, 1173 1168 max_t(unsigned int, arg->max_pages, 1)); 1174 1169 } 1175 - if (IS_ENABLED(CONFIG_FUSE_DAX) && 1176 - arg->flags & FUSE_MAP_ALIGNMENT && 1177 - !fuse_dax_check_alignment(fc, arg->map_alignment)) { 1178 - ok = false; 1170 + if (IS_ENABLED(CONFIG_FUSE_DAX)) { 1171 + if (flags & FUSE_MAP_ALIGNMENT && 1172 + !fuse_dax_check_alignment(fc, arg->map_alignment)) { 1173 + ok = false; 1174 + } 1175 + if (flags & FUSE_HAS_INODE_DAX) 1176 + fc->inode_dax = 1; 1179 1177 } 1180 - if (arg->flags & FUSE_HANDLE_KILLPRIV_V2) { 1178 + if (flags & FUSE_HANDLE_KILLPRIV_V2) { 1181 1179 fc->handle_killpriv_v2 = 1; 1182 1180 fm->sb->s_flags |= SB_NOSEC; 1183 1181 } 1184 - if (arg->flags & FUSE_SETXATTR_EXT) 1182 + if (flags & FUSE_SETXATTR_EXT) 1185 1183 fc->setxattr_ext = 1; 1184 + if (flags & FUSE_SECURITY_CTX) 1185 + fc->init_security = 1; 1186 1186 } else { 1187 1187 ra_pages = fc->max_read / PAGE_SIZE; 1188 1188 fc->no_lock = 1; ··· 1217 1203 void fuse_send_init(struct fuse_mount *fm) 1218 1204 { 1219 1205 struct fuse_init_args *ia; 1206 + u64 flags; 1220 1207 1221 1208 ia = kzalloc(sizeof(*ia), GFP_KERNEL | __GFP_NOFAIL); 1222 1209 1223 1210 ia->in.major = FUSE_KERNEL_VERSION; 1224 1211 ia->in.minor = FUSE_KERNEL_MINOR_VERSION; 1225 1212 ia->in.max_readahead = fm->sb->s_bdi->ra_pages * PAGE_SIZE; 1226 - ia->in.flags |= 1213 + flags = 1227 1214 FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC | 1228 1215 FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK | 1229 1216 FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ | ··· 1234 1219 FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL | 1235 1220 FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS | 1236 1221 FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA | 1237 - FUSE_HANDLE_KILLPRIV_V2 | FUSE_SETXATTR_EXT; 1222 + FUSE_HANDLE_KILLPRIV_V2 | FUSE_SETXATTR_EXT | FUSE_INIT_EXT | 1223 + FUSE_SECURITY_CTX; 1238 1224 #ifdef CONFIG_FUSE_DAX 1239 1225 if (fm->fc->dax) 1240 - ia->in.flags |= FUSE_MAP_ALIGNMENT; 1226 + flags |= FUSE_MAP_ALIGNMENT; 1227 + if (fuse_is_inode_dax_mode(fm->fc->dax_mode)) 1228 + flags |= FUSE_HAS_INODE_DAX; 1241 1229 #endif 1242 1230 if (fm->fc->auto_submounts) 1243 - ia->in.flags |= FUSE_SUBMOUNTS; 1231 + flags |= FUSE_SUBMOUNTS; 1232 + 1233 + ia->in.flags = flags; 1234 + ia->in.flags2 = flags >> 32; 1244 1235 1245 1236 ia->args.opcode = FUSE_INIT; 1246 1237 ia->args.in_numargs = 1; ··· 1535 1514 sb->s_subtype = ctx->subtype; 1536 1515 ctx->subtype = NULL; 1537 1516 if (IS_ENABLED(CONFIG_FUSE_DAX)) { 1538 - err = fuse_dax_conn_alloc(fc, ctx->dax_dev); 1517 + err = fuse_dax_conn_alloc(fc, ctx->dax_mode, ctx->dax_dev); 1539 1518 if (err) 1540 1519 goto err; 1541 1520 }
+15 -3
fs/fuse/virtio_fs.c
··· 88 88 static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq, 89 89 struct fuse_req *req, bool in_flight); 90 90 91 + static const struct constant_table dax_param_enums[] = { 92 + {"always", FUSE_DAX_ALWAYS }, 93 + {"never", FUSE_DAX_NEVER }, 94 + {"inode", FUSE_DAX_INODE_USER }, 95 + {} 96 + }; 97 + 91 98 enum { 92 99 OPT_DAX, 100 + OPT_DAX_ENUM, 93 101 }; 94 102 95 103 static const struct fs_parameter_spec virtio_fs_parameters[] = { 96 104 fsparam_flag("dax", OPT_DAX), 105 + fsparam_enum("dax", OPT_DAX_ENUM, dax_param_enums), 97 106 {} 98 107 }; 99 108 ··· 119 110 120 111 switch (opt) { 121 112 case OPT_DAX: 122 - ctx->dax = 1; 113 + ctx->dax_mode = FUSE_DAX_ALWAYS; 114 + break; 115 + case OPT_DAX_ENUM: 116 + ctx->dax_mode = result.uint_32; 123 117 break; 124 118 default: 125 119 return -EINVAL; ··· 1338 1326 1339 1327 /* virtiofs allocates and installs its own fuse devices */ 1340 1328 ctx->fudptr = NULL; 1341 - if (ctx->dax) { 1342 - if (!fs->dax_dev) { 1329 + if (ctx->dax_mode != FUSE_DAX_NEVER) { 1330 + if (ctx->dax_mode == FUSE_DAX_ALWAYS && !fs->dax_dev) { 1343 1331 err = -EINVAL; 1344 1332 pr_err("virtio-fs: dax can't be enabled as filesystem" 1345 1333 " device does not support it.\n");
+51 -4
include/uapi/linux/fuse.h
··· 187 187 * 188 188 * 7.35 189 189 * - add FOPEN_NOFLUSH 190 + * 191 + * 7.36 192 + * - extend fuse_init_in with reserved fields, add FUSE_INIT_EXT init flag 193 + * - add flags2 to fuse_init_in and fuse_init_out 194 + * - add FUSE_SECURITY_CTX init flag 195 + * - add security context to create, mkdir, symlink, and mknod requests 196 + * - add FUSE_HAS_INODE_DAX, FUSE_ATTR_DAX 190 197 */ 191 198 192 199 #ifndef _LINUX_FUSE_H ··· 229 222 #define FUSE_KERNEL_VERSION 7 230 223 231 224 /** Minor version number of this interface */ 232 - #define FUSE_KERNEL_MINOR_VERSION 35 225 + #define FUSE_KERNEL_MINOR_VERSION 36 233 226 234 227 /** The node ID of the root inode */ 235 228 #define FUSE_ROOT_ID 1 ··· 348 341 * write/truncate sgid is killed only if file has group 349 342 * execute permission. (Same as Linux VFS behavior). 350 343 * FUSE_SETXATTR_EXT: Server supports extended struct fuse_setxattr_in 344 + * FUSE_INIT_EXT: extended fuse_init_in request 345 + * FUSE_INIT_RESERVED: reserved, do not use 346 + * FUSE_SECURITY_CTX: add security context to create, mkdir, symlink, and 347 + * mknod 348 + * FUSE_HAS_INODE_DAX: use per inode DAX 351 349 */ 352 350 #define FUSE_ASYNC_READ (1 << 0) 353 351 #define FUSE_POSIX_LOCKS (1 << 1) ··· 384 372 #define FUSE_SUBMOUNTS (1 << 27) 385 373 #define FUSE_HANDLE_KILLPRIV_V2 (1 << 28) 386 374 #define FUSE_SETXATTR_EXT (1 << 29) 375 + #define FUSE_INIT_EXT (1 << 30) 376 + #define FUSE_INIT_RESERVED (1 << 31) 377 + /* bits 32..63 get shifted down 32 bits into the flags2 field */ 378 + #define FUSE_SECURITY_CTX (1ULL << 32) 379 + #define FUSE_HAS_INODE_DAX (1ULL << 33) 387 380 388 381 /** 389 382 * CUSE INIT request/reply flags ··· 471 454 * fuse_attr flags 472 455 * 473 456 * FUSE_ATTR_SUBMOUNT: Object is a submount root 457 + * FUSE_ATTR_DAX: Enable DAX for this file in per inode DAX mode 474 458 */ 475 459 #define FUSE_ATTR_SUBMOUNT (1 << 0) 460 + #define FUSE_ATTR_DAX (1 << 1) 476 461 477 462 /** 478 463 * Open flags ··· 760 741 uint32_t minor; 761 742 uint32_t max_readahead; 762 743 uint32_t flags; 744 + uint32_t flags2; 745 + uint32_t unused[11]; 763 746 }; 764 747 765 748 #define FUSE_COMPAT_INIT_OUT_SIZE 8 ··· 778 757 uint32_t time_gran; 779 758 uint16_t max_pages; 780 759 uint16_t map_alignment; 781 - uint32_t unused[8]; 760 + uint32_t flags2; 761 + uint32_t unused[7]; 782 762 }; 783 763 784 764 #define CUSE_INIT_INFO_MAX 4096 ··· 887 865 char name[]; 888 866 }; 889 867 890 - #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) 891 - #define FUSE_DIRENT_ALIGN(x) \ 868 + /* Align variable length records to 64bit boundary */ 869 + #define FUSE_REC_ALIGN(x) \ 892 870 (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1)) 871 + 872 + #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) 873 + #define FUSE_DIRENT_ALIGN(x) FUSE_REC_ALIGN(x) 893 874 #define FUSE_DIRENT_SIZE(d) \ 894 875 FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) 895 876 ··· 1007 982 1008 983 struct fuse_syncfs_in { 1009 984 uint64_t padding; 985 + }; 986 + 987 + /* 988 + * For each security context, send fuse_secctx with size of security context 989 + * fuse_secctx will be followed by security context name and this in turn 990 + * will be followed by actual context label. 991 + * fuse_secctx, name, context 992 + */ 993 + struct fuse_secctx { 994 + uint32_t size; 995 + uint32_t padding; 996 + }; 997 + 998 + /* 999 + * Contains the information about how many fuse_secctx structures are being 1000 + * sent and what's the total size of all security contexts (including 1001 + * size of fuse_secctx_header). 1002 + * 1003 + */ 1004 + struct fuse_secctx_header { 1005 + uint32_t size; 1006 + uint32_t nr_secctx; 1010 1007 }; 1011 1008 1012 1009 #endif /* _LINUX_FUSE_H */