From 8875527c317bf03aed9f1ffe0f1a5996e02f59cf Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Mon, 11 Feb 2002 10:03:32 -0800 Subject: [PATCH] [PATCH] BKL shifted into ->truncate() BKL shifted into all instances of ->truncate(). Callers updated. --- Documentation/filesystems/porting | 7 ++++++- fs/affs/file.c | 11 +++++++++-- fs/affs/inode.c | 2 +- fs/ext2/inode.c | 4 +--- fs/ext3/inode.c | 6 +++++- fs/fat/file.c | 3 +++ fs/fat/inode.c | 2 -- fs/hfs/file.c | 6 +++++- fs/hpfs/file.c | 3 +++ fs/minix/inode.c | 6 +++--- fs/qnx4/inode.c | 2 +- fs/qnx4/truncate.c | 3 +++ fs/reiserfs/file.c | 2 ++ fs/sysv/inode.c | 2 +- fs/sysv/itree.c | 3 +++ fs/udf/inode.c | 8 +++++--- fs/ufs/truncate.c | 3 +++ mm/memory.c | 5 +---- mm/shmem.c | 1 + 19 files changed, 56 insertions(+), 23 deletions(-) diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 99a47a8b7231..cd4e53210416 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -19,7 +19,7 @@ Declare /* fs-private stuff */ struct inode vfs_inode; }; - static inline FOO_I(struct inode *inode) + static inline struct foo_inode_info *FOO_I(struct inode *inode) { return list_entry(inode, struct foo_inode_info, vfs_inode); } @@ -84,3 +84,8 @@ can relax your locking. - that will guarantee the same locking you used to have. If your ->lookup() or its parts do not need BKL - better yet, now you can shift lock_kernel()/ unlock_kernel() so that they would protect exactly what needs to be protected. + +--- +[mandatory] + +->truncate() is called without BKL now (same as above). diff --git a/fs/affs/file.c b/fs/affs/file.c index de3d019352a3..4d7d470d209a 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -807,6 +807,7 @@ affs_truncate(struct inode *inode) pr_debug("AFFS: truncate(inode=%d, size=%u)\n", (u32)inode->i_ino, (u32)inode->i_size); + lock_kernel(); last_blk = 0; ext = 0; if (inode->i_size) { @@ -821,8 +822,10 @@ affs_truncate(struct inode *inode) int res; page = grab_cache_page(mapping, size >> PAGE_CACHE_SHIFT); - if (!page) + if (!page) { + unlock_kernel(); return; + } size = (size & (PAGE_CACHE_SIZE - 1)) + 1; res = mapping->a_ops->prepare_write(NULL, page, size, size); if (!res) @@ -830,9 +833,12 @@ affs_truncate(struct inode *inode) UnlockPage(page); page_cache_release(page); mark_inode_dirty(inode); + unlock_kernel(); return; - } else if (inode->i_size == AFFS_I(inode)->mmu_private) + } else if (inode->i_size == AFFS_I(inode)->mmu_private) { + unlock_kernel(); return; + } // lock cache ext_bh = affs_get_extblock(inode, ext); @@ -888,4 +894,5 @@ affs_truncate(struct inode *inode) ext_key = be32_to_cpu(AFFS_TAIL(sb, ext_bh)->extension); affs_brelse(ext_bh); } + unlock_kernel(); } diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 83e4ce9dd53d..33e2241a9944 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -275,11 +275,11 @@ void affs_delete_inode(struct inode *inode) { pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); - lock_kernel(); inode->i_size = 0; if (S_ISREG(inode->i_mode)) affs_truncate(inode); clear_inode(inode); + lock_kernel(); affs_free_block(inode->i_sb, inode->i_ino); unlock_kernel(); } diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 23849266c3f5..44fc7cf81bef 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -57,10 +57,10 @@ void ext2_delete_inode (struct inode * inode) mark_inode_dirty(inode); ext2_update_inode(inode, IS_SYNC(inode)); - lock_kernel(); inode->i_size = 0; if (inode->i_blocks) ext2_truncate (inode); + lock_kernel(); ext2_free_inode (inode); unlock_kernel(); @@ -801,7 +801,6 @@ void ext2_truncate (struct inode * inode) if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; - unlock_kernel(); ext2_discard_prealloc(inode); blocksize = inode->i_sb->s_blocksize; @@ -875,7 +874,6 @@ do_indirects: ext2_sync_inode (inode); else mark_inode_dirty(inode); - lock_kernel(); } void ext2_read_inode (struct inode * inode) diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 83cc1283e7a6..e9fa8a7beb5b 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -1848,11 +1848,14 @@ void ext3_truncate(struct inode * inode) if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; + lock_kernel(); ext3_discard_prealloc(inode); handle = start_transaction(inode); - if (IS_ERR(handle)) + if (IS_ERR(handle)) { + unlock_kernel(); return; /* AKPM: return what? */ + } blocksize = inode->i_sb->s_blocksize; last_block = (inode->i_size + blocksize-1) @@ -1974,6 +1977,7 @@ out_stop: ext3_orphan_del(handle, inode); ext3_journal_stop(handle, inode); + unlock_kernel(); } /* diff --git a/fs/fat/file.c b/fs/fat/file.c index 942fdebef2d9..78bcc8e97674 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -10,6 +10,7 @@ #include #include #include +#include #define PRINTK(x) #define Printk(x) printk x @@ -119,8 +120,10 @@ void fat_truncate(struct inode *inode) if (MSDOS_I(inode)->mmu_private > inode->i_size) MSDOS_I(inode)->mmu_private = inode->i_size; + lock_kernel(); fat_free(inode, (inode->i_size + (cluster - 1)) >> sbi->cluster_bits); MSDOS_I(inode)->i_attrs |= ATTR_ARCH; + unlock_kernel(); inode->i_ctime = inode->i_mtime = CURRENT_TIME; mark_inode_dirty(inode); } diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 9e3b7ec8235c..5f739cec6adb 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -147,10 +147,8 @@ out: void fat_delete_inode(struct inode *inode) { if (!is_bad_inode(inode)) { - lock_kernel(); inode->i_size = 0; fat_truncate(inode); - unlock_kernel(); } clear_inode(inode); } diff --git a/fs/hfs/file.c b/fs/hfs/file.c index f6b81d5748f6..e3248b6a021b 100644 --- a/fs/hfs/file.c +++ b/fs/hfs/file.c @@ -20,6 +20,7 @@ #include #include #include +#include /*================ Forward declarations ================*/ @@ -223,8 +224,10 @@ static hfs_rwret_t hfs_file_write(struct file * filp, const char * buf, */ static void hfs_file_truncate(struct inode * inode) { - struct hfs_fork *fork = HFS_I(inode)->fork; + struct hfs_fork *fork; + lock_kernel(); + fork = HFS_I(inode)->fork; fork->lsize = inode->i_size; hfs_extent_adj(fork); hfs_cat_mark_dirty(HFS_I(inode)->entry); @@ -232,6 +235,7 @@ static void hfs_file_truncate(struct inode * inode) inode->i_size = fork->lsize; inode->i_blocks = fork->psize; mark_inode_dirty(inode); + unlock_kernel(); } /* diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 10bc9d88782a..91ab1d99b9cd 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -62,11 +62,14 @@ secno hpfs_bmap(struct inode *inode, unsigned file_secno) void hpfs_truncate(struct inode *i) { if (IS_IMMUTABLE(i)) return /*-EPERM*/; + lock_kernel(); hpfs_i(i)->i_n_secs = 0; i->i_blocks = 1 + ((i->i_size + 511) >> 9); hpfs_i(i)->mmu_private = i->i_size; hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9)); hpfs_write_inode(i); + hpfs_i(i)->i_n_secs = 0; + unlock_kernel(); } int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) diff --git a/fs/minix/inode.c b/fs/minix/inode.c index be821723b7d0..d62b0ae9dd5b 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -27,12 +27,10 @@ static int minix_remount (struct super_block * sb, int * flags, char * data); static void minix_delete_inode(struct inode *inode) { - lock_kernel(); - inode->i_size = 0; minix_truncate(inode); + lock_kernel(); minix_free_inode(inode); - unlock_kernel(); } @@ -551,10 +549,12 @@ int minix_sync_inode(struct inode * inode) */ void minix_truncate(struct inode * inode) { + lock_kernel(); if (INODE_VERSION(inode) == MINIX_V1) V1_minix_truncate(inode); else V2_minix_truncate(inode); + unlock_kernel(); } static struct super_block *minix_get_sb(struct file_system_type *fs_type, diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index cd07c6652fd5..4d03f2928b64 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -63,9 +63,9 @@ int qnx4_sync_inode(struct inode *inode) static void qnx4_delete_inode(struct inode *inode) { QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino)); - lock_kernel(); inode->i_size = 0; qnx4_truncate(inode); + lock_kernel(); qnx4_free_inode(inode); unlock_kernel(); } diff --git a/fs/qnx4/truncate.c b/fs/qnx4/truncate.c index 10c312583c12..88d9e181565a 100644 --- a/fs/qnx4/truncate.c +++ b/fs/qnx4/truncate.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #ifdef CONFIG_QNX4FS_RW @@ -26,12 +27,14 @@ void qnx4_truncate(struct inode *inode) S_ISLNK(inode->i_mode))) { return; } + lock_kernel(); if (!(S_ISDIR(inode->i_mode))) { /* TODO */ } QNX4DEBUG(("qnx4: qnx4_truncate called\n")); inode->i_mtime = inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); + unlock_kernel(); } #endif diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 91e51da6b48b..cc9c874bd964 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -66,7 +66,9 @@ static int reiserfs_file_release (struct inode * inode, struct file * filp) } static void reiserfs_vfs_truncate_file(struct inode *inode) { + lock_kernel(); reiserfs_truncate_file(inode, 1) ; + unlock_kernel(); } /* Sync a reiserfs file. */ diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 58dfd6ac5862..3c367212ce60 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -260,9 +260,9 @@ int sysv_sync_inode(struct inode * inode) static void sysv_delete_inode(struct inode *inode) { - lock_kernel(); inode->i_size = 0; sysv_truncate(inode); + lock_kernel(); sysv_free_inode(inode); unlock_kernel(); } diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c index 4ff94df7a3a2..f86495440b42 100644 --- a/fs/sysv/itree.c +++ b/fs/sysv/itree.c @@ -371,6 +371,8 @@ void sysv_truncate (struct inode * inode) if (n == 0) return; + lock_kernel(); + if (n == 1) { free_data(inode, i_data+offsets[0], i_data + DIRECT); goto do_indirects; @@ -409,6 +411,7 @@ do_indirects: sysv_sync_inode (inode); else mark_inode_dirty(inode); + unlock_kernel(); } static int sysv_writepage(struct page *page) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 2f573745139d..64ee8ff91cfe 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -108,20 +108,19 @@ void udf_put_inode(struct inode * inode) */ void udf_delete_inode(struct inode * inode) { - lock_kernel(); - if (is_bad_inode(inode)) goto no_delete; inode->i_size = 0; udf_truncate(inode); + lock_kernel(); + udf_update_inode(inode, IS_SYNC(inode)); udf_free_inode(inode); unlock_kernel(); return; no_delete: - unlock_kernel(); clear_inode(inode); } @@ -858,6 +857,7 @@ void udf_truncate(struct inode * inode) if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; + lock_kernel(); if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) { if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + @@ -867,6 +867,7 @@ void udf_truncate(struct inode * inode) if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) { inode->i_size = UDF_I_LENALLOC(inode); + unlock_kernel(); return; } else @@ -899,6 +900,7 @@ void udf_truncate(struct inode * inode) udf_sync_inode (inode); else mark_inode_dirty(inode); + unlock_kernel(); } /* diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 2cec5fedfd71..a2b6ed7a016c 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "swab.h" #include "util.h" @@ -439,6 +440,7 @@ void ufs_truncate (struct inode * inode) return; if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; + lock_kernel(); while (1) { retry = ufs_trunc_direct(inode); retry |= ufs_trunc_indirect (inode, UFS_IND_BLOCK, @@ -464,6 +466,7 @@ void ufs_truncate (struct inode * inode) } inode->i_mtime = inode->i_ctime = CURRENT_TIME; ufsi->i_lastfrag = DIRECT_FRAGMENT; + unlock_kernel(); mark_inode_dirty(inode); UFSD(("EXIT\n")) } diff --git a/mm/memory.c b/mm/memory.c index e20f9d6e8899..4a2c29ee7744 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1048,11 +1048,8 @@ do_expand: inode->i_size = offset; out_truncate: - if (inode->i_op && inode->i_op->truncate) { - lock_kernel(); + if (inode->i_op && inode->i_op->truncate) inode->i_op->truncate(inode); - unlock_kernel(); - } out: return 0; } diff --git a/mm/shmem.c b/mm/shmem.c index 6c62058769e2..d4ca70bb0d79 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -311,6 +311,7 @@ shmem_truncate_indirect(struct shmem_inode_info *info, unsigned long index) return shmem_truncate_direct(base, start, len); } +/* SMP-safe */ static void shmem_truncate (struct inode * inode) { unsigned long index; -- 2.39.5