/* * lowlevel.c * * PURPOSE * Low Level Device Routines for the UDF filesystem * * COPYRIGHT * This file is distributed under the terms of the GNU General Public * License (GPL). Copies of the GPL can be obtained from: * ftp://prep.ai.mit.edu/pub/gnu/GPL * Each contributing author retains all rights to their own work. * * (C) 1999-2001 Ben Fennema * * HISTORY * * 03/26/99 blf Created. */ #include "udfdecl.h" #include #include #include #include "udf_sb.h" unsigned int udf_get_last_session(struct super_block *sb) { struct cdrom_multisession ms_info; unsigned int vol_desc_start; struct block_device *bdev = sb->s_bdev; int i; vol_desc_start = 0; ms_info.addr_format = CDROM_LBA; i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long)&ms_info); if (i == 0) { udf_debug("XA disk: %s, vol_desc_start=%d\n", ms_info.xa_flag ? "yes" : "no", ms_info.addr.lba); if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */ vol_desc_start = ms_info.addr.lba; } else { udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i); } return vol_desc_start; } unsigned long udf_get_last_block(struct super_block *sb) { struct block_device *bdev = sb->s_bdev; unsigned long lblock = 0; /* * ioctl failed or returned obviously bogus value? * Try using the device size... */ if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock) || lblock == 0) lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits; if (lblock) return lblock - 1; else return 0; } f30ac43242ead1ab3061e1f59'>refslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>2016-04-25 15:13:17 -0300
committerDavid S. Miller <davem@davemloft.net>2016-04-28 15:53:17 -0400
commit7b7483409f09c15f30ac43242ead1ab3061e1f59 (patch)
tree8f57c8a87aff3b662bb8146b0f5bf0f56fe5f177
parent62522ef3c399996f6c8120bfd14b94280bc9f490 (diff)
net: fix net_gso_ok for new GSO types.
Fix casting in net_gso_ok. Otherwise the shift on gso_type << NETIF_F_GSO_SHIFT may hit the 32th bit and make it look like a INT_MIN, which is then promoted from signed to uint64 which is 0xffffffff80000000, resulting in wrong behavior when it is and'ed with the feature itself, as in: This test app: #include <stdio.h> #include <stdint.h> int main(int argc, char **argv) { uint64_t feature1; uint64_t feature2; int gso_type = 1 << 15; feature1 = gso_type << 16; feature2 = (uint64_t)gso_type << 16; printf("%lx %lx\n", feature1, feature2); return 0; } Gives: ffffffff80000000 80000000 So that this: return (features & feature) == feature; Actually works on more bits than expected and invalid ones. Fix is to promote it earlier. Issue noted while rebasing SCTP GSO patch but posting separetely as someone else may experience this meanwhile. Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>