</chapter>
<chapter id="ataExceptions">
- <title>ATA errors & exceptions</title>
+ <title>ATA errors and exceptions</title>
<para>
This chapter tries to identify what error/exception conditions exist
ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
+ /* collect port action mask recorded in dev actions */
+ ehc->i.action |= ehc->i.dev_action[i] & ~ATA_EH_PERDEV_MASK;
+ ehc->i.dev_action[i] &= ATA_EH_PERDEV_MASK;
+
/* process hotplug request */
if (dev->flags & ATA_DFLAG_DETACH)
ata_eh_detach_dev(dev);
},
{ /* chip_7042 */
.sht = &mv_sht,
- .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
- MV_FLAG_DUAL_HC),
+ .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv_iie_ops,
{ PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x },
+ { PCI_VDEVICE(TTI, 0x2310), chip_7042 },
+
{ } /* terminate list */
};
static void vt6420_error_handler(struct ata_port *ap);
static const struct pci_device_id svia_pci_tbl[] = {
+ { PCI_VDEVICE(VIA, 0x5337), vt6420 },
{ PCI_VDEVICE(VIA, 0x0591), vt6420 },
{ PCI_VDEVICE(VIA, 0x3149), vt6420 },
{ PCI_VDEVICE(VIA, 0x3249), vt6421 },
struct cp_private *cp = netdev_priv(dev);
unsigned entry;
u32 eor, flags;
+ unsigned long intr_flags;
#if CP_VLAN_TAG_USED
u32 vlan_tag = 0;
#endif
int mss = 0;
- spin_lock_irq(&cp->lock);
+ spin_lock_irqsave(&cp->lock, intr_flags);
/* This is a hard error, log it. */
if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
netif_stop_queue(dev);
- spin_unlock_irq(&cp->lock);
+ spin_unlock_irqrestore(&cp->lock, intr_flags);
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name);
return 1;
if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
netif_stop_queue(dev);
- spin_unlock_irq(&cp->lock);
+ spin_unlock_irqrestore(&cp->lock, intr_flags);
cpw8(TxPoll, NormalTxPoll);
dev->trans_start = jiffies;
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.1.0"
+#define MYRI10GE_VERSION_STR "1.2.0"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n");
+static int myri10ge_wcfifo = 1;
+module_param(myri10ge_wcfifo, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
+
#define MYRI10GE_FW_OFFSET 1024*1024
#define MYRI10GE_HIGHPART_TO_U32(X) \
(sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0)
goto abort_with_irq;
}
- if (mgp->mtrr >= 0) {
+ if (myri10ge_wcfifo && mgp->mtrr >= 0) {
mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4;
mgp->rx_small.wc_fifo =
(u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL;
netdev->hard_start_xmit = myri10ge_xmit;
netdev->get_stats = myri10ge_get_stats;
netdev->base_addr = mgp->iomem_base;
- netdev->irq = pdev->irq;
netdev->change_mtu = myri10ge_change_mtu;
netdev->set_multicast_list = myri10ge_set_multicast_list;
netdev->set_mac_address = myri10ge_set_mac_address;
netdev->poll = myri10ge_poll;
netdev->weight = myri10ge_napi_weight;
+ /* make sure we can get an irq, and that MSI can be
+ * setup (if available). Also ensure netdev->irq
+ * is set to correct value if MSI is enabled */
+ status = myri10ge_request_irq(mgp);
+ if (status != 0)
+ goto abort_with_firmware;
+ netdev->irq = pdev->irq;
+ myri10ge_free_irq(mgp);
+
/* Save configuration space to be restored if the
* nic resets due to a parity error */
pci_save_state(pdev);
dev_err(&pdev->dev, "register_netdev failed: %d\n", status);
goto abort_with_state;
}
- dev_info(dev, "%d, tx bndry %d, fw %s, WC %s\n",
- pdev->irq, mgp->tx.boundary, mgp->fw_name,
+ dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
+ (mgp->msi_enabled ? "MSI" : "xPIC"),
+ netdev->irq, mgp->tx.boundary, mgp->fw_name,
(mgp->mtrr >= 0 ? "Enabled" : "Disabled"));
return 0;
for (i = 0; i < MAC_ADDR_LEN / 2; i++) {
__le16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i);
- ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w);
+ ((u16 *)dev->dev_addr)[i] = le16_to_cpu(w);
}
sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo));
#include <linux/fsl_devices.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
+#include <linux/workqueue.h>
#include <asm/of_platform.h>
#include <asm/uaccess.h>
kfree(enet_addr_cont);
}
-static int set_mac_addr(__be16 __iomem *reg, u8 *mac)
+static void set_mac_addr(__be16 __iomem *reg, u8 *mac)
{
out_be16(®[0], ((u16)mac[5] << 8) | mac[4]);
out_be16(®[1], ((u16)mac[3] << 8) | mac[2]);
}
/* Scheduled by the phy_interrupt/timer to handle PHY changes */
-static void ugeth_phy_change(void *data)
+static void ugeth_phy_change(struct work_struct *work)
{
- struct net_device *dev = (struct net_device *)data;
- struct ucc_geth_private *ugeth = netdev_priv(dev);
+ struct ucc_geth_private *ugeth =
+ container_of(work, struct ucc_geth_private, tq);
+ struct net_device *dev = ugeth->dev;
struct ucc_geth *ug_regs;
int result = 0;
#endif /* CONFIG_UGETH_NAPI */
/* Set up the PHY change work queue */
- INIT_WORK(&ugeth->tq, ugeth_phy_change, dev);
+ INIT_WORK(&ugeth->tq, ugeth_phy_change);
init_timer(&ugeth->phy_info_timer);
ugeth->phy_info_timer.function = &ugeth_phy_startup_timer;
static int genmii_config_aneg(struct ugeth_mii_info *mii_info);
static int genmii_update_link(struct ugeth_mii_info *mii_info);
static int genmii_read_status(struct ugeth_mii_info *mii_info);
-u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum);
-void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val);
+
+static u16 ucc_geth_phy_read(struct ugeth_mii_info *mii_info, u16 regnum)
+{
+ u16 retval;
+ unsigned long flags;
+
+ ugphy_vdbg("%s: IN", __FUNCTION__);
+
+ spin_lock_irqsave(&mii_info->mdio_lock, flags);
+ retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum);
+ spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
+
+ return retval;
+}
+
+static void ucc_geth_phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val)
+{
+ unsigned long flags;
+
+ ugphy_vdbg("%s: IN", __FUNCTION__);
+
+ spin_lock_irqsave(&mii_info->mdio_lock, flags);
+ mii_info->mdio_write(mii_info->dev, mii_info->mii_id, regnum, val);
+ spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
+}
/* Write value to the PHY for this device to the register at regnum, */
/* waiting until the write is done before it returns. All PHY */
advertise = mii_info->advertising;
/* Setup standard advertisement */
- adv = phy_read(mii_info, MII_ADVERTISE);
+ adv = ucc_geth_phy_read(mii_info, MII_ADVERTISE);
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
if (advertise & ADVERTISED_10baseT_Half)
adv |= ADVERTISE_10HALF;
adv |= ADVERTISE_100HALF;
if (advertise & ADVERTISED_100baseT_Full)
adv |= ADVERTISE_100FULL;
- phy_write(mii_info, MII_ADVERTISE, adv);
+ ucc_geth_phy_write(mii_info, MII_ADVERTISE, adv);
}
static void genmii_setup_forced(struct ugeth_mii_info *mii_info)
ugphy_vdbg("%s: IN", __FUNCTION__);
- ctrl = phy_read(mii_info, MII_BMCR);
+ ctrl = ucc_geth_phy_read(mii_info, MII_BMCR);
ctrl &=
~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
break;
}
- phy_write(mii_info, MII_BMCR, ctrl);
+ ucc_geth_phy_write(mii_info, MII_BMCR, ctrl);
}
/* Enable and Restart Autonegotiation */
ugphy_vdbg("%s: IN", __FUNCTION__);
- ctl = phy_read(mii_info, MII_BMCR);
+ ctl = ucc_geth_phy_read(mii_info, MII_BMCR);
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
- phy_write(mii_info, MII_BMCR, ctl);
+ ucc_geth_phy_write(mii_info, MII_BMCR, ctl);
}
static int gbit_config_aneg(struct ugeth_mii_info *mii_info)
config_genmii_advert(mii_info);
advertise = mii_info->advertising;
- adv = phy_read(mii_info, MII_1000BASETCONTROL);
+ adv = ucc_geth_phy_read(mii_info, MII_1000BASETCONTROL);
adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
MII_1000BASETCONTROL_HALFDUPLEXCAP);
if (advertise & SUPPORTED_1000baseT_Half)
adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
if (advertise & SUPPORTED_1000baseT_Full)
adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
- phy_write(mii_info, MII_1000BASETCONTROL, adv);
+ ucc_geth_phy_write(mii_info, MII_1000BASETCONTROL, adv);
/* Start/Restart aneg */
genmii_restart_aneg(mii_info);
ugphy_vdbg("%s: IN", __FUNCTION__);
/* Do a fake read */
- phy_read(mii_info, MII_BMSR);
+ ucc_geth_phy_read(mii_info, MII_BMSR);
/* Read link and autonegotiation status */
- status = phy_read(mii_info, MII_BMSR);
+ status = ucc_geth_phy_read(mii_info, MII_BMSR);
if ((status & BMSR_LSTATUS) == 0)
mii_info->link = 0;
else
return err;
if (mii_info->autoneg) {
- status = phy_read(mii_info, MII_LPA);
+ status = ucc_geth_phy_read(mii_info, MII_LPA);
if (status & (LPA_10FULL | LPA_100FULL))
mii_info->duplex = DUPLEX_FULL;
{
ugphy_vdbg("%s: IN", __FUNCTION__);
- phy_write(mii_info, 0x14, 0x0cd2);
- phy_write(mii_info, MII_BMCR,
- phy_read(mii_info, MII_BMCR) | BMCR_RESET);
+ ucc_geth_phy_write(mii_info, 0x14, 0x0cd2);
+ ucc_geth_phy_write(mii_info, MII_BMCR,
+ ucc_geth_phy_read(mii_info, MII_BMCR) | BMCR_RESET);
msleep(4000);
return 0;
/* The Marvell PHY has an errata which requires
* that certain registers get written in order
* to restart autonegotiation */
- phy_write(mii_info, MII_BMCR, BMCR_RESET);
+ ucc_geth_phy_write(mii_info, MII_BMCR, BMCR_RESET);
- phy_write(mii_info, 0x1d, 0x1f);
- phy_write(mii_info, 0x1e, 0x200c);
- phy_write(mii_info, 0x1d, 0x5);
- phy_write(mii_info, 0x1e, 0);
- phy_write(mii_info, 0x1e, 0x100);
+ ucc_geth_phy_write(mii_info, 0x1d, 0x1f);
+ ucc_geth_phy_write(mii_info, 0x1e, 0x200c);
+ ucc_geth_phy_write(mii_info, 0x1d, 0x5);
+ ucc_geth_phy_write(mii_info, 0x1e, 0);
+ ucc_geth_phy_write(mii_info, 0x1e, 0x100);
gbit_config_aneg(mii_info);
* are as set */
if (mii_info->autoneg && mii_info->link) {
int speed;
- status = phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS);
+ status = ucc_geth_phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS);
/* Get the duplexity */
if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
ugphy_vdbg("%s: IN", __FUNCTION__);
/* Clear the interrupts by reading the reg */
- phy_read(mii_info, MII_M1011_IEVENT);
+ ucc_geth_phy_read(mii_info, MII_M1011_IEVENT);
return 0;
}
ugphy_vdbg("%s: IN", __FUNCTION__);
if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
- phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
+ ucc_geth_phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
else
- phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
+ ucc_geth_phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
return 0;
}
{
ugphy_vdbg("%s: IN", __FUNCTION__);
- phy_write(mii_info, MII_CIS8201_AUX_CONSTAT,
+ ucc_geth_phy_write(mii_info, MII_CIS8201_AUX_CONSTAT,
MII_CIS8201_AUXCONSTAT_INIT);
- phy_write(mii_info, MII_CIS8201_EXT_CON1, MII_CIS8201_EXTCON1_INIT);
+ ucc_geth_phy_write(mii_info, MII_CIS8201_EXT_CON1, MII_CIS8201_EXTCON1_INIT);
return 0;
}
if (mii_info->autoneg && mii_info->link) {
int speed;
- status = phy_read(mii_info, MII_CIS8201_AUX_CONSTAT);
+ status = ucc_geth_phy_read(mii_info, MII_CIS8201_AUX_CONSTAT);
if (status & MII_CIS8201_AUXCONSTAT_DUPLEX)
mii_info->duplex = DUPLEX_FULL;
else
{
ugphy_vdbg("%s: IN", __FUNCTION__);
- phy_read(mii_info, MII_CIS8201_ISTAT);
+ ucc_geth_phy_read(mii_info, MII_CIS8201_ISTAT);
return 0;
}
ugphy_vdbg("%s: IN", __FUNCTION__);
if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
- phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK);
+ ucc_geth_phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK);
else
- phy_write(mii_info, MII_CIS8201_IMASK, 0);
+ ucc_geth_phy_write(mii_info, MII_CIS8201_IMASK, 0);
return 0;
}
/* If we aren't autonegotiating, assume speeds
* are as set */
if (mii_info->autoneg && mii_info->link) {
- status = phy_read(mii_info, MII_DM9161_SCSR);
+ status = ucc_geth_phy_read(mii_info, MII_DM9161_SCSR);
if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H))
mii_info->speed = SPEED_100;
else
{
struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data;
struct dm9161_private *priv = mii_info->priv;
- u16 status = phy_read(mii_info, MII_BMSR);
+ u16 status = ucc_geth_phy_read(mii_info, MII_BMSR);
ugphy_vdbg("%s: IN", __FUNCTION__);
/* Reset is not done yet */
priv->resetdone = 0;
- phy_write(mii_info, MII_BMCR,
- phy_read(mii_info, MII_BMCR) | BMCR_RESET);
+ ucc_geth_phy_write(mii_info, MII_BMCR,
+ ucc_geth_phy_read(mii_info, MII_BMCR) | BMCR_RESET);
- phy_write(mii_info, MII_BMCR,
- phy_read(mii_info, MII_BMCR) & ~BMCR_ISOLATE);
+ ucc_geth_phy_write(mii_info, MII_BMCR,
+ ucc_geth_phy_read(mii_info, MII_BMCR) & ~BMCR_ISOLATE);
config_genmii_advert(mii_info);
/* Start/Restart aneg */
ugphy_vdbg("%s: IN", __FUNCTION__);
/* Clear the interrupts by reading the reg */
- phy_read(mii_info, MII_DM9161_INTR);
+ ucc_geth_phy_read(mii_info, MII_DM9161_INTR);
return 0;
ugphy_vdbg("%s: IN", __FUNCTION__);
if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
- phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT);
+ ucc_geth_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT);
else
- phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP);
+ ucc_geth_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP);
return 0;
}
NULL
};
-u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum)
-{
- u16 retval;
- unsigned long flags;
-
- ugphy_vdbg("%s: IN", __FUNCTION__);
-
- spin_lock_irqsave(&mii_info->mdio_lock, flags);
- retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum);
- spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
-
- return retval;
-}
-
-void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val)
-{
- unsigned long flags;
-
- ugphy_vdbg("%s: IN", __FUNCTION__);
-
- spin_lock_irqsave(&mii_info->mdio_lock, flags);
- mii_info->mdio_write(mii_info->dev, mii_info->mii_id, regnum, val);
- spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
-}
-
/* Use the PHY ID registers to determine what type of PHY is attached
* to device dev. return a struct phy_info structure describing that PHY
*/
ugphy_vdbg("%s: IN", __FUNCTION__);
/* Grab the bits from PHYIR1, and put them in the upper half */
- phy_reg = phy_read(mii_info, MII_PHYSID1);
+ phy_reg = ucc_geth_phy_read(mii_info, MII_PHYSID1);
phy_ID = (phy_reg & 0xffff) << 16;
/* Grab the bits from PHYIR2, and put them in the lower half */
- phy_reg = phy_read(mii_info, MII_PHYSID2);
+ phy_reg = ucc_geth_phy_read(mii_info, MII_PHYSID2);
phy_ID |= (phy_reg & 0xffff);
/* loop through all the known PHY types, and find one that */
sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
/* extract core_id, core_rev, core_vendor */
- core_id = (sb_id_hi & 0xFFF0) >> 4;
- core_rev = (sb_id_hi & 0xF);
+ core_id = (sb_id_hi & 0x8FF0) >> 4;
+ core_rev = ((sb_id_hi & 0xF) | ((sb_id_hi & 0x7000) >> 8));
core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x\n",
sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
- sbimconfiglow |= 0x32;
+ if (bcm->bustype == BCM43xx_BUSTYPE_PCI)
+ sbimconfiglow |= 0x32;
+ else
+ sbimconfiglow |= 0x53;
bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
}
if (err)
goto out;
- if (bcm->current_core->rev < 6 ||
+ if (bcm->current_core->rev < 6 &&
bcm->current_core->id == BCM43xx_COREID_PCI) {
value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
value |= (1 << backplane_flag_nr);
inode = ocfs2_iget(OCFS2_SB(sb), handle->ih_blkno, 0);
- if (IS_ERR(inode)) {
- mlog_errno(PTR_ERR(inode));
+ if (IS_ERR(inode))
return (void *)inode;
- }
if (handle->ih_generation != inode->i_generation) {
iput(inode);
- mlog_errno(-ESTALE);
return ERR_PTR(-ESTALE);
}
if (is_bad_inode(inode)) {
iput(inode);
inode = ERR_PTR(-ESTALE);
- mlog_errno(PTR_ERR(inode));
goto bail;
}
mlog(0, "returning inode with number %llu\n",
(unsigned long long)OCFS2_I(inode)->ip_blkno);
mlog_exit_ptr(inode);
- } else
- mlog_errno(PTR_ERR(inode));
+ }
return inode;
}
* today. change if needed. */
if (!OCFS2_IS_VALID_DINODE(fe) ||
!(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL))) {
- mlog(ML_ERROR, "Invalid dinode: i_ino=%lu, i_blkno=%llu, "
+ mlog(0, "Invalid dinode: i_ino=%lu, i_blkno=%llu, "
"signature = %.*s, flags = 0x%x\n",
inode->i_ino,
(unsigned long long)le64_to_cpu(fe->i_blkno), 7,
S_ISBLK(le16_to_cpu(fe->i_mode)))
inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
- if (ocfs2_populate_inode(inode, fe, 0) < 0) {
- mlog(ML_ERROR, "populate failed! i_blkno=%llu, i_ino=%lu\n",
- (unsigned long long)fe->i_blkno, inode->i_ino);
+ if (ocfs2_populate_inode(inode, fe, 0) < 0)
goto bail;
- }
BUG_ON(args->fi_blkno != le64_to_cpu(fe->i_blkno));
goto leave;
}
- if (S_ISDIR(inode->i_mode)) {
+ dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+ if (S_ISDIR(inode->i_mode))
drop_nlink(dir);
- status = ocfs2_mark_inode_dirty(handle, dir,
- parent_node_bh);
- if (status < 0) {
- mlog_errno(status);
+
+ status = ocfs2_mark_inode_dirty(handle, dir, parent_node_bh);
+ if (status < 0) {
+ mlog_errno(status);
+ if (S_ISDIR(inode->i_mode))
inc_nlink(dir);
- }
}
leave:
char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
struct buffer_head *orphan_entry_bh = NULL;
struct buffer_head *newfe_bh = NULL;
+ struct buffer_head *old_inode_bh = NULL;
struct buffer_head *insert_entry_bh = NULL;
struct ocfs2_super *osb = NULL;
u64 newfe_blkno;
struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above
struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
// this is the 1st dirent bh
- nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink;
+ nlink_t old_dir_nlink = old_dir->i_nlink;
/* At some point it might be nice to break this function up a
* bit. */
}
/*
- * Though we don't require an inode meta data update if
- * old_inode is not a directory, we lock anyway here to ensure
- * the vote thread on other nodes won't have to concurrently
- * downconvert the inode and the dentry locks.
+ * Aside from allowing a meta data update, the locking here
+ * also ensures that the vote thread on other nodes won't have
+ * to concurrently downconvert the inode and the dentry locks.
*/
- status = ocfs2_meta_lock(old_inode, NULL, 1);
+ status = ocfs2_meta_lock(old_inode, &old_inode_bh, 1);
if (status < 0) {
if (status != -ENOENT)
mlog_errno(status);
old_inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(old_inode);
+ ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh);
/* now that the name has been added to new_dir, remove the old name */
status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
}
}
mark_inode_dirty(old_dir);
- if (new_inode)
+ ocfs2_mark_inode_dirty(handle, old_dir, old_dir_bh);
+ if (new_inode) {
mark_inode_dirty(new_inode);
+ ocfs2_mark_inode_dirty(handle, new_inode, newfe_bh);
+ }
- if (old_dir != new_dir)
- if (new_dir_nlink != new_dir->i_nlink) {
- if (!new_dir_bh) {
- mlog(ML_ERROR, "need to change nlink for new "
- "dir %llu from %d to %d but bh is NULL\n",
- (unsigned long long)OCFS2_I(new_dir)->ip_blkno,
- (int)new_dir_nlink, new_dir->i_nlink);
- } else {
- struct ocfs2_dinode *fe;
- status = ocfs2_journal_access(handle,
- new_dir,
- new_dir_bh,
- OCFS2_JOURNAL_ACCESS_WRITE);
- fe = (struct ocfs2_dinode *) new_dir_bh->b_data;
- fe->i_links_count = cpu_to_le16(new_dir->i_nlink);
- status = ocfs2_journal_dirty(handle, new_dir_bh);
- }
- }
+ if (old_dir != new_dir) {
+ /* Keep the same times on both directories.*/
+ new_dir->i_ctime = new_dir->i_mtime = old_dir->i_ctime;
+
+ /*
+ * This will also pick up the i_nlink change from the
+ * block above.
+ */
+ ocfs2_mark_inode_dirty(handle, new_dir, new_dir_bh);
+ }
if (old_dir_nlink != old_dir->i_nlink) {
if (!old_dir_bh) {
iput(new_inode);
if (newfe_bh)
brelse(newfe_bh);
+ if (old_inode_bh)
+ brelse(old_inode_bh);
if (old_dir_bh)
brelse(old_dir_bh);
if (new_dir_bh)
(le16_to_cpu(de->rec_len) >= rec_len)) ||
(le16_to_cpu(de->rec_len) >=
(OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) {
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ retval = ocfs2_mark_inode_dirty(handle, dir, parent_fe_bh);
+ if (retval < 0) {
+ mlog_errno(retval);
+ goto bail;
+ }
+
status = ocfs2_journal_access(handle, dir, insert_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
/* By now the buffer is marked for journaling */
de->name_len = namelen;
memcpy(de->name, name, namelen);
- dir->i_mtime = dir->i_ctime = CURRENT_TIME;
dir->i_version++;
status = ocfs2_journal_dirty(handle, insert_bh);
retval = 0;
#define OCFS2_CLEAR_INCOMPAT_FEATURE(sb,mask) \
OCFS2_SB(sb)->s_feature_incompat &= ~(mask)
-#define OCFS2_FEATURE_COMPAT_SUPP 0
+#define OCFS2_FEATURE_COMPAT_SUPP OCFS2_FEATURE_COMPAT_BACKUP_SB
#define OCFS2_FEATURE_INCOMPAT_SUPP OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT
#define OCFS2_FEATURE_RO_COMPAT_SUPP 0
/* Support for sparse allocation in b-trees */
#define OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC 0x0010
+/*
+ * backup superblock flag is used to indicate that this volume
+ * has backup superblocks.
+ */
+#define OCFS2_FEATURE_COMPAT_BACKUP_SB 0x0001
+
+/* The byte offset of the first backup block will be 1G.
+ * The following will be 4G, 16G, 64G, 256G and 1T.
+ */
+#define OCFS2_BACKUP_SB_START 1 << 30
+
+/* the max backup superblock nums */
+#define OCFS2_MAX_BACKUP_SUPERBLOCKS 6
+
/*
* Flags on ocfs2_dinode.i_flags
*/
return size / sizeof(struct ocfs2_truncate_rec);
}
+
+static inline u64 ocfs2_backup_super_blkno(struct super_block *sb, int index)
+{
+ u64 offset = OCFS2_BACKUP_SB_START;
+
+ if (index >= 0 && index < OCFS2_MAX_BACKUP_SUPERBLOCKS) {
+ offset <<= (2 * index);
+ offset /= sb->s_blocksize;
+ return offset;
+ }
+
+ return 0;
+
+}
#else
static inline int ocfs2_fast_symlink_chars(int blocksize)
{
return size / sizeof(struct ocfs2_truncate_rec);
}
+
+static inline uint64_t ocfs2_backup_super_blkno(int blocksize, int index)
+{
+ uint64_t offset = OCFS2_BACKUP_SB_START;
+
+ if (index >= 0 && index < OCFS2_MAX_BACKUP_SUPERBLOCKS) {
+ offset <<= (2 * index);
+ offset /= blocksize;
+ return offset;
+ }
+
+ return 0;
+}
#endif /* __KERNEL__ */
}
status = vfs_follow_link(nd, link);
- if (status && status != -ENOENT)
- mlog_errno(status);
+
bail:
if (page) {
kunmap(page);
static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
{
+ qc->dma_dir = DMA_NONE;
qc->__sg = NULL;
qc->flags = 0;
qc->cursect = qc->cursg = qc->cursg_ofs = 0;