diff options
author | Greg Kroah-Hartman <gregkh@google.com> | 2020-05-02 17:33:50 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@google.com> | 2020-05-02 17:33:50 +0200 |
commit | 5ddb3649549ffdf4b9bcc3619636fb32359452e8 (patch) | |
tree | 3e5981c03e66ecd87df5e931256f07719143e2ee /fs/ext4 | |
parent | d590d674fcce6ad896772d0b940664ddc39d60cb (diff) | |
parent | 54b0e1aed69edd904ba7e2e6516d37750c29beec (diff) |
Merge 4.4.221 into android-4.4-p
Changes in 4.4.221
ext4: fix extent_status fragmentation for plain files
ALSA: hda - Fix incorrect usage of IS_REACHABLE()
net: ipv4: emulate READ_ONCE() on ->hdrincl bit-field in raw_sendmsg()
net: ipv4: avoid unused variable warning for sysctl
crypto: mxs-dcp - make symbols 'sha1_null_hash' and 'sha256_null_hash' static
vti4: removed duplicate log message.
scsi: lpfc: Fix kasan slab-out-of-bounds error in lpfc_unreg_login
ceph: return ceph_mdsc_do_request() errors from __get_parent()
ceph: don't skip updating wanted caps when cap is stale
pwm: rcar: Fix late Runtime PM enablement
scsi: iscsi: Report unbind session event when the target has been removed
ASoC: Intel: atom: Take the drv->lock mutex before calling sst_send_slot_map()
kernel/gcov/fs.c: gcov_seq_next() should increase position index
ipc/util.c: sysvipc_find_ipc() should increase position index
s390/cio: avoid duplicated 'ADD' uevents
pwm: renesas-tpu: Fix late Runtime PM enablement
pwm: bcm2835: Dynamically allocate base
ipv6: fix restrict IPV6_ADDRFORM operation
macvlan: fix null dereference in macvlan_device_event()
net: netrom: Fix potential nr_neigh refcnt leak in nr_add_node
net/x25: Fix x25_neigh refcnt leak when receiving frame
tcp: cache line align MAX_TCP_HEADER
team: fix hang in team_mode_get()
xfrm: Always set XFRM_TRANSFORMED in xfrm{4,6}_output_finish
ALSA: hda: Remove ASUS ROG Zenith from the blacklist
iio: xilinx-xadc: Fix ADC-B powerdown
iio: xilinx-xadc: Fix clearing interrupt when enabling trigger
iio: xilinx-xadc: Fix sequencer configuration for aux channels in simultaneous mode
fs/namespace.c: fix mountpoint reference counter race
USB: sisusbvga: Change port variable from signed to unsigned
USB: Add USB_QUIRK_DELAY_CTRL_MSG and USB_QUIRK_DELAY_INIT for Corsair K70 RGB RAPIDFIRE
drivers: usb: core: Don't disable irqs in usb_sg_wait() during URB submit.
drivers: usb: core: Minimize irq disabling in usb_sg_cancel()
USB: core: Fix free-while-in-use bug in the USB S-Glibrary
USB: hub: Fix handling of connect changes during sleep
ALSA: usx2y: Fix potential NULL dereference
ALSA: usb-audio: Fix usb audio refcnt leak when getting spdif
ALSA: usb-audio: Filter out unsupported sample rates on Focusrite devices
KVM: Check validity of resolved slot when searching memslots
KVM: VMX: Enable machine check support for 32bit targets
tty: hvc: fix buffer overflow during hvc_alloc().
tty: rocket, avoid OOB access
usb-storage: Add unusual_devs entry for JMicron JMS566
audit: check the length of userspace generated audit records
ASoC: dapm: fixup dapm kcontrol widget
ARM: imx: provide v7_cpu_resume() only on ARM_CPU_SUSPEND=y
staging: comedi: dt2815: fix writing hi byte of analog output
staging: comedi: Fix comedi_device refcnt leak in comedi_open
staging: vt6656: Fix drivers TBTT timing counter.
staging: vt6656: Power save stop wake_up_count wrap around.
UAS: no use logging any details in case of ENODEV
UAS: fix deadlock in error handling and PM flushing work
usb: f_fs: Clear OS Extended descriptor counts to zero in ffs_data_reset()
remoteproc: Fix wrong rvring index computation
sctp: use right member as the param of list_for_each_entry
fuse: fix possibly missed wake-up after abort
mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer
usb: gadget: udc: bdc: Remove unnecessary NULL checks in bdc_req_complete
net/cxgb4: Check the return from t4_query_params properly
perf/core: fix parent pid/tid in task exit events
bpf, x86: Fix encoding for lower 8-bit registers in BPF_STX BPF_B
scsi: target: fix PR IN / READ FULL STATUS for FC
xen/xenbus: ensure xenbus_map_ring_valloc() returns proper grant status
ext4: convert BUG_ON's to WARN_ON's in mballoc.c
ext4: avoid declaring fs inconsistent due to invalid file handles
ext4: protect journal inode's blocks using block_validity
ext4: don't perform block validity checks on the journal inode
ext4: fix block validity checks for journal inodes using indirect blocks
ext4: unsigned int compared against zero
propagate_one(): mnt_set_mountpoint() needs mount_lock
Linux 4.4.221
Change-Id: I95cadd4206a7c89541de002faacea3a28e7b1ac3
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/block_validity.c | 54 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 15 | ||||
-rw-r--r-- | fs/ext4/extents.c | 59 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 2 | ||||
-rw-r--r-- | fs/ext4/inode.c | 48 | ||||
-rw-r--r-- | fs/ext4/ioctl.c | 2 | ||||
-rw-r--r-- | fs/ext4/mballoc.c | 6 | ||||
-rw-r--r-- | fs/ext4/namei.c | 4 | ||||
-rw-r--r-- | fs/ext4/resize.c | 5 | ||||
-rw-r--r-- | fs/ext4/super.c | 28 |
10 files changed, 158 insertions, 65 deletions
diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c index 02ddec6d8a7d..ccd80f2b3b19 100644 --- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c @@ -136,6 +136,49 @@ static void debug_print_tree(struct ext4_sb_info *sbi) printk("\n"); } +static int ext4_protect_reserved_inode(struct super_block *sb, u32 ino) +{ + struct inode *inode; + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct ext4_map_blocks map; + u32 i = 0, num; + int err = 0, n; + + if ((ino < EXT4_ROOT_INO) || + (ino > le32_to_cpu(sbi->s_es->s_inodes_count))) + return -EINVAL; + inode = ext4_iget(sb, ino, EXT4_IGET_SPECIAL); + if (IS_ERR(inode)) + return PTR_ERR(inode); + num = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; + while (i < num) { + map.m_lblk = i; + map.m_len = num - i; + n = ext4_map_blocks(NULL, inode, &map, 0); + if (n < 0) { + err = n; + break; + } + if (n == 0) { + i++; + } else { + if (!ext4_data_block_valid(sbi, map.m_pblk, n)) { + ext4_error(sb, "blocks %llu-%llu from inode %u " + "overlap system zone", map.m_pblk, + map.m_pblk + map.m_len - 1, ino); + err = -EFSCORRUPTED; + break; + } + err = add_system_zone(sbi, map.m_pblk, n); + if (err < 0) + break; + i += n; + } + } + iput(inode); + return err; +} + int ext4_setup_system_zone(struct super_block *sb) { ext4_group_t ngroups = ext4_get_groups_count(sb); @@ -170,6 +213,12 @@ int ext4_setup_system_zone(struct super_block *sb) if (ret) return ret; } + if (ext4_has_feature_journal(sb) && sbi->s_es->s_journal_inum) { + ret = ext4_protect_reserved_inode(sb, + le32_to_cpu(sbi->s_es->s_journal_inum)); + if (ret) + return ret; + } if (test_opt(sb, DEBUG)) debug_print_tree(EXT4_SB(sb)); @@ -226,6 +275,11 @@ int ext4_check_blockref(const char *function, unsigned int line, __le32 *bref = p; unsigned int blk; + if (ext4_has_feature_journal(inode->i_sb) && + (inode->i_ino == + le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) + return 0; + while (bref < p+max) { blk = le32_to_cpu(*bref++); if (blk && diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 1157a3587d71..c53c851e2b68 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2500,8 +2500,19 @@ int do_journal_get_write_access(handle_t *handle, #define FALL_BACK_TO_NONDELALLOC 1 #define CONVERT_INLINE_DATA 2 -extern struct inode *ext4_iget(struct super_block *, unsigned long); -extern struct inode *ext4_iget_normal(struct super_block *, unsigned long); +typedef enum { + EXT4_IGET_NORMAL = 0, + EXT4_IGET_SPECIAL = 0x0001, /* OK to iget a system inode */ + EXT4_IGET_HANDLE = 0x0002 /* Inode # is from a handle */ +} ext4_iget_flags; + +extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, + ext4_iget_flags flags, const char *function, + unsigned int line); + +#define ext4_iget(sb, ino, flags) \ + __ext4_iget((sb), (ino), (flags), __func__, __LINE__) + extern int ext4_write_inode(struct inode *, struct writeback_control *); extern int ext4_setattr(struct dentry *, struct iattr *); extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 7414bfd5a58e..96336830f035 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -505,6 +505,30 @@ int ext4_ext_check_inode(struct inode *inode) return ext4_ext_check(inode, ext_inode_hdr(inode), ext_depth(inode), 0); } +static void ext4_cache_extents(struct inode *inode, + struct ext4_extent_header *eh) +{ + struct ext4_extent *ex = EXT_FIRST_EXTENT(eh); + ext4_lblk_t prev = 0; + int i; + + for (i = le16_to_cpu(eh->eh_entries); i > 0; i--, ex++) { + unsigned int status = EXTENT_STATUS_WRITTEN; + ext4_lblk_t lblk = le32_to_cpu(ex->ee_block); + int len = ext4_ext_get_actual_len(ex); + + if (prev && (prev != lblk)) + ext4_es_cache_extent(inode, prev, lblk - prev, ~0, + EXTENT_STATUS_HOLE); + + if (ext4_ext_is_unwritten(ex)) + status = EXTENT_STATUS_UNWRITTEN; + ext4_es_cache_extent(inode, lblk, len, + ext4_ext_pblock(ex), status); + prev = lblk + len; + } +} + static struct buffer_head * __read_extent_tree_block(const char *function, unsigned int line, struct inode *inode, ext4_fsblk_t pblk, int depth, @@ -525,36 +549,21 @@ __read_extent_tree_block(const char *function, unsigned int line, } if (buffer_verified(bh) && !(flags & EXT4_EX_FORCE_CACHE)) return bh; - err = __ext4_ext_check(function, line, inode, - ext_block_hdr(bh), depth, pblk); - if (err) - goto errout; + if (!ext4_has_feature_journal(inode->i_sb) || + (inode->i_ino != + le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) { + err = __ext4_ext_check(function, line, inode, + ext_block_hdr(bh), depth, pblk); + if (err) + goto errout; + } set_buffer_verified(bh); /* * If this is a leaf block, cache all of its entries */ if (!(flags & EXT4_EX_NOCACHE) && depth == 0) { struct ext4_extent_header *eh = ext_block_hdr(bh); - struct ext4_extent *ex = EXT_FIRST_EXTENT(eh); - ext4_lblk_t prev = 0; - int i; - - for (i = le16_to_cpu(eh->eh_entries); i > 0; i--, ex++) { - unsigned int status = EXTENT_STATUS_WRITTEN; - ext4_lblk_t lblk = le32_to_cpu(ex->ee_block); - int len = ext4_ext_get_actual_len(ex); - - if (prev && (prev != lblk)) - ext4_es_cache_extent(inode, prev, - lblk - prev, ~0, - EXTENT_STATUS_HOLE); - - if (ext4_ext_is_unwritten(ex)) - status = EXTENT_STATUS_UNWRITTEN; - ext4_es_cache_extent(inode, lblk, len, - ext4_ext_pblock(ex), status); - prev = lblk + len; - } + ext4_cache_extents(inode, eh); } return bh; errout: @@ -902,6 +911,8 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block, path[0].p_bh = NULL; i = depth; + if (!(flags & EXT4_EX_NOCACHE) && depth == 0) + ext4_cache_extents(inode, eh); /* walk through the tree */ while (i) { ext_debug("depth %d: num %d, max %d\n", diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index c31b05f0bd69..3753a8a05a2e 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -1150,7 +1150,7 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino) if (!ext4_test_bit(bit, bitmap_bh->b_data)) goto bad_orphan; - inode = ext4_iget(sb, ino); + inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); if (IS_ERR(inode)) { err = PTR_ERR(inode); ext4_error(sb, "couldn't read orphan inode %lu (err %d)", diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 763e150246ad..e5708f6c985b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -378,6 +378,10 @@ static int __check_block_validity(struct inode *inode, const char *func, unsigned int line, struct ext4_map_blocks *map) { + if (ext4_has_feature_journal(inode->i_sb) && + (inode->i_ino == + le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) + return 0; if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), map->m_pblk, map->m_len)) { ext4_error_inode(inode, func, line, map->m_pblk, @@ -4271,7 +4275,9 @@ static inline void ext4_iget_extra_inode(struct inode *inode, EXT4_I(inode)->i_inline_off = 0; } -struct inode *ext4_iget(struct super_block *sb, unsigned long ino) +struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, + ext4_iget_flags flags, const char *function, + unsigned int line) { struct ext4_iloc iloc; struct ext4_inode *raw_inode; @@ -4284,6 +4290,18 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) uid_t i_uid; gid_t i_gid; + if (((flags & EXT4_IGET_NORMAL) && + (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) || + (ino < EXT4_ROOT_INO) || + (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) { + if (flags & EXT4_IGET_HANDLE) + return ERR_PTR(-ESTALE); + __ext4_error(sb, function, line, + "inode #%lu: comm %s: iget: illegal inode #", + ino, current->comm); + return ERR_PTR(-EFSCORRUPTED); + } + inode = iget_locked(sb, ino); if (!inode) return ERR_PTR(-ENOMEM); @@ -4299,11 +4317,18 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) raw_inode = ext4_raw_inode(&iloc); if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) { - EXT4_ERROR_INODE(inode, "root inode unallocated"); + ext4_error_inode(inode, function, line, 0, + "iget: root inode unallocated"); ret = -EFSCORRUPTED; goto bad_inode; } + if ((flags & EXT4_IGET_HANDLE) && + (raw_inode->i_links_count == 0) && (raw_inode->i_mode == 0)) { + ret = -ESTALE; + goto bad_inode; + } + if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > @@ -4330,7 +4355,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) } if (!ext4_inode_csum_verify(inode, raw_inode, ei)) { - EXT4_ERROR_INODE(inode, "checksum invalid"); + ext4_error_inode(inode, function, line, 0, + "iget: checksum invalid"); ret = -EFSBADCRC; goto bad_inode; } @@ -4378,7 +4404,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; inode->i_size = ext4_isize(raw_inode); if ((size = i_size_read(inode)) < 0) { - EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size); + ext4_error_inode(inode, function, line, 0, + "iget: bad i_size value: %lld", size); ret = -EFSCORRUPTED; goto bad_inode; } @@ -4461,7 +4488,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) ret = 0; if (ei->i_file_acl && !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) { - EXT4_ERROR_INODE(inode, "bad extended attribute block %llu", + ext4_error_inode(inode, function, line, 0, + "iget: bad extended attribute block %llu", ei->i_file_acl); ret = -EFSCORRUPTED; goto bad_inode; @@ -4516,7 +4544,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) make_bad_inode(inode); } else { ret = -EFSCORRUPTED; - EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode); + ext4_error_inode(inode, function, line, 0, + "iget: bogus i_mode (%o)", inode->i_mode); goto bad_inode; } brelse(iloc.bh); @@ -4530,13 +4559,6 @@ bad_inode: return ERR_PTR(ret); } -struct inode *ext4_iget_normal(struct super_block *sb, unsigned long ino) -{ - if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) - return ERR_PTR(-EFSCORRUPTED); - return ext4_iget(sb, ino); -} - static int ext4_inode_blocks_set(handle_t *handle, struct ext4_inode *raw_inode, struct ext4_inode_info *ei) diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 06ca0e647a97..aca311a57abd 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -105,7 +105,7 @@ static long swap_inode_boot_loader(struct super_block *sb, if (!inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) return -EPERM; - inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO); + inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL); if (IS_ERR(inode_bl)) return PTR_ERR(inode_bl); ei_bl = EXT4_I(inode_bl); diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 377641b91ee4..c80223bde667 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -1944,7 +1944,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, int free; free = e4b->bd_info->bb_free; - BUG_ON(free <= 0); + if (WARN_ON(free <= 0)) + return; i = e4b->bd_info->bb_first_free; @@ -1965,7 +1966,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, } mb_find_extent(e4b, i, ac->ac_g_ex.fe_len, &ex); - BUG_ON(ex.fe_len <= 0); + if (WARN_ON(ex.fe_len <= 0)) + break; if (free < ex.fe_len) { ext4_grp_locked_error(sb, e4b->bd_group, 0, 0, "%d free clusters as per " diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 49e0d97b2ee7..566a8b08ccdd 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1601,7 +1601,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi dentry); return ERR_PTR(-EFSCORRUPTED); } - inode = ext4_iget_normal(dir->i_sb, ino); + inode = ext4_iget(dir->i_sb, ino, EXT4_IGET_NORMAL); if (inode == ERR_PTR(-ESTALE)) { EXT4_ERROR_INODE(dir, "deleted inode referenced: %u", @@ -1646,7 +1646,7 @@ struct dentry *ext4_get_parent(struct dentry *child) return ERR_PTR(-EFSCORRUPTED); } - return d_obtain_alias(ext4_iget_normal(d_inode(child)->i_sb, ino)); + return d_obtain_alias(ext4_iget(d_inode(child)->i_sb, ino, EXT4_IGET_NORMAL)); } /* diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index f5b6667b0ab0..7ed01bcc2419 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -1649,7 +1649,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) "No reserved GDT blocks, can't resize"); return -EPERM; } - inode = ext4_iget(sb, EXT4_RESIZE_INO); + inode = ext4_iget(sb, EXT4_RESIZE_INO, EXT4_IGET_SPECIAL); if (IS_ERR(inode)) { ext4_warning(sb, "Error opening resize inode"); return PTR_ERR(inode); @@ -1977,7 +1977,8 @@ retry: } if (!resize_inode) - resize_inode = ext4_iget(sb, EXT4_RESIZE_INO); + resize_inode = ext4_iget(sb, EXT4_RESIZE_INO, + EXT4_IGET_SPECIAL); if (IS_ERR(resize_inode)) { ext4_warning(sb, "Error opening resize inode"); return PTR_ERR(resize_inode); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8dd1a305ed0e..066503e0c933 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1021,20 +1021,11 @@ static struct inode *ext4_nfs_get_inode(struct super_block *sb, { struct inode *inode; - if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) - return ERR_PTR(-ESTALE); - if (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)) - return ERR_PTR(-ESTALE); - - /* iget isn't really right if the inode is currently unallocated!! - * - * ext4_read_inode will return a bad_inode if the inode had been - * deleted, so we should be safe. - * + /* * Currently we don't know the generation for parent directory, so * a generation of 0 means "accept any" */ - inode = ext4_iget_normal(sb, ino); + inode = ext4_iget(sb, ino, EXT4_IGET_HANDLE); if (IS_ERR(inode)) return ERR_CAST(inode); if (generation && inode->i_generation != generation) { @@ -4035,7 +4026,7 @@ no_journal: * so we can safely mount the rest of the filesystem now. */ - root = ext4_iget(sb, EXT4_ROOT_INO); + root = ext4_iget(sb, EXT4_ROOT_INO, EXT4_IGET_SPECIAL); if (IS_ERR(root)) { ext4_msg(sb, KERN_ERR, "get root inode failed"); ret = PTR_ERR(root); @@ -4276,11 +4267,12 @@ static journal_t *ext4_get_journal(struct super_block *sb, BUG_ON(!ext4_has_feature_journal(sb)); - /* First, test for the existence of a valid inode on disk. Bad - * things happen if we iget() an unused inode, as the subsequent - * iput() will try to delete it. */ - - journal_inode = ext4_iget(sb, journal_inum); + /* + * Test for the existence of a valid inode on disk. Bad things + * happen if we iget() an unused inode, as the subsequent iput() + * will try to delete it. + */ + journal_inode = ext4_iget(sb, journal_inum, EXT4_IGET_SPECIAL); if (IS_ERR(journal_inode)) { ext4_msg(sb, KERN_ERR, "no journal found"); return NULL; @@ -5244,7 +5236,7 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id, if (!qf_inums[type]) return -EPERM; - qf_inode = ext4_iget(sb, qf_inums[type]); + qf_inode = ext4_iget(sb, qf_inums[type], EXT4_IGET_SPECIAL); if (IS_ERR(qf_inode)) { ext4_error(sb, "Bad quota inode # %lu", qf_inums[type]); return PTR_ERR(qf_inode); |