Pull vfs fixes from Christian Brauner: - Fix unitialized variable in statmount_string() - Fix hostfs mounting when passing host root during boot - Fix dynamic lookup to fail on cell lookup failure - Fix missing file type when reading bfs inodes from disk - Enforce checking of sb_min_blocksize() calls and update all callers accordingly - Restore write access before closing files opened by open_exec() in binfmt_misc - Always freeze efivarfs during suspend/hibernate cycles - Fix statmount()'s and listmount()'s grab_requested_mnt_ns() helper to actually allow mount namespace file descriptor in addition to mount namespace ids - Fix tmpfs remount when noswap is specified - Switch Landlock to iput_not_last() to remove false-positives from might_sleep() annotations in iput() - Remove dead node_to_mnt_ns() code - Ensure that per-queue kobjects are successfully created * tag 'vfs-6.18-rc7.fixes' of gitolite.kernel.org:pub/scm/linux/kernel/git/vfs/vfs: landlock: fix splats from iput() after it started calling might_sleep() fs: add iput_not_last() shmem: fix tmpfs reconfiguration (remount) when noswap is set fs/namespace: correctly handle errors returned by grab_requested_mnt_ns power: always freeze efivarfs binfmt_misc: restore write access before closing files opened by open_exec() block: add __must_check attribute to sb_min_blocksize() virtio-fs: fix incorrect check for fsvq->kobj xfs: check the return value of sb_min_blocksize() in xfs_fs_fill_super isofs: check the return value of sb_min_blocksize() in isofs_fill_super exfat: check return value of sb_min_blocksize in exfat_read_boot_sector vfat: fix missing sb_min_blocksize() return value checks mnt: Remove dead code which might prevent from building bfs: Reconstruct file type when loading from disk afs: Fix dynamic lookup to fail on cell lookup failure hostfs: Fix only passing host root in boot stage with new mount fs: Fix uninitialized 'offp' in statmount_string()
Unified · Split
| @@ -231,7 +231,7 @@ int sb_set_blocksize(struct super_block *sb, int size) · 230 unmodified lines | |||
| 231 | 231 | ||
| 232 | EXPORT_SYMBOL(sb_set_blocksize); | 232 | EXPORT_SYMBOL(sb_set_blocksize); |
| 233 | 233 | ||
| 234 | int sb_min_blocksize(struct super_block *sb, int size) | 234 | int __must_check sb_min_blocksize(struct super_block *sb, int size) |
| 235 | { | 235 | { |
| 236 | int minsize = bdev_logical_block_size(sb->s_bdev); | 236 | int minsize = bdev_logical_block_size(sb->s_bdev); |
| 237 | if (size < minsize) | 237 | if (size < minsize) |
| @@ -229,7 +229,7 @@ error: · 228 unmodified lines | |||
| 229 | * @name: The name of the cell. | 229 | * @name: The name of the cell. |
| 230 | * @namesz: The strlen of the cell name. | 230 | * @namesz: The strlen of the cell name. |
| 231 | * @vllist: A colon/comma separated list of numeric IP addresses or NULL. | 231 | * @vllist: A colon/comma separated list of numeric IP addresses or NULL. |
| 232 | * @excl: T if an error should be given if the cell name already exists. | 232 | * @reason: The reason we're doing the lookup |
| 233 | * @trace: The reason to be logged if the lookup is successful. | 233 | * @trace: The reason to be logged if the lookup is successful. |
| 234 | * | 234 | * |
| 235 | * Look up a cell record by name and query the DNS for VL server addresses if | 235 | * Look up a cell record by name and query the DNS for VL server addresses if |
| @@ -239,7 +239,8 @@ error: · 3 unmodified lines | |||
| 239 | */ | 239 | */ |
| 240 | struct afs_cell *afs_lookup_cell(struct afs_net *net, | 240 | struct afs_cell *afs_lookup_cell(struct afs_net *net, |
| 241 | const char *name, unsigned int namesz, | 241 | const char *name, unsigned int namesz, |
| 242 | const char *vllist, bool excl, | 242 | const char *vllist, |
| 243 | enum afs_lookup_cell_for reason, | ||
| 243 | enum afs_cell_trace trace) | 244 | enum afs_cell_trace trace) |
| 244 | { | 245 | { |
| 245 | struct afs_cell *cell, *candidate, *cursor; | 246 | struct afs_cell *cell, *candidate, *cursor; |
| @@ -247,12 +248,18 @@ struct afs_cell *afs_lookup_cell(struct afs_net *net, · 1 unmodified line | |||
| 247 | enum afs_cell_state state; | 248 | enum afs_cell_state state; |
| 248 | int ret, n; | 249 | int ret, n; |
| 249 | 250 | ||
| 250 | _enter("%s,%s", name, vllist); | 251 | _enter("%s,%s,%u", name, vllist, reason); |
| 251 | 252 | ||
| 252 | if (!excl) { | 253 | if (reason != AFS_LOOKUP_CELL_PRELOAD) { |
| 253 | cell = afs_find_cell(net, name, namesz, trace); | 254 | cell = afs_find_cell(net, name, namesz, trace); |
| 254 | if (!IS_ERR(cell)) | 255 | if (!IS_ERR(cell)) { |
| 256 | if (reason == AFS_LOOKUP_CELL_DYNROOT) | ||
| 257 | goto no_wait; | ||
| 258 | if (cell->state == AFS_CELL_SETTING_UP || | ||
| 259 | cell->state == AFS_CELL_UNLOOKED) | ||
| 260 | goto lookup_cell; | ||
| 255 | goto wait_for_cell; | 261 | goto wait_for_cell; |
| 262 | } | ||
| 256 | } | 263 | } |
| 257 | 264 | ||
| 258 | /* Assume we're probably going to create a cell and preallocate and | 265 | /* Assume we're probably going to create a cell and preallocate and |
| @@ -298,26 +305,69 @@ struct afs_cell *afs_lookup_cell(struct afs_net *net, · 39 unmodified lines | |||
| 298 | rb_insert_color(&cell->net_node, &net->cells); | 305 | rb_insert_color(&cell->net_node, &net->cells); |
| 299 | up_write(&net->cells_lock); | 306 | up_write(&net->cells_lock); |
| 300 | 307 | ||
| 301 | afs_queue_cell(cell, afs_cell_trace_queue_new); | 308 | lookup_cell: |
| 309 | if (reason != AFS_LOOKUP_CELL_PRELOAD && | ||
| 310 | reason != AFS_LOOKUP_CELL_ROOTCELL) { | ||
| 311 | set_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags); | ||
| 312 | afs_queue_cell(cell, afs_cell_trace_queue_new); | ||
| 313 | } | ||
| 302 | 314 | ||
| 303 | wait_for_cell: | 315 | wait_for_cell: |
| 304 | _debug("wait_for_cell"); | ||
| 305 | state = smp_load_acquire(&cell->state); /* vs error */ | 316 | state = smp_load_acquire(&cell->state); /* vs error */ |
| 306 | if (state != AFS_CELL_ACTIVE && | 317 | switch (state) { |
| 307 | state != AFS_CELL_DEAD) { | 318 | case AFS_CELL_ACTIVE: |
| 319 | case AFS_CELL_DEAD: | ||
| 320 | break; | ||
| 321 | case AFS_CELL_UNLOOKED: | ||
| 322 | default: | ||
| 323 | if (reason == AFS_LOOKUP_CELL_PRELOAD || | ||
| 324 | reason == AFS_LOOKUP_CELL_ROOTCELL) | ||
| 325 | break; | ||
| 326 | _debug("wait_for_cell"); | ||
| 308 | afs_see_cell(cell, afs_cell_trace_wait); | 327 | afs_see_cell(cell, afs_cell_trace_wait); |
| 309 | wait_var_event(&cell->state, | 328 | wait_var_event(&cell->state, |
| 310 | ({ | 329 | ({ |
| 311 | state = smp_load_acquire(&cell->state); /* vs error */ | 330 | state = smp_load_acquire(&cell->state); /* vs error */ |
| 312 | state == AFS_CELL_ACTIVE || state == AFS_CELL_DEAD; | 331 | state == AFS_CELL_ACTIVE || state == AFS_CELL_DEAD; |
| 313 | })); | 332 | })); |
| 333 | _debug("waited_for_cell %d %d", cell->state, cell->error); | ||
| 314 | } | 334 | } |
| 315 | 335 | ||
| 336 | no_wait: | ||
| 316 | /* Check the state obtained from the wait check. */ | 337 | /* Check the state obtained from the wait check. */ |
| 338 | state = smp_load_acquire(&cell->state); /* vs error */ | ||
| 317 | if (state == AFS_CELL_DEAD) { | 339 | if (state == AFS_CELL_DEAD) { |
| 318 | ret = cell->error; | 340 | ret = cell->error; |
| 319 | goto error; | 341 | goto error; |
| 320 | } | 342 | } |
| 343 | if (state == AFS_CELL_ACTIVE) { | ||
| 344 | switch (cell->dns_status) { | ||
| 345 | case DNS_LOOKUP_NOT_DONE: | ||
| 346 | if (cell->dns_source == DNS_RECORD_FROM_CONFIG) { | ||
| 347 | ret = 0; | ||
| 348 | break; | ||
| 349 | } | ||
| 350 | fallthrough; | ||
| 351 | default: | ||
| 352 | ret = -EIO; | ||
| 353 | goto error; | ||
| 354 | case DNS_LOOKUP_GOOD: | ||
| 355 | case DNS_LOOKUP_GOOD_WITH_BAD: | ||
| 356 | ret = 0; | ||
| 357 | break; | ||
| 358 | case DNS_LOOKUP_GOT_NOT_FOUND: | ||
| 359 | ret = -ENOENT; | ||
| 360 | goto error; | ||
| 361 | case DNS_LOOKUP_BAD: | ||
| 362 | ret = -EREMOTEIO; | ||
| 363 | goto error; | ||
| 364 | case DNS_LOOKUP_GOT_LOCAL_FAILURE: | ||
| 365 | case DNS_LOOKUP_GOT_TEMP_FAILURE: | ||
| 366 | case DNS_LOOKUP_GOT_NS_FAILURE: | ||
| 367 | ret = -EDESTADDRREQ; | ||
| 368 | goto error; | ||
| 369 | } | ||
| 370 | } | ||
| 321 | 371 | ||
| 322 | _leave(" = %p [cell]", cell); | 372 | _leave(" = %p [cell]", cell); |
| 323 | return cell; | 373 | return cell; |
| @@ -325,7 +375,7 @@ wait_for_cell: · 1 unmodified line | |||
| 325 | cell_already_exists: | 375 | cell_already_exists: |
| 326 | _debug("cell exists"); | 376 | _debug("cell exists"); |
| 327 | cell = cursor; | 377 | cell = cursor; |
| 328 | if (excl) { | 378 | if (reason == AFS_LOOKUP_CELL_PRELOAD) { |
| 329 | ret = -EEXIST; | 379 | ret = -EEXIST; |
| 330 | } else { | 380 | } else { |
| 331 | afs_use_cell(cursor, trace); | 381 | afs_use_cell(cursor, trace); |
| @@ -384,7 +434,8 @@ int afs_cell_init(struct afs_net *net, const char *rootcell) · 52 unmodified lines | |||
| 384 | return -EINVAL; | 434 | return -EINVAL; |
| 385 | 435 | ||
| 386 | /* allocate a cell record for the root/workstation cell */ | 436 | /* allocate a cell record for the root/workstation cell */ |
| 387 | new_root = afs_lookup_cell(net, rootcell, len, vllist, false, | 437 | new_root = afs_lookup_cell(net, rootcell, len, vllist, |
| 438 | AFS_LOOKUP_CELL_ROOTCELL, | ||
| 388 | afs_cell_trace_use_lookup_ws); | 439 | afs_cell_trace_use_lookup_ws); |
| 389 | if (IS_ERR(new_root)) { | 440 | if (IS_ERR(new_root)) { |
| 390 | _leave(" = %ld", PTR_ERR(new_root)); | 441 | _leave(" = %ld", PTR_ERR(new_root)); |
| @@ -777,6 +828,7 @@ static bool afs_manage_cell(struct afs_cell *cell) · 386 unmodified lines | |||
| 777 | switch (cell->state) { | 828 | switch (cell->state) { |
| 778 | case AFS_CELL_SETTING_UP: | 829 | case AFS_CELL_SETTING_UP: |
| 779 | goto set_up_cell; | 830 | goto set_up_cell; |
| 831 | case AFS_CELL_UNLOOKED: | ||
| 780 | case AFS_CELL_ACTIVE: | 832 | case AFS_CELL_ACTIVE: |
| 781 | goto cell_is_active; | 833 | goto cell_is_active; |
| 782 | case AFS_CELL_REMOVING: | 834 | case AFS_CELL_REMOVING: |
| @@ -797,7 +849,7 @@ set_up_cell: · 14 unmodified lines | |||
| 797 | goto remove_cell; | 849 | goto remove_cell; |
| 798 | } | 850 | } |
| 799 | 851 | ||
| 800 | afs_set_cell_state(cell, AFS_CELL_ACTIVE); | 852 | afs_set_cell_state(cell, AFS_CELL_UNLOOKED); |
| 801 | 853 | ||
| 802 | cell_is_active: | 854 | cell_is_active: |
| 803 | if (afs_has_cell_expired(cell, &next_manage)) | 855 | if (afs_has_cell_expired(cell, &next_manage)) |
| @@ -807,6 +859,8 @@ cell_is_active: · 3 unmodified lines | |||
| 807 | ret = afs_update_cell(cell); | 859 | ret = afs_update_cell(cell); |
| 808 | if (ret < 0) | 860 | if (ret < 0) |
| 809 | cell->error = ret; | 861 | cell->error = ret; |
| 862 | if (cell->state == AFS_CELL_UNLOOKED) | ||
| 863 | afs_set_cell_state(cell, AFS_CELL_ACTIVE); | ||
| 810 | } | 864 | } |
| 811 | 865 | ||
| 812 | if (next_manage < TIME64_MAX && cell->net->live) { | 866 | if (next_manage < TIME64_MAX && cell->net->live) { |
| @@ -108,7 +108,8 @@ static struct dentry *afs_dynroot_lookup_cell(struct inode *dir, struct dentry * · 107 unmodified lines | |||
| 108 | dotted = true; | 108 | dotted = true; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | cell = afs_lookup_cell(net, name, len, NULL, false, | 111 | cell = afs_lookup_cell(net, name, len, NULL, |
| 112 | AFS_LOOKUP_CELL_DYNROOT, | ||
| 112 | afs_cell_trace_use_lookup_dynroot); | 113 | afs_cell_trace_use_lookup_dynroot); |
| 113 | if (IS_ERR(cell)) { | 114 | if (IS_ERR(cell)) { |
| 114 | ret = PTR_ERR(cell); | 115 | ret = PTR_ERR(cell); |
| @@ -343,6 +343,7 @@ extern const char afs_init_sysname[]; · 342 unmodified lines | |||
| 343 | 343 | ||
| 344 | enum afs_cell_state { | 344 | enum afs_cell_state { |
| 345 | AFS_CELL_SETTING_UP, | 345 | AFS_CELL_SETTING_UP, |
| 346 | AFS_CELL_UNLOOKED, | ||
| 346 | AFS_CELL_ACTIVE, | 347 | AFS_CELL_ACTIVE, |
| 347 | AFS_CELL_REMOVING, | 348 | AFS_CELL_REMOVING, |
| 348 | AFS_CELL_DEAD, | 349 | AFS_CELL_DEAD, |
| @@ -1049,9 +1050,18 @@ static inline bool afs_cb_is_broken(unsigned int cb_break, · 700 unmodified lines | |||
| 1049 | extern int afs_cell_init(struct afs_net *, const char *); | 1050 | extern int afs_cell_init(struct afs_net *, const char *); |
| 1050 | extern struct afs_cell *afs_find_cell(struct afs_net *, const char *, unsigned, | 1051 | extern struct afs_cell *afs_find_cell(struct afs_net *, const char *, unsigned, |
| 1051 | enum afs_cell_trace); | 1052 | enum afs_cell_trace); |
| 1053 | enum afs_lookup_cell_for { | ||
| 1054 | AFS_LOOKUP_CELL_DYNROOT, | ||
| 1055 | AFS_LOOKUP_CELL_MOUNTPOINT, | ||
| 1056 | AFS_LOOKUP_CELL_DIRECT_MOUNT, | ||
| 1057 | AFS_LOOKUP_CELL_PRELOAD, | ||
| 1058 | AFS_LOOKUP_CELL_ROOTCELL, | ||
| 1059 | AFS_LOOKUP_CELL_ALIAS_CHECK, | ||
| 1060 | }; | ||
| 1052 | struct afs_cell *afs_lookup_cell(struct afs_net *net, | 1061 | struct afs_cell *afs_lookup_cell(struct afs_net *net, |
| 1053 | const char *name, unsigned int namesz, | 1062 | const char *name, unsigned int namesz, |
| 1054 | const char *vllist, bool excl, | 1063 | const char *vllist, |
| 1064 | enum afs_lookup_cell_for reason, | ||
| 1055 | enum afs_cell_trace trace); | 1065 | enum afs_cell_trace trace); |
| 1056 | extern struct afs_cell *afs_use_cell(struct afs_cell *, enum afs_cell_trace); | 1066 | extern struct afs_cell *afs_use_cell(struct afs_cell *, enum afs_cell_trace); |
| 1057 | void afs_unuse_cell(struct afs_cell *cell, enum afs_cell_trace reason); | 1067 | void afs_unuse_cell(struct afs_cell *cell, enum afs_cell_trace reason); |
| @@ -107,7 +107,8 @@ static int afs_mntpt_set_params(struct fs_context *fc, struct dentry *mntpt) · 106 unmodified lines | |||
| 107 | if (size > AFS_MAXCELLNAME) | 107 | if (size > AFS_MAXCELLNAME) |
| 108 | return -ENAMETOOLONG; | 108 | return -ENAMETOOLONG; |
| 109 | 109 | ||
| 110 | cell = afs_lookup_cell(ctx->net, p, size, NULL, false, | 110 | cell = afs_lookup_cell(ctx->net, p, size, NULL, |
| 111 | AFS_LOOKUP_CELL_MOUNTPOINT, | ||
| 111 | afs_cell_trace_use_lookup_mntpt); | 112 | afs_cell_trace_use_lookup_mntpt); |
| 112 | if (IS_ERR(cell)) { | 113 | if (IS_ERR(cell)) { |
| 113 | pr_err("kAFS: unable to lookup cell '%pd'\n", mntpt); | 114 | pr_err("kAFS: unable to lookup cell '%pd'\n", mntpt); |
| @@ -122,7 +122,8 @@ static int afs_proc_cells_write(struct file *file, char *buf, size_t size) · 121 unmodified lines | |||
| 122 | if (strcmp(buf, "add") == 0) { | 122 | if (strcmp(buf, "add") == 0) { |
| 123 | struct afs_cell *cell; | 123 | struct afs_cell *cell; |
| 124 | 124 | ||
| 125 | cell = afs_lookup_cell(net, name, strlen(name), args, true, | 125 | cell = afs_lookup_cell(net, name, strlen(name), args, |
| 126 | AFS_LOOKUP_CELL_PRELOAD, | ||
| 126 | afs_cell_trace_use_lookup_add); | 127 | afs_cell_trace_use_lookup_add); |
| 127 | if (IS_ERR(cell)) { | 128 | if (IS_ERR(cell)) { |
| 128 | ret = PTR_ERR(cell); | 129 | ret = PTR_ERR(cell); |
| @@ -290,7 +290,7 @@ static int afs_parse_source(struct fs_context *fc, struct fs_parameter *param) · 289 unmodified lines | |||
| 290 | /* lookup the cell record */ | 290 | /* lookup the cell record */ |
| 291 | if (cellname) { | 291 | if (cellname) { |
| 292 | cell = afs_lookup_cell(ctx->net, cellname, cellnamesz, | 292 | cell = afs_lookup_cell(ctx->net, cellname, cellnamesz, |
| 293 | NULL, false, | 293 | NULL, AFS_LOOKUP_CELL_DIRECT_MOUNT, |
| 294 | afs_cell_trace_use_lookup_mount); | 294 | afs_cell_trace_use_lookup_mount); |
| 295 | if (IS_ERR(cell)) { | 295 | if (IS_ERR(cell)) { |
| 296 | pr_err("kAFS: unable to lookup cell '%*.*s'\n", | 296 | pr_err("kAFS: unable to lookup cell '%*.*s'\n", |
| @@ -269,7 +269,8 @@ static int yfs_check_canonical_cell_name(struct afs_cell *cell, struct key *key) · 268 unmodified lines | |||
| 269 | if (!name_len || name_len > AFS_MAXCELLNAME) | 269 | if (!name_len || name_len > AFS_MAXCELLNAME) |
| 270 | master = ERR_PTR(-EOPNOTSUPP); | 270 | master = ERR_PTR(-EOPNOTSUPP); |
| 271 | else | 271 | else |
| 272 | master = afs_lookup_cell(cell->net, cell_name, name_len, NULL, false, | 272 | master = afs_lookup_cell(cell->net, cell_name, name_len, NULL, |
| 273 | AFS_LOOKUP_CELL_ALIAS_CHECK, | ||
| 273 | afs_cell_trace_use_lookup_canonical); | 274 | afs_cell_trace_use_lookup_canonical); |
| 274 | kfree(cell_name); | 275 | kfree(cell_name); |
| 275 | if (IS_ERR(master)) | 276 | if (IS_ERR(master)) |
| @@ -61,7 +61,19 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino) · 60 unmodified lines | |||
| 61 | off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; | 61 | off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; |
| 62 | di = (struct bfs_inode *)bh->b_data + off; | 62 | di = (struct bfs_inode *)bh->b_data + off; |
| 63 | 63 | ||
| 64 | inode->i_mode = 0x0000FFFF & le32_to_cpu(di->i_mode); | 64 | /* |
| 65 | * https://martin.hinner.info/fs/bfs/bfs-structure.html explains that | ||
| 66 | * BFS in SCO UnixWare environment used only lower 9 bits of di->i_mode | ||
| 67 | * value. This means that, although bfs_write_inode() saves whole | ||
| 68 | * inode->i_mode bits (which include S_IFMT bits and S_IS{UID,GID,VTX} | ||
| 69 | * bits), middle 7 bits of di->i_mode value can be garbage when these | ||
| 70 | * bits were not saved by bfs_write_inode(). | ||
| 71 | * Since we can't tell whether middle 7 bits are garbage, use only | ||
| 72 | * lower 12 bits (i.e. tolerate S_IS{UID,GID,VTX} bits possibly being | ||
| 73 | * garbage) and reconstruct S_IFMT bits for Linux environment from | ||
| 74 | * di->i_vtype value. | ||
| 75 | */ | ||
| 76 | inode->i_mode = 0x00000FFF & le32_to_cpu(di->i_mode); | ||
| 65 | if (le32_to_cpu(di->i_vtype) == BFS_VDIR) { | 77 | if (le32_to_cpu(di->i_vtype) == BFS_VDIR) { |
| 66 | inode->i_mode |= S_IFDIR; | 78 | inode->i_mode |= S_IFDIR; |
| 67 | inode->i_op = &bfs_dir_inops; | 79 | inode->i_op = &bfs_dir_inops; |
| @@ -71,6 +83,11 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino) · 3 unmodified lines | |||
| 71 | inode->i_op = &bfs_file_inops; | 83 | inode->i_op = &bfs_file_inops; |
| 72 | inode->i_fop = &bfs_file_operations; | 84 | inode->i_fop = &bfs_file_operations; |
| 73 | inode->i_mapping->a_ops = &bfs_aops; | 85 | inode->i_mapping->a_ops = &bfs_aops; |
| 86 | } else { | ||
| 87 | brelse(bh); | ||
| 88 | printf("Unknown vtype=%u %s:%08lx\n", | ||
| 89 | le32_to_cpu(di->i_vtype), inode->i_sb->s_id, ino); | ||
| 90 | goto error; | ||
| 74 | } | 91 | } |
| 75 | 92 | ||
| 76 | BFS_I(inode)->i_sblock = le32_to_cpu(di->i_sblock); | 93 | BFS_I(inode)->i_sblock = le32_to_cpu(di->i_sblock); |
| @@ -837,8 +837,10 @@ out: · 836 unmodified lines | |||
| 837 | inode_unlock(d_inode(root)); | 837 | inode_unlock(d_inode(root)); |
| 838 | 838 | ||
| 839 | if (err) { | 839 | if (err) { |
| 840 | if (f) | 840 | if (f) { |
| 841 | exe_file_allow_write_access(f); | ||
| 841 | filp_close(f, NULL); | 842 | filp_close(f, NULL); |
| 843 | } | ||
| 842 | kfree(e); | 844 | kfree(e); |
| 843 | return err; | 845 | return err; |
| 844 | } | 846 | } |
| @@ -533,6 +533,7 @@ static struct file_system_type efivarfs_type = { · 532 unmodified lines | |||
| 533 | .init_fs_context = efivarfs_init_fs_context, | 533 | .init_fs_context = efivarfs_init_fs_context, |
| 534 | .kill_sb = efivarfs_kill_sb, | 534 | .kill_sb = efivarfs_kill_sb, |
| 535 | .parameters = efivarfs_parameters, | 535 | .parameters = efivarfs_parameters, |
| 536 | .fs_flags = FS_POWER_FREEZE, | ||
| 536 | }; | 537 | }; |
| 537 | 538 | ||
| 538 | static __init int efivarfs_init(void) | 539 | static __init int efivarfs_init(void) |
| @@ -433,7 +433,10 @@ static int exfat_read_boot_sector(struct super_block *sb) · 432 unmodified lines | |||
| 433 | struct exfat_sb_info *sbi = EXFAT_SB(sb); | 433 | struct exfat_sb_info *sbi = EXFAT_SB(sb); |
| 434 | 434 | ||
| 435 | /* set block size to read super block */ | 435 | /* set block size to read super block */ |
| 436 | sb_min_blocksize(sb, 512); | 436 | if (!sb_min_blocksize(sb, 512)) { |
| 437 | exfat_err(sb, "unable to set blocksize"); | ||
| 438 | return -EINVAL; | ||
| 439 | } | ||
| 437 | 440 | ||
| 438 | /* read boot sector */ | 441 | /* read boot sector */ |
| 439 | sbi->boot_bh = sb_bread(sb, 0); | 442 | sbi->boot_bh = sb_bread(sb, 0); |
| @@ -1595,8 +1595,12 @@ int fat_fill_super(struct super_block *sb, struct fs_context *fc, · 1594 unmodified lines | |||
| 1595 | 1595 | ||
| 1596 | setup(sb); /* flavour-specific stuff that needs options */ | 1596 | setup(sb); /* flavour-specific stuff that needs options */ |
| 1597 | 1597 | ||
| 1598 | error = -EINVAL; | ||
| 1599 | if (!sb_min_blocksize(sb, 512)) { | ||
| 1600 | fat_msg(sb, KERN_ERR, "unable to set blocksize"); | ||
| 1601 | goto out_fail; | ||
| 1602 | } | ||
| 1598 | error = -EIO; | 1603 | error = -EIO; |
| 1599 | sb_min_blocksize(sb, 512); | ||
| 1600 | bh = sb_bread(sb, 0); | 1604 | bh = sb_bread(sb, 0); |
| 1601 | if (bh == NULL) { | 1605 | if (bh == NULL) { |
| 1602 | fat_msg(sb, KERN_ERR, "unable to read boot sector"); | 1606 | fat_msg(sb, KERN_ERR, "unable to read boot sector"); |
| @@ -373,7 +373,7 @@ static int virtio_fs_add_queues_sysfs(struct virtio_fs *fs) · 372 unmodified lines | |||
| 373 | 373 | ||
| 374 | sprintf(buff, "%d", i); | 374 | sprintf(buff, "%d", i); |
| 375 | fsvq->kobj = kobject_create_and_add(buff, fs->mqs_kobj); | 375 | fsvq->kobj = kobject_create_and_add(buff, fs->mqs_kobj); |
| 376 | if (!fs->mqs_kobj) { | 376 | if (!fsvq->kobj) { |
| 377 | ret = -ENOMEM; | 377 | ret = -ENOMEM; |
| 378 | goto out_del; | 378 | goto out_del; |
| 379 | } | 379 | } |
| @@ -979,7 +979,7 @@ static int hostfs_parse_param(struct fs_context *fc, struct fs_parameter *param) · 978 unmodified lines | |||
| 979 | { | 979 | { |
| 980 | struct hostfs_fs_info *fsi = fc->s_fs_info; | 980 | struct hostfs_fs_info *fsi = fc->s_fs_info; |
| 981 | struct fs_parse_result result; | 981 | struct fs_parse_result result; |
| 982 | char *host_root; | 982 | char *host_root, *tmp_root; |
| 983 | int opt; | 983 | int opt; |
| 984 | 984 | ||
| 985 | opt = fs_parse(fc, hostfs_param_specs, param, &result); | 985 | opt = fs_parse(fc, hostfs_param_specs, param, &result); |
| @@ -990,11 +990,13 @@ static int hostfs_parse_param(struct fs_context *fc, struct fs_parameter *param) · 4 unmodified lines | |||
| 990 | case Opt_hostfs: | 990 | case Opt_hostfs: |
| 991 | host_root = param->string; | 991 | host_root = param->string; |
| 992 | if (!*host_root) | 992 | if (!*host_root) |
| 993 | host_root = ""; | 993 | break; |
| 994 | fsi->host_root_path = | 994 | tmp_root = kasprintf(GFP_KERNEL, "%s%s", |
| 995 | kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root); | 995 | fsi->host_root_path, host_root); |
| 996 | if (fsi->host_root_path == NULL) | 996 | if (!tmp_root) |
| 997 | return -ENOMEM; | 997 | return -ENOMEM; |
| 998 | kfree(fsi->host_root_path); | ||
| 999 | fsi->host_root_path = tmp_root; | ||
| 998 | break; | 1000 | break; |
| 999 | } | 1001 | } |
| 1000 | 1002 | ||
| @@ -1004,17 +1006,17 @@ static int hostfs_parse_param(struct fs_context *fc, struct fs_parameter *param) · 3 unmodified lines | |||
| 1004 | static int hostfs_parse_monolithic(struct fs_context *fc, void *data) | 1006 | static int hostfs_parse_monolithic(struct fs_context *fc, void *data) |
| 1005 | { | 1007 | { |
| 1006 | struct hostfs_fs_info *fsi = fc->s_fs_info; | 1008 | struct hostfs_fs_info *fsi = fc->s_fs_info; |
| 1007 | char *host_root = (char *)data; | 1009 | char *tmp_root, *host_root = (char *)data; |
| 1008 | 1010 | ||
| 1009 | /* NULL is printed as '(null)' by printf(): avoid that. */ | 1011 | /* NULL is printed as '(null)' by printf(): avoid that. */ |
| 1010 | if (host_root == NULL) | 1012 | if (host_root == NULL) |
| 1011 | host_root = ""; | 1013 | return 0; |
| 1012 | 1014 | ||
| 1013 | fsi->host_root_path = | 1015 | tmp_root = kasprintf(GFP_KERNEL, "%s%s", fsi->host_root_path, host_root); |
| 1014 | kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root); | 1016 | if (!tmp_root) |
| 1015 | if (fsi->host_root_path == NULL) | ||
| 1016 | return -ENOMEM; | 1017 | return -ENOMEM; |
| 1017 | 1018 | kfree(fsi->host_root_path); | |
| 1019 | fsi->host_root_path = tmp_root; | ||
| 1018 | return 0; | 1020 | return 0; |
| 1019 | } | 1021 | } |
| 1020 | 1022 | ||
| @@ -1049,6 +1051,11 @@ static int hostfs_init_fs_context(struct fs_context *fc) · 28 unmodified lines | |||
| 1049 | if (!fsi) | 1051 | if (!fsi) |
| 1050 | return -ENOMEM; | 1052 | return -ENOMEM; |
| 1051 | 1053 | ||
| 1054 | fsi->host_root_path = kasprintf(GFP_KERNEL, "%s/", root_ino); | ||
| 1055 | if (!fsi->host_root_path) { | ||
| 1056 | kfree(fsi); | ||
| 1057 | return -ENOMEM; | ||
| 1058 | } | ||
| 1052 | fc->s_fs_info = fsi; | 1059 | fc->s_fs_info = fsi; |
| 1053 | fc->ops = &hostfs_context_ops; | 1060 | fc->ops = &hostfs_context_ops; |
| 1054 | return 0; | 1061 | return 0; |
| @@ -1967,6 +1967,18 @@ retry: · 1966 unmodified lines | |||
| 1967 | } | 1967 | } |
| 1968 | EXPORT_SYMBOL(iput); | 1968 | EXPORT_SYMBOL(iput); |
| 1969 | 1969 | ||
| 1970 | /** | ||
| 1971 | * iput_not_last - put an inode assuming this is not the last reference | ||
| 1972 | * @inode: inode to put | ||
| 1973 | */ | ||
| 1974 | void iput_not_last(struct inode *inode) | ||
| 1975 | { | ||
| 1976 | VFS_BUG_ON_INODE(atomic_read(&inode->i_count) < 2, inode); | ||
| 1977 | |||
| 1978 | WARN_ON(atomic_sub_return(1, &inode->i_count) == 0); | ||
| 1979 | } | ||
| 1980 | EXPORT_SYMBOL(iput_not_last); | ||
| 1981 | |||
| 1970 | #ifdef CONFIG_BLOCK | 1982 | #ifdef CONFIG_BLOCK |
| 1971 | /** | 1983 | /** |
| 1972 | * bmap - find a block number in a file | 1984 | * bmap - find a block number in a file |
| @@ -610,6 +610,11 @@ static int isofs_fill_super(struct super_block *s, struct fs_context *fc) · 609 unmodified lines | |||
| 610 | goto out_freesbi; | 610 | goto out_freesbi; |
| 611 | } | 611 | } |
| 612 | opt->blocksize = sb_min_blocksize(s, opt->blocksize); | 612 | opt->blocksize = sb_min_blocksize(s, opt->blocksize); |
| 613 | if (!opt->blocksize) { | ||
| 614 | printk(KERN_ERR | ||
| 615 | "ISOFS: unable to set blocksize\n"); | ||
| 616 | goto out_freesbi; | ||
| 617 | } | ||
| 613 | 618 | ||
| 614 | sbi->s_high_sierra = 0; /* default is iso9660 */ | 619 | sbi->s_high_sierra = 0; /* default is iso9660 */ |
| 615 | sbi->s_session = opt->session; | 620 | sbi->s_session = opt->session; |
| @@ -132,16 +132,6 @@ EXPORT_SYMBOL_GPL(fs_kobj); · 131 unmodified lines | |||
| 132 | */ | 132 | */ |
| 133 | __cacheline_aligned_in_smp DEFINE_SEQLOCK(mount_lock); | 133 | __cacheline_aligned_in_smp DEFINE_SEQLOCK(mount_lock); |
| 134 | 134 | ||
| 135 | static inline struct mnt_namespace *node_to_mnt_ns(const struct rb_node *node) | ||
| 136 | { | ||
| 137 | struct ns_common *ns; | ||
| 138 | |||
| 139 | if (!node) | ||
| 140 | return NULL; | ||
| 141 | ns = rb_entry(node, struct ns_common, ns_tree_node); | ||
| 142 | return container_of(ns, struct mnt_namespace, ns); | ||
| 143 | } | ||
| 144 | |||
| 145 | static void mnt_ns_release(struct mnt_namespace *ns) | 135 | static void mnt_ns_release(struct mnt_namespace *ns) |
| 146 | { | 136 | { |
| 147 | /* keep alive for {list,stat}mount() */ | 137 | /* keep alive for {list,stat}mount() */ |
| @@ -151,7 +141,8 @@ static void mnt_ns_release(struct mnt_namespace *ns) · 3 unmodified lines | |||
| 151 | kfree(ns); | 141 | kfree(ns); |
| 152 | } | 142 | } |
| 153 | } | 143 | } |
| 154 | DEFINE_FREE(mnt_ns_release, struct mnt_namespace *, if (_T) mnt_ns_release(_T)) | 144 | DEFINE_FREE(mnt_ns_release, struct mnt_namespace *, |
| 145 | if (!IS_ERR(_T)) mnt_ns_release(_T)) | ||
| 155 | 146 | ||
| 156 | static void mnt_ns_release_rcu(struct rcu_head *rcu) | 147 | static void mnt_ns_release_rcu(struct rcu_head *rcu) |
| 157 | { | 148 | { |
| @@ -5454,11 +5445,11 @@ static int statmount_string(struct kstatmount *s, u64 flag) · 5296 unmodified lines | |||
| 5454 | ret = statmount_sb_source(s, seq); | 5445 | ret = statmount_sb_source(s, seq); |
| 5455 | break; | 5446 | break; |
| 5456 | case STATMOUNT_MNT_UIDMAP: | 5447 | case STATMOUNT_MNT_UIDMAP: |
| 5457 | sm->mnt_uidmap = start; | 5448 | offp = &sm->mnt_uidmap; |
| 5458 | ret = statmount_mnt_uidmap(s, seq); | 5449 | ret = statmount_mnt_uidmap(s, seq); |
| 5459 | break; | 5450 | break; |
| 5460 | case STATMOUNT_MNT_GIDMAP: | 5451 | case STATMOUNT_MNT_GIDMAP: |
| 5461 | sm->mnt_gidmap = start; | 5452 | offp = &sm->mnt_gidmap; |
| 5462 | ret = statmount_mnt_gidmap(s, seq); | 5453 | ret = statmount_mnt_gidmap(s, seq); |
| 5463 | break; | 5454 | break; |
| 5464 | default: | 5455 | default: |
| @@ -5736,7 +5727,7 @@ static int copy_mnt_id_req(const struct mnt_id_req __user *req, · 271 unmodified lines | |||
| 5736 | ret = copy_struct_from_user(kreq, sizeof(*kreq), req, usize); | 5727 | ret = copy_struct_from_user(kreq, sizeof(*kreq), req, usize); |
| 5737 | if (ret) | 5728 | if (ret) |
| 5738 | return ret; | 5729 | return ret; |
| 5739 | if (kreq->spare != 0) | 5730 | if (kreq->mnt_ns_fd != 0 && kreq->mnt_ns_id) |
| 5740 | return -EINVAL; | 5731 | return -EINVAL; |
| 5741 | /* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */ | 5732 | /* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */ |
| 5742 | if (kreq->mnt_id <= MNT_UNIQUE_ID_OFFSET) | 5733 | if (kreq->mnt_id <= MNT_UNIQUE_ID_OFFSET) |
| @@ -5753,16 +5744,12 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq · 10 unmodified lines | |||
| 5753 | { | 5744 | { |
| 5754 | struct mnt_namespace *mnt_ns; | 5745 | struct mnt_namespace *mnt_ns; |
| 5755 | 5746 | ||
| 5756 | if (kreq->mnt_ns_id && kreq->spare) | 5747 | if (kreq->mnt_ns_id) { |
| 5757 | return ERR_PTR(-EINVAL); | 5748 | mnt_ns = lookup_mnt_ns(kreq->mnt_ns_id); |
| 5758 | 5749 | } else if (kreq->mnt_ns_fd) { | |
| 5759 | if (kreq->mnt_ns_id) | ||
| 5760 | return lookup_mnt_ns(kreq->mnt_ns_id); | ||
| 5761 | |||
| 5762 | if (kreq->spare) { | ||
| 5763 | struct ns_common *ns; | 5750 | struct ns_common *ns; |
| 5764 | 5751 | ||
| 5765 | CLASS(fd, f)(kreq->spare); | 5752 | CLASS(fd, f)(kreq->mnt_ns_fd); |
| 5766 | if (fd_empty(f)) | 5753 | if (fd_empty(f)) |
| 5767 | return ERR_PTR(-EBADF); | 5754 | return ERR_PTR(-EBADF); |
| 5768 | 5755 | ||
| @@ -5777,6 +5764,8 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq · 8 unmodified lines | |||
| 5777 | } else { | 5764 | } else { |
| 5778 | mnt_ns = current->nsproxy->mnt_ns; | 5765 | mnt_ns = current->nsproxy->mnt_ns; |
| 5779 | } | 5766 | } |
| 5767 | if (!mnt_ns) | ||
| 5768 | return ERR_PTR(-ENOENT); | ||
| 5780 | 5769 | ||
| 5781 | refcount_inc(&mnt_ns->passive); | 5770 | refcount_inc(&mnt_ns->passive); |
| 5782 | return mnt_ns; | 5771 | return mnt_ns; |
| @@ -5801,8 +5790,8 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req, · 18 unmodified lines | |||
| 5801 | return ret; | 5790 | return ret; |
| 5802 | 5791 | ||
| 5803 | ns = grab_requested_mnt_ns(&kreq); | 5792 | ns = grab_requested_mnt_ns(&kreq); |
| 5804 | if (!ns) | 5793 | if (IS_ERR(ns)) |
| 5805 | return -ENOENT; | 5794 | return PTR_ERR(ns); |
| 5806 | 5795 | ||
| 5807 | if (kreq.mnt_ns_id && (ns != current->nsproxy->mnt_ns) && | 5796 | if (kreq.mnt_ns_id && (ns != current->nsproxy->mnt_ns) && |
| 5808 | !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) | 5797 | !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) |
| @@ -5912,8 +5901,8 @@ static void __free_klistmount_free(const struct klistmount *kls) · 103 unmodified lines | |||
| 5912 | static inline int prepare_klistmount(struct klistmount *kls, struct mnt_id_req *kreq, | 5901 | static inline int prepare_klistmount(struct klistmount *kls, struct mnt_id_req *kreq, |
| 5913 | size_t nr_mnt_ids) | 5902 | size_t nr_mnt_ids) |
| 5914 | { | 5903 | { |
| 5915 | |||
| 5916 | u64 last_mnt_id = kreq->param; | 5904 | u64 last_mnt_id = kreq->param; |
| 5905 | struct mnt_namespace *ns; | ||
| 5917 | 5906 | ||
| 5918 | /* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */ | 5907 | /* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */ |
| 5919 | if (last_mnt_id != 0 && last_mnt_id <= MNT_UNIQUE_ID_OFFSET) | 5908 | if (last_mnt_id != 0 && last_mnt_id <= MNT_UNIQUE_ID_OFFSET) |
| @@ -5927,9 +5916,10 @@ static inline int prepare_klistmount(struct klistmount *kls, struct mnt_id_req * · 7 unmodified lines | |||
| 5927 | if (!kls->kmnt_ids) | 5916 | if (!kls->kmnt_ids) |
| 5928 | return -ENOMEM; | 5917 | return -ENOMEM; |
| 5929 | 5918 | ||
| 5930 | kls->ns = grab_requested_mnt_ns(kreq); | 5919 | ns = grab_requested_mnt_ns(kreq); |
| 5931 | if (!kls->ns) | 5920 | if (IS_ERR(ns)) |
| 5932 | return -ENOENT; | 5921 | return PTR_ERR(ns); |
| 5922 | kls->ns = ns; | ||
| 5933 | 5923 | ||
| 5934 | kls->mnt_parent_id = kreq->mnt_id; | 5924 | kls->mnt_parent_id = kreq->mnt_id; |
| 5935 | return 0; | 5925 | return 0; |
| @@ -1183,11 +1183,14 @@ static inline bool get_active_super(struct super_block *sb) · 1182 unmodified lines | |||
| 1183 | 1183 | ||
| 1184 | static const char *filesystems_freeze_ptr = "filesystems_freeze"; | 1184 | static const char *filesystems_freeze_ptr = "filesystems_freeze"; |
| 1185 | 1185 | ||
| 1186 | static void filesystems_freeze_callback(struct super_block *sb, void *unused) | 1186 | static void filesystems_freeze_callback(struct super_block *sb, void *freeze_all_ptr) |
| 1187 | { | 1187 | { |
| 1188 | if (!sb->s_op->freeze_fs && !sb->s_op->freeze_super) | 1188 | if (!sb->s_op->freeze_fs && !sb->s_op->freeze_super) |
| 1189 | return; | 1189 | return; |
| 1190 | 1190 | ||
| 1191 | if (freeze_all_ptr && !(sb->s_type->fs_flags & FS_POWER_FREEZE)) | ||
| 1192 | return; | ||
| 1193 | |||
| 1191 | if (!get_active_super(sb)) | 1194 | if (!get_active_super(sb)) |
| 1192 | return; | 1195 | return; |
| 1193 | 1196 | ||
| @@ -1201,9 +1204,13 @@ static void filesystems_freeze_callback(struct super_block *sb, void *unused) · 7 unmodified lines | |||
| 1201 | deactivate_super(sb); | 1204 | deactivate_super(sb); |
| 1202 | } | 1205 | } |
| 1203 | 1206 | ||
| 1204 | void filesystems_freeze(void) | 1207 | void filesystems_freeze(bool freeze_all) |
| 1205 | { | 1208 | { |
| 1206 | __iterate_supers(filesystems_freeze_callback, NULL, | 1209 | void *freeze_all_ptr = NULL; |
| 1210 | |||
| 1211 | if (freeze_all) | ||
| 1212 | freeze_all_ptr = &freeze_all; | ||
| 1213 | __iterate_supers(filesystems_freeze_callback, freeze_all_ptr, | ||
| 1207 | SUPER_ITER_UNLOCKED | SUPER_ITER_REVERSE); | 1214 | SUPER_ITER_UNLOCKED | SUPER_ITER_REVERSE); |
| 1208 | } | 1215 | } |
| 1209 | 1216 | ||
| @@ -1693,7 +1693,10 @@ xfs_fs_fill_super( · 1692 unmodified lines | |||
| 1693 | if (error) | 1693 | if (error) |
| 1694 | return error; | 1694 | return error; |
| 1695 | 1695 | ||
| 1696 | sb_min_blocksize(sb, BBSIZE); | 1696 | if (!sb_min_blocksize(sb, BBSIZE)) { |
| 1697 | xfs_err(mp, "unable to set blocksize"); | ||
| 1698 | return -EINVAL; | ||
| 1699 | } | ||
| 1697 | sb->s_xattr = xfs_xattr_handlers; | 1700 | sb->s_xattr = xfs_xattr_handlers; |
| 1698 | sb->s_export_op = &xfs_export_operations; | 1701 | sb->s_export_op = &xfs_export_operations; |
| 1699 | #ifdef CONFIG_XFS_QUOTA | 1702 | #ifdef CONFIG_XFS_QUOTA |
| @@ -2689,6 +2689,7 @@ struct file_system_type { · 2688 unmodified lines | |||
| 2689 | #define FS_ALLOW_IDMAP 32 /* FS has been updated to handle vfs idmappings. */ | 2689 | #define FS_ALLOW_IDMAP 32 /* FS has been updated to handle vfs idmappings. */ |
| 2690 | #define FS_MGTIME 64 /* FS uses multigrain timestamps */ | 2690 | #define FS_MGTIME 64 /* FS uses multigrain timestamps */ |
| 2691 | #define FS_LBS 128 /* FS supports LBS */ | 2691 | #define FS_LBS 128 /* FS supports LBS */ |
| 2692 | #define FS_POWER_FREEZE 256 /* Always freeze on suspend/hibernate */ | ||
| 2692 | #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ | 2693 | #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ |
| 2693 | int (*init_fs_context)(struct fs_context *); | 2694 | int (*init_fs_context)(struct fs_context *); |
| 2694 | const struct fs_parameter_spec *parameters; | 2695 | const struct fs_parameter_spec *parameters; |
| @@ -2823,6 +2824,7 @@ extern int current_umask(void); · 128 unmodified lines | |||
| 2823 | 2824 | ||
| 2824 | extern void ihold(struct inode * inode); | 2825 | extern void ihold(struct inode * inode); |
| 2825 | extern void iput(struct inode *); | 2826 | extern void iput(struct inode *); |
| 2827 | void iput_not_last(struct inode *); | ||
| 2826 | int inode_update_timestamps(struct inode *inode, int flags); | 2828 | int inode_update_timestamps(struct inode *inode, int flags); |
| 2827 | int generic_update_time(struct inode *, int); | 2829 | int generic_update_time(struct inode *, int); |
| 2828 | 2830 | ||
| @@ -3423,8 +3425,8 @@ static inline void remove_inode_hash(struct inode *inode) · 594 unmodified lines | |||
| 3423 | extern void inode_sb_list_add(struct inode *inode); | 3425 | extern void inode_sb_list_add(struct inode *inode); |
| 3424 | extern void inode_add_lru(struct inode *inode); | 3426 | extern void inode_add_lru(struct inode *inode); |
| 3425 | 3427 | ||
| 3426 | extern int sb_set_blocksize(struct super_block *, int); | 3428 | int sb_set_blocksize(struct super_block *sb, int size); |
| 3427 | extern int sb_min_blocksize(struct super_block *, int); | 3429 | int __must_check sb_min_blocksize(struct super_block *sb, int size); |
| 3428 | 3430 | ||
| 3429 | int generic_file_mmap(struct file *, struct vm_area_struct *); | 3431 | int generic_file_mmap(struct file *, struct vm_area_struct *); |
| 3430 | int generic_file_mmap_prepare(struct vm_area_desc *desc); | 3432 | int generic_file_mmap_prepare(struct vm_area_desc *desc); |
| @@ -3606,7 +3608,7 @@ extern void drop_super_exclusive(struct super_block *sb); · 175 unmodified lines | |||
| 3606 | extern void iterate_supers(void (*f)(struct super_block *, void *), void *arg); | 3608 | extern void iterate_supers(void (*f)(struct super_block *, void *), void *arg); |
| 3607 | extern void iterate_supers_type(struct file_system_type *, | 3609 | extern void iterate_supers_type(struct file_system_type *, |
| 3608 | void (*)(struct super_block *, void *), void *); | 3610 | void (*)(struct super_block *, void *), void *); |
| 3609 | void filesystems_freeze(void); | 3611 | void filesystems_freeze(bool freeze_all); |
| 3610 | void filesystems_thaw(void); | 3612 | void filesystems_thaw(void); |
| 3611 | 3613 | ||
| 3612 | extern int dcache_dir_open(struct inode *, struct file *); | 3614 | extern int dcache_dir_open(struct inode *, struct file *); |
| @@ -197,7 +197,7 @@ struct statmount { · 196 unmodified lines | |||
| 197 | */ | 197 | */ |
| 198 | struct mnt_id_req { | 198 | struct mnt_id_req { |
| 199 | __u32 size; | 199 | __u32 size; |
| 200 | __u32 spare; | 200 | __u32 mnt_ns_fd; |
| 201 | __u64 mnt_id; | 201 | __u64 mnt_id; |
| 202 | __u64 param; | 202 | __u64 param; |
| 203 | __u64 mnt_ns_id; | 203 | __u64 mnt_ns_id; |
| @@ -821,8 +821,7 @@ int hibernate(void) · 820 unmodified lines | |||
| 821 | goto Restore; | 821 | goto Restore; |
| 822 | 822 | ||
| 823 | ksys_sync_helper(); | 823 | ksys_sync_helper(); |
| 824 | if (filesystem_freeze_enabled) | 824 | filesystems_freeze(filesystem_freeze_enabled); |
| 825 | filesystems_freeze(); | ||
| 826 | 825 | ||
| 827 | error = freeze_processes(); | 826 | error = freeze_processes(); |
| 828 | if (error) | 827 | if (error) |
| @@ -928,8 +927,7 @@ int hibernate_quiet_exec(int (*func)(void *data), void *data) · 99 unmodified lines | |||
| 928 | if (error) | 927 | if (error) |
| 929 | goto restore; | 928 | goto restore; |
| 930 | 929 | ||
| 931 | if (filesystem_freeze_enabled) | 930 | filesystems_freeze(filesystem_freeze_enabled); |
| 932 | filesystems_freeze(); | ||
| 933 | 931 | ||
| 934 | error = freeze_processes(); | 932 | error = freeze_processes(); |
| 935 | if (error) | 933 | if (error) |
| @@ -1079,8 +1077,7 @@ static int software_resume(void) · 143 unmodified lines | |||
| 1079 | if (error) | 1077 | if (error) |
| 1080 | goto Restore; | 1078 | goto Restore; |
| 1081 | 1079 | ||
| 1082 | if (filesystem_freeze_enabled) | 1080 | filesystems_freeze(filesystem_freeze_enabled); |
| 1083 | filesystems_freeze(); | ||
| 1084 | 1081 | ||
| 1085 | pm_pr_dbg("Preparing processes for hibernation restore.\n"); | 1082 | pm_pr_dbg("Preparing processes for hibernation restore.\n"); |
| 1086 | error = freeze_processes(); | 1083 | error = freeze_processes(); |
| @@ -375,8 +375,7 @@ static int suspend_prepare(suspend_state_t state) · 374 unmodified lines | |||
| 375 | if (error) | 375 | if (error) |
| 376 | goto Restore; | 376 | goto Restore; |
| 377 | 377 | ||
| 378 | if (filesystem_freeze_enabled) | 378 | filesystems_freeze(filesystem_freeze_enabled); |
| 379 | filesystems_freeze(); | ||
| 380 | trace_suspend_resume(TPS("freeze_processes"), 0, true); | 379 | trace_suspend_resume(TPS("freeze_processes"), 0, true); |
| 381 | error = suspend_freeze_processes(); | 380 | error = suspend_freeze_processes(); |
| 382 | trace_suspend_resume(TPS("freeze_processes"), 0, false); | 381 | trace_suspend_resume(TPS("freeze_processes"), 0, false); |
| @@ -131,8 +131,7 @@ struct shmem_options { · 130 unmodified lines | |||
| 131 | #define SHMEM_SEEN_INODES 2 | 131 | #define SHMEM_SEEN_INODES 2 |
| 132 | #define SHMEM_SEEN_HUGE 4 | 132 | #define SHMEM_SEEN_HUGE 4 |
| 133 | #define SHMEM_SEEN_INUMS 8 | 133 | #define SHMEM_SEEN_INUMS 8 |
| 134 | #define SHMEM_SEEN_NOSWAP 16 | 134 | #define SHMEM_SEEN_QUOTA 16 |
| 135 | #define SHMEM_SEEN_QUOTA 32 | ||
| 136 | }; | 135 | }; |
| 137 | 136 | ||
| 138 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 137 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| @@ -4680,7 +4679,6 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) · 4541 unmodified lines | |||
| 4680 | "Turning off swap in unprivileged tmpfs mounts unsupported"); | 4679 | "Turning off swap in unprivileged tmpfs mounts unsupported"); |
| 4681 | } | 4680 | } |
| 4682 | ctx->noswap = true; | 4681 | ctx->noswap = true; |
| 4683 | ctx->seen |= SHMEM_SEEN_NOSWAP; | ||
| 4684 | break; | 4682 | break; |
| 4685 | case Opt_quota: | 4683 | case Opt_quota: |
| 4686 | if (fc->user_ns != &init_user_ns) | 4684 | if (fc->user_ns != &init_user_ns) |
| @@ -4830,14 +4828,15 @@ static int shmem_reconfigure(struct fs_context *fc) · 143 unmodified lines | |||
| 4830 | err = "Current inum too high to switch to 32-bit inums"; | 4828 | err = "Current inum too high to switch to 32-bit inums"; |
| 4831 | goto out; | 4829 | goto out; |
| 4832 | } | 4830 | } |
| 4833 | if ((ctx->seen & SHMEM_SEEN_NOSWAP) && ctx->noswap && !sbinfo->noswap) { | 4831 | |
| 4832 | /* | ||
| 4833 | * "noswap" doesn't use fsparam_flag_no, i.e. there's no "swap" | ||
| 4834 | * counterpart for (re-)enabling swap. | ||
| 4835 | */ | ||
| 4836 | if (ctx->noswap && !sbinfo->noswap) { | ||
| 4834 | err = "Cannot disable swap on remount"; | 4837 | err = "Cannot disable swap on remount"; |
| 4835 | goto out; | 4838 | goto out; |
| 4836 | } | 4839 | } |
| 4837 | if (!(ctx->seen & SHMEM_SEEN_NOSWAP) && !ctx->noswap && sbinfo->noswap) { | ||
| 4838 | err = "Cannot enable swap on remount if it was disabled on first mount"; | ||
| 4839 | goto out; | ||
| 4840 | } | ||
| 4841 | 4840 | ||
| 4842 | if (ctx->seen & SHMEM_SEEN_QUOTA && | 4841 | if (ctx->seen & SHMEM_SEEN_QUOTA && |
| 4843 | !sb_any_quota_loaded(fc->root->d_sb)) { | 4842 | !sb_any_quota_loaded(fc->root->d_sb)) { |
| @@ -1335,11 +1335,10 @@ static void hook_sb_delete(struct super_block *const sb) · 1334 unmodified lines | |||
| 1335 | * At this point, we own the ihold() reference that was | 1335 | * At this point, we own the ihold() reference that was |
| 1336 | * originally set up by get_inode_object() and the | 1336 | * originally set up by get_inode_object() and the |
| 1337 | * __iget() reference that we just set in this loop | 1337 | * __iget() reference that we just set in this loop |
| 1338 | * walk. Therefore the following call to iput() will | 1338 | * walk. Therefore there are at least two references |
| 1339 | * not sleep nor drop the inode because there is now at | 1339 | * on the inode. |
| 1340 | * least two references to it. | ||
| 1341 | */ | 1340 | */ |
| 1342 | iput(inode); | 1341 | iput_not_last(inode); |
| 1343 | } else { | 1342 | } else { |
| 1344 | spin_unlock(&object->lock); | 1343 | spin_unlock(&object->lock); |
| 1345 | rcu_read_unlock(); | 1344 | rcu_read_unlock(); |