| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * (C) 1997 Linus Torvalds |
|---|
| 3 | 4 | * (C) 1999 Andrea Arcangeli <andrea@suse.de> (dynamic inode allocation) |
|---|
| .. | .. |
|---|
| 10 | 11 | #include <linux/swap.h> |
|---|
| 11 | 12 | #include <linux/security.h> |
|---|
| 12 | 13 | #include <linux/cdev.h> |
|---|
| 13 | | -#include <linux/bootmem.h> |
|---|
| 14 | +#include <linux/memblock.h> |
|---|
| 14 | 15 | #include <linux/fscrypt.h> |
|---|
| 15 | 16 | #include <linux/fsnotify.h> |
|---|
| 16 | 17 | #include <linux/mount.h> |
|---|
| .. | .. |
|---|
| 107 | 108 | */ |
|---|
| 108 | 109 | #ifdef CONFIG_SYSCTL |
|---|
| 109 | 110 | int proc_nr_inodes(struct ctl_table *table, int write, |
|---|
| 110 | | - void __user *buffer, size_t *lenp, loff_t *ppos) |
|---|
| 111 | + void *buffer, size_t *lenp, loff_t *ppos) |
|---|
| 111 | 112 | { |
|---|
| 112 | 113 | inodes_stat.nr_inodes = get_nr_inodes(); |
|---|
| 113 | 114 | inodes_stat.nr_unused = get_nr_inodes_unused(); |
|---|
| .. | .. |
|---|
| 167 | 168 | inode->i_wb_frn_history = 0; |
|---|
| 168 | 169 | #endif |
|---|
| 169 | 170 | |
|---|
| 170 | | - if (security_inode_alloc(inode)) |
|---|
| 171 | | - goto out; |
|---|
| 172 | 171 | spin_lock_init(&inode->i_lock); |
|---|
| 173 | 172 | lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key); |
|---|
| 174 | 173 | |
|---|
| .. | .. |
|---|
| 180 | 179 | mapping->a_ops = &empty_aops; |
|---|
| 181 | 180 | mapping->host = inode; |
|---|
| 182 | 181 | mapping->flags = 0; |
|---|
| 182 | + if (sb->s_type->fs_flags & FS_THP_SUPPORT) |
|---|
| 183 | + __set_bit(AS_THP_SUPPORT, &mapping->flags); |
|---|
| 183 | 184 | mapping->wb_err = 0; |
|---|
| 184 | 185 | atomic_set(&mapping->i_mmap_writable, 0); |
|---|
| 186 | +#ifdef CONFIG_READ_ONLY_THP_FOR_FS |
|---|
| 187 | + atomic_set(&mapping->nr_thps, 0); |
|---|
| 188 | +#endif |
|---|
| 185 | 189 | mapping_set_gfp_mask(mapping, GFP_HIGHUSER_MOVABLE); |
|---|
| 186 | 190 | mapping->private_data = NULL; |
|---|
| 187 | 191 | mapping->writeback_index = 0; |
|---|
| .. | .. |
|---|
| 196 | 200 | inode->i_fsnotify_mask = 0; |
|---|
| 197 | 201 | #endif |
|---|
| 198 | 202 | inode->i_flctx = NULL; |
|---|
| 203 | + |
|---|
| 204 | + if (unlikely(security_inode_alloc(inode))) |
|---|
| 205 | + return -ENOMEM; |
|---|
| 199 | 206 | this_cpu_inc(nr_inodes); |
|---|
| 200 | 207 | |
|---|
| 201 | 208 | return 0; |
|---|
| 202 | | -out: |
|---|
| 203 | | - return -ENOMEM; |
|---|
| 204 | 209 | } |
|---|
| 205 | 210 | EXPORT_SYMBOL(inode_init_always); |
|---|
| 206 | 211 | |
|---|
| 212 | +void free_inode_nonrcu(struct inode *inode) |
|---|
| 213 | +{ |
|---|
| 214 | + kmem_cache_free(inode_cachep, inode); |
|---|
| 215 | +} |
|---|
| 216 | +EXPORT_SYMBOL(free_inode_nonrcu); |
|---|
| 217 | + |
|---|
| 218 | +static void i_callback(struct rcu_head *head) |
|---|
| 219 | +{ |
|---|
| 220 | + struct inode *inode = container_of(head, struct inode, i_rcu); |
|---|
| 221 | + if (inode->free_inode) |
|---|
| 222 | + inode->free_inode(inode); |
|---|
| 223 | + else |
|---|
| 224 | + free_inode_nonrcu(inode); |
|---|
| 225 | +} |
|---|
| 226 | + |
|---|
| 207 | 227 | static struct inode *alloc_inode(struct super_block *sb) |
|---|
| 208 | 228 | { |
|---|
| 229 | + const struct super_operations *ops = sb->s_op; |
|---|
| 209 | 230 | struct inode *inode; |
|---|
| 210 | 231 | |
|---|
| 211 | | - if (sb->s_op->alloc_inode) |
|---|
| 212 | | - inode = sb->s_op->alloc_inode(sb); |
|---|
| 232 | + if (ops->alloc_inode) |
|---|
| 233 | + inode = ops->alloc_inode(sb); |
|---|
| 213 | 234 | else |
|---|
| 214 | 235 | inode = kmem_cache_alloc(inode_cachep, GFP_KERNEL); |
|---|
| 215 | 236 | |
|---|
| .. | .. |
|---|
| 217 | 238 | return NULL; |
|---|
| 218 | 239 | |
|---|
| 219 | 240 | if (unlikely(inode_init_always(sb, inode))) { |
|---|
| 220 | | - if (inode->i_sb->s_op->destroy_inode) |
|---|
| 221 | | - inode->i_sb->s_op->destroy_inode(inode); |
|---|
| 222 | | - else |
|---|
| 223 | | - kmem_cache_free(inode_cachep, inode); |
|---|
| 241 | + if (ops->destroy_inode) { |
|---|
| 242 | + ops->destroy_inode(inode); |
|---|
| 243 | + if (!ops->free_inode) |
|---|
| 244 | + return NULL; |
|---|
| 245 | + } |
|---|
| 246 | + inode->free_inode = ops->free_inode; |
|---|
| 247 | + i_callback(&inode->i_rcu); |
|---|
| 224 | 248 | return NULL; |
|---|
| 225 | 249 | } |
|---|
| 226 | 250 | |
|---|
| 227 | 251 | return inode; |
|---|
| 228 | 252 | } |
|---|
| 229 | | - |
|---|
| 230 | | -void free_inode_nonrcu(struct inode *inode) |
|---|
| 231 | | -{ |
|---|
| 232 | | - kmem_cache_free(inode_cachep, inode); |
|---|
| 233 | | -} |
|---|
| 234 | | -EXPORT_SYMBOL(free_inode_nonrcu); |
|---|
| 235 | 253 | |
|---|
| 236 | 254 | void __destroy_inode(struct inode *inode) |
|---|
| 237 | 255 | { |
|---|
| .. | .. |
|---|
| 255 | 273 | } |
|---|
| 256 | 274 | EXPORT_SYMBOL(__destroy_inode); |
|---|
| 257 | 275 | |
|---|
| 258 | | -static void i_callback(struct rcu_head *head) |
|---|
| 259 | | -{ |
|---|
| 260 | | - struct inode *inode = container_of(head, struct inode, i_rcu); |
|---|
| 261 | | - kmem_cache_free(inode_cachep, inode); |
|---|
| 262 | | -} |
|---|
| 263 | | - |
|---|
| 264 | 276 | static void destroy_inode(struct inode *inode) |
|---|
| 265 | 277 | { |
|---|
| 278 | + const struct super_operations *ops = inode->i_sb->s_op; |
|---|
| 279 | + |
|---|
| 266 | 280 | BUG_ON(!list_empty(&inode->i_lru)); |
|---|
| 267 | 281 | __destroy_inode(inode); |
|---|
| 268 | | - if (inode->i_sb->s_op->destroy_inode) |
|---|
| 269 | | - inode->i_sb->s_op->destroy_inode(inode); |
|---|
| 270 | | - else |
|---|
| 271 | | - call_rcu(&inode->i_rcu, i_callback); |
|---|
| 282 | + if (ops->destroy_inode) { |
|---|
| 283 | + ops->destroy_inode(inode); |
|---|
| 284 | + if (!ops->free_inode) |
|---|
| 285 | + return; |
|---|
| 286 | + } |
|---|
| 287 | + inode->free_inode = ops->free_inode; |
|---|
| 288 | + call_rcu(&inode->i_rcu, i_callback); |
|---|
| 272 | 289 | } |
|---|
| 273 | 290 | |
|---|
| 274 | 291 | /** |
|---|
| .. | .. |
|---|
| 289 | 306 | if (!inode->i_nlink) |
|---|
| 290 | 307 | atomic_long_inc(&inode->i_sb->s_remove_count); |
|---|
| 291 | 308 | } |
|---|
| 292 | | -EXPORT_SYMBOL(drop_nlink); |
|---|
| 309 | +EXPORT_SYMBOL_NS(drop_nlink, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 293 | 310 | |
|---|
| 294 | 311 | /** |
|---|
| 295 | 312 | * clear_nlink - directly zero an inode's link count |
|---|
| .. | .. |
|---|
| 328 | 345 | inode->__i_nlink = nlink; |
|---|
| 329 | 346 | } |
|---|
| 330 | 347 | } |
|---|
| 331 | | -EXPORT_SYMBOL(set_nlink); |
|---|
| 348 | +EXPORT_SYMBOL_NS(set_nlink, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 332 | 349 | |
|---|
| 333 | 350 | /** |
|---|
| 334 | 351 | * inc_nlink - directly increment an inode's link count |
|---|
| .. | .. |
|---|
| 351 | 368 | |
|---|
| 352 | 369 | static void __address_space_init_once(struct address_space *mapping) |
|---|
| 353 | 370 | { |
|---|
| 354 | | - INIT_RADIX_TREE(&mapping->i_pages, GFP_ATOMIC | __GFP_ACCOUNT); |
|---|
| 371 | + xa_init_flags(&mapping->i_pages, XA_FLAGS_LOCK_IRQ | XA_FLAGS_ACCOUNT); |
|---|
| 355 | 372 | init_rwsem(&mapping->i_mmap_rwsem); |
|---|
| 356 | 373 | INIT_LIST_HEAD(&mapping->private_list); |
|---|
| 357 | 374 | spin_lock_init(&mapping->private_lock); |
|---|
| .. | .. |
|---|
| 381 | 398 | __address_space_init_once(&inode->i_data); |
|---|
| 382 | 399 | i_size_ordered_init(inode); |
|---|
| 383 | 400 | } |
|---|
| 384 | | -EXPORT_SYMBOL(inode_init_once); |
|---|
| 401 | +EXPORT_SYMBOL_NS(inode_init_once, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 385 | 402 | |
|---|
| 386 | 403 | static void init_once(void *foo) |
|---|
| 387 | 404 | { |
|---|
| .. | .. |
|---|
| 405 | 422 | { |
|---|
| 406 | 423 | WARN_ON(atomic_inc_return(&inode->i_count) < 2); |
|---|
| 407 | 424 | } |
|---|
| 408 | | -EXPORT_SYMBOL(ihold); |
|---|
| 425 | +EXPORT_SYMBOL_NS(ihold, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 409 | 426 | |
|---|
| 410 | 427 | static void inode_lru_list_add(struct inode *inode) |
|---|
| 411 | 428 | { |
|---|
| .. | .. |
|---|
| 481 | 498 | |
|---|
| 482 | 499 | spin_lock(&inode_hash_lock); |
|---|
| 483 | 500 | spin_lock(&inode->i_lock); |
|---|
| 484 | | - hlist_add_head(&inode->i_hash, b); |
|---|
| 501 | + hlist_add_head_rcu(&inode->i_hash, b); |
|---|
| 485 | 502 | spin_unlock(&inode->i_lock); |
|---|
| 486 | 503 | spin_unlock(&inode_hash_lock); |
|---|
| 487 | 504 | } |
|---|
| 488 | | -EXPORT_SYMBOL(__insert_inode_hash); |
|---|
| 505 | +EXPORT_SYMBOL_NS(__insert_inode_hash, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 489 | 506 | |
|---|
| 490 | 507 | /** |
|---|
| 491 | 508 | * __remove_inode_hash - remove an inode from the hash |
|---|
| .. | .. |
|---|
| 497 | 514 | { |
|---|
| 498 | 515 | spin_lock(&inode_hash_lock); |
|---|
| 499 | 516 | spin_lock(&inode->i_lock); |
|---|
| 500 | | - hlist_del_init(&inode->i_hash); |
|---|
| 517 | + hlist_del_init_rcu(&inode->i_hash); |
|---|
| 501 | 518 | spin_unlock(&inode->i_lock); |
|---|
| 502 | 519 | spin_unlock(&inode_hash_lock); |
|---|
| 503 | 520 | } |
|---|
| 504 | | -EXPORT_SYMBOL(__remove_inode_hash); |
|---|
| 521 | +EXPORT_SYMBOL_NS(__remove_inode_hash, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 505 | 522 | |
|---|
| 506 | 523 | void clear_inode(struct inode *inode) |
|---|
| 507 | 524 | { |
|---|
| .. | .. |
|---|
| 521 | 538 | /* don't need i_lock here, no concurrent mods to i_state */ |
|---|
| 522 | 539 | inode->i_state = I_FREEING | I_CLEAR; |
|---|
| 523 | 540 | } |
|---|
| 524 | | -EXPORT_SYMBOL(clear_inode); |
|---|
| 541 | +EXPORT_SYMBOL_NS(clear_inode, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 525 | 542 | |
|---|
| 526 | 543 | /* |
|---|
| 527 | 544 | * Free the inode passed in, removing it from the lists it is still connected |
|---|
| .. | .. |
|---|
| 983 | 1000 | wake_up_bit(&inode->i_state, __I_NEW); |
|---|
| 984 | 1001 | spin_unlock(&inode->i_lock); |
|---|
| 985 | 1002 | } |
|---|
| 986 | | -EXPORT_SYMBOL(unlock_new_inode); |
|---|
| 1003 | +EXPORT_SYMBOL_NS(unlock_new_inode, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 987 | 1004 | |
|---|
| 988 | 1005 | void discard_new_inode(struct inode *inode) |
|---|
| 989 | 1006 | { |
|---|
| .. | .. |
|---|
| 997 | 1014 | iput(inode); |
|---|
| 998 | 1015 | } |
|---|
| 999 | 1016 | EXPORT_SYMBOL(discard_new_inode); |
|---|
| 1017 | + |
|---|
| 1018 | +/** |
|---|
| 1019 | + * lock_two_inodes - lock two inodes (may be regular files but also dirs) |
|---|
| 1020 | + * |
|---|
| 1021 | + * Lock any non-NULL argument. The caller must make sure that if he is passing |
|---|
| 1022 | + * in two directories, one is not ancestor of the other. Zero, one or two |
|---|
| 1023 | + * objects may be locked by this function. |
|---|
| 1024 | + * |
|---|
| 1025 | + * @inode1: first inode to lock |
|---|
| 1026 | + * @inode2: second inode to lock |
|---|
| 1027 | + * @subclass1: inode lock subclass for the first lock obtained |
|---|
| 1028 | + * @subclass2: inode lock subclass for the second lock obtained |
|---|
| 1029 | + */ |
|---|
| 1030 | +void lock_two_inodes(struct inode *inode1, struct inode *inode2, |
|---|
| 1031 | + unsigned subclass1, unsigned subclass2) |
|---|
| 1032 | +{ |
|---|
| 1033 | + if (!inode1 || !inode2) { |
|---|
| 1034 | + /* |
|---|
| 1035 | + * Make sure @subclass1 will be used for the acquired lock. |
|---|
| 1036 | + * This is not strictly necessary (no current caller cares) but |
|---|
| 1037 | + * let's keep things consistent. |
|---|
| 1038 | + */ |
|---|
| 1039 | + if (!inode1) |
|---|
| 1040 | + swap(inode1, inode2); |
|---|
| 1041 | + goto lock; |
|---|
| 1042 | + } |
|---|
| 1043 | + |
|---|
| 1044 | + /* |
|---|
| 1045 | + * If one object is directory and the other is not, we must make sure |
|---|
| 1046 | + * to lock directory first as the other object may be its child. |
|---|
| 1047 | + */ |
|---|
| 1048 | + if (S_ISDIR(inode2->i_mode) == S_ISDIR(inode1->i_mode)) { |
|---|
| 1049 | + if (inode1 > inode2) |
|---|
| 1050 | + swap(inode1, inode2); |
|---|
| 1051 | + } else if (!S_ISDIR(inode1->i_mode)) |
|---|
| 1052 | + swap(inode1, inode2); |
|---|
| 1053 | +lock: |
|---|
| 1054 | + if (inode1) |
|---|
| 1055 | + inode_lock_nested(inode1, subclass1); |
|---|
| 1056 | + if (inode2 && inode2 != inode1) |
|---|
| 1057 | + inode_lock_nested(inode2, subclass2); |
|---|
| 1058 | +} |
|---|
| 1000 | 1059 | |
|---|
| 1001 | 1060 | /** |
|---|
| 1002 | 1061 | * lock_two_nondirectories - take two i_mutexes on non-directory objects |
|---|
| .. | .. |
|---|
| 1091 | 1150 | */ |
|---|
| 1092 | 1151 | spin_lock(&inode->i_lock); |
|---|
| 1093 | 1152 | inode->i_state |= I_NEW; |
|---|
| 1094 | | - hlist_add_head(&inode->i_hash, head); |
|---|
| 1153 | + hlist_add_head_rcu(&inode->i_hash, head); |
|---|
| 1095 | 1154 | spin_unlock(&inode->i_lock); |
|---|
| 1096 | 1155 | if (!creating) |
|---|
| 1097 | 1156 | inode_sb_list_add(inode); |
|---|
| .. | .. |
|---|
| 1140 | 1199 | } |
|---|
| 1141 | 1200 | return inode; |
|---|
| 1142 | 1201 | } |
|---|
| 1143 | | -EXPORT_SYMBOL(iget5_locked); |
|---|
| 1202 | +EXPORT_SYMBOL_NS(iget5_locked, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 1144 | 1203 | |
|---|
| 1145 | 1204 | /** |
|---|
| 1146 | 1205 | * iget_locked - obtain an inode from a mounted file system |
|---|
| .. | .. |
|---|
| 1185 | 1244 | inode->i_ino = ino; |
|---|
| 1186 | 1245 | spin_lock(&inode->i_lock); |
|---|
| 1187 | 1246 | inode->i_state = I_NEW; |
|---|
| 1188 | | - hlist_add_head(&inode->i_hash, head); |
|---|
| 1247 | + hlist_add_head_rcu(&inode->i_hash, head); |
|---|
| 1189 | 1248 | spin_unlock(&inode->i_lock); |
|---|
| 1190 | 1249 | inode_sb_list_add(inode); |
|---|
| 1191 | 1250 | spin_unlock(&inode_hash_lock); |
|---|
| .. | .. |
|---|
| 1228 | 1287 | struct hlist_head *b = inode_hashtable + hash(sb, ino); |
|---|
| 1229 | 1288 | struct inode *inode; |
|---|
| 1230 | 1289 | |
|---|
| 1231 | | - spin_lock(&inode_hash_lock); |
|---|
| 1232 | | - hlist_for_each_entry(inode, b, i_hash) { |
|---|
| 1233 | | - if (inode->i_ino == ino && inode->i_sb == sb) { |
|---|
| 1234 | | - spin_unlock(&inode_hash_lock); |
|---|
| 1290 | + hlist_for_each_entry_rcu(inode, b, i_hash) { |
|---|
| 1291 | + if (inode->i_ino == ino && inode->i_sb == sb) |
|---|
| 1235 | 1292 | return 0; |
|---|
| 1236 | | - } |
|---|
| 1237 | 1293 | } |
|---|
| 1238 | | - spin_unlock(&inode_hash_lock); |
|---|
| 1239 | | - |
|---|
| 1240 | 1294 | return 1; |
|---|
| 1241 | 1295 | } |
|---|
| 1242 | 1296 | |
|---|
| .. | .. |
|---|
| 1265 | 1319 | static unsigned int counter; |
|---|
| 1266 | 1320 | ino_t res; |
|---|
| 1267 | 1321 | |
|---|
| 1322 | + rcu_read_lock(); |
|---|
| 1268 | 1323 | spin_lock(&iunique_lock); |
|---|
| 1269 | 1324 | do { |
|---|
| 1270 | 1325 | if (counter <= max_reserved) |
|---|
| .. | .. |
|---|
| 1272 | 1327 | res = counter++; |
|---|
| 1273 | 1328 | } while (!test_inode_iunique(sb, res)); |
|---|
| 1274 | 1329 | spin_unlock(&iunique_lock); |
|---|
| 1330 | + rcu_read_unlock(); |
|---|
| 1275 | 1331 | |
|---|
| 1276 | 1332 | return res; |
|---|
| 1277 | 1333 | } |
|---|
| 1278 | | -EXPORT_SYMBOL(iunique); |
|---|
| 1334 | +EXPORT_SYMBOL_NS(iunique, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 1279 | 1335 | |
|---|
| 1280 | 1336 | struct inode *igrab(struct inode *inode) |
|---|
| 1281 | 1337 | { |
|---|
| .. | .. |
|---|
| 1358 | 1414 | } |
|---|
| 1359 | 1415 | return inode; |
|---|
| 1360 | 1416 | } |
|---|
| 1361 | | -EXPORT_SYMBOL(ilookup5); |
|---|
| 1417 | +EXPORT_SYMBOL_NS(ilookup5, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 1362 | 1418 | |
|---|
| 1363 | 1419 | /** |
|---|
| 1364 | 1420 | * ilookup - search for an inode in the inode cache |
|---|
| .. | .. |
|---|
| 1440 | 1496 | } |
|---|
| 1441 | 1497 | EXPORT_SYMBOL(find_inode_nowait); |
|---|
| 1442 | 1498 | |
|---|
| 1499 | +/** |
|---|
| 1500 | + * find_inode_rcu - find an inode in the inode cache |
|---|
| 1501 | + * @sb: Super block of file system to search |
|---|
| 1502 | + * @hashval: Key to hash |
|---|
| 1503 | + * @test: Function to test match on an inode |
|---|
| 1504 | + * @data: Data for test function |
|---|
| 1505 | + * |
|---|
| 1506 | + * Search for the inode specified by @hashval and @data in the inode cache, |
|---|
| 1507 | + * where the helper function @test will return 0 if the inode does not match |
|---|
| 1508 | + * and 1 if it does. The @test function must be responsible for taking the |
|---|
| 1509 | + * i_lock spin_lock and checking i_state for an inode being freed or being |
|---|
| 1510 | + * initialized. |
|---|
| 1511 | + * |
|---|
| 1512 | + * If successful, this will return the inode for which the @test function |
|---|
| 1513 | + * returned 1 and NULL otherwise. |
|---|
| 1514 | + * |
|---|
| 1515 | + * The @test function is not permitted to take a ref on any inode presented. |
|---|
| 1516 | + * It is also not permitted to sleep. |
|---|
| 1517 | + * |
|---|
| 1518 | + * The caller must hold the RCU read lock. |
|---|
| 1519 | + */ |
|---|
| 1520 | +struct inode *find_inode_rcu(struct super_block *sb, unsigned long hashval, |
|---|
| 1521 | + int (*test)(struct inode *, void *), void *data) |
|---|
| 1522 | +{ |
|---|
| 1523 | + struct hlist_head *head = inode_hashtable + hash(sb, hashval); |
|---|
| 1524 | + struct inode *inode; |
|---|
| 1525 | + |
|---|
| 1526 | + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), |
|---|
| 1527 | + "suspicious find_inode_rcu() usage"); |
|---|
| 1528 | + |
|---|
| 1529 | + hlist_for_each_entry_rcu(inode, head, i_hash) { |
|---|
| 1530 | + if (inode->i_sb == sb && |
|---|
| 1531 | + !(READ_ONCE(inode->i_state) & (I_FREEING | I_WILL_FREE)) && |
|---|
| 1532 | + test(inode, data)) |
|---|
| 1533 | + return inode; |
|---|
| 1534 | + } |
|---|
| 1535 | + return NULL; |
|---|
| 1536 | +} |
|---|
| 1537 | +EXPORT_SYMBOL(find_inode_rcu); |
|---|
| 1538 | + |
|---|
| 1539 | +/** |
|---|
| 1540 | + * find_inode_by_rcu - Find an inode in the inode cache |
|---|
| 1541 | + * @sb: Super block of file system to search |
|---|
| 1542 | + * @ino: The inode number to match |
|---|
| 1543 | + * |
|---|
| 1544 | + * Search for the inode specified by @hashval and @data in the inode cache, |
|---|
| 1545 | + * where the helper function @test will return 0 if the inode does not match |
|---|
| 1546 | + * and 1 if it does. The @test function must be responsible for taking the |
|---|
| 1547 | + * i_lock spin_lock and checking i_state for an inode being freed or being |
|---|
| 1548 | + * initialized. |
|---|
| 1549 | + * |
|---|
| 1550 | + * If successful, this will return the inode for which the @test function |
|---|
| 1551 | + * returned 1 and NULL otherwise. |
|---|
| 1552 | + * |
|---|
| 1553 | + * The @test function is not permitted to take a ref on any inode presented. |
|---|
| 1554 | + * It is also not permitted to sleep. |
|---|
| 1555 | + * |
|---|
| 1556 | + * The caller must hold the RCU read lock. |
|---|
| 1557 | + */ |
|---|
| 1558 | +struct inode *find_inode_by_ino_rcu(struct super_block *sb, |
|---|
| 1559 | + unsigned long ino) |
|---|
| 1560 | +{ |
|---|
| 1561 | + struct hlist_head *head = inode_hashtable + hash(sb, ino); |
|---|
| 1562 | + struct inode *inode; |
|---|
| 1563 | + |
|---|
| 1564 | + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), |
|---|
| 1565 | + "suspicious find_inode_by_ino_rcu() usage"); |
|---|
| 1566 | + |
|---|
| 1567 | + hlist_for_each_entry_rcu(inode, head, i_hash) { |
|---|
| 1568 | + if (inode->i_ino == ino && |
|---|
| 1569 | + inode->i_sb == sb && |
|---|
| 1570 | + !(READ_ONCE(inode->i_state) & (I_FREEING | I_WILL_FREE))) |
|---|
| 1571 | + return inode; |
|---|
| 1572 | + } |
|---|
| 1573 | + return NULL; |
|---|
| 1574 | +} |
|---|
| 1575 | +EXPORT_SYMBOL(find_inode_by_ino_rcu); |
|---|
| 1576 | + |
|---|
| 1443 | 1577 | int insert_inode_locked(struct inode *inode) |
|---|
| 1444 | 1578 | { |
|---|
| 1445 | 1579 | struct super_block *sb = inode->i_sb; |
|---|
| .. | .. |
|---|
| 1464 | 1598 | if (likely(!old)) { |
|---|
| 1465 | 1599 | spin_lock(&inode->i_lock); |
|---|
| 1466 | 1600 | inode->i_state |= I_NEW | I_CREATING; |
|---|
| 1467 | | - hlist_add_head(&inode->i_hash, head); |
|---|
| 1601 | + hlist_add_head_rcu(&inode->i_hash, head); |
|---|
| 1468 | 1602 | spin_unlock(&inode->i_lock); |
|---|
| 1469 | 1603 | spin_unlock(&inode_hash_lock); |
|---|
| 1470 | 1604 | return 0; |
|---|
| .. | .. |
|---|
| 1524 | 1658 | { |
|---|
| 1525 | 1659 | struct super_block *sb = inode->i_sb; |
|---|
| 1526 | 1660 | const struct super_operations *op = inode->i_sb->s_op; |
|---|
| 1661 | + unsigned long state; |
|---|
| 1527 | 1662 | int drop; |
|---|
| 1528 | 1663 | |
|---|
| 1529 | 1664 | WARN_ON(inode->i_state & I_NEW); |
|---|
| .. | .. |
|---|
| 1533 | 1668 | else |
|---|
| 1534 | 1669 | drop = generic_drop_inode(inode); |
|---|
| 1535 | 1670 | |
|---|
| 1536 | | - if (!drop && (sb->s_flags & SB_ACTIVE)) { |
|---|
| 1671 | + if (!drop && |
|---|
| 1672 | + !(inode->i_state & I_DONTCACHE) && |
|---|
| 1673 | + (sb->s_flags & SB_ACTIVE)) { |
|---|
| 1537 | 1674 | inode_add_lru(inode); |
|---|
| 1538 | 1675 | spin_unlock(&inode->i_lock); |
|---|
| 1539 | 1676 | return; |
|---|
| 1540 | 1677 | } |
|---|
| 1541 | 1678 | |
|---|
| 1679 | + state = inode->i_state; |
|---|
| 1542 | 1680 | if (!drop) { |
|---|
| 1543 | | - inode->i_state |= I_WILL_FREE; |
|---|
| 1681 | + WRITE_ONCE(inode->i_state, state | I_WILL_FREE); |
|---|
| 1544 | 1682 | spin_unlock(&inode->i_lock); |
|---|
| 1683 | + |
|---|
| 1545 | 1684 | write_inode_now(inode, 1); |
|---|
| 1685 | + |
|---|
| 1546 | 1686 | spin_lock(&inode->i_lock); |
|---|
| 1547 | | - WARN_ON(inode->i_state & I_NEW); |
|---|
| 1548 | | - inode->i_state &= ~I_WILL_FREE; |
|---|
| 1687 | + state = inode->i_state; |
|---|
| 1688 | + WARN_ON(state & I_NEW); |
|---|
| 1689 | + state &= ~I_WILL_FREE; |
|---|
| 1549 | 1690 | } |
|---|
| 1550 | 1691 | |
|---|
| 1551 | | - inode->i_state |= I_FREEING; |
|---|
| 1692 | + WRITE_ONCE(inode->i_state, state | I_FREEING); |
|---|
| 1552 | 1693 | if (!list_empty(&inode->i_lru)) |
|---|
| 1553 | 1694 | inode_lru_list_del(inode); |
|---|
| 1554 | 1695 | spin_unlock(&inode->i_lock); |
|---|
| .. | .. |
|---|
| 1584 | 1725 | } |
|---|
| 1585 | 1726 | EXPORT_SYMBOL(iput); |
|---|
| 1586 | 1727 | |
|---|
| 1728 | +#ifdef CONFIG_BLOCK |
|---|
| 1587 | 1729 | /** |
|---|
| 1588 | 1730 | * bmap - find a block number in a file |
|---|
| 1589 | | - * @inode: inode of file |
|---|
| 1590 | | - * @block: block to find |
|---|
| 1731 | + * @inode: inode owning the block number being requested |
|---|
| 1732 | + * @block: pointer containing the block to find |
|---|
| 1591 | 1733 | * |
|---|
| 1592 | | - * Returns the block number on the device holding the inode that |
|---|
| 1593 | | - * is the disk block number for the block of the file requested. |
|---|
| 1594 | | - * That is, asked for block 4 of inode 1 the function will return the |
|---|
| 1595 | | - * disk block relative to the disk start that holds that block of the |
|---|
| 1596 | | - * file. |
|---|
| 1734 | + * Replaces the value in ``*block`` with the block number on the device holding |
|---|
| 1735 | + * corresponding to the requested block number in the file. |
|---|
| 1736 | + * That is, asked for block 4 of inode 1 the function will replace the |
|---|
| 1737 | + * 4 in ``*block``, with disk block relative to the disk start that holds that |
|---|
| 1738 | + * block of the file. |
|---|
| 1739 | + * |
|---|
| 1740 | + * Returns -EINVAL in case of error, 0 otherwise. If mapping falls into a |
|---|
| 1741 | + * hole, returns 0 and ``*block`` is also set to 0. |
|---|
| 1597 | 1742 | */ |
|---|
| 1598 | | -sector_t bmap(struct inode *inode, sector_t block) |
|---|
| 1743 | +int bmap(struct inode *inode, sector_t *block) |
|---|
| 1599 | 1744 | { |
|---|
| 1600 | | - sector_t res = 0; |
|---|
| 1601 | | - if (inode->i_mapping->a_ops->bmap) |
|---|
| 1602 | | - res = inode->i_mapping->a_ops->bmap(inode->i_mapping, block); |
|---|
| 1603 | | - return res; |
|---|
| 1745 | + if (!inode->i_mapping->a_ops->bmap) |
|---|
| 1746 | + return -EINVAL; |
|---|
| 1747 | + |
|---|
| 1748 | + *block = inode->i_mapping->a_ops->bmap(inode->i_mapping, *block); |
|---|
| 1749 | + return 0; |
|---|
| 1604 | 1750 | } |
|---|
| 1605 | 1751 | EXPORT_SYMBOL(bmap); |
|---|
| 1752 | +#endif |
|---|
| 1606 | 1753 | |
|---|
| 1607 | 1754 | /* |
|---|
| 1608 | 1755 | * With relative atime, only update atime if the previous atime is |
|---|
| .. | .. |
|---|
| 1610 | 1757 | * passed since the last atime update. |
|---|
| 1611 | 1758 | */ |
|---|
| 1612 | 1759 | static int relatime_need_update(struct vfsmount *mnt, struct inode *inode, |
|---|
| 1613 | | - struct timespec now) |
|---|
| 1760 | + struct timespec64 now) |
|---|
| 1614 | 1761 | { |
|---|
| 1615 | 1762 | |
|---|
| 1616 | 1763 | if (!(mnt->mnt_flags & MNT_RELATIME)) |
|---|
| .. | .. |
|---|
| 1666 | 1813 | * This does the actual work of updating an inodes time or version. Must have |
|---|
| 1667 | 1814 | * had called mnt_want_write() before calling this. |
|---|
| 1668 | 1815 | */ |
|---|
| 1669 | | -static int update_time(struct inode *inode, struct timespec64 *time, int flags) |
|---|
| 1816 | +int inode_update_time(struct inode *inode, struct timespec64 *time, int flags) |
|---|
| 1670 | 1817 | { |
|---|
| 1671 | | - int (*update_time)(struct inode *, struct timespec64 *, int); |
|---|
| 1672 | | - |
|---|
| 1673 | | - update_time = inode->i_op->update_time ? inode->i_op->update_time : |
|---|
| 1674 | | - generic_update_time; |
|---|
| 1675 | | - |
|---|
| 1676 | | - return update_time(inode, time, flags); |
|---|
| 1818 | + if (inode->i_op->update_time) |
|---|
| 1819 | + return inode->i_op->update_time(inode, time, flags); |
|---|
| 1820 | + return generic_update_time(inode, time, flags); |
|---|
| 1677 | 1821 | } |
|---|
| 1822 | +EXPORT_SYMBOL(inode_update_time); |
|---|
| 1678 | 1823 | |
|---|
| 1679 | 1824 | /** |
|---|
| 1680 | 1825 | * touch_atime - update the access time |
|---|
| .. | .. |
|---|
| 1711 | 1856 | |
|---|
| 1712 | 1857 | now = current_time(inode); |
|---|
| 1713 | 1858 | |
|---|
| 1714 | | - if (!relatime_need_update(mnt, inode, timespec64_to_timespec(now))) |
|---|
| 1859 | + if (!relatime_need_update(mnt, inode, now)) |
|---|
| 1715 | 1860 | return false; |
|---|
| 1716 | 1861 | |
|---|
| 1717 | 1862 | if (timespec64_equal(&inode->i_atime, &now)) |
|---|
| .. | .. |
|---|
| 1744 | 1889 | * of the fs read only, e.g. subvolumes in Btrfs. |
|---|
| 1745 | 1890 | */ |
|---|
| 1746 | 1891 | now = current_time(inode); |
|---|
| 1747 | | - update_time(inode, &now, S_ATIME); |
|---|
| 1892 | + inode_update_time(inode, &now, S_ATIME); |
|---|
| 1748 | 1893 | __mnt_drop_write(mnt); |
|---|
| 1749 | 1894 | skip_update: |
|---|
| 1750 | 1895 | sb_end_write(inode->i_sb); |
|---|
| 1751 | 1896 | } |
|---|
| 1752 | | -EXPORT_SYMBOL(touch_atime); |
|---|
| 1753 | | - |
|---|
| 1754 | | -/* |
|---|
| 1755 | | - * The logic we want is |
|---|
| 1756 | | - * |
|---|
| 1757 | | - * if suid or (sgid and xgrp) |
|---|
| 1758 | | - * remove privs |
|---|
| 1759 | | - */ |
|---|
| 1760 | | -int should_remove_suid(struct dentry *dentry) |
|---|
| 1761 | | -{ |
|---|
| 1762 | | - umode_t mode = d_inode(dentry)->i_mode; |
|---|
| 1763 | | - int kill = 0; |
|---|
| 1764 | | - |
|---|
| 1765 | | - /* suid always must be killed */ |
|---|
| 1766 | | - if (unlikely(mode & S_ISUID)) |
|---|
| 1767 | | - kill = ATTR_KILL_SUID; |
|---|
| 1768 | | - |
|---|
| 1769 | | - /* |
|---|
| 1770 | | - * sgid without any exec bits is just a mandatory locking mark; leave |
|---|
| 1771 | | - * it alone. If some exec bits are set, it's a real sgid; kill it. |
|---|
| 1772 | | - */ |
|---|
| 1773 | | - if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) |
|---|
| 1774 | | - kill |= ATTR_KILL_SGID; |
|---|
| 1775 | | - |
|---|
| 1776 | | - if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode))) |
|---|
| 1777 | | - return kill; |
|---|
| 1778 | | - |
|---|
| 1779 | | - return 0; |
|---|
| 1780 | | -} |
|---|
| 1781 | | -EXPORT_SYMBOL(should_remove_suid); |
|---|
| 1897 | +EXPORT_SYMBOL_NS(touch_atime, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 1782 | 1898 | |
|---|
| 1783 | 1899 | /* |
|---|
| 1784 | 1900 | * Return mask of changes for notify_change() that need to be done as a |
|---|
| .. | .. |
|---|
| 1794 | 1910 | if (IS_NOSEC(inode)) |
|---|
| 1795 | 1911 | return 0; |
|---|
| 1796 | 1912 | |
|---|
| 1797 | | - mask = should_remove_suid(dentry); |
|---|
| 1913 | + mask = setattr_should_drop_suidgid(inode); |
|---|
| 1798 | 1914 | ret = security_inode_need_killpriv(dentry); |
|---|
| 1799 | 1915 | if (ret < 0) |
|---|
| 1800 | 1916 | return ret; |
|---|
| .. | .. |
|---|
| 1803 | 1919 | return mask; |
|---|
| 1804 | 1920 | } |
|---|
| 1805 | 1921 | |
|---|
| 1806 | | -static int __remove_privs(struct vfsmount *mnt, struct dentry *dentry, int kill) |
|---|
| 1922 | +static int __remove_privs(struct dentry *dentry, int kill) |
|---|
| 1807 | 1923 | { |
|---|
| 1808 | 1924 | struct iattr newattrs; |
|---|
| 1809 | 1925 | |
|---|
| .. | .. |
|---|
| 1812 | 1928 | * Note we call this on write, so notify_change will not |
|---|
| 1813 | 1929 | * encounter any conflicting delegations: |
|---|
| 1814 | 1930 | */ |
|---|
| 1815 | | - return notify_change2(mnt, dentry, &newattrs, NULL); |
|---|
| 1931 | + return notify_change(dentry, &newattrs, NULL); |
|---|
| 1816 | 1932 | } |
|---|
| 1817 | 1933 | |
|---|
| 1818 | 1934 | /* |
|---|
| .. | .. |
|---|
| 1839 | 1955 | if (kill < 0) |
|---|
| 1840 | 1956 | return kill; |
|---|
| 1841 | 1957 | if (kill) |
|---|
| 1842 | | - error = __remove_privs(file->f_path.mnt, dentry, kill); |
|---|
| 1958 | + error = __remove_privs(dentry, kill); |
|---|
| 1843 | 1959 | if (!error) |
|---|
| 1844 | 1960 | inode_has_no_xattr(inode); |
|---|
| 1845 | 1961 | |
|---|
| 1846 | 1962 | return error; |
|---|
| 1847 | 1963 | } |
|---|
| 1848 | | -EXPORT_SYMBOL(file_remove_privs); |
|---|
| 1964 | +EXPORT_SYMBOL_NS(file_remove_privs, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 1849 | 1965 | |
|---|
| 1850 | 1966 | /** |
|---|
| 1851 | 1967 | * file_update_time - update mtime and ctime time |
|---|
| .. | .. |
|---|
| 1888 | 2004 | if (__mnt_want_write_file(file)) |
|---|
| 1889 | 2005 | return 0; |
|---|
| 1890 | 2006 | |
|---|
| 1891 | | - ret = update_time(inode, &now, sync_it); |
|---|
| 2007 | + ret = inode_update_time(inode, &now, sync_it); |
|---|
| 1892 | 2008 | __mnt_drop_write_file(file); |
|---|
| 1893 | 2009 | |
|---|
| 1894 | 2010 | return ret; |
|---|
| 1895 | 2011 | } |
|---|
| 1896 | 2012 | EXPORT_SYMBOL(file_update_time); |
|---|
| 2013 | + |
|---|
| 2014 | +/* Caller must hold the file's inode lock */ |
|---|
| 2015 | +int file_modified(struct file *file) |
|---|
| 2016 | +{ |
|---|
| 2017 | + int err; |
|---|
| 2018 | + |
|---|
| 2019 | + /* |
|---|
| 2020 | + * Clear the security bits if the process is not being run by root. |
|---|
| 2021 | + * This keeps people from modifying setuid and setgid binaries. |
|---|
| 2022 | + */ |
|---|
| 2023 | + err = file_remove_privs(file); |
|---|
| 2024 | + if (err) |
|---|
| 2025 | + return err; |
|---|
| 2026 | + |
|---|
| 2027 | + if (unlikely(file->f_mode & FMODE_NOCMTIME)) |
|---|
| 2028 | + return 0; |
|---|
| 2029 | + |
|---|
| 2030 | + return file_update_time(file); |
|---|
| 2031 | +} |
|---|
| 2032 | +EXPORT_SYMBOL(file_modified); |
|---|
| 1897 | 2033 | |
|---|
| 1898 | 2034 | int inode_needs_sync(struct inode *inode) |
|---|
| 1899 | 2035 | { |
|---|
| .. | .. |
|---|
| 2006 | 2142 | " inode %s:%lu\n", mode, inode->i_sb->s_id, |
|---|
| 2007 | 2143 | inode->i_ino); |
|---|
| 2008 | 2144 | } |
|---|
| 2009 | | -EXPORT_SYMBOL(init_special_inode); |
|---|
| 2145 | +EXPORT_SYMBOL_NS(init_special_inode, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 2010 | 2146 | |
|---|
| 2011 | 2147 | /** |
|---|
| 2012 | 2148 | * inode_init_owner - Init uid,gid,mode for new inode according to posix standards |
|---|
| .. | .. |
|---|
| 2024 | 2160 | /* Directories are special, and always inherit S_ISGID */ |
|---|
| 2025 | 2161 | if (S_ISDIR(mode)) |
|---|
| 2026 | 2162 | mode |= S_ISGID; |
|---|
| 2027 | | - else if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP) && |
|---|
| 2028 | | - !in_group_p(inode->i_gid) && |
|---|
| 2029 | | - !capable_wrt_inode_uidgid(dir, CAP_FSETID)) |
|---|
| 2030 | | - mode &= ~S_ISGID; |
|---|
| 2031 | 2163 | } else |
|---|
| 2032 | 2164 | inode->i_gid = current_fsgid(); |
|---|
| 2033 | 2165 | inode->i_mode = mode; |
|---|
| 2034 | 2166 | } |
|---|
| 2035 | | -EXPORT_SYMBOL(inode_init_owner); |
|---|
| 2167 | +EXPORT_SYMBOL_NS(inode_init_owner, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 2036 | 2168 | |
|---|
| 2037 | 2169 | /** |
|---|
| 2038 | 2170 | * inode_owner_or_capable - check current task permissions to inode |
|---|
| .. | .. |
|---|
| 2086 | 2218 | if (atomic_read(&inode->i_dio_count)) |
|---|
| 2087 | 2219 | __inode_dio_wait(inode); |
|---|
| 2088 | 2220 | } |
|---|
| 2089 | | -EXPORT_SYMBOL(inode_dio_wait); |
|---|
| 2221 | +EXPORT_SYMBOL_NS(inode_dio_wait, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 2090 | 2222 | |
|---|
| 2091 | 2223 | /* |
|---|
| 2092 | 2224 | * inode_set_flags - atomically set some inode flags |
|---|
| .. | .. |
|---|
| 2107 | 2239 | void inode_set_flags(struct inode *inode, unsigned int flags, |
|---|
| 2108 | 2240 | unsigned int mask) |
|---|
| 2109 | 2241 | { |
|---|
| 2110 | | - unsigned int old_flags, new_flags; |
|---|
| 2111 | | - |
|---|
| 2112 | 2242 | WARN_ON_ONCE(flags & ~mask); |
|---|
| 2113 | | - do { |
|---|
| 2114 | | - old_flags = READ_ONCE(inode->i_flags); |
|---|
| 2115 | | - new_flags = (old_flags & ~mask) | flags; |
|---|
| 2116 | | - } while (unlikely(cmpxchg(&inode->i_flags, old_flags, |
|---|
| 2117 | | - new_flags) != old_flags)); |
|---|
| 2243 | + set_mask_bits(&inode->i_flags, mask, flags); |
|---|
| 2118 | 2244 | } |
|---|
| 2119 | | -EXPORT_SYMBOL(inode_set_flags); |
|---|
| 2245 | +EXPORT_SYMBOL_NS(inode_set_flags, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 2120 | 2246 | |
|---|
| 2121 | 2247 | void inode_nohighmem(struct inode *inode) |
|---|
| 2122 | 2248 | { |
|---|
| .. | .. |
|---|
| 2125 | 2251 | EXPORT_SYMBOL(inode_nohighmem); |
|---|
| 2126 | 2252 | |
|---|
| 2127 | 2253 | /** |
|---|
| 2128 | | - * timespec64_trunc - Truncate timespec64 to a granularity |
|---|
| 2129 | | - * @t: Timespec64 |
|---|
| 2130 | | - * @gran: Granularity in ns. |
|---|
| 2254 | + * timestamp_truncate - Truncate timespec to a granularity |
|---|
| 2255 | + * @t: Timespec |
|---|
| 2256 | + * @inode: inode being updated |
|---|
| 2131 | 2257 | * |
|---|
| 2132 | | - * Truncate a timespec64 to a granularity. Always rounds down. gran must |
|---|
| 2258 | + * Truncate a timespec to the granularity supported by the fs |
|---|
| 2259 | + * containing the inode. Always rounds down. gran must |
|---|
| 2133 | 2260 | * not be 0 nor greater than a second (NSEC_PER_SEC, or 10^9 ns). |
|---|
| 2134 | 2261 | */ |
|---|
| 2135 | | -struct timespec64 timespec64_trunc(struct timespec64 t, unsigned gran) |
|---|
| 2262 | +struct timespec64 timestamp_truncate(struct timespec64 t, struct inode *inode) |
|---|
| 2136 | 2263 | { |
|---|
| 2137 | | - /* Avoid division in the common cases 1 ns and 1 s. */ |
|---|
| 2138 | | - if (gran == 1) { |
|---|
| 2139 | | - /* nothing */ |
|---|
| 2140 | | - } else if (gran == NSEC_PER_SEC) { |
|---|
| 2264 | + struct super_block *sb = inode->i_sb; |
|---|
| 2265 | + unsigned int gran = sb->s_time_gran; |
|---|
| 2266 | + |
|---|
| 2267 | + t.tv_sec = clamp(t.tv_sec, sb->s_time_min, sb->s_time_max); |
|---|
| 2268 | + if (unlikely(t.tv_sec == sb->s_time_max || t.tv_sec == sb->s_time_min)) |
|---|
| 2141 | 2269 | t.tv_nsec = 0; |
|---|
| 2142 | | - } else if (gran > 1 && gran < NSEC_PER_SEC) { |
|---|
| 2270 | + |
|---|
| 2271 | + /* Avoid division in the common cases 1 ns and 1 s. */ |
|---|
| 2272 | + if (gran == 1) |
|---|
| 2273 | + ; /* nothing */ |
|---|
| 2274 | + else if (gran == NSEC_PER_SEC) |
|---|
| 2275 | + t.tv_nsec = 0; |
|---|
| 2276 | + else if (gran > 1 && gran < NSEC_PER_SEC) |
|---|
| 2143 | 2277 | t.tv_nsec -= t.tv_nsec % gran; |
|---|
| 2144 | | - } else { |
|---|
| 2145 | | - WARN(1, "illegal file time granularity: %u", gran); |
|---|
| 2146 | | - } |
|---|
| 2278 | + else |
|---|
| 2279 | + WARN(1, "invalid file time granularity: %u", gran); |
|---|
| 2147 | 2280 | return t; |
|---|
| 2148 | 2281 | } |
|---|
| 2149 | | -EXPORT_SYMBOL(timespec64_trunc); |
|---|
| 2282 | +EXPORT_SYMBOL_NS(timestamp_truncate, ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 2150 | 2283 | |
|---|
| 2151 | 2284 | /** |
|---|
| 2152 | 2285 | * current_time - Return FS time |
|---|
| .. | .. |
|---|
| 2160 | 2293 | */ |
|---|
| 2161 | 2294 | struct timespec64 current_time(struct inode *inode) |
|---|
| 2162 | 2295 | { |
|---|
| 2163 | | - struct timespec64 now = current_kernel_time64(); |
|---|
| 2296 | + struct timespec64 now; |
|---|
| 2297 | + |
|---|
| 2298 | + ktime_get_coarse_real_ts64(&now); |
|---|
| 2164 | 2299 | |
|---|
| 2165 | 2300 | if (unlikely(!inode->i_sb)) { |
|---|
| 2166 | 2301 | WARN(1, "current_time() called with uninitialized super_block in the inode"); |
|---|
| 2167 | 2302 | return now; |
|---|
| 2168 | 2303 | } |
|---|
| 2169 | 2304 | |
|---|
| 2170 | | - return timespec64_trunc(now, inode->i_sb->s_time_gran); |
|---|
| 2305 | + return timestamp_truncate(now, inode); |
|---|
| 2171 | 2306 | } |
|---|
| 2172 | 2307 | EXPORT_SYMBOL(current_time); |
|---|
| 2173 | 2308 | |
|---|
| .. | .. |
|---|
| 2256 | 2391 | return 0; |
|---|
| 2257 | 2392 | } |
|---|
| 2258 | 2393 | EXPORT_SYMBOL(vfs_ioc_fssetxattr_check); |
|---|
| 2394 | + |
|---|
| 2395 | +/** |
|---|
| 2396 | + * in_group_or_capable - check whether caller is CAP_FSETID privileged |
|---|
| 2397 | + * @inode: inode to check |
|---|
| 2398 | + * @gid: the new/current gid of @inode |
|---|
| 2399 | + * |
|---|
| 2400 | + * Check wether @gid is in the caller's group list or if the caller is |
|---|
| 2401 | + * privileged with CAP_FSETID over @inode. This can be used to determine |
|---|
| 2402 | + * whether the setgid bit can be kept or must be dropped. |
|---|
| 2403 | + * |
|---|
| 2404 | + * Return: true if the caller is sufficiently privileged, false if not. |
|---|
| 2405 | + */ |
|---|
| 2406 | +bool in_group_or_capable(const struct inode *inode, kgid_t gid) |
|---|
| 2407 | +{ |
|---|
| 2408 | + if (in_group_p(gid)) |
|---|
| 2409 | + return true; |
|---|
| 2410 | + if (capable_wrt_inode_uidgid(inode, CAP_FSETID)) |
|---|
| 2411 | + return true; |
|---|
| 2412 | + return false; |
|---|
| 2413 | +} |
|---|
| 2414 | + |
|---|
| 2415 | +/** |
|---|
| 2416 | + * mode_strip_sgid - handle the sgid bit for non-directories |
|---|
| 2417 | + * @dir: parent directory inode |
|---|
| 2418 | + * @mode: mode of the file to be created in @dir |
|---|
| 2419 | + * |
|---|
| 2420 | + * If the @mode of the new file has both the S_ISGID and S_IXGRP bit |
|---|
| 2421 | + * raised and @dir has the S_ISGID bit raised ensure that the caller is |
|---|
| 2422 | + * either in the group of the parent directory or they have CAP_FSETID |
|---|
| 2423 | + * in their user namespace and are privileged over the parent directory. |
|---|
| 2424 | + * In all other cases, strip the S_ISGID bit from @mode. |
|---|
| 2425 | + * |
|---|
| 2426 | + * Return: the new mode to use for the file |
|---|
| 2427 | + */ |
|---|
| 2428 | +umode_t mode_strip_sgid(const struct inode *dir, umode_t mode) |
|---|
| 2429 | +{ |
|---|
| 2430 | + if ((mode & (S_ISGID | S_IXGRP)) != (S_ISGID | S_IXGRP)) |
|---|
| 2431 | + return mode; |
|---|
| 2432 | + if (S_ISDIR(mode) || !dir || !(dir->i_mode & S_ISGID)) |
|---|
| 2433 | + return mode; |
|---|
| 2434 | + if (in_group_or_capable(dir, dir->i_gid)) |
|---|
| 2435 | + return mode; |
|---|
| 2436 | + return mode & ~S_ISGID; |
|---|
| 2437 | +} |
|---|
| 2438 | +EXPORT_SYMBOL(mode_strip_sgid); |
|---|