in fs/devfs/base.c,
the struct devfsd_notify_struct is approx 1056 bytes, allocating it on
a stack of 8k seems unreasonable. here we simply move it to the heap, i
don't think it is a _must_ be on stack type thing
-aki-
--- fs/devfs/base.c.orig Tue Apr 17 15:04:10 2001
+++ fs/devfs/base.c Tue May 22 23:59:54 2001
@@ -3153,7 +3153,7 @@
int done = FALSE;
int ival;
loff_t pos, devname_offset, tlen, rpos;
- struct devfsd_notify_struct info;
+ struct devfsd_notify_struct* info;
struct devfsd_buf_entry *entry;
struct fs_info *fs_info = file->f_dentry->d_inode->i_sb->u.generic_sbp;
DECLARE_WAITQUEUE (wait, current);
@@ -3162,8 +3162,14 @@
if (ppos != &file->f_pos) return -ESPIPE;
/* Verify the task has grabbed the queue */
if (fs_info->devfsd_task != current) return -EPERM;
- info.major = 0;
- info.minor = 0;
+
+ /* must alloc the info struct */
+ info = kmalloc(sizeof(struct devfsd_notify_struct), GFP_KERNEL);
+ if(info == NULL)
+ return -ENOMEM;
+
+ info->major = 0;
+ info->minor = 0;
/* Block for a new entry */
add_wait_queue (&fs_info->devfsd_wait_queue, &wait);
current->state = TASK_INTERRUPTIBLE;
@@ -3177,6 +3183,7 @@
{
remove_wait_queue (&fs_info->devfsd_wait_queue, &wait);
current->state = TASK_RUNNING;
+ kfree(info);
return -EINTR;
}
set_current_state(TASK_INTERRUPTIBLE);
@@ -3186,18 +3193,18 @@
/* Now play with the data */
ival = atomic_read (&fs_info->devfsd_overrun_count);
if (ival > 0) atomic_sub (ival, &fs_info->devfsd_overrun_count);
- info.overrun_count = ival;
+ info->overrun_count = ival;
entry = (struct devfsd_buf_entry *) fs_info->devfsd_buffer +
fs_info->devfsd_buf_out;
- info.type = entry->type;
- info.mode = entry->mode;
- info.uid = entry->uid;
- info.gid = entry->gid;
+ info->type = entry->type;
+ info->mode = entry->mode;
+ info->uid = entry->uid;
+ info->gid = entry->gid;
if (entry->type == DEVFSD_NOTIFY_LOOKUP)
{
- info.namelen = strlen (entry->data);
+ info->namelen = strlen (entry->data);
pos = 0;
- memcpy (info.devname, entry->data, info.namelen + 1);
+ memcpy (info->devname, entry->data, info->namelen + 1);
}
else
{
@@ -3205,23 +3212,27 @@
if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) )
{
- info.major = de->u.fcb.u.device.major;
- info.minor = de->u.fcb.u.device.minor;
+ info->major = de->u.fcb.u.device.major;
+ info->minor = de->u.fcb.u.device.minor;
+ }
+ pos = devfs_generate_path (de, info->devname, DEVFS_PATHLEN);
+ if (pos < 0) {
+ kfree(info);
+ return pos;
}
- pos = devfs_generate_path (de, info.devname, DEVFS_PATHLEN);
- if (pos < 0) return pos;
- info.namelen = DEVFS_PATHLEN - pos - 1;
- if (info.mode == 0) info.mode = de->mode;
+ info->namelen = DEVFS_PATHLEN - pos - 1;
+ if (info->mode == 0) info->mode = de->mode;
}
- devname_offset = info.devname - (char *) &info;
+ devname_offset = info->devname - (char *) info;
rpos = *ppos;
if (rpos < devname_offset)
{
/* Copy parts of the header */
tlen = devname_offset - rpos;
if (tlen > len) tlen = len;
- if ( copy_to_user (buf, (char *) &info + rpos, tlen) )
+ if ( copy_to_user (buf, (char *) info + rpos, tlen) )
{
+ kfree(info);
return -EFAULT;
}
rpos += tlen;
@@ -3231,12 +3242,13 @@
if ( (rpos >= devname_offset) && (len > 0) )
{
/* Copy the name */
- tlen = info.namelen + 1;
+ tlen = info->namelen + 1;
if (tlen > len) tlen = len;
else done = TRUE;
- if ( copy_to_user (buf, info.devname + pos + rpos - devname_offset,
+ if ( copy_to_user (buf, info->devname + pos + rpos - devname_offset,
tlen) )
{
+ kfree(info);
return -EFAULT;
}
rpos += tlen;
@@ -3251,6 +3263,7 @@
*ppos = 0;
}
else *ppos = rpos;
+ kfree(info);
return tlen;
} /* End Function devfsd_read */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/