aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-07-22 06:06:20 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-08-13 04:28:44 -0400
commitde94eb558b542873d3f6f9ede1b8575fb5662248 (patch)
tree3ba858a1c87870e22886ac3d4774287bbf367131 /fs
parent014eb04b03202dc75c1c749df4246d98045f5e69 (diff)
UBIFS: optimize deletions
Every time anything is deleted, UBIFS writes the deletion inode node twice - once in 'ubifs_jnl_update()' and the second time in 'ubifs_jnl_write_inode()'. However, the second write is not needed if no commit happened after 'ubifs_jnl_update()'. This patch checks that condition and avoids writing the deletion inode for the second time. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ubifs/journal.c60
-rw-r--r--fs/ubifs/super.c6
-rw-r--r--fs/ubifs/ubifs.h12
3 files changed, 73 insertions, 5 deletions
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 3bc3fc947099..0bcee7d221e8 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -604,6 +604,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
604 release_head(c, BASEHD); 604 release_head(c, BASEHD);
605 goto out_finish; 605 goto out_finish;
606 } 606 }
607 ui->del_cmtno = c->cmt_no;
607 } 608 }
608 609
609 err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, sync); 610 err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, sync);
@@ -821,6 +822,64 @@ out_free:
821} 822}
822 823
823/** 824/**
825 * ubifs_jnl_write_inode - delete an inode.
826 * @c: UBIFS file-system description object
827 * @inode: inode to delete
828 *
829 * This function deletes inode @inode which includes removing it from orphans,
830 * deleting it from TNC and, in some cases, writing a deletion inode to the
831 * journal.
832 *
833 * When regular file inodes are unlinked or a directory inode is removed, the
834 * 'ubifs_jnl_update()' function write corresponding deletion inode and
835 * direntry to the media, and adds the inode to orphans. After this, when the
836 * last reference to this inode has been dropped, this function is called. In
837 * general, it has to write one more deletion inode to the media, because if
838 * a commit happened between 'ubifs_jnl_update()' and
839 * 'ubifs_jnl_delete_inode()', the deletion inode is not in the journal
840 * anymore, and in fact it might be not on the flash anymore, becouse it might
841 * have been garbage-collected already. And for optimization reasond UBIFS does
842 * not read the orphan area if it has been unmounted cleanly, so it would have
843 * no indication in the journal that there is a deleted inode which has to be
844 * removed from TNC.
845 *
846 * However, if there was no commit between 'ubifs_jnl_update()' and
847 * 'ubifs_jnl_delete_inode()', then there is no need to write the deletion
848 * inode to the media for the second time. And this is quite typical case.
849 *
850 * This function returns zero in case of success and a negative error code in
851 * case of failure.
852 */
853int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode)
854{
855 int err;
856 struct ubifs_inode *ui = ubifs_inode(inode);
857
858 ubifs_assert(inode->i_nlink == 0);
859
860 if (ui->del_cmtno != c->cmt_no)
861 /* A commit happened for sure */
862 return ubifs_jnl_write_inode(c, inode);
863
864 down_read(&c->commit_sem);
865 /*
866 * Check commit number again, because the first test has been done
867 * without @c->commit_sem, so a commit might have happened.
868 */
869 if (ui->del_cmtno != c->cmt_no) {
870 up_read(&c->commit_sem);
871 return ubifs_jnl_write_inode(c, inode);
872 }
873
874 ubifs_delete_orphan(c, inode->i_ino);
875 err = ubifs_tnc_remove_ino(c, inode->i_ino);
876 if (err)
877 ubifs_ro_mode(c, err);
878 up_read(&c->commit_sem);
879 return err;
880}
881
882/**
824 * ubifs_jnl_rename - rename a directory entry. 883 * ubifs_jnl_rename - rename a directory entry.
825 * @c: UBIFS file-system description object 884 * @c: UBIFS file-system description object
826 * @old_dir: parent inode of directory entry to rename 885 * @old_dir: parent inode of directory entry to rename
@@ -928,6 +987,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
928 release_head(c, BASEHD); 987 release_head(c, BASEHD);
929 goto out_finish; 988 goto out_finish;
930 } 989 }
990 new_ui->del_cmtno = c->cmt_no;
931 } 991 }
932 992
933 err = write_head(c, BASEHD, dent, len, &lnum, &offs, sync); 993 err = write_head(c, BASEHD, dent, len, &lnum, &offs, sync);
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index cf1fb6cffa09..6cc4175f23c1 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -341,13 +341,15 @@ static void ubifs_delete_inode(struct inode *inode)
341 goto out; 341 goto out;
342 342
343 ui->ui_size = inode->i_size = 0; 343 ui->ui_size = inode->i_size = 0;
344 err = ubifs_jnl_write_inode(c, inode); 344 err = ubifs_jnl_delete_inode(c, inode);
345 if (err) 345 if (err)
346 /* 346 /*
347 * Worst case we have a lost orphan inode wasting space, so a 347 * Worst case we have a lost orphan inode wasting space, so a
348 * simple error message is ok here. 348 * simple error message is ok here.
349 */ 349 */
350 ubifs_err("can't write inode %lu, error %d", inode->i_ino, err); 350 ubifs_err("can't delete inode %lu, error %d",
351 inode->i_ino, err);
352
351out: 353out:
352 if (ui->dirty) 354 if (ui->dirty)
353 ubifs_release_dirty_inode_budget(c, ui); 355 ubifs_release_dirty_inode_budget(c, ui);
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 21502b6040f0..dfb4b93614ff 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -322,6 +322,8 @@ struct ubifs_gced_idx_leb {
322 * struct ubifs_inode - UBIFS in-memory inode description. 322 * struct ubifs_inode - UBIFS in-memory inode description.
323 * @vfs_inode: VFS inode description object 323 * @vfs_inode: VFS inode description object
324 * @creat_sqnum: sequence number at time of creation 324 * @creat_sqnum: sequence number at time of creation
325 * @del_cmtno: commit number corresponding to the time the inode was deleted,
326 * protected by @c->commit_sem;
325 * @xattr_size: summarized size of all extended attributes in bytes 327 * @xattr_size: summarized size of all extended attributes in bytes
326 * @xattr_cnt: count of extended attributes this inode has 328 * @xattr_cnt: count of extended attributes this inode has
327 * @xattr_names: sum of lengths of all extended attribute names belonging to 329 * @xattr_names: sum of lengths of all extended attribute names belonging to
@@ -372,7 +374,10 @@ struct ubifs_gced_idx_leb {
372 */ 374 */
373struct ubifs_inode { 375struct ubifs_inode {
374 struct inode vfs_inode; 376 struct inode vfs_inode;
375 unsigned long long creat_sqnum; 377 union {
378 unsigned long long creat_sqnum;
379 unsigned long long del_cmtno;
380 };
376 unsigned int xattr_size; 381 unsigned int xattr_size;
377 unsigned int xattr_cnt; 382 unsigned int xattr_cnt;
378 unsigned int xattr_names; 383 unsigned int xattr_names;
@@ -779,7 +784,7 @@ struct ubifs_compressor {
779/** 784/**
780 * struct ubifs_budget_req - budget requirements of an operation. 785 * struct ubifs_budget_req - budget requirements of an operation.
781 * 786 *
782 * @fast: non-zero if the budgeting should try to aquire budget quickly and 787 * @fast: non-zero if the budgeting should try to acquire budget quickly and
783 * should not try to call write-back 788 * should not try to call write-back
784 * @recalculate: non-zero if @idx_growth, @data_growth, and @dd_growth fields 789 * @recalculate: non-zero if @idx_growth, @data_growth, and @dd_growth fields
785 * have to be re-calculated 790 * have to be re-calculated
@@ -860,7 +865,7 @@ struct ubifs_mount_opts {
860 * struct ubifs_info - UBIFS file-system description data structure 865 * struct ubifs_info - UBIFS file-system description data structure
861 * (per-superblock). 866 * (per-superblock).
862 * @vfs_sb: VFS @struct super_block object 867 * @vfs_sb: VFS @struct super_block object
863 * @bdi: backing device info object to make VFS happy and disable readahead 868 * @bdi: backing device info object to make VFS happy and disable read-ahead
864 * 869 *
865 * @highest_inum: highest used inode number 870 * @highest_inum: highest used inode number
866 * @vfs_gen: VFS inode generation counter 871 * @vfs_gen: VFS inode generation counter
@@ -1402,6 +1407,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
1402int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, 1407int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
1403 const union ubifs_key *key, const void *buf, int len); 1408 const union ubifs_key *key, const void *buf, int len);
1404int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode); 1409int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode);
1410int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode);
1405int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, 1411int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
1406 const struct dentry *old_dentry, 1412 const struct dentry *old_dentry,
1407 const struct inode *new_dir, 1413 const struct inode *new_dir,