aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-26 14:19:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-26 14:19:18 -0400
commitd1e14f1d63eb15ebe97d1a8544ddc143486b0204 (patch)
treea73e7c751f23835483f1e8029d04547192611975 /fs/ext4
parent2cc91884b6b3f7328680b8ea7563016d3aee3d19 (diff)
parentdb6ec212b53abc29a5bb6ac8c810010fc28d5191 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro: "overlayfs merge + leak fix for d_splice_alias() failure exits" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: overlayfs: embed middle into overlay_readdir_data overlayfs: embed root into overlay_readdir_data overlayfs: make ovl_cache_entry->name an array instead of pointer overlayfs: don't hold ->i_mutex over opening the real directory fix inode leaks on d_splice_alias() failure exits fs: limit filesystem stacking depth overlay: overlay filesystem documentation overlayfs: implement show_options overlayfs: add statfs support overlay filesystem shmem: support RENAME_WHITEOUT ext4: support RENAME_WHITEOUT vfs: add RENAME_WHITEOUT vfs: add whiteout support vfs: export check_sticky() vfs: introduce clone_private_mount() vfs: export __inode_permission() to modules vfs: export do_splice_direct() to modules vfs: add i_op->dentry_open()
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/namei.c95
1 files changed, 78 insertions, 17 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index adb559de23c1..123798c5ac31 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -3148,6 +3148,39 @@ static void ext4_update_dir_count(handle_t *handle, struct ext4_renament *ent)
3148 } 3148 }
3149} 3149}
3150 3150
3151static struct inode *ext4_whiteout_for_rename(struct ext4_renament *ent,
3152 int credits, handle_t **h)
3153{
3154 struct inode *wh;
3155 handle_t *handle;
3156 int retries = 0;
3157
3158 /*
3159 * for inode block, sb block, group summaries,
3160 * and inode bitmap
3161 */
3162 credits += (EXT4_MAXQUOTAS_TRANS_BLOCKS(ent->dir->i_sb) +
3163 EXT4_XATTR_TRANS_BLOCKS + 4);
3164retry:
3165 wh = ext4_new_inode_start_handle(ent->dir, S_IFCHR | WHITEOUT_MODE,
3166 &ent->dentry->d_name, 0, NULL,
3167 EXT4_HT_DIR, credits);
3168
3169 handle = ext4_journal_current_handle();
3170 if (IS_ERR(wh)) {
3171 if (handle)
3172 ext4_journal_stop(handle);
3173 if (PTR_ERR(wh) == -ENOSPC &&
3174 ext4_should_retry_alloc(ent->dir->i_sb, &retries))
3175 goto retry;
3176 } else {
3177 *h = handle;
3178 init_special_inode(wh, wh->i_mode, WHITEOUT_DEV);
3179 wh->i_op = &ext4_special_inode_operations;
3180 }
3181 return wh;
3182}
3183
3151/* 3184/*
3152 * Anybody can rename anything with this: the permission checks are left to the 3185 * Anybody can rename anything with this: the permission checks are left to the
3153 * higher-level routines. 3186 * higher-level routines.
@@ -3157,7 +3190,8 @@ static void ext4_update_dir_count(handle_t *handle, struct ext4_renament *ent)
3157 * This comes from rename(const char *oldpath, const char *newpath) 3190 * This comes from rename(const char *oldpath, const char *newpath)
3158 */ 3191 */
3159static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, 3192static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
3160 struct inode *new_dir, struct dentry *new_dentry) 3193 struct inode *new_dir, struct dentry *new_dentry,
3194 unsigned int flags)
3161{ 3195{
3162 handle_t *handle = NULL; 3196 handle_t *handle = NULL;
3163 struct ext4_renament old = { 3197 struct ext4_renament old = {
@@ -3172,6 +3206,9 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
3172 }; 3206 };
3173 int force_reread; 3207 int force_reread;
3174 int retval; 3208 int retval;
3209 struct inode *whiteout = NULL;
3210 int credits;
3211 u8 old_file_type;
3175 3212
3176 dquot_initialize(old.dir); 3213 dquot_initialize(old.dir);
3177 dquot_initialize(new.dir); 3214 dquot_initialize(new.dir);
@@ -3210,11 +3247,17 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
3210 if (new.inode && !test_opt(new.dir->i_sb, NO_AUTO_DA_ALLOC)) 3247 if (new.inode && !test_opt(new.dir->i_sb, NO_AUTO_DA_ALLOC))
3211 ext4_alloc_da_blocks(old.inode); 3248 ext4_alloc_da_blocks(old.inode);
3212 3249
3213 handle = ext4_journal_start(old.dir, EXT4_HT_DIR, 3250 credits = (2 * EXT4_DATA_TRANS_BLOCKS(old.dir->i_sb) +
3214 (2 * EXT4_DATA_TRANS_BLOCKS(old.dir->i_sb) + 3251 EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2);
3215 EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2)); 3252 if (!(flags & RENAME_WHITEOUT)) {
3216 if (IS_ERR(handle)) 3253 handle = ext4_journal_start(old.dir, EXT4_HT_DIR, credits);
3217 return PTR_ERR(handle); 3254 if (IS_ERR(handle))
3255 return PTR_ERR(handle);
3256 } else {
3257 whiteout = ext4_whiteout_for_rename(&old, credits, &handle);
3258 if (IS_ERR(whiteout))
3259 return PTR_ERR(whiteout);
3260 }
3218 3261
3219 if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir)) 3262 if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir))
3220 ext4_handle_sync(handle); 3263 ext4_handle_sync(handle);
@@ -3242,13 +3285,26 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
3242 */ 3285 */
3243 force_reread = (new.dir->i_ino == old.dir->i_ino && 3286 force_reread = (new.dir->i_ino == old.dir->i_ino &&
3244 ext4_test_inode_flag(new.dir, EXT4_INODE_INLINE_DATA)); 3287 ext4_test_inode_flag(new.dir, EXT4_INODE_INLINE_DATA));
3288
3289 old_file_type = old.de->file_type;
3290 if (whiteout) {
3291 /*
3292 * Do this before adding a new entry, so the old entry is sure
3293 * to be still pointing to the valid old entry.
3294 */
3295 retval = ext4_setent(handle, &old, whiteout->i_ino,
3296 EXT4_FT_CHRDEV);
3297 if (retval)
3298 goto end_rename;
3299 ext4_mark_inode_dirty(handle, whiteout);
3300 }
3245 if (!new.bh) { 3301 if (!new.bh) {
3246 retval = ext4_add_entry(handle, new.dentry, old.inode); 3302 retval = ext4_add_entry(handle, new.dentry, old.inode);
3247 if (retval) 3303 if (retval)
3248 goto end_rename; 3304 goto end_rename;
3249 } else { 3305 } else {
3250 retval = ext4_setent(handle, &new, 3306 retval = ext4_setent(handle, &new,
3251 old.inode->i_ino, old.de->file_type); 3307 old.inode->i_ino, old_file_type);
3252 if (retval) 3308 if (retval)
3253 goto end_rename; 3309 goto end_rename;
3254 } 3310 }
@@ -3263,10 +3319,12 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
3263 old.inode->i_ctime = ext4_current_time(old.inode); 3319 old.inode->i_ctime = ext4_current_time(old.inode);
3264 ext4_mark_inode_dirty(handle, old.inode); 3320 ext4_mark_inode_dirty(handle, old.inode);
3265 3321
3266 /* 3322 if (!whiteout) {
3267 * ok, that's it 3323 /*
3268 */ 3324 * ok, that's it
3269 ext4_rename_delete(handle, &old, force_reread); 3325 */
3326 ext4_rename_delete(handle, &old, force_reread);
3327 }
3270 3328
3271 if (new.inode) { 3329 if (new.inode) {
3272 ext4_dec_count(handle, new.inode); 3330 ext4_dec_count(handle, new.inode);
@@ -3302,6 +3360,12 @@ end_rename:
3302 brelse(old.dir_bh); 3360 brelse(old.dir_bh);
3303 brelse(old.bh); 3361 brelse(old.bh);
3304 brelse(new.bh); 3362 brelse(new.bh);
3363 if (whiteout) {
3364 if (retval)
3365 drop_nlink(whiteout);
3366 unlock_new_inode(whiteout);
3367 iput(whiteout);
3368 }
3305 if (handle) 3369 if (handle)
3306 ext4_journal_stop(handle); 3370 ext4_journal_stop(handle);
3307 return retval; 3371 return retval;
@@ -3434,18 +3498,15 @@ static int ext4_rename2(struct inode *old_dir, struct dentry *old_dentry,
3434 struct inode *new_dir, struct dentry *new_dentry, 3498 struct inode *new_dir, struct dentry *new_dentry,
3435 unsigned int flags) 3499 unsigned int flags)
3436{ 3500{
3437 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) 3501 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
3438 return -EINVAL; 3502 return -EINVAL;
3439 3503
3440 if (flags & RENAME_EXCHANGE) { 3504 if (flags & RENAME_EXCHANGE) {
3441 return ext4_cross_rename(old_dir, old_dentry, 3505 return ext4_cross_rename(old_dir, old_dentry,
3442 new_dir, new_dentry); 3506 new_dir, new_dentry);
3443 } 3507 }
3444 /* 3508
3445 * Existence checking was done by the VFS, otherwise "RENAME_NOREPLACE" 3509 return ext4_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
3446 * is equivalent to regular rename.
3447 */
3448 return ext4_rename(old_dir, old_dentry, new_dir, new_dentry);
3449} 3510}
3450 3511
3451/* 3512/*