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

Pull fuse updates from Miklos Szeredi:

- Add mechanism for cleaning out unused, stale dentries; controlled via
a module option (Luis Henriques)

- Fix various bugs

- Cleanups

* tag 'fuse-update-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
fuse: Uninitialized variable in fuse_epoch_work()
fuse: fix io-uring list corruption for terminated non-committed requests
fuse: signal that a fuse inode should exhibit local fs behaviors
fuse: Always flush the page cache before FOPEN_DIRECT_IO write
fuse: Invalidate the page cache after FOPEN_DIRECT_IO write
fuse: rename 'namelen' to 'namesize'
fuse: use strscpy instead of strcpy
fuse: refactor fuse_conn_put() to remove negative logic.
fuse: new work queue to invalidate dentries from old epochs
fuse: new work queue to periodically invalidate expired dentries
dcache: export shrink_dentry_list() and add new helper d_dispose_if_unused()
fuse: add WARN_ON and comment for RCU revalidate
fuse: Fix whitespace for fuse_uring_args_to_ring() comment
fuse: missing copy_finish in fuse-over-io-uring argument copies
fuse: fix readahead reclaim deadlock

+343 -74
+12 -6
fs/dcache.c
··· 1104 1104 return de; 1105 1105 } 1106 1106 1107 + void d_dispose_if_unused(struct dentry *dentry, struct list_head *dispose) 1108 + { 1109 + spin_lock(&dentry->d_lock); 1110 + if (!dentry->d_lockref.count) 1111 + to_shrink_list(dentry, dispose); 1112 + spin_unlock(&dentry->d_lock); 1113 + } 1114 + EXPORT_SYMBOL(d_dispose_if_unused); 1115 + 1107 1116 /* 1108 1117 * Try to kill dentries associated with this inode. 1109 1118 * WARNING: you must own a reference to inode. ··· 1123 1114 struct dentry *dentry; 1124 1115 1125 1116 spin_lock(&inode->i_lock); 1126 - hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { 1127 - spin_lock(&dentry->d_lock); 1128 - if (!dentry->d_lockref.count) 1129 - to_shrink_list(dentry, &dispose); 1130 - spin_unlock(&dentry->d_lock); 1131 - } 1117 + hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) 1118 + d_dispose_if_unused(dentry, &dispose); 1132 1119 spin_unlock(&inode->i_lock); 1133 1120 shrink_dentry_list(&dispose); 1134 1121 } ··· 1164 1159 shrink_kill(dentry); 1165 1160 } 1166 1161 } 1162 + EXPORT_SYMBOL(shrink_dentry_list); 1167 1163 1168 1164 static enum lru_status dentry_lru_isolate(struct list_head *item, 1169 1165 struct list_lru_one *lru, void *arg)
+5 -4
fs/fuse/dev.c
··· 846 846 } 847 847 848 848 /* Unmap and put previous page of userspace buffer */ 849 - static void fuse_copy_finish(struct fuse_copy_state *cs) 849 + void fuse_copy_finish(struct fuse_copy_state *cs) 850 850 { 851 851 if (cs->currbuf) { 852 852 struct pipe_buffer *buf = cs->currbuf; ··· 2041 2041 2042 2042 /* 2043 2043 * Increments the fuse connection epoch. This will result of dentries from 2044 - * previous epochs to be invalidated. 2045 - * 2046 - * XXX optimization: add call to shrink_dcache_sb()? 2044 + * previous epochs to be invalidated. Additionally, if inval_wq is set, a work 2045 + * queue is scheduled to trigger the invalidation. 2047 2046 */ 2048 2047 static int fuse_notify_inc_epoch(struct fuse_conn *fc) 2049 2048 { 2050 2049 atomic_inc(&fc->epoch); 2050 + if (inval_wq) 2051 + schedule_work(&fc->epoch_work); 2051 2052 2052 2053 return 0; 2053 2054 }
+8 -4
fs/fuse/dev_uring.c
··· 86 86 lockdep_assert_not_held(&queue->lock); 87 87 spin_lock(&queue->lock); 88 88 ent->fuse_req = NULL; 89 + list_del_init(&req->list); 89 90 if (test_bit(FR_BACKGROUND, &req->flags)) { 90 91 queue->active_background--; 91 92 spin_lock(&fc->bg_lock); ··· 599 598 cs.is_uring = true; 600 599 cs.req = req; 601 600 602 - return fuse_copy_out_args(&cs, args, ring_in_out.payload_sz); 601 + err = fuse_copy_out_args(&cs, args, ring_in_out.payload_sz); 602 + fuse_copy_finish(&cs); 603 + return err; 603 604 } 604 605 605 - /* 606 - * Copy data from the req to the ring buffer 607 - */ 606 + /* 607 + * Copy data from the req to the ring buffer 608 + */ 608 609 static int fuse_uring_args_to_ring(struct fuse_ring *ring, struct fuse_req *req, 609 610 struct fuse_ring_ent *ent) 610 611 { ··· 652 649 /* copy the payload */ 653 650 err = fuse_copy_args(&cs, num_args, args->in_pages, 654 651 (struct fuse_arg *)in_args, 0); 652 + fuse_copy_finish(&cs); 655 653 if (err) { 656 654 pr_info_ratelimited("%s fuse_copy_args failed\n", __func__); 657 655 return err;
+225 -31
fs/fuse/dir.c
··· 27 27 MODULE_PARM_DESC(allow_sys_admin_access, 28 28 "Allow users with CAP_SYS_ADMIN in initial userns to bypass allow_other access check"); 29 29 30 + struct dentry_bucket { 31 + struct rb_root tree; 32 + spinlock_t lock; 33 + }; 34 + 35 + #define HASH_BITS 5 36 + #define HASH_SIZE (1 << HASH_BITS) 37 + static struct dentry_bucket dentry_hash[HASH_SIZE]; 38 + struct delayed_work dentry_tree_work; 39 + 40 + /* Minimum invalidation work queue frequency */ 41 + #define FUSE_DENTRY_INVAL_FREQ_MIN 5 42 + 43 + unsigned __read_mostly inval_wq; 44 + static int inval_wq_set(const char *val, const struct kernel_param *kp) 45 + { 46 + unsigned int num; 47 + unsigned int old = inval_wq; 48 + int ret; 49 + 50 + if (!val) 51 + return -EINVAL; 52 + 53 + ret = kstrtouint(val, 0, &num); 54 + if (ret) 55 + return ret; 56 + 57 + if ((num < FUSE_DENTRY_INVAL_FREQ_MIN) && (num != 0)) 58 + return -EINVAL; 59 + 60 + /* This should prevent overflow in secs_to_jiffies() */ 61 + if (num > USHRT_MAX) 62 + return -EINVAL; 63 + 64 + *((unsigned int *)kp->arg) = num; 65 + 66 + if (num && !old) 67 + schedule_delayed_work(&dentry_tree_work, 68 + secs_to_jiffies(num)); 69 + else if (!num && old) 70 + cancel_delayed_work_sync(&dentry_tree_work); 71 + 72 + return 0; 73 + } 74 + static const struct kernel_param_ops inval_wq_ops = { 75 + .set = inval_wq_set, 76 + .get = param_get_uint, 77 + }; 78 + module_param_cb(inval_wq, &inval_wq_ops, &inval_wq, 0644); 79 + __MODULE_PARM_TYPE(inval_wq, "uint"); 80 + MODULE_PARM_DESC(inval_wq, 81 + "Dentries invalidation work queue period in secs (>= " 82 + __stringify(FUSE_DENTRY_INVAL_FREQ_MIN) ")."); 83 + 84 + static inline struct dentry_bucket *get_dentry_bucket(struct dentry *dentry) 85 + { 86 + int i = hash_ptr(dentry, HASH_BITS); 87 + 88 + return &dentry_hash[i]; 89 + } 90 + 30 91 static void fuse_advise_use_readdirplus(struct inode *dir) 31 92 { 32 93 struct fuse_inode *fi = get_fuse_inode(dir); ··· 95 34 set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state); 96 35 } 97 36 98 - #if BITS_PER_LONG >= 64 99 - static inline void __fuse_dentry_settime(struct dentry *entry, u64 time) 100 - { 101 - entry->d_fsdata = (void *) time; 102 - } 103 - 104 - static inline u64 fuse_dentry_time(const struct dentry *entry) 105 - { 106 - return (u64)entry->d_fsdata; 107 - } 108 - 109 - #else 110 - union fuse_dentry { 37 + struct fuse_dentry { 111 38 u64 time; 112 - struct rcu_head rcu; 39 + union { 40 + struct rcu_head rcu; 41 + struct rb_node node; 42 + }; 43 + struct dentry *dentry; 113 44 }; 45 + 46 + static void __fuse_dentry_tree_del_node(struct fuse_dentry *fd, 47 + struct dentry_bucket *bucket) 48 + { 49 + if (!RB_EMPTY_NODE(&fd->node)) { 50 + rb_erase(&fd->node, &bucket->tree); 51 + RB_CLEAR_NODE(&fd->node); 52 + } 53 + } 54 + 55 + static void fuse_dentry_tree_del_node(struct dentry *dentry) 56 + { 57 + struct fuse_dentry *fd = dentry->d_fsdata; 58 + struct dentry_bucket *bucket = get_dentry_bucket(dentry); 59 + 60 + spin_lock(&bucket->lock); 61 + __fuse_dentry_tree_del_node(fd, bucket); 62 + spin_unlock(&bucket->lock); 63 + } 64 + 65 + static void fuse_dentry_tree_add_node(struct dentry *dentry) 66 + { 67 + struct fuse_dentry *fd = dentry->d_fsdata; 68 + struct dentry_bucket *bucket; 69 + struct fuse_dentry *cur; 70 + struct rb_node **p, *parent = NULL; 71 + 72 + if (!inval_wq) 73 + return; 74 + 75 + bucket = get_dentry_bucket(dentry); 76 + 77 + spin_lock(&bucket->lock); 78 + 79 + __fuse_dentry_tree_del_node(fd, bucket); 80 + 81 + p = &bucket->tree.rb_node; 82 + while (*p) { 83 + parent = *p; 84 + cur = rb_entry(*p, struct fuse_dentry, node); 85 + if (fd->time < cur->time) 86 + p = &(*p)->rb_left; 87 + else 88 + p = &(*p)->rb_right; 89 + } 90 + rb_link_node(&fd->node, parent, p); 91 + rb_insert_color(&fd->node, &bucket->tree); 92 + spin_unlock(&bucket->lock); 93 + } 94 + 95 + /* 96 + * work queue which, when enabled, will periodically check for expired dentries 97 + * in the dentries tree. 98 + */ 99 + static void fuse_dentry_tree_work(struct work_struct *work) 100 + { 101 + LIST_HEAD(dispose); 102 + struct fuse_dentry *fd; 103 + struct rb_node *node; 104 + int i; 105 + 106 + for (i = 0; i < HASH_SIZE; i++) { 107 + spin_lock(&dentry_hash[i].lock); 108 + node = rb_first(&dentry_hash[i].tree); 109 + while (node) { 110 + fd = rb_entry(node, struct fuse_dentry, node); 111 + if (time_after64(get_jiffies_64(), fd->time)) { 112 + rb_erase(&fd->node, &dentry_hash[i].tree); 113 + RB_CLEAR_NODE(&fd->node); 114 + spin_unlock(&dentry_hash[i].lock); 115 + d_dispose_if_unused(fd->dentry, &dispose); 116 + cond_resched(); 117 + spin_lock(&dentry_hash[i].lock); 118 + } else 119 + break; 120 + node = rb_first(&dentry_hash[i].tree); 121 + } 122 + spin_unlock(&dentry_hash[i].lock); 123 + shrink_dentry_list(&dispose); 124 + } 125 + 126 + if (inval_wq) 127 + schedule_delayed_work(&dentry_tree_work, 128 + secs_to_jiffies(inval_wq)); 129 + } 130 + 131 + void fuse_epoch_work(struct work_struct *work) 132 + { 133 + struct fuse_conn *fc = container_of(work, struct fuse_conn, 134 + epoch_work); 135 + struct fuse_mount *fm; 136 + struct inode *inode; 137 + 138 + down_read(&fc->killsb); 139 + 140 + inode = fuse_ilookup(fc, FUSE_ROOT_ID, &fm); 141 + if (inode) { 142 + iput(inode); 143 + /* Remove all possible active references to cached inodes */ 144 + shrink_dcache_sb(fm->sb); 145 + } else 146 + pr_warn("Failed to get root inode"); 147 + 148 + up_read(&fc->killsb); 149 + } 150 + 151 + void fuse_dentry_tree_init(void) 152 + { 153 + int i; 154 + 155 + for (i = 0; i < HASH_SIZE; i++) { 156 + spin_lock_init(&dentry_hash[i].lock); 157 + dentry_hash[i].tree = RB_ROOT; 158 + } 159 + INIT_DELAYED_WORK(&dentry_tree_work, fuse_dentry_tree_work); 160 + } 161 + 162 + void fuse_dentry_tree_cleanup(void) 163 + { 164 + int i; 165 + 166 + inval_wq = 0; 167 + cancel_delayed_work_sync(&dentry_tree_work); 168 + 169 + for (i = 0; i < HASH_SIZE; i++) 170 + WARN_ON_ONCE(!RB_EMPTY_ROOT(&dentry_hash[i].tree)); 171 + } 114 172 115 173 static inline void __fuse_dentry_settime(struct dentry *dentry, u64 time) 116 174 { 117 - ((union fuse_dentry *) dentry->d_fsdata)->time = time; 175 + ((struct fuse_dentry *) dentry->d_fsdata)->time = time; 118 176 } 119 177 120 178 static inline u64 fuse_dentry_time(const struct dentry *entry) 121 179 { 122 - return ((union fuse_dentry *) entry->d_fsdata)->time; 180 + return ((struct fuse_dentry *) entry->d_fsdata)->time; 123 181 } 124 - #endif 125 182 126 183 static void fuse_dentry_settime(struct dentry *dentry, u64 time) 127 184 { ··· 260 81 } 261 82 262 83 __fuse_dentry_settime(dentry, time); 84 + fuse_dentry_tree_add_node(dentry); 263 85 } 264 86 265 87 /* ··· 463 283 goto out; 464 284 } 465 285 466 - #if BITS_PER_LONG < 64 467 286 static int fuse_dentry_init(struct dentry *dentry) 468 287 { 469 - dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry), 470 - GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE); 288 + struct fuse_dentry *fd; 471 289 472 - return dentry->d_fsdata ? 0 : -ENOMEM; 290 + fd = kzalloc(sizeof(struct fuse_dentry), 291 + GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE); 292 + if (!fd) 293 + return -ENOMEM; 294 + 295 + fd->dentry = dentry; 296 + RB_CLEAR_NODE(&fd->node); 297 + dentry->d_fsdata = fd; 298 + 299 + return 0; 473 300 } 301 + 302 + static void fuse_dentry_prune(struct dentry *dentry) 303 + { 304 + struct fuse_dentry *fd = dentry->d_fsdata; 305 + 306 + if (!RB_EMPTY_NODE(&fd->node)) 307 + fuse_dentry_tree_del_node(dentry); 308 + } 309 + 474 310 static void fuse_dentry_release(struct dentry *dentry) 475 311 { 476 - union fuse_dentry *fd = dentry->d_fsdata; 312 + struct fuse_dentry *fd = dentry->d_fsdata; 477 313 478 314 kfree_rcu(fd, rcu); 479 315 } 480 - #endif 481 316 482 317 static int fuse_dentry_delete(const struct dentry *dentry) 483 318 { ··· 526 331 const struct dentry_operations fuse_dentry_operations = { 527 332 .d_revalidate = fuse_dentry_revalidate, 528 333 .d_delete = fuse_dentry_delete, 529 - #if BITS_PER_LONG < 64 530 334 .d_init = fuse_dentry_init, 335 + .d_prune = fuse_dentry_prune, 531 336 .d_release = fuse_dentry_release, 532 - #endif 533 337 .d_automount = fuse_dentry_automount, 534 338 }; 535 339 ··· 665 471 u32 total_len = sizeof(*header); 666 472 int err, nr_ctx = 0; 667 473 const char *name = NULL; 668 - size_t namelen; 474 + size_t namesize; 669 475 670 476 err = security_dentry_init_security(entry, mode, &entry->d_name, 671 477 &name, &lsmctx); ··· 676 482 677 483 if (lsmctx.len) { 678 484 nr_ctx = 1; 679 - namelen = strlen(name) + 1; 485 + namesize = strlen(name) + 1; 680 486 err = -EIO; 681 - if (WARN_ON(namelen > XATTR_NAME_MAX + 1 || 487 + if (WARN_ON(namesize > XATTR_NAME_MAX + 1 || 682 488 lsmctx.len > S32_MAX)) 683 489 goto out_err; 684 - total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen + 490 + total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namesize + 685 491 lsmctx.len); 686 492 } 687 493 ··· 698 504 fctx->size = lsmctx.len; 699 505 ptr += sizeof(*fctx); 700 506 701 - strcpy(ptr, name); 702 - ptr += namelen; 507 + strscpy(ptr, name, namesize); 508 + ptr += namesize; 703 509 704 510 memcpy(ptr, lsmctx.context, lsmctx.len); 705 511 }
+29 -8
fs/fuse/file.c
··· 110 110 fuse_file_io_release(ff, ra->inode); 111 111 112 112 if (!args) { 113 - /* Do nothing when server does not implement 'open' */ 113 + /* Do nothing when server does not implement 'opendir' */ 114 + } else if (args->opcode == FUSE_RELEASE && ff->fm->fc->no_open) { 115 + fuse_release_end(ff->fm, args, 0); 114 116 } else if (sync) { 115 117 fuse_simple_request(ff->fm, args); 116 118 fuse_release_end(ff->fm, args, 0); ··· 133 131 struct fuse_file *ff; 134 132 int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN; 135 133 bool open = isdir ? !fc->no_opendir : !fc->no_open; 134 + bool release = !isdir || open; 136 135 137 - ff = fuse_file_alloc(fm, open); 136 + /* 137 + * ff->args->release_args still needs to be allocated (so we can hold an 138 + * inode reference while there are pending inflight file operations when 139 + * ->release() is called, see fuse_prepare_release()) even if 140 + * fc->no_open is set else it becomes possible for reclaim to deadlock 141 + * if while servicing the readahead request the server triggers reclaim 142 + * and reclaim evicts the inode of the file being read ahead. 143 + */ 144 + ff = fuse_file_alloc(fm, release); 138 145 if (!ff) 139 146 return ERR_PTR(-ENOMEM); 140 147 ··· 163 152 fuse_file_free(ff); 164 153 return ERR_PTR(err); 165 154 } else { 166 - /* No release needed */ 167 - kfree(ff->args); 168 - ff->args = NULL; 169 - if (isdir) 155 + if (isdir) { 156 + /* No release needed */ 157 + kfree(ff->args); 158 + ff->args = NULL; 170 159 fc->no_opendir = 1; 171 - else 160 + } else { 172 161 fc->no_open = 1; 162 + } 173 163 } 174 164 } 175 165 ··· 1664 1652 if (!ia) 1665 1653 return -ENOMEM; 1666 1654 1667 - if (fopen_direct_io && fc->direct_io_allow_mmap) { 1655 + if (fopen_direct_io) { 1668 1656 res = filemap_write_and_wait_range(mapping, pos, pos + count - 1); 1669 1657 if (res) { 1670 1658 fuse_io_free(ia); ··· 1737 1725 fuse_io_free(ia); 1738 1726 if (res > 0) 1739 1727 *ppos = pos; 1728 + 1729 + if (res > 0 && write && fopen_direct_io) { 1730 + /* 1731 + * As in generic_file_direct_write(), invalidate after the 1732 + * write, to invalidate read-ahead cache that may have competed 1733 + * with the write. 1734 + */ 1735 + invalidate_inode_pages2_range(mapping, idx_from, idx_to); 1736 + } 1740 1737 1741 1738 return res > 0 ? res : err; 1742 1739 }
+1
fs/fuse/fuse_dev_i.h
··· 62 62 63 63 void fuse_copy_init(struct fuse_copy_state *cs, bool write, 64 64 struct iov_iter *iter); 65 + void fuse_copy_finish(struct fuse_copy_state *cs); 65 66 int fuse_copy_args(struct fuse_copy_state *cs, unsigned int numargs, 66 67 unsigned int argpages, struct fuse_arg *args, 67 68 int zeroing);
+27 -1
fs/fuse/fuse_i.h
··· 54 54 /** Frequency (in jiffies) of request timeout checks, if opted into */ 55 55 extern const unsigned long fuse_timeout_timer_freq; 56 56 57 + /* 58 + * Dentries invalidation workqueue period, in seconds. The value of this 59 + * parameter shall be >= FUSE_DENTRY_INVAL_FREQ_MIN seconds, or 0 (zero), in 60 + * which case no workqueue will be created. 61 + */ 62 + extern unsigned inval_wq __read_mostly; 63 + 57 64 /** Maximum of max_pages received in init_out */ 58 65 extern unsigned int fuse_max_pages_limit; 59 66 /* ··· 239 232 FUSE_I_BTIME, 240 233 /* Wants or already has page cache IO */ 241 234 FUSE_I_CACHE_IO_MODE, 235 + /* 236 + * Client has exclusive access to the inode, either because fs is local 237 + * or the fuse server has an exclusive "lease" on distributed fs 238 + */ 239 + FUSE_I_EXCLUSIVE, 242 240 }; 243 241 244 242 struct fuse_conn; ··· 654 642 /** Current epoch for up-to-date dentries */ 655 643 atomic_t epoch; 656 644 645 + struct work_struct epoch_work; 646 + 657 647 struct rcu_head rcu; 658 648 659 649 /** The user id for this mount */ ··· 1052 1038 return get_fuse_mount_super(inode->i_sb)->fc; 1053 1039 } 1054 1040 1055 - static inline struct fuse_inode *get_fuse_inode(struct inode *inode) 1041 + static inline struct fuse_inode *get_fuse_inode(const struct inode *inode) 1056 1042 { 1057 1043 return container_of(inode, struct fuse_inode, inode); 1058 1044 } ··· 1092 1078 static inline bool fuse_is_bad(struct inode *inode) 1093 1079 { 1094 1080 return unlikely(test_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state)); 1081 + } 1082 + 1083 + static inline bool fuse_inode_is_exclusive(const struct inode *inode) 1084 + { 1085 + const struct fuse_inode *fi = get_fuse_inode(inode); 1086 + 1087 + return test_bit(FUSE_I_EXCLUSIVE, &fi->state); 1095 1088 } 1096 1089 1097 1090 static inline struct folio **fuse_folios_alloc(unsigned int nfolios, gfp_t flags, ··· 1289 1268 1290 1269 /* Check if any requests timed out */ 1291 1270 void fuse_check_timeout(struct work_struct *work); 1271 + 1272 + void fuse_dentry_tree_init(void); 1273 + void fuse_dentry_tree_cleanup(void); 1274 + 1275 + void fuse_epoch_work(struct work_struct *work); 1292 1276 1293 1277 /** 1294 1278 * Invalidate inode attributes
+24 -18
fs/fuse/inode.c
··· 977 977 refcount_set(&fc->count, 1); 978 978 atomic_set(&fc->dev_count, 1); 979 979 atomic_set(&fc->epoch, 1); 980 + INIT_WORK(&fc->epoch_work, fuse_epoch_work); 980 981 init_waitqueue_head(&fc->blocked_waitq); 981 982 fuse_iqueue_init(&fc->iq, fiq_ops, fiq_priv); 982 983 INIT_LIST_HEAD(&fc->bg_queue); ··· 1022 1021 1023 1022 void fuse_conn_put(struct fuse_conn *fc) 1024 1023 { 1025 - if (refcount_dec_and_test(&fc->count)) { 1026 - struct fuse_iqueue *fiq = &fc->iq; 1027 - struct fuse_sync_bucket *bucket; 1024 + struct fuse_iqueue *fiq = &fc->iq; 1025 + struct fuse_sync_bucket *bucket; 1028 1026 1029 - if (IS_ENABLED(CONFIG_FUSE_DAX)) 1030 - fuse_dax_conn_free(fc); 1031 - if (fc->timeout.req_timeout) 1032 - cancel_delayed_work_sync(&fc->timeout.work); 1033 - if (fiq->ops->release) 1034 - fiq->ops->release(fiq); 1035 - put_pid_ns(fc->pid_ns); 1036 - bucket = rcu_dereference_protected(fc->curr_bucket, 1); 1037 - if (bucket) { 1038 - WARN_ON(atomic_read(&bucket->count) != 1); 1039 - kfree(bucket); 1040 - } 1041 - if (IS_ENABLED(CONFIG_FUSE_PASSTHROUGH)) 1042 - fuse_backing_files_free(fc); 1043 - call_rcu(&fc->rcu, delayed_release); 1027 + if (!refcount_dec_and_test(&fc->count)) 1028 + return; 1029 + 1030 + if (IS_ENABLED(CONFIG_FUSE_DAX)) 1031 + fuse_dax_conn_free(fc); 1032 + if (fc->timeout.req_timeout) 1033 + cancel_delayed_work_sync(&fc->timeout.work); 1034 + cancel_work_sync(&fc->epoch_work); 1035 + if (fiq->ops->release) 1036 + fiq->ops->release(fiq); 1037 + put_pid_ns(fc->pid_ns); 1038 + bucket = rcu_dereference_protected(fc->curr_bucket, 1); 1039 + if (bucket) { 1040 + WARN_ON(atomic_read(&bucket->count) != 1); 1041 + kfree(bucket); 1044 1042 } 1043 + if (IS_ENABLED(CONFIG_FUSE_PASSTHROUGH)) 1044 + fuse_backing_files_free(fc); 1045 + call_rcu(&fc->rcu, delayed_release); 1045 1046 } 1046 1047 EXPORT_SYMBOL_GPL(fuse_conn_put); 1047 1048 ··· 2286 2283 if (res) 2287 2284 goto err_sysfs_cleanup; 2288 2285 2286 + fuse_dentry_tree_init(); 2287 + 2289 2288 sanitize_global_limit(&max_user_bgreq); 2290 2289 sanitize_global_limit(&max_user_congthresh); 2291 2290 ··· 2307 2302 { 2308 2303 pr_debug("exit\n"); 2309 2304 2305 + fuse_dentry_tree_cleanup(); 2310 2306 fuse_ctl_cleanup(); 2311 2307 fuse_sysfs_cleanup(); 2312 2308 fuse_fs_cleanup();
+10 -2
fs/overlayfs/super.c
··· 128 128 unsigned int i; 129 129 int ret = 1; 130 130 131 - /* Careful in RCU mode */ 132 - if (!inode) 131 + if (!inode) { 132 + /* 133 + * Lookup of negative dentries will call ovl_dentry_init_flags() 134 + * with NULL upperdentry and NULL oe, resulting in the 135 + * DCACHE_OP*_REVALIDATE flags being cleared. Hence the only 136 + * way to get a negative inode is due to a race with dentry 137 + * destruction. 138 + */ 139 + WARN_ON(!(flags & LOOKUP_RCU)); 133 140 return -ECHILD; 141 + } 134 142 135 143 oe = OVL_I_E(inode); 136 144 lowerstack = ovl_lowerstack(oe);
+2
include/linux/dcache.h
··· 268 268 269 269 extern struct dentry *d_find_alias(struct inode *); 270 270 extern void d_prune_aliases(struct inode *); 271 + extern void d_dispose_if_unused(struct dentry *, struct list_head *); 272 + extern void shrink_dentry_list(struct list_head *); 271 273 272 274 extern struct dentry *d_find_alias_rcu(struct inode *); 273 275