Commit d13a7654 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.123pre3

parent 36800b1c
......@@ -331,13 +331,7 @@ IP FIREWALL
P: Paul Russell
M: Paul.Russell@rustcorp.com.au
W: http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html
S: Maintained
IP FIREWALL
P: Paul Russell
M: Paul.Russell@rustcorp.com.au
W: http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html
S: Maintained
S: Supported
IPX/SPX NETWORK LAYER
P: Jay Schulist
......
/*
* 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
* Visionary Computing
......@@ -170,6 +170,7 @@ PCI_STUB(write, dword, u32)
#define PCI_PROBE_CONF2 4
#define PCI_NO_SORT 0x100
#define PCI_BIOS_SORT 0x200
#define PCI_NO_CHECKS 0x400
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 = {
* whether bus 00 contains a host bridge (this is similar to checking
* 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).
*
* 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))
{
u16 dfn, class;
u16 dfn, x;
if (pci_probe & PCI_NO_CHECKS)
return 1;
for(dfn=0; dfn < 0x100; dfn++)
if (!a->read_config_word(0, dfn, PCI_CLASS_DEVICE, &class) &&
class == PCI_CLASS_BRIDGE_HOST)
if ((!a->read_config_word(0, dfn, PCI_CLASS_DEVICE, &x) &&
x == PCI_CLASS_BRIDGE_HOST) ||
(!a->read_config_word(0, dfn, PCI_VENDOR_ID, &x) &&
x == PCI_VENDOR_ID_INTEL))
return 1;
DBG("PCI: Sanity check failed\n");
return 0;
......@@ -945,7 +953,7 @@ __initfunc(void pcibios_fixup_ghosts(struct pci_bus *b))
__initfunc(void pcibios_fixup_peer_bridges(void))
{
struct pci_bus *b = &pci_root;
int i, cnt=-1;
int i, n, cnt=-1;
struct pci_dev *d;
#ifdef CONFIG_PCI_DIRECT
......@@ -960,8 +968,8 @@ __initfunc(void pcibios_fixup_peer_bridges(void))
for(d=b->devices; d; d=d->sibling)
if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
cnt++;
do {
int n = b->subordinate+1;
n = b->subordinate + 1;
while (n <= 0xff) {
int found = 0;
u16 l;
for(i=0; i<256; i += 8)
......@@ -973,8 +981,9 @@ __initfunc(void pcibios_fixup_peer_bridges(void))
l == PCI_CLASS_BRIDGE_HOST)
cnt++;
}
if (found && cnt > 0) {
cnt--;
if (cnt-- <= 0)
break;
if (found) {
printk("PCI: Discovered primary peer bus %02x\n", n);
b = kmalloc(sizeof(*b), GFP_KERNEL);
memset(b, 0, sizeof(*b));
......@@ -983,9 +992,10 @@ __initfunc(void pcibios_fixup_peer_bridges(void))
b->number = b->secondary = n;
b->subordinate = 0xff;
b->subordinate = pci_scan_bus(b);
break;
n = b->subordinate;
}
} while (i < 256);
n++;
}
}
/*
......@@ -1146,11 +1156,11 @@ __initfunc(char *pcibios_setup(char *str))
#endif
#ifdef CONFIG_PCI_DIRECT
else if (!strcmp(str, "conf1")) {
pci_probe = PCI_PROBE_CONF1;
pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
return NULL;
}
else if (!strcmp(str, "conf2")) {
pci_probe = PCI_PROBE_CONF2;
pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS;
return NULL;
}
#endif
......
......@@ -371,9 +371,16 @@ static int __init MPBIOS_trigger(int idx)
{
switch (mp_bus_id_to_type[bus])
{
case MP_BUS_ISA: /* ISA pin, edge */
{
trigger = 0;
case MP_BUS_ISA: {
/* ISA pin, read the Edge/Level control register */
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;
}
case MP_BUS_PCI: /* PCI pin, level */
......@@ -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 (!action)
if (!action) {
printk("Unhandled edge irq %d (%x %p)\n", irq, status, desc->action);
return;
}
/*
* Edge triggered interrupts need to remember
......@@ -1061,8 +1070,10 @@ static void do_level_ioapic_IRQ(unsigned int irq, struct pt_regs * regs)
spin_unlock(&irq_controller_lock);
/* 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;
}
handle_IRQ_event(irq, regs, action);
......
......@@ -664,8 +664,10 @@ static void do_8259A_IRQ(unsigned int irq, struct pt_regs * regs)
spin_unlock(&irq_controller_lock);
/* 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;
}
handle_IRQ_event(irq, regs, action);
......
......@@ -426,8 +426,7 @@ static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_s
&& (q->sector & 63) == 1
&& (q->end_sector & 63) == 63) {
unsigned int heads = q->end_head + 1;
if (heads == 15 || heads == 16 ||
heads == 32 || heads == 64 ||
if (heads == 32 || heads == 64 ||
heads == 128 || heads == 240 ||
heads == 255) {
(void) ide_xlate_1024(dev, heads, " [PTBL]");
......
......@@ -102,7 +102,7 @@ static struct esp_pio_buffer *free_pio_buf;
#define WAKEUP_CHARS 1024
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);
......@@ -2615,6 +2615,9 @@ __initfunc(int espserial_init(void))
}
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;
offset = 0;
......@@ -2644,8 +2647,6 @@ __initfunc(int espserial_init(void))
info->callout_termios = esp_callout_driver.init_termios;
info->normal_termios = esp_driver.init_termios;
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_off = flow_off;
info->config.pio_threshold = pio_threshold;
......@@ -2681,6 +2682,9 @@ __initfunc(int espserial_init(void))
}
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) {
i++;
......
......@@ -611,13 +611,18 @@ static char * __init initialize_kbd(void)
void __init pckbd_init_hw(void)
{
disable_irq(KEYBOARD_IRQ);
/* Flush any pending input. */
kbd_clear_input();
if (kbd_startup_reset) {
char *msg = initialize_kbd();
if (msg)
if (msg) {
printk(KERN_WARNING "initialize_kbd: %s\n", msg);
aux_device_present = 0;
return;
}
}
request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL);
......
......@@ -1386,6 +1386,7 @@ ppp_ioctl(struct ppp *ppp, unsigned int param2, unsigned long param3)
break;
if (temp_i < PPP_MRU)
temp_i = PPP_MRU;
ppp->mru = temp_i;
if (ppp->flags & SC_DEBUG)
printk(KERN_INFO
"ppp_ioctl: set mru to %x\n", temp_i);
......
......@@ -65,8 +65,7 @@ static imm_struct imm_hosts[NO_HOSTS] =
#define IMM_BASE(x) imm_hosts[(x)].base
int base[NO_HOSTS] =
{0x03bc, 0x0378, 0x0278, 0x0000};
int parbus_base[NO_HOSTS] = {0x03bc, 0x0378, 0x0278, 0x0000};
void imm_wakeup(void *ref)
{
......
This diff is collapsed.
......@@ -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)
{
struct buffer_head * bh;
......@@ -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) &
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))
ext2_error (sb, "ext2_check_blocks_bitmap",
"Superblock in group %d "
......
......@@ -764,8 +764,8 @@ void cleanup_module(void)
int ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
{
unsigned long overhead;
unsigned long overhead_per_group;
struct statfs tmp;
int ngroups, i;
if (test_opt (sb, MINIX_DF))
overhead = 0;
......@@ -773,13 +773,35 @@ int ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
/*
* Compute the overhead (FS structures)
*/
overhead_per_group = 1 /* super block */ +
sb->u.ext2_sb.s_db_per_group /* descriptors */ +
1 /* block bitmap */ +
1 /* inode bitmap */ +
sb->u.ext2_sb.s_itb_per_group /* inode table */;
overhead = le32_to_cpu(sb->u.ext2_sb.s_es->s_first_data_block) +
sb->u.ext2_sb.s_groups_count * overhead_per_group;
/*
* All of the blocks before first_data_block are
* overhead
*/
overhead = le32_to_cpu(sb->u.ext2_sb.s_es->s_first_data_block);
/*
* 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;
......
This diff is collapsed.
......@@ -54,25 +54,23 @@
{if (buffer) kfree(buffer); \
if (cont_extent){ \
int block, offset, offset1; \
struct buffer_head * bh; \
struct buffer_head * pbh; \
buffer = kmalloc(cont_size,GFP_KERNEL); \
if (!buffer) goto out; \
block = cont_extent; \
offset = cont_offset; \
offset1 = 0; \
if(buffer) { \
bh = bread(DEV->i_dev, block, ISOFS_BUFFER_SIZE(DEV)); \
if(bh){ \
memcpy(buffer + offset1, bh->b_data + offset, cont_size - offset1); \
brelse(bh); \
chr = (unsigned char *) buffer; \
len = cont_size; \
cont_extent = 0; \
cont_size = 0; \
cont_offset = 0; \
goto LABEL; \
}; \
} \
pbh = bread(DEV->i_dev, block, ISOFS_BUFFER_SIZE(DEV)); \
if(pbh){ \
memcpy(buffer + offset1, pbh->b_data + offset, cont_size - offset1); \
brelse(pbh); \
chr = (unsigned char *) buffer; \
len = cont_size; \
cont_extent = 0; \
cont_size = 0; \
cont_offset = 0; \
goto LABEL; \
}; \
printk("Unable to read rock-ridge attributes\n"); \
}}
......@@ -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;
*retname = 0;
retnamlen = 0;
SETUP_ROCK_RIDGE(de, chr, len);
repeat:
......@@ -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 -> i_sb -> u.isofs_sb.s_log_zone_size;
reloc = iget(inode->i_sb, inode->u.isofs_i.i_first_extent);
if (!reloc)
goto out;
inode->i_mode = reloc->i_mode;
inode->i_nlink = reloc->i_nlink;
inode->i_uid = reloc->i_uid;
......@@ -396,8 +395,8 @@ char * get_rock_ridge_symlink(struct inode * inode)
unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
struct buffer_head * bh;
char * rpnt = NULL;
unsigned char * pnt;
char * rpnt;
struct iso_directory_record * raw_inode;
CONTINUE_DECLS;
int block;
......@@ -410,13 +409,10 @@ char * get_rock_ridge_symlink(struct inode * inode)
if (!inode->i_sb->u.isofs_sb.s_rock)
panic("Cannot have symlink with high sierra variant of iso filesystem\n");
rpnt = 0;
block = inode->i_ino >> bufbits;
if (!(bh=bread(inode->i_dev,block, bufsize))) {
printk("unable to read i-node block");
return NULL;
};
bh = bread(inode->i_dev, block, bufsize);
if (!bh)
goto out_noread;
pnt = ((unsigned char *) bh->b_data) + (inode->i_ino & (bufsize - 1));
......@@ -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 ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize){
printk("symlink spans iso9660 blocks\n");
return NULL;
};
if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize)
goto out_bad_span;
/* Now test for possible Rock Ridge extensions which will override some of
these numbers in the inode structure. */
......@@ -511,16 +505,23 @@ char * get_rock_ridge_symlink(struct inode * inode)
};
};
MAYBE_CONTINUE(repeat,inode);
brelse(bh);
return rpnt;
out:
if(buffer) kfree(buffer);
return 0;
out_freebh:
brelse(bh);
return rpnt;
/* 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)
}
/*
* The bitmask for a follow event: normal
* follow, and follow requires a directory
* entry due to a slash ('/') after the
* name, and whether to continue to parse
* the name..
* The bitmask for a lookup event:
* - follow links at the end
* - require a directory
* - ending slashes ok even for nonexistent files
* - internal "there are more path compnents" flag
*/
#define FOLLOW_LINK (1)
#define FOLLOW_DIRECTORY (2)
#define FOLLOW_CONTINUE (4)
#define LOOKUP_FOLLOW (1)
#define LOOKUP_DIRECTORY (2)
#define LOOKUP_SLASHOK (4)
#define LOOKUP_CONTINUE (8)
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)
* This is the basic name resolution function, turning a pathname
* 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 inode *inode;
......@@ -351,14 +352,14 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned
goto return_base;
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. */
for(;;) {
int err;
unsigned long hash;
struct qstr this;
unsigned int follow;
unsigned int flags;
unsigned int c;
err = permission(inode, MAY_EXEC);
......@@ -379,16 +380,16 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned
this.hash = end_name_hash(hash);
/* remove trailing slashes? */
follow = follow_link;
flags = lookup_flags;
if (c) {
char tmp;
follow |= FOLLOW_DIRECTORY;
flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
do {
tmp = *++name;
} while (tmp == '/');
if (tmp)
follow |= FOLLOW_CONTINUE;
flags |= LOOKUP_CONTINUE;
}
/*
......@@ -418,26 +419,47 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned
/* Check mountpoints.. */
dentry = follow_mount(dentry);
if (!follow)
if (!(flags & LOOKUP_FOLLOW))
break;
base = do_follow_link(base, dentry, follow);
base = do_follow_link(base, dentry, flags);
if (IS_ERR(base))
goto return_base;
dentry = ERR_PTR(-ENOENT);
inode = base->d_inode;
if (follow & FOLLOW_DIRECTORY) {
if (flags & LOOKUP_DIRECTORY) {
if (!inode)
break;
goto no_inode;
dentry = ERR_PTR(-ENOTDIR);
if (!inode->i_op || !inode->i_op->lookup)
break;
if (follow & FOLLOW_CONTINUE)
if (flags & LOOKUP_CONTINUE)
continue;
}
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);
return dentry;
......@@ -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
* 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;
struct dentry *dentry;
......@@ -461,7 +483,7 @@ struct dentry * __namei(const char *pathname, unsigned int follow_link)
name = getname(pathname);
dentry = (struct dentry *) name;
if (!IS_ERR(name)) {
dentry = lookup_dentry(name, NULL, follow_link);
dentry = lookup_dentry(name, NULL, lookup_flags);
putname(name);
if (!IS_ERR(dentry)) {
if (!dentry->d_inode) {
......@@ -659,7 +681,7 @@ struct dentry * do_mknod(const char * filename, int mode, dev_t dev)
struct dentry *dentry, *retval;
mode &= ~current->fs->umask;
dentry = lookup_dentry(filename, NULL, 1);
dentry = lookup_dentry(filename, NULL, LOOKUP_FOLLOW);
if (IS_ERR(dentry))
return dentry;
......@@ -743,7 +765,7 @@ static inline int do_mkdir(const char * pathname, int mode)
struct dentry *dir;
struct dentry *dentry;
dentry = lookup_dentry(pathname, NULL, 0);
dentry = lookup_dentry(pathname, NULL, LOOKUP_SLASHOK);
error = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto exit;
......@@ -1150,7 +1172,16 @@ static inline int do_rename(const char * oldname, const char * newname)
if (IS_ERR(old_dentry))
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);
if (IS_ERR(new_dentry))
......@@ -1161,10 +1192,6 @@ static inline int do_rename(const char * oldname, const char * newname)
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);
if (error)
goto exit_lock;
......
......@@ -416,23 +416,16 @@ parent->d_name.name, dentry->d_name.name);
*/
error = nfs_proc_lookup(NFS_DSERVER(parent), NFS_FH(parent),
dentry->d_name.name, &fhandle, &fattr);
if (error) {
printk("nfs_lookup_revalidate: error=%d\n", error);
if (error)
goto out_bad;
}
/* Inode number matches? */
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);
if (fattr.fileid != inode->i_ino)
goto out_bad;
}
/* Filehandle matches? */
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);
if (memcmp(dentry->d_fsdata, &fhandle, sizeof(struct nfs_fh)))
goto out_bad;
}
out_valid:
return 1;
......
......@@ -322,18 +322,20 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
goto out_shutdown;
out_no_iod:
printk("NFS: couldn't start rpciod!\n");
printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
out_shutdown:
rpc_shutdown_client(server->client);
goto out_unlock;
goto out_free_host;
out_no_client:
printk("NFS: cannot create RPC client.\n");
printk(KERN_WARNING "NFS: cannot create RPC client.\n");
xprt_destroy(xprt);
goto out_unlock;
goto out_free_host;
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);
out_unlock:
unlock_super(sb);
......@@ -393,9 +395,10 @@ void nfs_free_dentries(struct inode *inode)
tmp = head;
while ((tmp = tmp->next) != head) {
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) {
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);
d_drop(dentry);
dput(dentry);
......
......@@ -215,7 +215,7 @@ int mem_mmap(struct file * file, struct vm_area_struct * vma)
pgd_t *src_dir, *dest_dir;
pmd_t *src_middle, *dest_middle;
pte_t *src_table, *dest_table;
unsigned long stmp, dtmp;
unsigned long stmp, dtmp, mapnr;
struct vm_area_struct *src_vma = NULL;
struct inode *inode = file->f_dentry->d_inode;
......@@ -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(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;
dtmp += PAGE_SIZE;
......
......@@ -868,17 +868,19 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
struct vfsmount *vfsmnt;
int error;
down(&mount_sem);
error = -EACCES;
if (!(flags & MS_RDONLY) && dev && is_read_only(dev))
goto out;
/*flags |= MS_RDONLY;*/
/*
* Do the lookup first to force automounting.
*/
dir_d = namei(dir_name);
error = PTR_ERR(dir_d);
if (IS_ERR(dir_d))
goto out;
down(&mount_sem);
error = -ENOTDIR;
if (!S_ISDIR(dir_d->d_inode->i_mode))
goto dput_and_out;
......@@ -906,18 +908,16 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
error = -ENOMEM;
vfsmnt = add_vfsmnt(sb, dev_name, dir_name);
if (!vfsmnt)
goto dput_and_out;
d_mount(dir_d, sb->s_root);
error = 0; /* we don't dput(dir_d) - see umount */
out:
up(&mount_sem);
return error;
if (vfsmnt) {
d_mount(dget(dir_d), sb->s_root);
error = 0;
}
dput_and_out:
dput(dir_d);
goto out;
up(&mount_sem);
out:
return error;
}
......
......@@ -20,6 +20,7 @@
#include <asm/uaccess.h>
#define UMSDOS_SPECIAL_DIRFPOS 3
extern struct dentry *saved_root;
extern struct inode *pseudo_root;
/* #define UMSDOS_DEBUG_VERBOSE 1 */
......@@ -53,42 +54,6 @@ static struct dentry_operations umsdos_dentry_operations =
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.
......@@ -203,9 +168,11 @@ Printk (("umsdos_readdir_x: what UMSDOS_SPECIAL_DIRFPOS /mn/?\n"));
ret = PTR_ERR(demd);
if (IS_ERR(demd))
goto out_end;
ret = 0;
ret = -EIO;
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;
}
......@@ -404,18 +371,17 @@ static int UMSDOS_readdir (struct file *filp, void *dirbuf, filldir_t filldir)
* does this automatically.
*/
void umsdos_lookup_patch (struct inode *dir, struct inode *inode,
struct umsdos_dirent *entry, off_t emd_pos)
void umsdos_lookup_patch_new(struct dentry *dentry, struct umsdos_info *info)
{
if (inode->i_sb != dir->i_sb)
goto out;
if (umsdos_isinit (inode))
goto out;
struct inode *inode = dentry->d_inode;
struct umsdos_dirent *entry = &info->entry;
if (S_ISDIR (inode->i_mode))
umsdos_lockcreate (inode);
if (umsdos_isinit (inode))
goto out_unlock;
/*
* This part of the initialization depends only on i_patched.
*/
if (inode->u.umsdos_i.i_patched)
goto out;
inode->u.umsdos_i.i_patched = 1;
if (S_ISREG (entry->mode))
entry->mtime = inode->i_mtime;
......@@ -444,149 +410,17 @@ void umsdos_lookup_patch (struct inode *dir, struct inode *inode,
"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:
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.
*/
......@@ -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)
{
const char *name = dentry->d_name.name;
int len = dentry->d_name.len;
struct dentry *dret = NULL;
struct inode *inode;
int ret = -ENOENT;
......@@ -640,28 +472,13 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
#endif
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)) {
/* #Specification: pseudo root / lookup(DOS)
* A lookup of DOS in the pseudo root will always succeed
* and return the inode of the real root.
*/
inode = iget(dir->i_sb, UMSDOS_ROOT_INO);
if (inode)
goto out_add;
ret = -ENOMEM;
goto out;
inode = saved_root->d_inode;
goto out_add;
}
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);
inode = dret->d_inode;
if (!inode)
goto out_remove;
umsdos_lookup_patch_new(dret, &info.entry, info.f_pos);
umsdos_lookup_patch_new(dret, &info);
#ifdef UMSDOS_DEBUG_VERBOSE
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);
......@@ -726,6 +543,7 @@ dret->d_parent->d_name.name, dret->d_name.name);
* mode.
*/
printk(KERN_WARNING "umsdos_lookup_x: untested, inode == Pseudo_root\n");
ret = -ENOENT;
goto out_dput;
}
......
......@@ -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)
{
......@@ -202,6 +204,8 @@ struct dentry *umsdos_get_emd_dentry(struct dentry *parent)
/*
* 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)
{
......@@ -219,11 +223,12 @@ int umsdos_have_emd(struct dentry *dir)
/*
* Create the EMD file for a directory if it doesn't
* 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)
{
struct dentry *demd = umsdos_get_emd_dentry(parent);
struct inode *inode;
int err = PTR_ERR(demd);
if (IS_ERR(demd)) {
......@@ -234,8 +239,7 @@ int umsdos_make_emd(struct dentry *parent)
/* already created? */
err = 0;
inode = demd->d_inode;
if (inode)
if (demd->d_inode)
goto out_set;
Printk(("umsdos_make_emd: creating EMD %s/%s\n",
......@@ -244,15 +248,12 @@ parent->d_name.name, demd->d_name.name));
err = msdos_create(parent->d_inode, demd, S_IFREG | 0777);
if (err) {
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);
goto out_dput;
}
inode = demd->d_inode;
out_set:
parent->d_inode->u.umsdos_i.i_emd_dir = inode->i_ino;
/* Disable UMSDOS_notify_change() for EMD file */
inode->u.umsdos_i.i_emd_owner = 0xffffffff;
parent->d_inode->u.umsdos_i.i_emd_dir = demd->d_inode->i_ino;
out_dput:
dput(demd);
......@@ -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.
* Support variable length record.
......@@ -387,6 +302,8 @@ Printk (("umsdos_emd_dir_readentry /mn/: returning len=%d,name=%.*s\n",
/*
* Write an entry in the EMD file.
* 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,
int free_entry)
......@@ -405,8 +322,9 @@ static int umsdos_writeentry (struct dentry *parent, struct umsdos_info *info,
/* make sure there's an EMD file */
ret = -EIO;
if (!emd_dentry->d_inode) {
printk("umsdos_writeentry: no EMD file in %s/%s\n",
parent->d_parent->d_name.name, parent->d_name.name);
printk(KERN_WARNING
"umsdos_writeentry: no EMD file in %s/%s\n",
parent->d_parent->d_name.name, parent->d_name.name);
goto out_dput;
}
......@@ -468,6 +386,8 @@ struct find_buffer {
* Unread bytes are simply moved to the beginning.
*
* 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)
......@@ -518,6 +438,7 @@ static int umsdos_fillbuf (struct find_buffer *buf)
* All this to say that umsdos_writeentry must be called after this
* 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
* 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));
* is in the dos_dirent.name field and the destination
* 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.
*/
old_dentry = umsdos_lookup_dentry (dentry,
......@@ -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);
dput(new_dentry);
}
d_drop(old_dentry);
dput(old_dentry);
goto out;
}
......@@ -306,6 +305,11 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
data.umsdos_dirent.name_len, &info);
ret = umsdos_delentry (dentry, &info,
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;
}
else if (cmd == UMSDOS_UNLINK_DOS) {
......@@ -324,9 +328,11 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
if (IS_ERR(temp))
goto out;
ret = -ENOENT;
if (temp->d_inode)
ret = msdos_unlink (dir, temp);
d_drop(temp);
if (temp->d_inode) {
ret = -EISDIR;
if (!S_ISDIR(temp->d_inode->i_mode))
ret = msdos_unlink (dir, temp);
}
dput (temp);
goto out;
}
......@@ -346,9 +352,11 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
if (IS_ERR(temp))
goto out;
ret = -ENOENT;
if (temp->d_inode)
ret = msdos_rmdir (dir, temp);
d_drop(temp);
if (temp->d_inode) {
ret = -ENOTDIR;
if (S_ISDIR(temp->d_inode->i_mode))
ret = msdos_rmdir (dir, temp);
}
dput (temp);
goto out;
......@@ -385,7 +393,6 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
sizeof (data.stat)))
ret = 0;
}
d_drop(dret);
dput(dret);
goto out;
}
......
This diff is collapsed.
......@@ -19,6 +19,7 @@
#include <asm/uaccess.h>
extern struct dentry *saved_root;
extern struct inode *pseudo_root;
extern struct dentry_operations umsdos_dentry_operations;
......@@ -64,9 +65,7 @@ static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t filldir)
bufk.filldir = filldir;
bufk.dirbuf = dirbuf;
bufk.real_root = pseudo_root &&
dir->i_ino == UMSDOS_ROOT_INO &&
dir->i_sb == pseudo_root->i_sb;
bufk.real_root = pseudo_root && (dir == saved_root->d_inode);
return fat_readdir (filp, &bufk, rdir_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)
{
/* so locating "linux" will work */
const char *name = dentry->d_name.name;
int len = dentry->d_name.len;
struct inode *inode;
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] == '.' &&
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");
pseudo_root->i_count++;
d_add(dentry, pseudo_root);
ret = 0;
goto out;
}
#endif
ret = msdos_lookup (dir, dentry);
if (ret) {
printk(KERN_WARNING "umsdos_rlookup_x: lookup failed, ret=%d\n",
ret);
printk(KERN_WARNING
"umsdos_rlookup_x: %s/%s failed, ret=%d\n",
dentry->d_parent->d_name.name, dentry->d_name.name,ret);
goto out;
}
inode = dentry->d_inode;
if (inode) {
if (inode == pseudo_root && !nopseudo) {
if (dentry->d_inode) {
/* We must install 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_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
* Even in the real root directory (c:\), the directory
* /linux won't show
......@@ -114,20 +124,11 @@ printk(KERN_WARNING "umsdos_rlookup_x: do the pseudo-thingy...\n");
/* make the dentry negative */
d_delete(dentry);
}
else if (S_ISDIR (inode->i_mode)) {
/* 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);
}
#endif
}
out:
/* always install our dentry ops ... */
dentry->d_op = &umsdos_dentry_operations;
PRINTK ((KERN_DEBUG "umsdos_rlookup_x: returning %d\n", ret));
return ret;
}
......@@ -168,18 +169,18 @@ static int UMSDOS_rrmdir ( struct inode *dir, struct dentry *dentry)
if (umsdos_is_pseudodos (dir, dentry))
goto out;
umsdos_lockcreate (dir);
ret = -EBUSY;
if (dentry->d_count > 1) {
shrink_dcache_parent(dentry);
if (dentry->d_count > 1)
goto out_unlock;
goto out;
}
ret = msdos_rmdir (dir, dentry);
if (ret != -ENOTEMPTY)
goto out_unlock;
goto out;
down(&dentry->d_inode->i_sem);
empty = umsdos_isempty (dentry);
if (empty == 1) {
struct dentry *demd;
......@@ -192,14 +193,14 @@ static int UMSDOS_rrmdir ( struct inode *dir, struct dentry *dentry)
ret = msdos_unlink (dentry->d_inode, demd);
dput(demd);
}
if (ret)
goto out_unlock;
}
up(&dentry->d_inode->i_sem);
if (ret)
goto out;
/* now retry the original ... */
ret = msdos_rmdir (dir, dentry);
out_unlock:
umsdos_unlockcreate (dir);
out:
return ret;
}
......
......@@ -520,6 +520,7 @@ struct ext2_dir_entry_2 {
extern int ext2_permission (struct inode *, int);
/* balloc.c */
extern int ext2_group_sparse(int group);
extern int ext2_new_block (const struct inode *, unsigned long,
__u32 *, __u32 *, int *);
extern void ext2_free_blocks (const struct inode *, unsigned long,
......
......@@ -165,19 +165,23 @@ struct dqstats {
#define DQ_FAKE 0x40 /* no limits only usage */
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) */
short dq_type; /* Type of quota */
kdev_t dq_dev; /* Device this applies to */
short dq_type; /* Type of quota */
short dq_flags; /* See DQ_* */
short dq_count; /* Reference count */
unsigned long dq_referenced; /* Number of times this dquot was referenced during its lifetime */
struct vfsmount *dq_mnt; /* VFS_mount_point this applies to */
unsigned long dq_referenced; /* Number of times this dquot was
referenced during its lifetime */
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
......
......@@ -14,6 +14,8 @@
#include <linux/config.h>
#include <linux/sunrpc/sched.h>
/* size of the nodename buffer */
#define UNX_MAXNODENAME 32
/*
* Client user credentials
......
......@@ -52,6 +52,9 @@ struct rpc_clnt {
struct rpc_portmap cl_pmap; /* port mapping */
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_prog cl_pmap.pm_prog
......
......@@ -71,7 +71,7 @@ enum {
};
#define TCP_STATE_MASK 0xF
#define TCP_ACTION_FIN 1 << 7
#define TCP_ACTION_FIN (1 << 7)
enum {
TCPF_ESTABLISHED = (1 << 1),
......
......@@ -2,31 +2,14 @@
void check_page_tables (void);
/* 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,
char *buf,
size_t size,
loff_t *count);
char * umsdos_d_path(struct dentry *, char *, int);
void umsdos_lookup_patch_new(struct dentry *, struct umsdos_dirent *, off_t);
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);
void umsdos_lookup_patch_new(struct dentry *, struct umsdos_info *);
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);
int UMSDOS_lookup(struct inode *, struct dentry *);
struct dentry *umsdos_lookup_dentry(struct dentry *, char *, int, int);
......@@ -52,7 +35,6 @@ ssize_t umsdos_emd_dir_read (struct file *filp,
struct dentry *umsdos_get_emd_dentry(struct dentry *);
int umsdos_have_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_newentry (struct dentry *, struct umsdos_info *);
int umsdos_newhidden (struct dentry *, struct umsdos_info *);
......@@ -63,32 +45,20 @@ int umsdos_isempty (struct dentry *);
/* file.c 25/01/95 02.25.38 */
/* 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);
struct dentry *creat_dentry (const char *name,
const int len,
struct inode *inode,
struct dentry *parent);
void UMSDOS_read_inode (struct inode *);
void UMSDOS_write_inode (struct inode *);
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 *);
int UMSDOS_statfs (struct super_block *, struct statfs *, int);
struct super_block *UMSDOS_read_super (struct super_block *, void *, int);
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_inode (struct inode *inode);
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);
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);
/* ioctl.c 22/06/95 00.22.08 */
......@@ -96,6 +66,7 @@ int UMSDOS_ioctl_dir (struct inode *dir,
struct file *filp,
unsigned int cmd,
unsigned long data);
/* mangle.c 25/01/95 02.25.38 */
void umsdos_manglename (struct umsdos_info *info);
int umsdos_evalrecsize (int len);
......@@ -135,9 +106,13 @@ int UMSDOS_rename (struct inode *old_dir,
struct dentry *new_dentry);
/* rdir.c 22/03/95 03.31.42 */
int umsdos_rlookup_x (struct inode *dir,
struct dentry *dentry,
int nopseudo);
int UMSDOS_rlookup (struct inode *dir,
struct dentry *dentry);
int umsdos_rlookup_x (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 */
/* 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 {
struct msdos_inode_info msdos_info;
struct pipe_inode_info pipe_info;
struct dir_locking_info dir_info;
} u; /* Simply a filler, never referenced by fs/umsdos/... */
unsigned long i_dir_owner; /* Inode of the dir which hold this entry */
unsigned long i_emd_owner; /* Inode of the EMD file of i_dir_owner */
} u;
int i_patched; /* Inode has been patched */
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 */
/* The rest is used only if this inode describe a directory */
unsigned long i_emd_dir; /* Inode of the EMD file of this inode */
/* The rest is used only if this inode describes a directory */
struct dentry *i_emd_dentry; /* EMD dentry for this directory */
unsigned long i_emd_dir; /* Inode of the EMD file */
};
#endif
......@@ -598,9 +598,9 @@ unsigned int tcp_poll(struct file * file, struct socket *sock, poll_table *wait)
sk->urginline || !tp->urg_data))
mask |= POLLIN | POLLRDNORM;
/* Always wake the user up when an error occurred */
if (sock_wspace(sk) >= tcp_min_write_space(sk, tp) || sk->err)
if (sock_wspace(sk) >= tcp_min_write_space(sk, tp))
mask |= POLLOUT | POLLWRNORM;
if (tp->urg_data & URG_VALID)
mask |= POLLPRI;
}
......@@ -1458,7 +1458,8 @@ void tcp_close(struct sock *sk, unsigned long timeout)
* reader process may not have drained the data yet!
*/
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);
}
......
......@@ -10,7 +10,6 @@
#include <linux/malloc.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/utsname.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/auth.h>
......@@ -28,13 +27,7 @@ struct unx_cred {
#define UNX_CRED_EXPIRE (60 * HZ)
#ifndef DONT_FILLIN_HOSTNAME
/* # 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
#define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2))
#ifdef RPC_DEBUG
# define RPCDBG_FACILITY RPCDBG_AUTH
......@@ -170,6 +163,7 @@ unx_match(struct rpc_task * task, struct rpc_cred *rcred)
static u32 *
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;
u32 *base, *hold;
int i, n;
......@@ -177,20 +171,15 @@ unx_marshal(struct rpc_task *task, u32 *p, int ruid)
*p++ = htonl(RPC_AUTH_UNIX);
base = p++;
*p++ = htonl(jiffies/HZ);
#ifndef DONT_FILLIN_HOSTNAME
/*
* Problem: The UTS name could change under us. We can't lock
* here to handle this. On the other hand we can't really
* go building a bad RPC!
* Copy the UTS nodename captured when the client was created.
*/
if ((n = strlen((char *) system_utsname.nodename)) > UNX_MAXNODENAME)
n = UNX_MAXNODENAME;
n = clnt->cl_nodelen;
*p++ = htonl(n);
memcpy(p, system_utsname.nodename, n);
memcpy(p, clnt->cl_nodename, n);
p += (n + 3) >> 2;
#else
*p++ = 0;
#endif
if (ruid) {
*p++ = htonl((u32) cred->uc_uid);
*p++ = htonl((u32) cred->uc_gid);
......
......@@ -28,6 +28,7 @@
#include <linux/mm.h>
#include <linux/malloc.h>
#include <linux/in.h>
#include <linux/utsname.h>
#include <linux/sunrpc/clnt.h>
......@@ -101,6 +102,12 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
if (!rpcauth_create(flavor, clnt))
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:
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