Commit d13a7654 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.123pre3

parent 36800b1c
...@@ -331,13 +331,7 @@ IP FIREWALL ...@@ -331,13 +331,7 @@ IP FIREWALL
P: Paul Russell P: Paul Russell
M: Paul.Russell@rustcorp.com.au M: Paul.Russell@rustcorp.com.au
W: http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html W: http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html
S: Maintained S: Supported
IP FIREWALL
P: Paul Russell
M: Paul.Russell@rustcorp.com.au
W: http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html
S: Maintained
IPX/SPX NETWORK LAYER IPX/SPX NETWORK LAYER
P: Jay Schulist P: Jay Schulist
......
/* /*
* bios32.c - Low-Level PCI Access * bios32.c - Low-Level PCI Access
* *
* $Id: bios32.c,v 1.45 1998/08/15 10:41:04 mj Exp $ * $Id: bios32.c,v 1.48 1998/09/26 08:06:55 mj Exp $
* *
* Copyright 1993, 1994 Drew Eckhardt * Copyright 1993, 1994 Drew Eckhardt
* Visionary Computing * Visionary Computing
...@@ -170,6 +170,7 @@ PCI_STUB(write, dword, u32) ...@@ -170,6 +170,7 @@ PCI_STUB(write, dword, u32)
#define PCI_PROBE_CONF2 4 #define PCI_PROBE_CONF2 4
#define PCI_NO_SORT 0x100 #define PCI_NO_SORT 0x100
#define PCI_BIOS_SORT 0x200 #define PCI_BIOS_SORT 0x200
#define PCI_NO_CHECKS 0x400
static unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2; static unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
...@@ -343,14 +344,21 @@ static struct pci_access pci_direct_conf2 = { ...@@ -343,14 +344,21 @@ static struct pci_access pci_direct_conf2 = {
* whether bus 00 contains a host bridge (this is similar to checking * whether bus 00 contains a host bridge (this is similar to checking
* techniques used in XFree86, but ours should be more reliable since we * techniques used in XFree86, but ours should be more reliable since we
* attempt to make use of direct access hints provided by the PCI BIOS). * attempt to make use of direct access hints provided by the PCI BIOS).
*
* This should be close to trivial, but it isn't, because there are buggy
* chipsets (yes, you guessed it, by Intel) that have no class ID.
*/ */
__initfunc(int pci_sanity_check(struct pci_access *a)) __initfunc(int pci_sanity_check(struct pci_access *a))
{ {
u16 dfn, class; u16 dfn, x;
if (pci_probe & PCI_NO_CHECKS)
return 1;
for(dfn=0; dfn < 0x100; dfn++) for(dfn=0; dfn < 0x100; dfn++)
if (!a->read_config_word(0, dfn, PCI_CLASS_DEVICE, &class) && if ((!a->read_config_word(0, dfn, PCI_CLASS_DEVICE, &x) &&
class == PCI_CLASS_BRIDGE_HOST) x == PCI_CLASS_BRIDGE_HOST) ||
(!a->read_config_word(0, dfn, PCI_VENDOR_ID, &x) &&
x == PCI_VENDOR_ID_INTEL))
return 1; return 1;
DBG("PCI: Sanity check failed\n"); DBG("PCI: Sanity check failed\n");
return 0; return 0;
...@@ -945,7 +953,7 @@ __initfunc(void pcibios_fixup_ghosts(struct pci_bus *b)) ...@@ -945,7 +953,7 @@ __initfunc(void pcibios_fixup_ghosts(struct pci_bus *b))
__initfunc(void pcibios_fixup_peer_bridges(void)) __initfunc(void pcibios_fixup_peer_bridges(void))
{ {
struct pci_bus *b = &pci_root; struct pci_bus *b = &pci_root;
int i, cnt=-1; int i, n, cnt=-1;
struct pci_dev *d; struct pci_dev *d;
#ifdef CONFIG_PCI_DIRECT #ifdef CONFIG_PCI_DIRECT
...@@ -960,8 +968,8 @@ __initfunc(void pcibios_fixup_peer_bridges(void)) ...@@ -960,8 +968,8 @@ __initfunc(void pcibios_fixup_peer_bridges(void))
for(d=b->devices; d; d=d->sibling) for(d=b->devices; d; d=d->sibling)
if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST) if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
cnt++; cnt++;
do { n = b->subordinate + 1;
int n = b->subordinate+1; while (n <= 0xff) {
int found = 0; int found = 0;
u16 l; u16 l;
for(i=0; i<256; i += 8) for(i=0; i<256; i += 8)
...@@ -973,8 +981,9 @@ __initfunc(void pcibios_fixup_peer_bridges(void)) ...@@ -973,8 +981,9 @@ __initfunc(void pcibios_fixup_peer_bridges(void))
l == PCI_CLASS_BRIDGE_HOST) l == PCI_CLASS_BRIDGE_HOST)
cnt++; cnt++;
} }
if (found && cnt > 0) { if (cnt-- <= 0)
cnt--; break;
if (found) {
printk("PCI: Discovered primary peer bus %02x\n", n); printk("PCI: Discovered primary peer bus %02x\n", n);
b = kmalloc(sizeof(*b), GFP_KERNEL); b = kmalloc(sizeof(*b), GFP_KERNEL);
memset(b, 0, sizeof(*b)); memset(b, 0, sizeof(*b));
...@@ -983,9 +992,10 @@ __initfunc(void pcibios_fixup_peer_bridges(void)) ...@@ -983,9 +992,10 @@ __initfunc(void pcibios_fixup_peer_bridges(void))
b->number = b->secondary = n; b->number = b->secondary = n;
b->subordinate = 0xff; b->subordinate = 0xff;
b->subordinate = pci_scan_bus(b); b->subordinate = pci_scan_bus(b);
break; n = b->subordinate;
} }
} while (i < 256); n++;
}
} }
/* /*
...@@ -1146,11 +1156,11 @@ __initfunc(char *pcibios_setup(char *str)) ...@@ -1146,11 +1156,11 @@ __initfunc(char *pcibios_setup(char *str))
#endif #endif
#ifdef CONFIG_PCI_DIRECT #ifdef CONFIG_PCI_DIRECT
else if (!strcmp(str, "conf1")) { else if (!strcmp(str, "conf1")) {
pci_probe = PCI_PROBE_CONF1; pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
return NULL; return NULL;
} }
else if (!strcmp(str, "conf2")) { else if (!strcmp(str, "conf2")) {
pci_probe = PCI_PROBE_CONF2; pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS;
return NULL; return NULL;
} }
#endif #endif
......
...@@ -371,9 +371,16 @@ static int __init MPBIOS_trigger(int idx) ...@@ -371,9 +371,16 @@ static int __init MPBIOS_trigger(int idx)
{ {
switch (mp_bus_id_to_type[bus]) switch (mp_bus_id_to_type[bus])
{ {
case MP_BUS_ISA: /* ISA pin, edge */ case MP_BUS_ISA: {
{ /* ISA pin, read the Edge/Level control register */
trigger = 0; unsigned int irq = mp_irqs[idx].mpc_dstirq;
if (irq < 16) {
unsigned int port = 0x4d0 + (irq >> 3);
trigger = (inb(port) >> (irq & 7)) & 1;
break;
}
printk("Broken MPtable reports ISA irq %d\n", irq);
trigger = 1;
break; break;
} }
case MP_BUS_PCI: /* PCI pin, level */ case MP_BUS_PCI: /* PCI pin, level */
...@@ -1009,8 +1016,10 @@ static void do_edge_ioapic_IRQ(unsigned int irq, struct pt_regs * regs) ...@@ -1009,8 +1016,10 @@ static void do_edge_ioapic_IRQ(unsigned int irq, struct pt_regs * regs)
/* /*
* If there is no IRQ handler or it was disabled, exit early. * If there is no IRQ handler or it was disabled, exit early.
*/ */
if (!action) if (!action) {
printk("Unhandled edge irq %d (%x %p)\n", irq, status, desc->action);
return; return;
}
/* /*
* Edge triggered interrupts need to remember * Edge triggered interrupts need to remember
...@@ -1061,8 +1070,10 @@ static void do_level_ioapic_IRQ(unsigned int irq, struct pt_regs * regs) ...@@ -1061,8 +1070,10 @@ static void do_level_ioapic_IRQ(unsigned int irq, struct pt_regs * regs)
spin_unlock(&irq_controller_lock); spin_unlock(&irq_controller_lock);
/* Exit early if we had no action or it was disabled */ /* Exit early if we had no action or it was disabled */
if (!action) if (!action) {
printk("Unhandled level irq %d (%x)\n", irq, status);
return; return;
}
handle_IRQ_event(irq, regs, action); handle_IRQ_event(irq, regs, action);
......
...@@ -664,8 +664,10 @@ static void do_8259A_IRQ(unsigned int irq, struct pt_regs * regs) ...@@ -664,8 +664,10 @@ static void do_8259A_IRQ(unsigned int irq, struct pt_regs * regs)
spin_unlock(&irq_controller_lock); spin_unlock(&irq_controller_lock);
/* Exit early if we had no action or it was disabled */ /* Exit early if we had no action or it was disabled */
if (!action) if (!action) {
printk("Unhandled irq %d (%x)\n", irq, desc->status);
return; return;
}
handle_IRQ_event(irq, regs, action); handle_IRQ_event(irq, regs, action);
......
...@@ -426,8 +426,7 @@ static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_s ...@@ -426,8 +426,7 @@ static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_s
&& (q->sector & 63) == 1 && (q->sector & 63) == 1
&& (q->end_sector & 63) == 63) { && (q->end_sector & 63) == 63) {
unsigned int heads = q->end_head + 1; unsigned int heads = q->end_head + 1;
if (heads == 15 || heads == 16 || if (heads == 32 || heads == 64 ||
heads == 32 || heads == 64 ||
heads == 128 || heads == 240 || heads == 128 || heads == 240 ||
heads == 255) { heads == 255) {
(void) ide_xlate_1024(dev, heads, " [PTBL]"); (void) ide_xlate_1024(dev, heads, " [PTBL]");
......
...@@ -102,7 +102,7 @@ static struct esp_pio_buffer *free_pio_buf; ...@@ -102,7 +102,7 @@ static struct esp_pio_buffer *free_pio_buf;
#define WAKEUP_CHARS 1024 #define WAKEUP_CHARS 1024
static char *serial_name = "ESP serial driver"; static char *serial_name = "ESP serial driver";
static char *serial_version = "2.1"; static char *serial_version = "2.2";
static DECLARE_TASK_QUEUE(tq_esp); static DECLARE_TASK_QUEUE(tq_esp);
...@@ -2615,6 +2615,9 @@ __initfunc(int espserial_init(void)) ...@@ -2615,6 +2615,9 @@ __initfunc(int espserial_init(void))
} }
memset((void *)info, 0, sizeof(struct esp_struct)); memset((void *)info, 0, sizeof(struct esp_struct));
/* rx_trigger, tx_trigger are needed by autoconfig */
info->config.rx_trigger = rx_trigger;
info->config.tx_trigger = tx_trigger;
i = 0; i = 0;
offset = 0; offset = 0;
...@@ -2644,8 +2647,6 @@ __initfunc(int espserial_init(void)) ...@@ -2644,8 +2647,6 @@ __initfunc(int espserial_init(void))
info->callout_termios = esp_callout_driver.init_termios; info->callout_termios = esp_callout_driver.init_termios;
info->normal_termios = esp_driver.init_termios; info->normal_termios = esp_driver.init_termios;
info->config.rx_timeout = rx_timeout; info->config.rx_timeout = rx_timeout;
info->config.rx_trigger = rx_trigger;
info->config.tx_trigger = tx_trigger;
info->config.flow_on = flow_on; info->config.flow_on = flow_on;
info->config.flow_off = flow_off; info->config.flow_off = flow_off;
info->config.pio_threshold = pio_threshold; info->config.pio_threshold = pio_threshold;
...@@ -2681,6 +2682,9 @@ __initfunc(int espserial_init(void)) ...@@ -2681,6 +2682,9 @@ __initfunc(int espserial_init(void))
} }
memset((void *)info, 0, sizeof(struct esp_struct)); memset((void *)info, 0, sizeof(struct esp_struct));
/* rx_trigger, tx_trigger are needed by autoconfig */
info->config.rx_trigger = rx_trigger;
info->config.tx_trigger = tx_trigger;
if (offset == 56) { if (offset == 56) {
i++; i++;
......
...@@ -611,13 +611,18 @@ static char * __init initialize_kbd(void) ...@@ -611,13 +611,18 @@ static char * __init initialize_kbd(void)
void __init pckbd_init_hw(void) void __init pckbd_init_hw(void)
{ {
disable_irq(KEYBOARD_IRQ);
/* Flush any pending input. */ /* Flush any pending input. */
kbd_clear_input(); kbd_clear_input();
if (kbd_startup_reset) { if (kbd_startup_reset) {
char *msg = initialize_kbd(); char *msg = initialize_kbd();
if (msg) if (msg) {
printk(KERN_WARNING "initialize_kbd: %s\n", msg); printk(KERN_WARNING "initialize_kbd: %s\n", msg);
aux_device_present = 0;
return;
}
} }
request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL); request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL);
......
...@@ -1386,6 +1386,7 @@ ppp_ioctl(struct ppp *ppp, unsigned int param2, unsigned long param3) ...@@ -1386,6 +1386,7 @@ ppp_ioctl(struct ppp *ppp, unsigned int param2, unsigned long param3)
break; break;
if (temp_i < PPP_MRU) if (temp_i < PPP_MRU)
temp_i = PPP_MRU; temp_i = PPP_MRU;
ppp->mru = temp_i;
if (ppp->flags & SC_DEBUG) if (ppp->flags & SC_DEBUG)
printk(KERN_INFO printk(KERN_INFO
"ppp_ioctl: set mru to %x\n", temp_i); "ppp_ioctl: set mru to %x\n", temp_i);
......
...@@ -65,8 +65,7 @@ static imm_struct imm_hosts[NO_HOSTS] = ...@@ -65,8 +65,7 @@ static imm_struct imm_hosts[NO_HOSTS] =
#define IMM_BASE(x) imm_hosts[(x)].base #define IMM_BASE(x) imm_hosts[(x)].base
int base[NO_HOSTS] = int parbus_base[NO_HOSTS] = {0x03bc, 0x0378, 0x0278, 0x0000};
{0x03bc, 0x0378, 0x0278, 0x0000};
void imm_wakeup(void *ref) void imm_wakeup(void *ref)
{ {
......
This diff is collapsed.
...@@ -686,6 +686,12 @@ static int test_root(int a, int b) ...@@ -686,6 +686,12 @@ static int test_root(int a, int b)
} }
} }
int ext2_group_sparse(int group)
{
return (test_root(group, 3) || test_root(group, 5) ||
test_root(group, 7));
}
void ext2_check_blocks_bitmap (struct super_block * sb) void ext2_check_blocks_bitmap (struct super_block * sb)
{ {
struct buffer_head * bh; struct buffer_head * bh;
...@@ -716,7 +722,7 @@ void ext2_check_blocks_bitmap (struct super_block * sb) ...@@ -716,7 +722,7 @@ void ext2_check_blocks_bitmap (struct super_block * sb)
if (!(le32_to_cpu(sb->u.ext2_sb.s_feature_ro_compat) & if (!(le32_to_cpu(sb->u.ext2_sb.s_feature_ro_compat) &
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) || EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) ||
(test_root(i, 3) || test_root(i, 5) || test_root(i, 7))) { ext2_group_sparse(i)) {
if (!ext2_test_bit (0, bh->b_data)) if (!ext2_test_bit (0, bh->b_data))
ext2_error (sb, "ext2_check_blocks_bitmap", ext2_error (sb, "ext2_check_blocks_bitmap",
"Superblock in group %d " "Superblock in group %d "
......
...@@ -764,8 +764,8 @@ void cleanup_module(void) ...@@ -764,8 +764,8 @@ void cleanup_module(void)
int ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz) int ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
{ {
unsigned long overhead; unsigned long overhead;
unsigned long overhead_per_group;
struct statfs tmp; struct statfs tmp;
int ngroups, i;
if (test_opt (sb, MINIX_DF)) if (test_opt (sb, MINIX_DF))
overhead = 0; overhead = 0;
...@@ -773,13 +773,35 @@ int ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz) ...@@ -773,13 +773,35 @@ int ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
/* /*
* Compute the overhead (FS structures) * Compute the overhead (FS structures)
*/ */
overhead_per_group = 1 /* super block */ +
sb->u.ext2_sb.s_db_per_group /* descriptors */ + /*
1 /* block bitmap */ + * All of the blocks before first_data_block are
1 /* inode bitmap */ + * overhead
sb->u.ext2_sb.s_itb_per_group /* inode table */; */
overhead = le32_to_cpu(sb->u.ext2_sb.s_es->s_first_data_block) + overhead = le32_to_cpu(sb->u.ext2_sb.s_es->s_first_data_block);
sb->u.ext2_sb.s_groups_count * overhead_per_group;
/*
* Add the overhead attributed to the superblock and
* block group descriptors. If this is sparse
* superblocks is turned on, then not all groups have
* this.
*/
if (le32_to_cpu(sb->u.ext2_sb.s_feature_ro_compat) &
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) {
ngroups = 0;
for (i=0 ; i < sb->u.ext2_sb.s_groups_count; i++)
if (ext2_group_sparse(i))
ngroups++;
} else
ngroups = sb->u.ext2_sb.s_groups_count;
overhead += ngroups * (1 + sb->u.ext2_sb.s_db_per_group);
/*
* Every block group has an inode bitmap, a block
* bitmap, and an inode table.
*/
overhead += (sb->u.ext2_sb.s_groups_count *
(2 + sb->u.ext2_sb.s_itb_per_group));
} }
tmp.f_type = EXT2_SUPER_MAGIC; tmp.f_type = EXT2_SUPER_MAGIC;
......
This diff is collapsed.
...@@ -54,25 +54,23 @@ ...@@ -54,25 +54,23 @@
{if (buffer) kfree(buffer); \ {if (buffer) kfree(buffer); \
if (cont_extent){ \ if (cont_extent){ \
int block, offset, offset1; \ int block, offset, offset1; \
struct buffer_head * bh; \ struct buffer_head * pbh; \
buffer = kmalloc(cont_size,GFP_KERNEL); \ buffer = kmalloc(cont_size,GFP_KERNEL); \
if (!buffer) goto out; \ if (!buffer) goto out; \
block = cont_extent; \ block = cont_extent; \
offset = cont_offset; \ offset = cont_offset; \
offset1 = 0; \ offset1 = 0; \
if(buffer) { \ pbh = bread(DEV->i_dev, block, ISOFS_BUFFER_SIZE(DEV)); \
bh = bread(DEV->i_dev, block, ISOFS_BUFFER_SIZE(DEV)); \ if(pbh){ \
if(bh){ \ memcpy(buffer + offset1, pbh->b_data + offset, cont_size - offset1); \
memcpy(buffer + offset1, bh->b_data + offset, cont_size - offset1); \ brelse(pbh); \
brelse(bh); \ chr = (unsigned char *) buffer; \
chr = (unsigned char *) buffer; \ len = cont_size; \
len = cont_size; \ cont_extent = 0; \
cont_extent = 0; \ cont_size = 0; \
cont_size = 0; \ cont_offset = 0; \
cont_offset = 0; \ goto LABEL; \
goto LABEL; \ }; \
}; \
} \
printk("Unable to read rock-ridge attributes\n"); \ printk("Unable to read rock-ridge attributes\n"); \
}} }}
...@@ -162,7 +160,6 @@ int get_rock_ridge_filename(struct iso_directory_record * de, ...@@ -162,7 +160,6 @@ int get_rock_ridge_filename(struct iso_directory_record * de,
if (!inode->i_sb->u.isofs_sb.s_rock) return 0; if (!inode->i_sb->u.isofs_sb.s_rock) return 0;
*retname = 0; *retname = 0;
retnamlen = 0;
SETUP_ROCK_RIDGE(de, chr, len); SETUP_ROCK_RIDGE(de, chr, len);
repeat: repeat:
...@@ -364,6 +361,8 @@ int parse_rock_ridge_inode(struct iso_directory_record * de, ...@@ -364,6 +361,8 @@ int parse_rock_ridge_inode(struct iso_directory_record * de,
inode->u.isofs_i.i_first_extent = isonum_733(rr->u.CL.location) << inode->u.isofs_i.i_first_extent = isonum_733(rr->u.CL.location) <<
inode -> i_sb -> u.isofs_sb.s_log_zone_size; inode -> i_sb -> u.isofs_sb.s_log_zone_size;
reloc = iget(inode->i_sb, inode->u.isofs_i.i_first_extent); reloc = iget(inode->i_sb, inode->u.isofs_i.i_first_extent);
if (!reloc)
goto out;
inode->i_mode = reloc->i_mode; inode->i_mode = reloc->i_mode;
inode->i_nlink = reloc->i_nlink; inode->i_nlink = reloc->i_nlink;
inode->i_uid = reloc->i_uid; inode->i_uid = reloc->i_uid;
...@@ -396,8 +395,8 @@ char * get_rock_ridge_symlink(struct inode * inode) ...@@ -396,8 +395,8 @@ char * get_rock_ridge_symlink(struct inode * inode)
unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
unsigned char bufbits = ISOFS_BUFFER_BITS(inode); unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
struct buffer_head * bh; struct buffer_head * bh;
char * rpnt = NULL;
unsigned char * pnt; unsigned char * pnt;
char * rpnt;
struct iso_directory_record * raw_inode; struct iso_directory_record * raw_inode;
CONTINUE_DECLS; CONTINUE_DECLS;
int block; int block;
...@@ -410,13 +409,10 @@ char * get_rock_ridge_symlink(struct inode * inode) ...@@ -410,13 +409,10 @@ char * get_rock_ridge_symlink(struct inode * inode)
if (!inode->i_sb->u.isofs_sb.s_rock) if (!inode->i_sb->u.isofs_sb.s_rock)
panic("Cannot have symlink with high sierra variant of iso filesystem\n"); panic("Cannot have symlink with high sierra variant of iso filesystem\n");
rpnt = 0;
block = inode->i_ino >> bufbits; block = inode->i_ino >> bufbits;
if (!(bh=bread(inode->i_dev,block, bufsize))) { bh = bread(inode->i_dev, block, bufsize);
printk("unable to read i-node block"); if (!bh)
return NULL; goto out_noread;
};
pnt = ((unsigned char *) bh->b_data) + (inode->i_ino & (bufsize - 1)); pnt = ((unsigned char *) bh->b_data) + (inode->i_ino & (bufsize - 1));
...@@ -425,10 +421,8 @@ char * get_rock_ridge_symlink(struct inode * inode) ...@@ -425,10 +421,8 @@ char * get_rock_ridge_symlink(struct inode * inode)
/* /*
* If we go past the end of the buffer, there is some sort of error. * If we go past the end of the buffer, there is some sort of error.
*/ */
if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize){ if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize)
printk("symlink spans iso9660 blocks\n"); goto out_bad_span;
return NULL;
};
/* Now test for possible Rock Ridge extensions which will override some of /* Now test for possible Rock Ridge extensions which will override some of
these numbers in the inode structure. */ these numbers in the inode structure. */
...@@ -511,16 +505,23 @@ char * get_rock_ridge_symlink(struct inode * inode) ...@@ -511,16 +505,23 @@ char * get_rock_ridge_symlink(struct inode * inode)
}; };
}; };
MAYBE_CONTINUE(repeat,inode); MAYBE_CONTINUE(repeat,inode);
brelse(bh);
return rpnt; out_freebh:
out: brelse(bh);
if(buffer) kfree(buffer); return rpnt;
return 0;
/* error exit from macro */
out:
if(buffer)
kfree(buffer);
if(rpnt)
kfree(rpnt);
rpnt = NULL;
goto out_freebh;
out_noread:
printk("unable to read i-node block");
goto out_freebh;
out_bad_span:
printk("symlink spans iso9660 blocks\n");
goto out_freebh;
} }
...@@ -281,15 +281,16 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name) ...@@ -281,15 +281,16 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name)
} }
/* /*
* The bitmask for a follow event: normal * The bitmask for a lookup event:
* follow, and follow requires a directory * - follow links at the end
* entry due to a slash ('/') after the * - require a directory
* name, and whether to continue to parse * - ending slashes ok even for nonexistent files
* the name.. * - internal "there are more path compnents" flag
*/ */
#define FOLLOW_LINK (1) #define LOOKUP_FOLLOW (1)
#define FOLLOW_DIRECTORY (2) #define LOOKUP_DIRECTORY (2)
#define FOLLOW_CONTINUE (4) #define LOOKUP_SLASHOK (4)
#define LOOKUP_CONTINUE (8)
static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry, unsigned int follow) static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry, unsigned int follow)
{ {
...@@ -331,7 +332,7 @@ static inline struct dentry * follow_mount(struct dentry * dentry) ...@@ -331,7 +332,7 @@ static inline struct dentry * follow_mount(struct dentry * dentry)
* This is the basic name resolution function, turning a pathname * This is the basic name resolution function, turning a pathname
* into the final dentry. * into the final dentry.
*/ */
struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned int follow_link) struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned int lookup_flags)
{ {
struct dentry * dentry; struct dentry * dentry;
struct inode *inode; struct inode *inode;
...@@ -351,14 +352,14 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned ...@@ -351,14 +352,14 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned
goto return_base; goto return_base;
inode = base->d_inode; inode = base->d_inode;
follow_link &= FOLLOW_LINK | FOLLOW_DIRECTORY; lookup_flags &= LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_SLASHOK;
/* At this point we know we have a real path component. */ /* At this point we know we have a real path component. */
for(;;) { for(;;) {
int err; int err;
unsigned long hash; unsigned long hash;
struct qstr this; struct qstr this;
unsigned int follow; unsigned int flags;
unsigned int c; unsigned int c;
err = permission(inode, MAY_EXEC); err = permission(inode, MAY_EXEC);
...@@ -379,16 +380,16 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned ...@@ -379,16 +380,16 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned
this.hash = end_name_hash(hash); this.hash = end_name_hash(hash);
/* remove trailing slashes? */ /* remove trailing slashes? */
follow = follow_link; flags = lookup_flags;
if (c) { if (c) {
char tmp; char tmp;
follow |= FOLLOW_DIRECTORY; flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
do { do {
tmp = *++name; tmp = *++name;
} while (tmp == '/'); } while (tmp == '/');
if (tmp) if (tmp)
follow |= FOLLOW_CONTINUE; flags |= LOOKUP_CONTINUE;
} }
/* /*
...@@ -418,26 +419,47 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned ...@@ -418,26 +419,47 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned
/* Check mountpoints.. */ /* Check mountpoints.. */
dentry = follow_mount(dentry); dentry = follow_mount(dentry);
if (!follow) if (!(flags & LOOKUP_FOLLOW))
break; break;
base = do_follow_link(base, dentry, follow); base = do_follow_link(base, dentry, flags);
if (IS_ERR(base)) if (IS_ERR(base))
goto return_base; goto return_base;
dentry = ERR_PTR(-ENOENT);
inode = base->d_inode; inode = base->d_inode;
if (follow & FOLLOW_DIRECTORY) { if (flags & LOOKUP_DIRECTORY) {
if (!inode) if (!inode)
break; goto no_inode;
dentry = ERR_PTR(-ENOTDIR); dentry = ERR_PTR(-ENOTDIR);
if (!inode->i_op || !inode->i_op->lookup) if (!inode->i_op || !inode->i_op->lookup)
break; break;
if (follow & FOLLOW_CONTINUE) if (flags & LOOKUP_CONTINUE)
continue; continue;
} }
return_base: return_base:
return base; return base;
/*
* The case of a nonexisting file is special.
*
* In the middle of a pathname lookup (ie when
* LOOKUP_CONTINUE is set), it's an obvious
* error and returns ENOENT.
*
* At the end of a pathname lookup it's legal,
* and we return a negative dentry. However, we
* get here only if there were trailing slashes,
* which is legal only if we know it's supposed
* to be a directory (ie "mkdir"). Thus the
* LOOKUP_SLASHOK flag.
*/
no_inode:
dentry = ERR_PTR(-ENOENT);
if (flags & LOOKUP_CONTINUE)
break;
if (flags & LOOKUP_SLASHOK)
goto return_base;
dentry = ERR_PTR(-ENOTDIR);
break;
} }
dput(base); dput(base);
return dentry; return dentry;
...@@ -453,7 +475,7 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned ...@@ -453,7 +475,7 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned
* namei exists in two versions: namei/lnamei. The only difference is * namei exists in two versions: namei/lnamei. The only difference is
* that namei follows links, while lnamei does not. * that namei follows links, while lnamei does not.
*/ */
struct dentry * __namei(const char *pathname, unsigned int follow_link) struct dentry * __namei(const char *pathname, unsigned int lookup_flags)
{ {
char *name; char *name;
struct dentry *dentry; struct dentry *dentry;
...@@ -461,7 +483,7 @@ struct dentry * __namei(const char *pathname, unsigned int follow_link) ...@@ -461,7 +483,7 @@ struct dentry * __namei(const char *pathname, unsigned int follow_link)
name = getname(pathname); name = getname(pathname);
dentry = (struct dentry *) name; dentry = (struct dentry *) name;
if (!IS_ERR(name)) { if (!IS_ERR(name)) {
dentry = lookup_dentry(name, NULL, follow_link); dentry = lookup_dentry(name, NULL, lookup_flags);
putname(name); putname(name);
if (!IS_ERR(dentry)) { if (!IS_ERR(dentry)) {
if (!dentry->d_inode) { if (!dentry->d_inode) {
...@@ -659,7 +681,7 @@ struct dentry * do_mknod(const char * filename, int mode, dev_t dev) ...@@ -659,7 +681,7 @@ struct dentry * do_mknod(const char * filename, int mode, dev_t dev)
struct dentry *dentry, *retval; struct dentry *dentry, *retval;
mode &= ~current->fs->umask; mode &= ~current->fs->umask;
dentry = lookup_dentry(filename, NULL, 1); dentry = lookup_dentry(filename, NULL, LOOKUP_FOLLOW);
if (IS_ERR(dentry)) if (IS_ERR(dentry))
return dentry; return dentry;
...@@ -743,7 +765,7 @@ static inline int do_mkdir(const char * pathname, int mode) ...@@ -743,7 +765,7 @@ static inline int do_mkdir(const char * pathname, int mode)
struct dentry *dir; struct dentry *dir;
struct dentry *dentry; struct dentry *dentry;
dentry = lookup_dentry(pathname, NULL, 0); dentry = lookup_dentry(pathname, NULL, LOOKUP_SLASHOK);
error = PTR_ERR(dentry); error = PTR_ERR(dentry);
if (IS_ERR(dentry)) if (IS_ERR(dentry))
goto exit; goto exit;
...@@ -1150,7 +1172,16 @@ static inline int do_rename(const char * oldname, const char * newname) ...@@ -1150,7 +1172,16 @@ static inline int do_rename(const char * oldname, const char * newname)
if (IS_ERR(old_dentry)) if (IS_ERR(old_dentry))
goto exit; goto exit;
new_dentry = lookup_dentry(newname, NULL, 0); error = -ENOENT;
if (!old_dentry->d_inode)
goto exit;
{
unsigned int flags = 0;
if (S_ISDIR(old_dentry->d_inode->i_mode))
flags = LOOKUP_SLASHOK;
new_dentry = lookup_dentry(newname, NULL, flags);
}
error = PTR_ERR(new_dentry); error = PTR_ERR(new_dentry);
if (IS_ERR(new_dentry)) if (IS_ERR(new_dentry))
...@@ -1161,10 +1192,6 @@ static inline int do_rename(const char * oldname, const char * newname) ...@@ -1161,10 +1192,6 @@ static inline int do_rename(const char * oldname, const char * newname)
double_lock(new_dir, old_dir); double_lock(new_dir, old_dir);
error = -ENOENT;
if (!old_dentry->d_inode)
goto exit_lock;
error = permission(old_dir->d_inode,MAY_WRITE | MAY_EXEC); error = permission(old_dir->d_inode,MAY_WRITE | MAY_EXEC);
if (error) if (error)
goto exit_lock; goto exit_lock;
......
...@@ -416,23 +416,16 @@ parent->d_name.name, dentry->d_name.name); ...@@ -416,23 +416,16 @@ parent->d_name.name, dentry->d_name.name);
*/ */
error = nfs_proc_lookup(NFS_DSERVER(parent), NFS_FH(parent), error = nfs_proc_lookup(NFS_DSERVER(parent), NFS_FH(parent),
dentry->d_name.name, &fhandle, &fattr); dentry->d_name.name, &fhandle, &fattr);
if (error) { if (error)
printk("nfs_lookup_revalidate: error=%d\n", error);
goto out_bad; goto out_bad;
}
/* Inode number matches? */ /* Inode number matches? */
if (fattr.fileid != inode->i_ino) { if (fattr.fileid != inode->i_ino)
printk("nfs_lookup_revalidate: %s/%s inode mismatch, old=%ld, new=%u\n",
parent->d_name.name, dentry->d_name.name, inode->i_ino, fattr.fileid);
goto out_bad; goto out_bad;
}
/* Filehandle matches? */ /* Filehandle matches? */
if (memcmp(dentry->d_fsdata, &fhandle, sizeof(struct nfs_fh))) { if (memcmp(dentry->d_fsdata, &fhandle, sizeof(struct nfs_fh)))
printk("nfs_lookup_revalidate: %s/%s fh changed\n",
parent->d_name.name, dentry->d_name.name);
goto out_bad; goto out_bad;
}
out_valid: out_valid:
return 1; return 1;
......
...@@ -322,18 +322,20 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent) ...@@ -322,18 +322,20 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
goto out_shutdown; goto out_shutdown;
out_no_iod: out_no_iod:
printk("NFS: couldn't start rpciod!\n"); printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
out_shutdown: out_shutdown:
rpc_shutdown_client(server->client); rpc_shutdown_client(server->client);
goto out_unlock; goto out_free_host;
out_no_client: out_no_client:
printk("NFS: cannot create RPC client.\n"); printk(KERN_WARNING "NFS: cannot create RPC client.\n");
xprt_destroy(xprt); xprt_destroy(xprt);
goto out_unlock; goto out_free_host;
out_no_xprt: out_no_xprt:
printk("NFS: cannot create RPC transport.\n"); printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
out_free_host:
kfree(server->hostname); kfree(server->hostname);
out_unlock: out_unlock:
unlock_super(sb); unlock_super(sb);
...@@ -393,9 +395,10 @@ void nfs_free_dentries(struct inode *inode) ...@@ -393,9 +395,10 @@ void nfs_free_dentries(struct inode *inode)
tmp = head; tmp = head;
while ((tmp = tmp->next) != head) { while ((tmp = tmp->next) != head) {
struct dentry *dentry = list_entry(tmp, struct dentry, d_alias); struct dentry *dentry = list_entry(tmp, struct dentry, d_alias);
printk("nfs_free_dentries: found %s/%s, d_count=%d, hashed=%d\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
dentry->d_count, !list_empty(&dentry->d_hash));
if (!dentry->d_count) { if (!dentry->d_count) {
printk("nfs_free_dentries: freeing %s/%s, i_count=%d\n",
dentry->d_parent->d_name.name, dentry->d_name.name, inode->i_count);
dget(dentry); dget(dentry);
d_drop(dentry); d_drop(dentry);
dput(dentry); dput(dentry);
......
...@@ -215,7 +215,7 @@ int mem_mmap(struct file * file, struct vm_area_struct * vma) ...@@ -215,7 +215,7 @@ int mem_mmap(struct file * file, struct vm_area_struct * vma)
pgd_t *src_dir, *dest_dir; pgd_t *src_dir, *dest_dir;
pmd_t *src_middle, *dest_middle; pmd_t *src_middle, *dest_middle;
pte_t *src_table, *dest_table; pte_t *src_table, *dest_table;
unsigned long stmp, dtmp; unsigned long stmp, dtmp, mapnr;
struct vm_area_struct *src_vma = NULL; struct vm_area_struct *src_vma = NULL;
struct inode *inode = file->f_dentry->d_inode; struct inode *inode = file->f_dentry->d_inode;
...@@ -296,7 +296,9 @@ int mem_mmap(struct file * file, struct vm_area_struct * vma) ...@@ -296,7 +296,9 @@ int mem_mmap(struct file * file, struct vm_area_struct * vma)
set_pte(src_table, pte_mkdirty(*src_table)); set_pte(src_table, pte_mkdirty(*src_table));
set_pte(dest_table, *src_table); set_pte(dest_table, *src_table);
atomic_inc(&mem_map[MAP_NR(pte_page(*src_table))].count); mapnr = MAP_NR(pte_page(*src_table));
if (mapnr < max_mapnr)
atomic_inc(&mem_map[MAP_NR(pte_page(*src_table))].count);
stmp += PAGE_SIZE; stmp += PAGE_SIZE;
dtmp += PAGE_SIZE; dtmp += PAGE_SIZE;
......
...@@ -868,17 +868,19 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha ...@@ -868,17 +868,19 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
struct vfsmount *vfsmnt; struct vfsmount *vfsmnt;
int error; int error;
down(&mount_sem);
error = -EACCES; error = -EACCES;
if (!(flags & MS_RDONLY) && dev && is_read_only(dev)) if (!(flags & MS_RDONLY) && dev && is_read_only(dev))
goto out; goto out;
/*flags |= MS_RDONLY;*/
/*
* Do the lookup first to force automounting.
*/
dir_d = namei(dir_name); dir_d = namei(dir_name);
error = PTR_ERR(dir_d); error = PTR_ERR(dir_d);
if (IS_ERR(dir_d)) if (IS_ERR(dir_d))
goto out; goto out;
down(&mount_sem);
error = -ENOTDIR; error = -ENOTDIR;
if (!S_ISDIR(dir_d->d_inode->i_mode)) if (!S_ISDIR(dir_d->d_inode->i_mode))
goto dput_and_out; goto dput_and_out;
...@@ -906,18 +908,16 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha ...@@ -906,18 +908,16 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
error = -ENOMEM; error = -ENOMEM;
vfsmnt = add_vfsmnt(sb, dev_name, dir_name); vfsmnt = add_vfsmnt(sb, dev_name, dir_name);
if (!vfsmnt) if (vfsmnt) {
goto dput_and_out; d_mount(dget(dir_d), sb->s_root);
d_mount(dir_d, sb->s_root); error = 0;
error = 0; /* we don't dput(dir_d) - see umount */ }
out:
up(&mount_sem);
return error;
dput_and_out: dput_and_out:
dput(dir_d); dput(dir_d);
goto out; up(&mount_sem);
out:
return error;
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#define UMSDOS_SPECIAL_DIRFPOS 3 #define UMSDOS_SPECIAL_DIRFPOS 3
extern struct dentry *saved_root;
extern struct inode *pseudo_root; extern struct inode *pseudo_root;
/* #define UMSDOS_DEBUG_VERBOSE 1 */ /* #define UMSDOS_DEBUG_VERBOSE 1 */
...@@ -53,42 +54,6 @@ static struct dentry_operations umsdos_dentry_operations = ...@@ -53,42 +54,6 @@ static struct dentry_operations umsdos_dentry_operations =
NULL, NULL,
}; };
/*
* This needs to have the parent dentry passed to it.
* N.B. Try to get rid of this soon!
*/
int compat_msdos_create (struct inode *dir, const char *name, int len,
int mode, struct inode **inode)
{
int ret;
struct dentry *dentry, *d_dir;
check_inode (dir);
ret = -ENOMEM;
d_dir = geti_dentry (dir);
if (!d_dir) {
printk(KERN_ERR "compat_msdos_create: flaky i_dentry didn't work\n");
goto out;
}
dget(d_dir);
dentry = creat_dentry (name, len, NULL, d_dir);
dput(d_dir);
if (!dentry)
goto out;
check_dentry_path (dentry, "compat_msdos_create START");
ret = msdos_create (dir, dentry, mode);
check_dentry_path (dentry, "compat_msdos_create END");
if (ret)
goto out;
if (inode != NULL)
*inode = dentry->d_inode;
check_inode (dir);
out:
return ret;
}
/* /*
* So grep * doesn't complain in the presence of directories. * So grep * doesn't complain in the presence of directories.
...@@ -203,9 +168,11 @@ Printk (("umsdos_readdir_x: what UMSDOS_SPECIAL_DIRFPOS /mn/?\n")); ...@@ -203,9 +168,11 @@ Printk (("umsdos_readdir_x: what UMSDOS_SPECIAL_DIRFPOS /mn/?\n"));
ret = PTR_ERR(demd); ret = PTR_ERR(demd);
if (IS_ERR(demd)) if (IS_ERR(demd))
goto out_end; goto out_end;
ret = 0; ret = -EIO;
if (!demd->d_inode) { if (!demd->d_inode) {
printk("no EMD file??\n"); printk(KERN_WARNING
"umsdos_readir_x: EMD file %s/%s not found\n",
demd->d_parent->d_name.name, demd->d_name.name);
goto out_dput; goto out_dput;
} }
...@@ -404,18 +371,17 @@ static int UMSDOS_readdir (struct file *filp, void *dirbuf, filldir_t filldir) ...@@ -404,18 +371,17 @@ static int UMSDOS_readdir (struct file *filp, void *dirbuf, filldir_t filldir)
* does this automatically. * does this automatically.
*/ */
void umsdos_lookup_patch (struct inode *dir, struct inode *inode, void umsdos_lookup_patch_new(struct dentry *dentry, struct umsdos_info *info)
struct umsdos_dirent *entry, off_t emd_pos)
{ {
if (inode->i_sb != dir->i_sb) struct inode *inode = dentry->d_inode;
goto out; struct umsdos_dirent *entry = &info->entry;
if (umsdos_isinit (inode))
goto out;
if (S_ISDIR (inode->i_mode)) /*
umsdos_lockcreate (inode); * This part of the initialization depends only on i_patched.
if (umsdos_isinit (inode)) */
goto out_unlock; if (inode->u.umsdos_i.i_patched)
goto out;
inode->u.umsdos_i.i_patched = 1;
if (S_ISREG (entry->mode)) if (S_ISREG (entry->mode))
entry->mtime = inode->i_mtime; entry->mtime = inode->i_mtime;
...@@ -444,149 +410,17 @@ void umsdos_lookup_patch (struct inode *dir, struct inode *inode, ...@@ -444,149 +410,17 @@ void umsdos_lookup_patch (struct inode *dir, struct inode *inode,
"UMSDOS: lookup_patch entry->nlink < 1 ???\n"); "UMSDOS: lookup_patch entry->nlink < 1 ???\n");
} }
} }
umsdos_patch_inode (inode, dir, emd_pos); /*
* The mode may have changed, so patch the inode again.
*/
umsdos_patch_dentry_inode(dentry, info->f_pos);
umsdos_set_dirinfo_new(dentry, info->f_pos);
out_unlock:
if (S_ISDIR (inode->i_mode))
umsdos_unlockcreate (inode);
if (inode->u.umsdos_i.i_emd_owner == 0)
printk (KERN_WARNING "UMSDOS: emd_owner still 0?\n");
out: out:
return; return;
} }
/*
* The preferred interface to the above routine ...
*/
void umsdos_lookup_patch_new(struct dentry *dentry, struct umsdos_dirent *entry,
off_t emd_pos)
{
umsdos_lookup_patch(dentry->d_parent->d_inode, dentry->d_inode, entry,
emd_pos);
}
struct UMSDOS_DIRENT_K {
off_t f_pos; /* will hold the offset of the entry in EMD */
ino_t ino;
};
/*
* Just to record the offset of one entry.
*/
static int umsdos_filldir_k ( void *buf,
const char *name,
int len,
off_t offset,
ino_t ino)
{
struct UMSDOS_DIRENT_K *d = (struct UMSDOS_DIRENT_K *) buf;
d->f_pos = offset;
d->ino = ino;
return 0;
}
struct UMSDOS_DIR_SEARCH {
struct umsdos_dirent *entry;
int found;
ino_t search_ino;
};
static int umsdos_dir_search ( void *buf,
const char *name,
int len,
off_t offset,
ino_t ino)
{
int ret = 0;
struct UMSDOS_DIR_SEARCH *d = (struct UMSDOS_DIR_SEARCH *) buf;
if (d->search_ino == ino) {
d->found = 1;
memcpy (d->entry->name, name, len);
d->entry->name[len] = '\0';
d->entry->name_len = len;
ret = 1; /* So fat_readdir will terminate */
}
return ret;
}
/*
* Locate the directory entry for a dentry in its parent directory.
* Return 0 or a negative error code.
*
* Normally, this function must succeed. It means a strange corruption
* in the file system if not.
*/
int umsdos_dentry_to_entry(struct dentry *dentry, struct umsdos_dirent *entry)
{
struct dentry *parent = dentry->d_parent;
struct inode *inode = dentry->d_inode;
int ret = -ENOENT, err;
struct file filp;
struct UMSDOS_DIR_SEARCH bufsrch;
struct UMSDOS_DIRENT_K bufk;
if (pseudo_root && inode == pseudo_root) {
/*
* Quick way to find the name.
* Also umsdos_readdir_x won't show /linux anyway
*/
memcpy (entry->name, UMSDOS_PSDROOT_NAME, UMSDOS_PSDROOT_LEN + 1);
entry->name_len = UMSDOS_PSDROOT_LEN;
ret = 0;
goto out;
}
/* initialize the file */
fill_new_filp (&filp, parent);
if (!umsdos_have_emd(parent)) {
/* This is a DOS directory. */
filp.f_pos = 0;
bufsrch.entry = entry;
bufsrch.search_ino = inode->i_ino;
fat_readdir (&filp, &bufsrch, umsdos_dir_search);
if (bufsrch.found) {
ret = 0;
inode->u.umsdos_i.i_emd_owner = 0;
if (!S_ISDIR(inode->i_mode))
printk("UMSDOS: %s/%s not a directory!\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
/* N.B. why call this? not always a dir ... */
umsdos_setup_dir(dentry);
}
goto out;
}
/* skip . and .. see umsdos_readdir_x() */
filp.f_pos = UMSDOS_SPECIAL_DIRFPOS;
while (1) {
err = umsdos_readdir_x (parent->d_inode, &filp, &bufk, 1,
entry, 0, umsdos_filldir_k);
if (err < 0) {
printk ("umsdos_dentry_to_entry: ino=%ld, err=%d\n",
inode->i_ino, err);
break;
}
if (bufk.ino == inode->i_ino) {
ret = 0;
umsdos_lookup_patch_new(dentry, entry, bufk.f_pos);
break;
}
}
out:
return ret;
}
/* /*
* Return != 0 if an entry is the pseudo DOS entry in the pseudo root. * Return != 0 if an entry is the pseudo DOS entry in the pseudo root.
*/ */
...@@ -627,8 +461,6 @@ int umsdos_is_pseudodos (struct inode *dir, struct dentry *dentry) ...@@ -627,8 +461,6 @@ int umsdos_is_pseudodos (struct inode *dir, struct dentry *dentry)
int umsdos_lookup_x (struct inode *dir, struct dentry *dentry, int nopseudo) int umsdos_lookup_x (struct inode *dir, struct dentry *dentry, int nopseudo)
{ {
const char *name = dentry->d_name.name;
int len = dentry->d_name.len;
struct dentry *dret = NULL; struct dentry *dret = NULL;
struct inode *inode; struct inode *inode;
int ret = -ENOENT; int ret = -ENOENT;
...@@ -640,28 +472,13 @@ dentry->d_parent->d_name.name, dentry->d_name.name); ...@@ -640,28 +472,13 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
#endif #endif
umsdos_startlookup (dir); umsdos_startlookup (dir);
/* this shouldn't happen ... */
if (len == 1 && name[0] == '.') {
printk("umsdos_lookup_x: UMSDOS broken, please report!\n");
goto out;
}
/* this shouldn't happen ... */
if (len == 2 && name[0] == '.' && name[1] == '.') {
printk("umsdos_lookup_x: UMSDOS broken, please report!\n");
goto out;
}
if (umsdos_is_pseudodos (dir, dentry)) { if (umsdos_is_pseudodos (dir, dentry)) {
/* #Specification: pseudo root / lookup(DOS) /* #Specification: pseudo root / lookup(DOS)
* A lookup of DOS in the pseudo root will always succeed * A lookup of DOS in the pseudo root will always succeed
* and return the inode of the real root. * and return the inode of the real root.
*/ */
inode = iget(dir->i_sb, UMSDOS_ROOT_INO); inode = saved_root->d_inode;
if (inode) goto out_add;
goto out_add;
ret = -ENOMEM;
goto out;
} }
ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info); ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
...@@ -693,7 +510,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, ret); ...@@ -693,7 +510,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, ret);
inode = dret->d_inode; inode = dret->d_inode;
if (!inode) if (!inode)
goto out_remove; goto out_remove;
umsdos_lookup_patch_new(dret, &info.entry, info.f_pos); umsdos_lookup_patch_new(dret, &info);
#ifdef UMSDOS_DEBUG_VERBOSE #ifdef UMSDOS_DEBUG_VERBOSE
printk("umsdos_lookup_x: found %s/%s, ino=%ld\n", printk("umsdos_lookup_x: found %s/%s, ino=%ld\n",
dret->d_parent->d_name.name, dret->d_name.name, dret->d_inode->i_ino); dret->d_parent->d_name.name, dret->d_name.name, dret->d_inode->i_ino);
...@@ -726,6 +543,7 @@ dret->d_parent->d_name.name, dret->d_name.name); ...@@ -726,6 +543,7 @@ dret->d_parent->d_name.name, dret->d_name.name);
* mode. * mode.
*/ */
printk(KERN_WARNING "umsdos_lookup_x: untested, inode == Pseudo_root\n"); printk(KERN_WARNING "umsdos_lookup_x: untested, inode == Pseudo_root\n");
ret = -ENOENT;
goto out_dput; goto out_dput;
} }
......
...@@ -189,7 +189,9 @@ ssize_t umsdos_emd_dir_read (struct file *filp, char *buf, size_t count) ...@@ -189,7 +189,9 @@ ssize_t umsdos_emd_dir_read (struct file *filp, char *buf, size_t count)
/* /*
* Create the EMD dentry for a directory. * Lookup the EMD dentry for a directory.
*
* Note: the caller must hold a lock on the parent directory.
*/ */
struct dentry *umsdos_get_emd_dentry(struct dentry *parent) struct dentry *umsdos_get_emd_dentry(struct dentry *parent)
{ {
...@@ -202,6 +204,8 @@ struct dentry *umsdos_get_emd_dentry(struct dentry *parent) ...@@ -202,6 +204,8 @@ struct dentry *umsdos_get_emd_dentry(struct dentry *parent)
/* /*
* Check whether a directory has an EMD file. * Check whether a directory has an EMD file.
*
* Note: the caller must hold a lock on the parent directory.
*/ */
int umsdos_have_emd(struct dentry *dir) int umsdos_have_emd(struct dentry *dir)
{ {
...@@ -219,11 +223,12 @@ int umsdos_have_emd(struct dentry *dir) ...@@ -219,11 +223,12 @@ int umsdos_have_emd(struct dentry *dir)
/* /*
* Create the EMD file for a directory if it doesn't * Create the EMD file for a directory if it doesn't
* already exist. Returns 0 or an error code. * already exist. Returns 0 or an error code.
*
* Note: the caller must hold a lock on the parent directory.
*/ */
int umsdos_make_emd(struct dentry *parent) int umsdos_make_emd(struct dentry *parent)
{ {
struct dentry *demd = umsdos_get_emd_dentry(parent); struct dentry *demd = umsdos_get_emd_dentry(parent);
struct inode *inode;
int err = PTR_ERR(demd); int err = PTR_ERR(demd);
if (IS_ERR(demd)) { if (IS_ERR(demd)) {
...@@ -234,8 +239,7 @@ int umsdos_make_emd(struct dentry *parent) ...@@ -234,8 +239,7 @@ int umsdos_make_emd(struct dentry *parent)
/* already created? */ /* already created? */
err = 0; err = 0;
inode = demd->d_inode; if (demd->d_inode)
if (inode)
goto out_set; goto out_set;
Printk(("umsdos_make_emd: creating EMD %s/%s\n", Printk(("umsdos_make_emd: creating EMD %s/%s\n",
...@@ -244,15 +248,12 @@ parent->d_name.name, demd->d_name.name)); ...@@ -244,15 +248,12 @@ parent->d_name.name, demd->d_name.name));
err = msdos_create(parent->d_inode, demd, S_IFREG | 0777); err = msdos_create(parent->d_inode, demd, S_IFREG | 0777);
if (err) { if (err) {
printk (KERN_WARNING printk (KERN_WARNING
"UMSDOS: create %s/%s failed, err=%d\n", "umsdos_make_emd: create %s/%s failed, err=%d\n",
parent->d_name.name, demd->d_name.name, err); parent->d_name.name, demd->d_name.name, err);
goto out_dput; goto out_dput;
} }
inode = demd->d_inode;
out_set: out_set:
parent->d_inode->u.umsdos_i.i_emd_dir = inode->i_ino; parent->d_inode->u.umsdos_i.i_emd_dir = demd->d_inode->i_ino;
/* Disable UMSDOS_notify_change() for EMD file */
inode->u.umsdos_i.i_emd_owner = 0xffffffff;
out_dput: out_dput:
dput(demd); dput(demd);
...@@ -261,92 +262,6 @@ parent->d_name.name, demd->d_name.name)); ...@@ -261,92 +262,6 @@ parent->d_name.name, demd->d_name.name));
} }
/*
* Locate the EMD file in a directory.
*
* Return NULL if error, dir->u.umsdos_i.emd_inode if OK.
* Caller must iput() returned inode when finished with it!
* Note: deprecated; get rid of this soon!
*/
struct inode *umsdos_emd_dir_lookup (struct inode *dir, int creat)
{
struct inode *ret = NULL;
struct dentry *d_dir=NULL, *dlook=NULL;
int rv;
Printk ((KERN_DEBUG "Entering umsdos_emd_dir_lookup\n"));
if (!dir) {
printk (KERN_CRIT "umsdos_emd_dir_lookup: FATAL, dir=NULL!\n");
goto out;
}
check_inode (dir);
if (dir->u.umsdos_i.i_emd_dir != 0) {
ret = iget (dir->i_sb, dir->u.umsdos_i.i_emd_dir);
Printk (("umsdos_emd_dir_lookup: deja trouve %ld %p\n",
dir->u.umsdos_i.i_emd_dir, ret));
goto out;
}
PRINTK ((KERN_DEBUG "umsdos /mn/: Looking for %.*s -",
UMSDOS_EMD_NAMELEN, UMSDOS_EMD_FILE));
d_dir = geti_dentry (dir);
if (!d_dir) {
printk("UMSDOS: flaky i_dentry hack failed\n");
goto out;
}
dlook = creat_dentry (UMSDOS_EMD_FILE, UMSDOS_EMD_NAMELEN, NULL, d_dir);
if (!dlook)
goto out;
rv = msdos_lookup (dir, dlook);
PRINTK ((KERN_DEBUG "-returned %d\n", rv));
Printk ((KERN_INFO "emd_dir_lookup "));
ret = dlook->d_inode;
if (ret) {
Printk (("Found --linux "));
dir->u.umsdos_i.i_emd_dir = ret->i_ino;
ret->i_count++; /* we'll need the inode */
check_inode (ret);
} else if (creat) {
int code;
Printk ((" * ERROR * /mn/: creat not yet implemented? not fixed? "));
Printk (("avant create "));
check_inode (ret);
code = compat_msdos_create (dir, UMSDOS_EMD_FILE,
UMSDOS_EMD_NAMELEN,
S_IFREG | 0777, &ret);
check_inode (ret);
Printk (("Creat EMD code %d ret %p ", code, ret));
if (ret != NULL) {
Printk ((" ino=%lu", ret->i_ino));
dir->u.umsdos_i.i_emd_dir = ret->i_ino;
} else {
printk (KERN_WARNING "UMSDOS: Can't create EMD file\n");
}
}
dput(dlook);
if (ret != NULL) {
/* Disable UMSDOS_notify_change() for EMD file */
ret->u.umsdos_i.i_emd_owner = 0xffffffff;
}
out:
#if UMS_DEBUG
Printk ((KERN_DEBUG "umsdos_emd_dir_lookup returning %p /mn/\n", ret));
if (ret != NULL)
Printk ((KERN_DEBUG " returning ino=%lu\n", ret->i_ino));
#endif
return ret;
}
/* /*
* Read an entry from the EMD file. * Read an entry from the EMD file.
* Support variable length record. * Support variable length record.
...@@ -387,6 +302,8 @@ Printk (("umsdos_emd_dir_readentry /mn/: returning len=%d,name=%.*s\n", ...@@ -387,6 +302,8 @@ Printk (("umsdos_emd_dir_readentry /mn/: returning len=%d,name=%.*s\n",
/* /*
* Write an entry in the EMD file. * Write an entry in the EMD file.
* Return 0 if OK, -EIO if some error. * Return 0 if OK, -EIO if some error.
*
* Note: the caller must hold a lock on the parent directory.
*/ */
static int umsdos_writeentry (struct dentry *parent, struct umsdos_info *info, static int umsdos_writeentry (struct dentry *parent, struct umsdos_info *info,
int free_entry) int free_entry)
...@@ -405,8 +322,9 @@ static int umsdos_writeentry (struct dentry *parent, struct umsdos_info *info, ...@@ -405,8 +322,9 @@ static int umsdos_writeentry (struct dentry *parent, struct umsdos_info *info,
/* make sure there's an EMD file */ /* make sure there's an EMD file */
ret = -EIO; ret = -EIO;
if (!emd_dentry->d_inode) { if (!emd_dentry->d_inode) {
printk("umsdos_writeentry: no EMD file in %s/%s\n", printk(KERN_WARNING
parent->d_parent->d_name.name, parent->d_name.name); "umsdos_writeentry: no EMD file in %s/%s\n",
parent->d_parent->d_name.name, parent->d_name.name);
goto out_dput; goto out_dput;
} }
...@@ -468,6 +386,8 @@ struct find_buffer { ...@@ -468,6 +386,8 @@ struct find_buffer {
* Unread bytes are simply moved to the beginning. * Unread bytes are simply moved to the beginning.
* *
* Return -ENOENT if EOF, 0 if OK, a negative error code if any problem. * Return -ENOENT if EOF, 0 if OK, a negative error code if any problem.
*
* Note: the caller must hold a lock on the parent directory.
*/ */
static int umsdos_fillbuf (struct find_buffer *buf) static int umsdos_fillbuf (struct find_buffer *buf)
...@@ -518,6 +438,7 @@ static int umsdos_fillbuf (struct find_buffer *buf) ...@@ -518,6 +438,7 @@ static int umsdos_fillbuf (struct find_buffer *buf)
* All this to say that umsdos_writeentry must be called after this * All this to say that umsdos_writeentry must be called after this
* function since it relies on the f_pos field of info. * function since it relies on the f_pos field of info.
* *
* Note: the caller must hold a lock on the parent directory.
*/ */
/* #Specification: EMD file structure /* #Specification: EMD file structure
* The EMD file uses a fairly simple layout. It is made of records * The EMD file uses a fairly simple layout. It is made of records
......
This diff is collapsed.
...@@ -262,7 +262,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, ret)); ...@@ -262,7 +262,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, ret));
* is in the dos_dirent.name field and the destination * is in the dos_dirent.name field and the destination
* is in umsdos_dirent.name field. * is in umsdos_dirent.name field.
* *
* This ioctl allows umssync to rename a mangle file * This ioctl allows umssync to rename a mangled file
* name before syncing it back in the EMD. * name before syncing it back in the EMD.
*/ */
old_dentry = umsdos_lookup_dentry (dentry, old_dentry = umsdos_lookup_dentry (dentry,
...@@ -282,7 +282,6 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); ...@@ -282,7 +282,6 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
ret = msdos_rename (dir, old_dentry, dir, new_dentry); ret = msdos_rename (dir, old_dentry, dir, new_dentry);
dput(new_dentry); dput(new_dentry);
} }
d_drop(old_dentry);
dput(old_dentry); dput(old_dentry);
goto out; goto out;
} }
...@@ -306,6 +305,11 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); ...@@ -306,6 +305,11 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
data.umsdos_dirent.name_len, &info); data.umsdos_dirent.name_len, &info);
ret = umsdos_delentry (dentry, &info, ret = umsdos_delentry (dentry, &info,
S_ISDIR (data.umsdos_dirent.mode)); S_ISDIR (data.umsdos_dirent.mode));
if (ret) {
printk(KERN_WARNING
"umsdos_ioctl: delentry %s/%s failed, ret=%d\n",
dentry->d_name.name, info.entry.name, ret);
}
goto out; goto out;
} }
else if (cmd == UMSDOS_UNLINK_DOS) { else if (cmd == UMSDOS_UNLINK_DOS) {
...@@ -324,9 +328,11 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); ...@@ -324,9 +328,11 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
if (IS_ERR(temp)) if (IS_ERR(temp))
goto out; goto out;
ret = -ENOENT; ret = -ENOENT;
if (temp->d_inode) if (temp->d_inode) {
ret = msdos_unlink (dir, temp); ret = -EISDIR;
d_drop(temp); if (!S_ISDIR(temp->d_inode->i_mode))
ret = msdos_unlink (dir, temp);
}
dput (temp); dput (temp);
goto out; goto out;
} }
...@@ -346,9 +352,11 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); ...@@ -346,9 +352,11 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
if (IS_ERR(temp)) if (IS_ERR(temp))
goto out; goto out;
ret = -ENOENT; ret = -ENOENT;
if (temp->d_inode) if (temp->d_inode) {
ret = msdos_rmdir (dir, temp); ret = -ENOTDIR;
d_drop(temp); if (S_ISDIR(temp->d_inode->i_mode))
ret = msdos_rmdir (dir, temp);
}
dput (temp); dput (temp);
goto out; goto out;
...@@ -385,7 +393,6 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); ...@@ -385,7 +393,6 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
sizeof (data.stat))) sizeof (data.stat)))
ret = 0; ret = 0;
} }
d_drop(dret);
dput(dret); dput(dret);
goto out; goto out;
} }
......
This diff is collapsed.
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
extern struct dentry *saved_root;
extern struct inode *pseudo_root; extern struct inode *pseudo_root;
extern struct dentry_operations umsdos_dentry_operations; extern struct dentry_operations umsdos_dentry_operations;
...@@ -64,9 +65,7 @@ static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t filldir) ...@@ -64,9 +65,7 @@ static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t filldir)
bufk.filldir = filldir; bufk.filldir = filldir;
bufk.dirbuf = dirbuf; bufk.dirbuf = dirbuf;
bufk.real_root = pseudo_root && bufk.real_root = pseudo_root && (dir == saved_root->d_inode);
dir->i_ino == UMSDOS_ROOT_INO &&
dir->i_sb == pseudo_root->i_sb;
return fat_readdir (filp, &bufk, rdir_filldir); return fat_readdir (filp, &bufk, rdir_filldir);
} }
...@@ -82,30 +81,41 @@ static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t filldir) ...@@ -82,30 +81,41 @@ static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t filldir)
*/ */
int umsdos_rlookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo) int umsdos_rlookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo)
{ {
/* so locating "linux" will work */
const char *name = dentry->d_name.name;
int len = dentry->d_name.len;
struct inode *inode;
int ret; int ret;
/* N.B. this won't work ... lookups of `..' are done by VFS */
#ifdef BROKEN_TO_BITS
if (pseudo_root && len == 2 && name[0] == '.' && name[1] == '.' && if (pseudo_root && len == 2 && name[0] == '.' && name[1] == '.' &&
dir->i_ino == UMSDOS_ROOT_INO && dir->i_sb == pseudo_root->i_sb) { dir == saved_root->d_inode) {
printk (KERN_WARNING "umsdos_rlookup_x: we are at pseudo-root thingy?\n"); printk (KERN_WARNING "umsdos_rlookup_x: we are at pseudo-root thingy?\n");
pseudo_root->i_count++; pseudo_root->i_count++;
d_add(dentry, pseudo_root); d_add(dentry, pseudo_root);
ret = 0; ret = 0;
goto out; goto out;
} }
#endif
ret = msdos_lookup (dir, dentry); ret = msdos_lookup (dir, dentry);
if (ret) { if (ret) {
printk(KERN_WARNING "umsdos_rlookup_x: lookup failed, ret=%d\n", printk(KERN_WARNING
ret); "umsdos_rlookup_x: %s/%s failed, ret=%d\n",
dentry->d_parent->d_name.name, dentry->d_name.name,ret);
goto out; goto out;
} }
inode = dentry->d_inode; if (dentry->d_inode) {
if (inode) { /* We must install the proper function table
if (inode == pseudo_root && !nopseudo) { * depending on whether this is an MS-DOS or
* a UMSDOS directory
*/
Printk ((KERN_DEBUG "umsdos_rlookup_x: setting up setup_dir_inode %lu...\n",
inode->i_ino));
umsdos_patch_dentry_inode(dentry, 0);
/* N.B. Won't work -- /linux dentry will already have
* an inode, so we'll never get called here.
*/
#ifdef BROKEN_TO_BITS
if (dentry->d_inode == pseudo_root && !nopseudo) {
/* #Specification: pseudo root / DOS/linux /* #Specification: pseudo root / DOS/linux
* Even in the real root directory (c:\), the directory * Even in the real root directory (c:\), the directory
* /linux won't show * /linux won't show
...@@ -114,20 +124,11 @@ printk(KERN_WARNING "umsdos_rlookup_x: do the pseudo-thingy...\n"); ...@@ -114,20 +124,11 @@ printk(KERN_WARNING "umsdos_rlookup_x: do the pseudo-thingy...\n");
/* make the dentry negative */ /* make the dentry negative */
d_delete(dentry); d_delete(dentry);
} }
else if (S_ISDIR (inode->i_mode)) { #endif
/* We must place the proper function table
* depending on whether this is an MS-DOS or
* a UMSDOS directory
*/
Printk ((KERN_DEBUG "umsdos_rlookup_x: setting up setup_dir_inode %lu...\n",
inode->i_ino));
umsdos_setup_dir(dentry);
}
} }
out: out:
/* always install our dentry ops ... */ /* always install our dentry ops ... */
dentry->d_op = &umsdos_dentry_operations; dentry->d_op = &umsdos_dentry_operations;
PRINTK ((KERN_DEBUG "umsdos_rlookup_x: returning %d\n", ret));
return ret; return ret;
} }
...@@ -168,18 +169,18 @@ static int UMSDOS_rrmdir ( struct inode *dir, struct dentry *dentry) ...@@ -168,18 +169,18 @@ static int UMSDOS_rrmdir ( struct inode *dir, struct dentry *dentry)
if (umsdos_is_pseudodos (dir, dentry)) if (umsdos_is_pseudodos (dir, dentry))
goto out; goto out;
umsdos_lockcreate (dir);
ret = -EBUSY; ret = -EBUSY;
if (dentry->d_count > 1) { if (dentry->d_count > 1) {
shrink_dcache_parent(dentry); shrink_dcache_parent(dentry);
if (dentry->d_count > 1) if (dentry->d_count > 1)
goto out_unlock; goto out;
} }
ret = msdos_rmdir (dir, dentry); ret = msdos_rmdir (dir, dentry);
if (ret != -ENOTEMPTY) if (ret != -ENOTEMPTY)
goto out_unlock; goto out;
down(&dentry->d_inode->i_sem);
empty = umsdos_isempty (dentry); empty = umsdos_isempty (dentry);
if (empty == 1) { if (empty == 1) {
struct dentry *demd; struct dentry *demd;
...@@ -192,14 +193,14 @@ static int UMSDOS_rrmdir ( struct inode *dir, struct dentry *dentry) ...@@ -192,14 +193,14 @@ static int UMSDOS_rrmdir ( struct inode *dir, struct dentry *dentry)
ret = msdos_unlink (dentry->d_inode, demd); ret = msdos_unlink (dentry->d_inode, demd);
dput(demd); dput(demd);
} }
if (ret)
goto out_unlock;
} }
up(&dentry->d_inode->i_sem);
if (ret)
goto out;
/* now retry the original ... */ /* now retry the original ... */
ret = msdos_rmdir (dir, dentry); ret = msdos_rmdir (dir, dentry);
out_unlock:
umsdos_unlockcreate (dir);
out: out:
return ret; return ret;
} }
......
...@@ -520,6 +520,7 @@ struct ext2_dir_entry_2 { ...@@ -520,6 +520,7 @@ struct ext2_dir_entry_2 {
extern int ext2_permission (struct inode *, int); extern int ext2_permission (struct inode *, int);
/* balloc.c */ /* balloc.c */
extern int ext2_group_sparse(int group);
extern int ext2_new_block (const struct inode *, unsigned long, extern int ext2_new_block (const struct inode *, unsigned long,
__u32 *, __u32 *, int *); __u32 *, __u32 *, int *);
extern void ext2_free_blocks (const struct inode *, unsigned long, extern void ext2_free_blocks (const struct inode *, unsigned long,
......
...@@ -165,19 +165,23 @@ struct dqstats { ...@@ -165,19 +165,23 @@ struct dqstats {
#define DQ_FAKE 0x40 /* no limits only usage */ #define DQ_FAKE 0x40 /* no limits only usage */
struct dquot { struct dquot {
struct dquot *dq_next; /* Pointer to next dquot */
struct dquot **dq_pprev;
struct list_head dq_free; /* free list element */
struct dquot *dq_hash_next; /* Pointer to next in dquot_hash */
struct dquot **dq_hash_pprev; /* Pointer to previous in dquot_hash */
struct wait_queue *dq_wait; /* Pointer to waitqueue */
int dq_count; /* Reference count */
/* fields after this point are cleared when invalidating */
struct vfsmount *dq_mnt; /* VFS_mount_point this applies to */
unsigned int dq_id; /* ID this applies to (uid, gid) */ unsigned int dq_id; /* ID this applies to (uid, gid) */
short dq_type; /* Type of quota */
kdev_t dq_dev; /* Device this applies to */ kdev_t dq_dev; /* Device this applies to */
short dq_type; /* Type of quota */
short dq_flags; /* See DQ_* */ short dq_flags; /* See DQ_* */
short dq_count; /* Reference count */ unsigned long dq_referenced; /* Number of times this dquot was
unsigned long dq_referenced; /* Number of times this dquot was referenced during its lifetime */ referenced during its lifetime */
struct vfsmount *dq_mnt; /* VFS_mount_point this applies to */
struct dqblk dq_dqb; /* Diskquota usage */ struct dqblk dq_dqb; /* Diskquota usage */
struct wait_queue *dq_wait; /* Pointer to waitqueue */
struct dquot *dq_next; /* Pointer to next dquot */
struct dquot *dq_hash_next; /* Pointer to next in dquot_hash */
struct dquot **dq_hash_pprev; /* Pointer to previous in dquot_hash */
struct dquot **dq_pprev;
}; };
#define NODQUOT (struct dquot *)NULL #define NODQUOT (struct dquot *)NULL
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/sunrpc/sched.h> #include <linux/sunrpc/sched.h>
/* size of the nodename buffer */
#define UNX_MAXNODENAME 32
/* /*
* Client user credentials * Client user credentials
......
...@@ -52,6 +52,9 @@ struct rpc_clnt { ...@@ -52,6 +52,9 @@ struct rpc_clnt {
struct rpc_portmap cl_pmap; /* port mapping */ struct rpc_portmap cl_pmap; /* port mapping */
struct rpc_wait_queue cl_bindwait; /* waiting on getport() */ struct rpc_wait_queue cl_bindwait; /* waiting on getport() */
int cl_nodelen; /* nodename length */
char cl_nodename[UNX_MAXNODENAME];
}; };
#define cl_timeout cl_xprt->timeout #define cl_timeout cl_xprt->timeout
#define cl_prog cl_pmap.pm_prog #define cl_prog cl_pmap.pm_prog
......
...@@ -71,7 +71,7 @@ enum { ...@@ -71,7 +71,7 @@ enum {
}; };
#define TCP_STATE_MASK 0xF #define TCP_STATE_MASK 0xF
#define TCP_ACTION_FIN 1 << 7 #define TCP_ACTION_FIN (1 << 7)
enum { enum {
TCPF_ESTABLISHED = (1 << 1), TCPF_ESTABLISHED = (1 << 1),
......
...@@ -2,31 +2,14 @@ ...@@ -2,31 +2,14 @@
void check_page_tables (void); void check_page_tables (void);
/* dir.c 22/06/95 00.22.12 */ /* dir.c 22/06/95 00.22.12 */
int compat_msdos_create(struct inode *dir,
const char *name,
int len,
int mode,
struct inode **inode);
int dummy_dir_read ( struct file *filp, int dummy_dir_read ( struct file *filp,
char *buf, char *buf,
size_t size, size_t size,
loff_t *count); loff_t *count);
char * umsdos_d_path(struct dentry *, char *, int); char * umsdos_d_path(struct dentry *, char *, int);
void umsdos_lookup_patch_new(struct dentry *, struct umsdos_dirent *, off_t); void umsdos_lookup_patch_new(struct dentry *, struct umsdos_info *);
void umsdos_lookup_patch (struct inode *dir,
struct inode *inode,
struct umsdos_dirent *entry,
off_t emd_pos);
int umsdos_dentry_to_entry (struct dentry *, struct umsdos_dirent *);
int umsdos_inode2entry (struct inode *dir,
struct inode *inode,
struct umsdos_dirent *entry);
int umsdos_locate_path (struct inode *inode, char *path);
int umsdos_is_pseudodos (struct inode *dir, struct dentry *dentry); int umsdos_is_pseudodos (struct inode *dir, struct dentry *dentry);
int umsdos_lookup_x ( int umsdos_lookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo);
struct inode *dir,
struct dentry *dentry,
int nopseudo);
int UMSDOS_lookup(struct inode *, struct dentry *); int UMSDOS_lookup(struct inode *, struct dentry *);
struct dentry *umsdos_lookup_dentry(struct dentry *, char *, int, int); struct dentry *umsdos_lookup_dentry(struct dentry *, char *, int, int);
...@@ -52,7 +35,6 @@ ssize_t umsdos_emd_dir_read (struct file *filp, ...@@ -52,7 +35,6 @@ ssize_t umsdos_emd_dir_read (struct file *filp,
struct dentry *umsdos_get_emd_dentry(struct dentry *); struct dentry *umsdos_get_emd_dentry(struct dentry *);
int umsdos_have_emd(struct dentry *); int umsdos_have_emd(struct dentry *);
int umsdos_make_emd(struct dentry *); int umsdos_make_emd(struct dentry *);
struct inode *umsdos_emd_dir_lookup (struct inode *dir, int creat);
int umsdos_emd_dir_readentry (struct file *, struct umsdos_dirent *); int umsdos_emd_dir_readentry (struct file *, struct umsdos_dirent *);
int umsdos_newentry (struct dentry *, struct umsdos_info *); int umsdos_newentry (struct dentry *, struct umsdos_info *);
int umsdos_newhidden (struct dentry *, struct umsdos_info *); int umsdos_newhidden (struct dentry *, struct umsdos_info *);
...@@ -63,32 +45,20 @@ int umsdos_isempty (struct dentry *); ...@@ -63,32 +45,20 @@ int umsdos_isempty (struct dentry *);
/* file.c 25/01/95 02.25.38 */ /* file.c 25/01/95 02.25.38 */
/* inode.c 12/06/95 09.49.40 */ /* inode.c 12/06/95 09.49.40 */
inline struct dentry *geti_dentry (struct inode *inode);
void checkd_inode (struct inode *inode);
void check_inode (struct inode *inode);
void check_dentry (struct dentry *dentry);
void check_dentry_path (struct dentry *dentry, const char *desc);
void fill_new_filp (struct file *filp, struct dentry *dentry); void fill_new_filp (struct file *filp, struct dentry *dentry);
struct dentry *creat_dentry (const char *name,
const int len,
struct inode *inode,
struct dentry *parent);
void UMSDOS_read_inode (struct inode *); void UMSDOS_read_inode (struct inode *);
void UMSDOS_write_inode (struct inode *); void UMSDOS_write_inode (struct inode *);
int UMSDOS_notify_change (struct dentry *, struct iattr *attr); int UMSDOS_notify_change (struct dentry *, struct iattr *attr);
int umsdos_notify_change_locked(struct dentry *, struct iattr *attr);
void UMSDOS_put_inode (struct inode *); void UMSDOS_put_inode (struct inode *);
int UMSDOS_statfs (struct super_block *, struct statfs *, int); int UMSDOS_statfs (struct super_block *, struct statfs *, int);
struct super_block *UMSDOS_read_super (struct super_block *, void *, int); struct super_block *UMSDOS_read_super (struct super_block *, void *, int);
void UMSDOS_put_super (struct super_block *); void UMSDOS_put_super (struct super_block *);
int umsdos_real_lookup(struct inode *, struct dentry *);
void umsdos_setup_dir(struct dentry *); void umsdos_setup_dir(struct dentry *);
void umsdos_setup_dir_inode (struct inode *inode);
void umsdos_set_dirinfo_new(struct dentry *, off_t); void umsdos_set_dirinfo_new(struct dentry *, off_t);
void umsdos_set_dirinfo (struct inode *, struct inode *, off_t);
int umsdos_isinit (struct inode *inode); int umsdos_isinit (struct inode *inode);
void umsdos_patch_dentry_inode (struct dentry *, off_t); void umsdos_patch_dentry_inode (struct dentry *, off_t);
void umsdos_patch_inode (struct inode *, struct inode *, off_t);
int umsdos_get_dirowner (struct inode *inode, struct inode **result); int umsdos_get_dirowner (struct inode *inode, struct inode **result);
/* ioctl.c 22/06/95 00.22.08 */ /* ioctl.c 22/06/95 00.22.08 */
...@@ -96,6 +66,7 @@ int UMSDOS_ioctl_dir (struct inode *dir, ...@@ -96,6 +66,7 @@ int UMSDOS_ioctl_dir (struct inode *dir,
struct file *filp, struct file *filp,
unsigned int cmd, unsigned int cmd,
unsigned long data); unsigned long data);
/* mangle.c 25/01/95 02.25.38 */ /* mangle.c 25/01/95 02.25.38 */
void umsdos_manglename (struct umsdos_info *info); void umsdos_manglename (struct umsdos_info *info);
int umsdos_evalrecsize (int len); int umsdos_evalrecsize (int len);
...@@ -135,9 +106,13 @@ int UMSDOS_rename (struct inode *old_dir, ...@@ -135,9 +106,13 @@ int UMSDOS_rename (struct inode *old_dir,
struct dentry *new_dentry); struct dentry *new_dentry);
/* rdir.c 22/03/95 03.31.42 */ /* rdir.c 22/03/95 03.31.42 */
int umsdos_rlookup_x (struct inode *dir, int umsdos_rlookup_x (struct inode *dir, struct dentry *dentry, int nopseudo);
struct dentry *dentry, int UMSDOS_rlookup (struct inode *dir, struct dentry *dentry);
int nopseudo);
int UMSDOS_rlookup (struct inode *dir,
struct dentry *dentry);
/* symlink.c 23/01/95 03.38.30 */ /* symlink.c 23/01/95 03.38.30 */
/* check.c */
void checkd_inode (struct inode *inode);
void check_inode (struct inode *inode);
void check_dentry (struct dentry *dentry);
void check_dentry_path (struct dentry *dentry, const char *desc);
...@@ -62,12 +62,14 @@ struct umsdos_inode_info { ...@@ -62,12 +62,14 @@ struct umsdos_inode_info {
struct msdos_inode_info msdos_info; struct msdos_inode_info msdos_info;
struct pipe_inode_info pipe_info; struct pipe_inode_info pipe_info;
struct dir_locking_info dir_info; struct dir_locking_info dir_info;
} u; /* Simply a filler, never referenced by fs/umsdos/... */ } u;
unsigned long i_dir_owner; /* Inode of the dir which hold this entry */ int i_patched; /* Inode has been patched */
unsigned long i_emd_owner; /* Inode of the EMD file of i_dir_owner */ int i_is_hlink; /* Resolved hardlink inode? */
unsigned long i_emd_owner; /* Is this the EMD file inode? */
off_t pos; /* Entry offset in the emd_owner file */ off_t pos; /* Entry offset in the emd_owner file */
/* The rest is used only if this inode describe a directory */ /* The rest is used only if this inode describes a directory */
unsigned long i_emd_dir; /* Inode of the EMD file of this inode */ struct dentry *i_emd_dentry; /* EMD dentry for this directory */
unsigned long i_emd_dir; /* Inode of the EMD file */
}; };
#endif #endif
...@@ -598,9 +598,9 @@ unsigned int tcp_poll(struct file * file, struct socket *sock, poll_table *wait) ...@@ -598,9 +598,9 @@ unsigned int tcp_poll(struct file * file, struct socket *sock, poll_table *wait)
sk->urginline || !tp->urg_data)) sk->urginline || !tp->urg_data))
mask |= POLLIN | POLLRDNORM; mask |= POLLIN | POLLRDNORM;
/* Always wake the user up when an error occurred */ if (sock_wspace(sk) >= tcp_min_write_space(sk, tp))
if (sock_wspace(sk) >= tcp_min_write_space(sk, tp) || sk->err)
mask |= POLLOUT | POLLWRNORM; mask |= POLLOUT | POLLWRNORM;
if (tp->urg_data & URG_VALID) if (tp->urg_data & URG_VALID)
mask |= POLLPRI; mask |= POLLPRI;
} }
...@@ -1458,7 +1458,8 @@ void tcp_close(struct sock *sk, unsigned long timeout) ...@@ -1458,7 +1458,8 @@ void tcp_close(struct sock *sk, unsigned long timeout)
* reader process may not have drained the data yet! * reader process may not have drained the data yet!
*/ */
while((skb=__skb_dequeue(&sk->receive_queue))!=NULL) { while((skb=__skb_dequeue(&sk->receive_queue))!=NULL) {
data_was_unread++; u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq - skb->h.th->fin;
data_was_unread += len;
kfree_skb(skb); kfree_skb(skb);
} }
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <linux/malloc.h> #include <linux/malloc.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/utsname.h>
#include <linux/sunrpc/clnt.h> #include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/auth.h> #include <linux/sunrpc/auth.h>
...@@ -28,13 +27,7 @@ struct unx_cred { ...@@ -28,13 +27,7 @@ struct unx_cred {
#define UNX_CRED_EXPIRE (60 * HZ) #define UNX_CRED_EXPIRE (60 * HZ)
#ifndef DONT_FILLIN_HOSTNAME #define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2))
/* # define UNX_MAXNODENAME (sizeof(system_utsname.nodename)-1) */
# define UNX_MAXNODENAME 32
# define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2))
#else
# define UNX_WRITESLACK 20
#endif
#ifdef RPC_DEBUG #ifdef RPC_DEBUG
# define RPCDBG_FACILITY RPCDBG_AUTH # define RPCDBG_FACILITY RPCDBG_AUTH
...@@ -170,6 +163,7 @@ unx_match(struct rpc_task * task, struct rpc_cred *rcred) ...@@ -170,6 +163,7 @@ unx_match(struct rpc_task * task, struct rpc_cred *rcred)
static u32 * static u32 *
unx_marshal(struct rpc_task *task, u32 *p, int ruid) unx_marshal(struct rpc_task *task, u32 *p, int ruid)
{ {
struct rpc_clnt *clnt = task->tk_client;
struct unx_cred *cred = (struct unx_cred *) task->tk_cred; struct unx_cred *cred = (struct unx_cred *) task->tk_cred;
u32 *base, *hold; u32 *base, *hold;
int i, n; int i, n;
...@@ -177,20 +171,15 @@ unx_marshal(struct rpc_task *task, u32 *p, int ruid) ...@@ -177,20 +171,15 @@ unx_marshal(struct rpc_task *task, u32 *p, int ruid)
*p++ = htonl(RPC_AUTH_UNIX); *p++ = htonl(RPC_AUTH_UNIX);
base = p++; base = p++;
*p++ = htonl(jiffies/HZ); *p++ = htonl(jiffies/HZ);
#ifndef DONT_FILLIN_HOSTNAME
/* /*
* Problem: The UTS name could change under us. We can't lock * Copy the UTS nodename captured when the client was created.
* here to handle this. On the other hand we can't really
* go building a bad RPC!
*/ */
if ((n = strlen((char *) system_utsname.nodename)) > UNX_MAXNODENAME) n = clnt->cl_nodelen;
n = UNX_MAXNODENAME;
*p++ = htonl(n); *p++ = htonl(n);
memcpy(p, system_utsname.nodename, n); memcpy(p, clnt->cl_nodename, n);
p += (n + 3) >> 2; p += (n + 3) >> 2;
#else
*p++ = 0;
#endif
if (ruid) { if (ruid) {
*p++ = htonl((u32) cred->uc_uid); *p++ = htonl((u32) cred->uc_uid);
*p++ = htonl((u32) cred->uc_gid); *p++ = htonl((u32) cred->uc_gid);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/malloc.h> #include <linux/malloc.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/utsname.h>
#include <linux/sunrpc/clnt.h> #include <linux/sunrpc/clnt.h>
...@@ -101,6 +102,12 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname, ...@@ -101,6 +102,12 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
if (!rpcauth_create(flavor, clnt)) if (!rpcauth_create(flavor, clnt))
goto out_no_auth; goto out_no_auth;
/* save the nodename */
clnt->cl_nodelen = strlen(system_utsname.nodename);
if (clnt->cl_nodelen > UNX_MAXNODENAME)
clnt->cl_nodelen = UNX_MAXNODENAME;
memcpy(clnt->cl_nodename, system_utsname.nodename, clnt->cl_nodelen);
out: out:
return clnt; return clnt;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment