namei.c (5f8f965287494d55e8ba3551e3727a5e9d0eb702) | namei.c (a80f7fcf18672ae4971a6b713b58c0d389aa99fe) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * linux/fs/ext4/namei.c 4 * 5 * Copyright (C) 1992, 1993, 1994, 1995 6 * Remy Card (card@masi.ibp.fr) 7 * Laboratoire MASI - Institut Blaise Pascal 8 * Universite Pierre et Marie Curie (Paris VI) --- 2592 unchanged lines hidden (view full) --- 2601 * 2602 * If the create succeeds, we fill in the inode information 2603 * with d_instantiate(). 2604 */ 2605static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode, 2606 bool excl) 2607{ 2608 handle_t *handle; | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * linux/fs/ext4/namei.c 4 * 5 * Copyright (C) 1992, 1993, 1994, 1995 6 * Remy Card (card@masi.ibp.fr) 7 * Laboratoire MASI - Institut Blaise Pascal 8 * Universite Pierre et Marie Curie (Paris VI) --- 2592 unchanged lines hidden (view full) --- 2601 * 2602 * If the create succeeds, we fill in the inode information 2603 * with d_instantiate(). 2604 */ 2605static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode, 2606 bool excl) 2607{ 2608 handle_t *handle; |
2609 struct inode *inode, *inode_save; | 2609 struct inode *inode; |
2610 int err, credits, retries = 0; 2611 2612 err = dquot_initialize(dir); 2613 if (err) 2614 return err; 2615 2616 credits = (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + 2617 EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3); 2618retry: 2619 inode = ext4_new_inode_start_handle(dir, mode, &dentry->d_name, 0, 2620 NULL, EXT4_HT_DIR, credits); 2621 handle = ext4_journal_current_handle(); 2622 err = PTR_ERR(inode); 2623 if (!IS_ERR(inode)) { 2624 inode->i_op = &ext4_file_inode_operations; 2625 inode->i_fop = &ext4_file_operations; 2626 ext4_set_aops(inode); | 2610 int err, credits, retries = 0; 2611 2612 err = dquot_initialize(dir); 2613 if (err) 2614 return err; 2615 2616 credits = (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + 2617 EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3); 2618retry: 2619 inode = ext4_new_inode_start_handle(dir, mode, &dentry->d_name, 0, 2620 NULL, EXT4_HT_DIR, credits); 2621 handle = ext4_journal_current_handle(); 2622 err = PTR_ERR(inode); 2623 if (!IS_ERR(inode)) { 2624 inode->i_op = &ext4_file_inode_operations; 2625 inode->i_fop = &ext4_file_operations; 2626 ext4_set_aops(inode); |
2627 inode_save = inode; 2628 ihold(inode_save); | |
2629 err = ext4_add_nondir(handle, dentry, &inode); | 2627 err = ext4_add_nondir(handle, dentry, &inode); |
2630 ext4_fc_track_create(inode_save, dentry); 2631 iput(inode_save); | 2628 if (!err) 2629 ext4_fc_track_create(handle, dentry); |
2632 } 2633 if (handle) 2634 ext4_journal_stop(handle); 2635 if (!IS_ERR_OR_NULL(inode)) 2636 iput(inode); 2637 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) 2638 goto retry; 2639 return err; 2640} 2641 2642static int ext4_mknod(struct inode *dir, struct dentry *dentry, 2643 umode_t mode, dev_t rdev) 2644{ 2645 handle_t *handle; | 2630 } 2631 if (handle) 2632 ext4_journal_stop(handle); 2633 if (!IS_ERR_OR_NULL(inode)) 2634 iput(inode); 2635 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) 2636 goto retry; 2637 return err; 2638} 2639 2640static int ext4_mknod(struct inode *dir, struct dentry *dentry, 2641 umode_t mode, dev_t rdev) 2642{ 2643 handle_t *handle; |
2646 struct inode *inode, *inode_save; | 2644 struct inode *inode; |
2647 int err, credits, retries = 0; 2648 2649 err = dquot_initialize(dir); 2650 if (err) 2651 return err; 2652 2653 credits = (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + 2654 EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3); 2655retry: 2656 inode = ext4_new_inode_start_handle(dir, mode, &dentry->d_name, 0, 2657 NULL, EXT4_HT_DIR, credits); 2658 handle = ext4_journal_current_handle(); 2659 err = PTR_ERR(inode); 2660 if (!IS_ERR(inode)) { 2661 init_special_inode(inode, inode->i_mode, rdev); 2662 inode->i_op = &ext4_special_inode_operations; | 2645 int err, credits, retries = 0; 2646 2647 err = dquot_initialize(dir); 2648 if (err) 2649 return err; 2650 2651 credits = (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + 2652 EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3); 2653retry: 2654 inode = ext4_new_inode_start_handle(dir, mode, &dentry->d_name, 0, 2655 NULL, EXT4_HT_DIR, credits); 2656 handle = ext4_journal_current_handle(); 2657 err = PTR_ERR(inode); 2658 if (!IS_ERR(inode)) { 2659 init_special_inode(inode, inode->i_mode, rdev); 2660 inode->i_op = &ext4_special_inode_operations; |
2663 inode_save = inode; 2664 ihold(inode_save); | |
2665 err = ext4_add_nondir(handle, dentry, &inode); 2666 if (!err) | 2661 err = ext4_add_nondir(handle, dentry, &inode); 2662 if (!err) |
2667 ext4_fc_track_create(inode_save, dentry); 2668 iput(inode_save); | 2663 ext4_fc_track_create(handle, dentry); |
2669 } 2670 if (handle) 2671 ext4_journal_stop(handle); 2672 if (!IS_ERR_OR_NULL(inode)) 2673 iput(inode); 2674 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) 2675 goto retry; 2676 return err; --- 147 unchanged lines hidden (view full) --- 2824 unlock_new_inode(inode); 2825 err2 = ext4_mark_inode_dirty(handle, inode); 2826 if (unlikely(err2)) 2827 err = err2; 2828 ext4_journal_stop(handle); 2829 iput(inode); 2830 goto out_retry; 2831 } | 2664 } 2665 if (handle) 2666 ext4_journal_stop(handle); 2667 if (!IS_ERR_OR_NULL(inode)) 2668 iput(inode); 2669 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) 2670 goto retry; 2671 return err; --- 147 unchanged lines hidden (view full) --- 2819 unlock_new_inode(inode); 2820 err2 = ext4_mark_inode_dirty(handle, inode); 2821 if (unlikely(err2)) 2822 err = err2; 2823 ext4_journal_stop(handle); 2824 iput(inode); 2825 goto out_retry; 2826 } |
2832 ext4_fc_track_create(inode, dentry); | |
2833 ext4_inc_count(dir); 2834 2835 ext4_update_dx_flag(dir); 2836 err = ext4_mark_inode_dirty(handle, dir); 2837 if (err) 2838 goto out_clear_inode; 2839 d_instantiate_new(dentry, inode); | 2827 ext4_inc_count(dir); 2828 2829 ext4_update_dx_flag(dir); 2830 err = ext4_mark_inode_dirty(handle, dir); 2831 if (err) 2832 goto out_clear_inode; 2833 d_instantiate_new(dentry, inode); |
2834 ext4_fc_track_create(handle, dentry); |
|
2840 if (IS_DIRSYNC(dir)) 2841 ext4_handle_sync(handle); 2842 2843out_stop: 2844 if (handle) 2845 ext4_journal_stop(handle); 2846out_retry: 2847 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) --- 318 unchanged lines hidden (view full) --- 3166 inode->i_size = 0; 3167 ext4_orphan_add(handle, inode); 3168 inode->i_ctime = dir->i_ctime = dir->i_mtime = current_time(inode); 3169 retval = ext4_mark_inode_dirty(handle, inode); 3170 if (retval) 3171 goto end_rmdir; 3172 ext4_dec_count(dir); 3173 ext4_update_dx_flag(dir); | 2835 if (IS_DIRSYNC(dir)) 2836 ext4_handle_sync(handle); 2837 2838out_stop: 2839 if (handle) 2840 ext4_journal_stop(handle); 2841out_retry: 2842 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) --- 318 unchanged lines hidden (view full) --- 3161 inode->i_size = 0; 3162 ext4_orphan_add(handle, inode); 3163 inode->i_ctime = dir->i_ctime = dir->i_mtime = current_time(inode); 3164 retval = ext4_mark_inode_dirty(handle, inode); 3165 if (retval) 3166 goto end_rmdir; 3167 ext4_dec_count(dir); 3168 ext4_update_dx_flag(dir); |
3174 ext4_fc_track_unlink(inode, dentry); | 3169 ext4_fc_track_unlink(handle, dentry); |
3175 retval = ext4_mark_inode_dirty(handle, dir); 3176 3177#ifdef CONFIG_UNICODE 3178 /* VFS negative dentries are incompatible with Encoding and 3179 * Case-insensitiveness. Eventually we'll want avoid 3180 * invalidating the dentries here, alongside with returning the 3181 * negative dentries at ext4_lookup(), when it is better 3182 * supported by the VFS for the CI case. --- 4 unchanged lines hidden (view full) --- 3187 3188end_rmdir: 3189 brelse(bh); 3190 if (handle) 3191 ext4_journal_stop(handle); 3192 return retval; 3193} 3194 | 3170 retval = ext4_mark_inode_dirty(handle, dir); 3171 3172#ifdef CONFIG_UNICODE 3173 /* VFS negative dentries are incompatible with Encoding and 3174 * Case-insensitiveness. Eventually we'll want avoid 3175 * invalidating the dentries here, alongside with returning the 3176 * negative dentries at ext4_lookup(), when it is better 3177 * supported by the VFS for the CI case. --- 4 unchanged lines hidden (view full) --- 3182 3183end_rmdir: 3184 brelse(bh); 3185 if (handle) 3186 ext4_journal_stop(handle); 3187 return retval; 3188} 3189 |
3195int __ext4_unlink(struct inode *dir, const struct qstr *d_name, | 3190int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name, |
3196 struct inode *inode) 3197{ 3198 int retval = -ENOENT; 3199 struct buffer_head *bh; 3200 struct ext4_dir_entry_2 *de; | 3191 struct inode *inode) 3192{ 3193 int retval = -ENOENT; 3194 struct buffer_head *bh; 3195 struct ext4_dir_entry_2 *de; |
3201 handle_t *handle = NULL; | |
3202 int skip_remove_dentry = 0; 3203 3204 bh = ext4_find_entry(dir, d_name, &de, NULL); 3205 if (IS_ERR(bh)) 3206 return PTR_ERR(bh); 3207 3208 if (!bh) 3209 return -ENOENT; 3210 3211 if (le32_to_cpu(de->inode) != inode->i_ino) { 3212 /* 3213 * It's okay if we find dont find dentry which matches 3214 * the inode. That's because it might have gotten 3215 * renamed to a different inode number 3216 */ 3217 if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY) 3218 skip_remove_dentry = 1; 3219 else | 3196 int skip_remove_dentry = 0; 3197 3198 bh = ext4_find_entry(dir, d_name, &de, NULL); 3199 if (IS_ERR(bh)) 3200 return PTR_ERR(bh); 3201 3202 if (!bh) 3203 return -ENOENT; 3204 3205 if (le32_to_cpu(de->inode) != inode->i_ino) { 3206 /* 3207 * It's okay if we find dont find dentry which matches 3208 * the inode. That's because it might have gotten 3209 * renamed to a different inode number 3210 */ 3211 if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY) 3212 skip_remove_dentry = 1; 3213 else |
3220 goto out_bh; | 3214 goto out; |
3221 } 3222 | 3215 } 3216 |
3223 handle = ext4_journal_start(dir, EXT4_HT_DIR, 3224 EXT4_DATA_TRANS_BLOCKS(dir->i_sb)); 3225 if (IS_ERR(handle)) { 3226 retval = PTR_ERR(handle); 3227 goto out_bh; 3228 } 3229 | |
3230 if (IS_DIRSYNC(dir)) 3231 ext4_handle_sync(handle); 3232 3233 if (!skip_remove_dentry) { 3234 retval = ext4_delete_entry(handle, dir, de, bh); 3235 if (retval) | 3217 if (IS_DIRSYNC(dir)) 3218 ext4_handle_sync(handle); 3219 3220 if (!skip_remove_dentry) { 3221 retval = ext4_delete_entry(handle, dir, de, bh); 3222 if (retval) |
3236 goto out_handle; | 3223 goto out; |
3237 dir->i_ctime = dir->i_mtime = current_time(dir); 3238 ext4_update_dx_flag(dir); 3239 retval = ext4_mark_inode_dirty(handle, dir); 3240 if (retval) | 3224 dir->i_ctime = dir->i_mtime = current_time(dir); 3225 ext4_update_dx_flag(dir); 3226 retval = ext4_mark_inode_dirty(handle, dir); 3227 if (retval) |
3241 goto out_handle; | 3228 goto out; |
3242 } else { 3243 retval = 0; 3244 } 3245 if (inode->i_nlink == 0) 3246 ext4_warning_inode(inode, "Deleting file '%.*s' with no links", 3247 d_name->len, d_name->name); 3248 else 3249 drop_nlink(inode); 3250 if (!inode->i_nlink) 3251 ext4_orphan_add(handle, inode); 3252 inode->i_ctime = current_time(inode); 3253 retval = ext4_mark_inode_dirty(handle, inode); 3254 | 3229 } else { 3230 retval = 0; 3231 } 3232 if (inode->i_nlink == 0) 3233 ext4_warning_inode(inode, "Deleting file '%.*s' with no links", 3234 d_name->len, d_name->name); 3235 else 3236 drop_nlink(inode); 3237 if (!inode->i_nlink) 3238 ext4_orphan_add(handle, inode); 3239 inode->i_ctime = current_time(inode); 3240 retval = ext4_mark_inode_dirty(handle, inode); 3241 |
3255out_handle: 3256 ext4_journal_stop(handle); 3257out_bh: | 3242out: |
3258 brelse(bh); 3259 return retval; 3260} 3261 3262static int ext4_unlink(struct inode *dir, struct dentry *dentry) 3263{ | 3243 brelse(bh); 3244 return retval; 3245} 3246 3247static int ext4_unlink(struct inode *dir, struct dentry *dentry) 3248{ |
3249 handle_t *handle; |
|
3264 int retval; 3265 3266 if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb)))) 3267 return -EIO; 3268 3269 trace_ext4_unlink_enter(dir, dentry); 3270 /* 3271 * Initialize quotas before so that eventual writes go 3272 * in separate transaction 3273 */ 3274 retval = dquot_initialize(dir); 3275 if (retval) 3276 goto out_trace; 3277 retval = dquot_initialize(d_inode(dentry)); 3278 if (retval) 3279 goto out_trace; 3280 | 3250 int retval; 3251 3252 if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb)))) 3253 return -EIO; 3254 3255 trace_ext4_unlink_enter(dir, dentry); 3256 /* 3257 * Initialize quotas before so that eventual writes go 3258 * in separate transaction 3259 */ 3260 retval = dquot_initialize(dir); 3261 if (retval) 3262 goto out_trace; 3263 retval = dquot_initialize(d_inode(dentry)); 3264 if (retval) 3265 goto out_trace; 3266 |
3281 retval = __ext4_unlink(dir, &dentry->d_name, d_inode(dentry)); | 3267 handle = ext4_journal_start(dir, EXT4_HT_DIR, 3268 EXT4_DATA_TRANS_BLOCKS(dir->i_sb)); 3269 if (IS_ERR(handle)) { 3270 retval = PTR_ERR(handle); 3271 goto out_trace; 3272 } 3273 3274 retval = __ext4_unlink(handle, dir, &dentry->d_name, d_inode(dentry)); |
3282 if (!retval) | 3275 if (!retval) |
3283 ext4_fc_track_unlink(d_inode(dentry), dentry); | 3276 ext4_fc_track_unlink(handle, dentry); |
3284#ifdef CONFIG_UNICODE 3285 /* VFS negative dentries are incompatible with Encoding and 3286 * Case-insensitiveness. Eventually we'll want avoid 3287 * invalidating the dentries here, alongside with returning the 3288 * negative dentries at ext4_lookup(), when it is better 3289 * supported by the VFS for the CI case. 3290 */ 3291 if (IS_CASEFOLDED(dir)) 3292 d_invalidate(dentry); 3293#endif | 3277#ifdef CONFIG_UNICODE 3278 /* VFS negative dentries are incompatible with Encoding and 3279 * Case-insensitiveness. Eventually we'll want avoid 3280 * invalidating the dentries here, alongside with returning the 3281 * negative dentries at ext4_lookup(), when it is better 3282 * supported by the VFS for the CI case. 3283 */ 3284 if (IS_CASEFOLDED(dir)) 3285 d_invalidate(dentry); 3286#endif |
3287 if (handle) 3288 ext4_journal_stop(handle); |
|
3294 3295out_trace: 3296 trace_ext4_unlink_exit(dentry, retval); 3297 return retval; 3298} 3299 3300static int ext4_symlink(struct inode *dir, 3301 struct dentry *dentry, const char *symname) --- 140 unchanged lines hidden (view full) --- 3442 ext4_handle_sync(handle); 3443 3444 inode->i_ctime = current_time(inode); 3445 ext4_inc_count(inode); 3446 ihold(inode); 3447 3448 err = ext4_add_entry(handle, dentry, inode); 3449 if (!err) { | 3289 3290out_trace: 3291 trace_ext4_unlink_exit(dentry, retval); 3292 return retval; 3293} 3294 3295static int ext4_symlink(struct inode *dir, 3296 struct dentry *dentry, const char *symname) --- 140 unchanged lines hidden (view full) --- 3437 ext4_handle_sync(handle); 3438 3439 inode->i_ctime = current_time(inode); 3440 ext4_inc_count(inode); 3441 ihold(inode); 3442 3443 err = ext4_add_entry(handle, dentry, inode); 3444 if (!err) { |
3450 ext4_fc_track_link(inode, dentry); | |
3451 err = ext4_mark_inode_dirty(handle, inode); 3452 /* this can happen only for tmpfile being 3453 * linked the first time 3454 */ 3455 if (inode->i_nlink == 1) 3456 ext4_orphan_del(handle, inode); 3457 d_instantiate(dentry, inode); | 3445 err = ext4_mark_inode_dirty(handle, inode); 3446 /* this can happen only for tmpfile being 3447 * linked the first time 3448 */ 3449 if (inode->i_nlink == 1) 3450 ext4_orphan_del(handle, inode); 3451 d_instantiate(dentry, inode); |
3452 ext4_fc_track_link(handle, dentry); |
|
3458 } else { 3459 drop_nlink(inode); 3460 iput(inode); 3461 } 3462 ext4_journal_stop(handle); 3463 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) 3464 goto retry; 3465 return err; --- 444 unchanged lines hidden (view full) --- 3910 * We disable fast commits here that's because the 3911 * replay code is not yet capable of changing dot dot 3912 * dirents in directories. 3913 */ 3914 ext4_fc_mark_ineligible(old.inode->i_sb, 3915 EXT4_FC_REASON_RENAME_DIR); 3916 } else { 3917 if (new.inode) | 3453 } else { 3454 drop_nlink(inode); 3455 iput(inode); 3456 } 3457 ext4_journal_stop(handle); 3458 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) 3459 goto retry; 3460 return err; --- 444 unchanged lines hidden (view full) --- 3905 * We disable fast commits here that's because the 3906 * replay code is not yet capable of changing dot dot 3907 * dirents in directories. 3908 */ 3909 ext4_fc_mark_ineligible(old.inode->i_sb, 3910 EXT4_FC_REASON_RENAME_DIR); 3911 } else { 3912 if (new.inode) |
3918 ext4_fc_track_unlink(new.inode, new.dentry); 3919 ext4_fc_track_link(old.inode, new.dentry); 3920 ext4_fc_track_unlink(old.inode, old.dentry); | 3913 ext4_fc_track_unlink(handle, new.dentry); 3914 __ext4_fc_track_link(handle, old.inode, new.dentry); 3915 __ext4_fc_track_unlink(handle, old.inode, old.dentry); |
3921 } 3922 3923 if (new.inode) { 3924 retval = ext4_mark_inode_dirty(handle, new.inode); 3925 if (unlikely(retval)) 3926 goto end_rename; 3927 if (!new.inode->i_nlink) 3928 ext4_orphan_add(handle, new.inode); --- 217 unchanged lines hidden --- | 3916 } 3917 3918 if (new.inode) { 3919 retval = ext4_mark_inode_dirty(handle, new.inode); 3920 if (unlikely(retval)) 3921 goto end_rename; 3922 if (!new.inode->i_nlink) 3923 ext4_orphan_add(handle, new.inode); --- 217 unchanged lines hidden --- |