Commit 4251bd1a authored by Linus Torvalds's avatar Linus Torvalds

Merge

parents 2a257ccb c7766898
......@@ -338,9 +338,9 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
__asm__ __volatile__("andl %%esp,%0" :
"=r" (esp) : "0" (8191));
if (unlikely(esp < (sizeof(struct task_struct) + 1024))) {
if (unlikely(esp < (sizeof(struct thread_info) + 1024))) {
printk("do_IRQ: stack overflow: %ld\n",
esp - sizeof(struct task_struct));
esp - sizeof(struct thread_info));
dump_stack();
}
}
......
......@@ -2911,7 +2911,11 @@ static void redo_fd_request(void)
for (;;) {
if (!current_req) {
struct request *req = elv_next_request(&floppy_queue);
struct request *req;
spin_lock_irq(floppy_queue.queue_lock);
req = elv_next_request(&floppy_queue);
spin_unlock_irq(floppy_queue.queue_lock);
if (!req) {
do_floppy = NULL;
unlock_fdc();
......
......@@ -305,6 +305,7 @@ static dev_link_t *tc574_attach(void)
link = &lp->link; dev = &lp->dev;
link->priv = dev->priv = link->irq.Instance = lp;
init_timer(&link->release);
link->release.function = &tc574_release;
link->release.data = (u_long)link;
link->io.NumPorts1 = 32;
......
......@@ -229,6 +229,7 @@ static dev_link_t *tc589_attach(void)
link = &lp->link; dev = &lp->dev;
link->priv = dev->priv = link->irq.Instance = lp;
init_timer(&link->release);
link->release.function = &tc589_release;
link->release.data = (unsigned long)link;
link->io.NumPorts1 = 16;
......
......@@ -246,6 +246,7 @@ static dev_link_t *awc_attach(void)
memset(link->dev, 0, sizeof(struct dev_node_t));
init_timer(&link->release);
link->release.function = &awc_release;
link->release.data = (u_long)link;
// link->io.NumPorts1 = 32;
......
......@@ -203,6 +203,7 @@ static dev_link_t *axnet_attach(void)
link = &info->link; dev = &info->dev;
link->priv = info;
init_timer(&link->release);
link->release.function = &axnet_release;
link->release.data = (u_long)link;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
......
......@@ -221,6 +221,7 @@ static dev_link_t *com20020_attach(void)
memset(link, 0, sizeof(struct dev_link_t));
dev->priv = lp;
init_timer(&link->release);
link->release.function = &com20020_release;
link->release.data = (u_long)link;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
......
......@@ -221,6 +221,7 @@ static dev_link_t *ibmtr_attach(void)
memset(info, 0, sizeof(*info));
link = &info->link; link->priv = info;
init_timer(&link->release);
link->release.function = &ibmtr_release;
link->release.data = (u_long)link;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
......
......@@ -493,6 +493,7 @@ static dev_link_t *nmclan_attach(void)
link = &lp->link; dev = &lp->dev;
link->priv = dev->priv = link->irq.Instance = lp;
init_timer(&link->release);
link->release.function = &nmclan_release;
link->release.data = (u_long)link;
link->io.NumPorts1 = 32;
......
......@@ -378,6 +378,7 @@ static dev_link_t *ray_attach(void)
memset(dev, 0, sizeof(struct net_device));
memset(local, 0, sizeof(ray_dev_t));
init_timer(&link->release);
link->release.function = &ray_release;
link->release.data = (u_long)link;
......
......@@ -632,6 +632,7 @@ xirc2ps_attach(void)
link = &local->link; dev = &local->dev;
link->priv = dev->priv = local;
init_timer(&link->release);
link->release.function = &xirc2ps_release;
link->release.data = (u_long) link;
......
......@@ -216,6 +216,7 @@ static dev_link_t *airo_attach(void)
return NULL;
}
memset(link, 0, sizeof(struct dev_link_t));
init_timer(&link->release);
link->release.function = &airo_release;
link->release.data = (u_long)link;
......
......@@ -462,6 +462,7 @@ static dev_link_t *netwave_attach(void)
memset(priv, 0, sizeof(*priv));
link = &priv->link; dev = &priv->dev;
link->priv = dev->priv = priv;
init_timer(&link->release);
link->release.function = &netwave_release;
link->release.data = (u_long)link;
......
......@@ -203,6 +203,7 @@ orinoco_cs_attach(void)
link->priv = dev;
/* Initialize the dev_link_t structure */
init_timer(&link->release);
link->release.function = &orinoco_cs_release;
link->release.data = (u_long) link;
......
......@@ -134,6 +134,7 @@ static dev_link_t *parport_attach(void)
memset(info, 0, sizeof(*info));
link = &info->link; link->priv = info;
init_timer(&link->release);
link->release.function = &parport_cs_release;
link->release.data = (u_long)link;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
......
......@@ -142,6 +142,7 @@ static dev_link_t *aha152x_attach(void)
if (!info) return NULL;
memset(info, 0, sizeof(*info));
link = &info->link; link->priv = info;
init_timer(&link->release);
link->release.function = &aha152x_release_cs;
link->release.data = (u_long)link;
......
......@@ -122,6 +122,7 @@ static dev_link_t *fdomain_attach(void)
if (!info) return NULL;
memset(info, 0, sizeof(*info));
link = &info->link; link->priv = info;
init_timer(&link->release);
link->release.function = &fdomain_release;
link->release.data = (u_long)link;
......
......@@ -126,6 +126,7 @@ static dev_link_t *qlogic_attach(void)
memset(info, 0, sizeof(*info));
link = &info->link;
link->priv = info;
init_timer(&link->release);
link->release.function = &qlogic_release;
link->release.data = (u_long) link;
......
......@@ -63,6 +63,7 @@ static dev_link_t *ixj_attach(void)
if (!link)
return NULL;
memset(link, 0, sizeof(struct dev_link_t));
init_timer(&link->release);
link->release.function = &ixj_cs_release;
link->release.data = (u_long) link;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
......
......@@ -81,21 +81,11 @@ init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private)
* Return the address of the waitqueue_head to be used for this
* buffer_head
*/
static wait_queue_head_t *bh_waitq_head(struct buffer_head *bh)
wait_queue_head_t *bh_waitq_head(struct buffer_head *bh)
{
return &bh_wait_queue_heads[hash_ptr(bh, BH_WAIT_TABLE_ORDER)].wqh;
}
/*
* Wait on a buffer until someone does a wakeup on it. Needs
* lots of external locking. ext3 uses this. Fix it.
*/
void sleep_on_buffer(struct buffer_head *bh)
{
wait_queue_head_t *wq = bh_waitq_head(bh);
sleep_on(wq);
}
EXPORT_SYMBOL(sleep_on_buffer);
EXPORT_SYMBOL(bh_waitq_head);
void wake_up_buffer(struct buffer_head *bh)
{
......@@ -139,7 +129,7 @@ void __wait_on_buffer(struct buffer_head * bh)
prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
blk_run_queues();
if (buffer_locked(bh))
schedule();
io_schedule();
} while (buffer_locked(bh));
put_bh(bh);
finish_wait(wqh, &wait);
......
......@@ -1147,21 +1147,24 @@ static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
namelen = dentry->d_name.len;
buflen -= namelen + 1;
if (buflen < 0)
break;
return ERR_PTR(-ENAMETOOLONG);
end -= namelen;
memcpy(end, dentry->d_name.name, namelen);
*--end = '/';
retval = end;
dentry = parent;
}
return retval;
global_root:
namelen = dentry->d_name.len;
buflen -= namelen;
if (buflen >= 0) {
retval -= namelen-1; /* hit the slash */
memcpy(retval, dentry->d_name.name, namelen);
}
} else
retval = ERR_PTR(-ENAMETOOLONG);
return retval;
}
......@@ -1229,6 +1232,10 @@ asmlinkage long sys_getcwd(char *buf, unsigned long size)
cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE);
spin_unlock(&dcache_lock);
error = PTR_ERR(cwd);
if (IS_ERR(cwd))
goto out;
error = -ERANGE;
len = PAGE_SIZE + page - cwd;
if (len <= size) {
......@@ -1238,6 +1245,8 @@ asmlinkage long sys_getcwd(char *buf, unsigned long size)
}
} else
spin_unlock(&dcache_lock);
out:
dput(pwd);
mntput(pwdmnt);
dput(root);
......
......@@ -892,15 +892,14 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
ret = do_direct_IO(dio);
if (ret) {
dio_cleanup(dio);
break;
}
dio->result += iov[seg].iov_len -
((dio->final_block_in_request - dio->block_in_file) <<
blkbits);
if (ret) {
dio_cleanup(dio);
break;
}
} /* end iovec loop */
/*
......
......@@ -159,7 +159,7 @@ static void put_quota_format(struct quota_format_type *fmt)
* Note that any operation which operates on dquot data (ie. dq_dqb) must
* hold dq_data_lock.
*
* Any operation working with dquots must hold dqoff_sem. If operation is
* Any operation working with dquots must hold dqptr_sem. If operation is
* just reading pointers from inodes than read lock is enough. If pointers
* are altered function must hold write lock.
*
......@@ -270,7 +270,7 @@ static int commit_dqblk(struct dquot *dquot)
}
/* Invalidate all dquots on the list. Note that this function is called after
* quota is disabled so no new quota might be created. Because we hold dqoff_sem
* quota is disabled so no new quota might be created. Because we hold dqptr_sem
* for writing and pointers were already removed from inodes we actually know that
* no quota for this sb+type should be held. */
static void invalidate_dquots(struct super_block *sb, int type)
......@@ -287,7 +287,7 @@ static void invalidate_dquots(struct super_block *sb, int type)
if (dquot->dq_type != type)
continue;
#ifdef __DQUOT_PARANOIA
/* There should be no users of quota - we hold dqoff_sem for writing */
/* There should be no users of quota - we hold dqptr_sem for writing */
if (atomic_read(&dquot->dq_count))
BUG();
#endif
......@@ -307,7 +307,7 @@ static int vfs_quota_sync(struct super_block *sb, int type)
struct quota_info *dqopt = sb_dqopt(sb);
int cnt;
down_read(&dqopt->dqoff_sem);
down_read(&dqopt->dqptr_sem);
restart:
/* At this point any dirty dquot will definitely be written so we can clear
dirty flag from info */
......@@ -340,7 +340,7 @@ static int vfs_quota_sync(struct super_block *sb, int type)
spin_lock(&dq_list_lock);
dqstats.syncs++;
spin_unlock(&dq_list_lock);
up_read(&dqopt->dqoff_sem);
up_read(&dqopt->dqptr_sem);
return 0;
}
......@@ -427,7 +427,7 @@ static int shrink_dqcache_memory(int nr, unsigned int gfp_mask)
/*
* Put reference to dquot
* NOTE: If you change this function please check whether dqput_blocks() works right...
* MUST be called with dqoff_sem held
* MUST be called with dqptr_sem held
*/
static void dqput(struct dquot *dquot)
{
......@@ -492,7 +492,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
/*
* Get reference to dquot
* MUST be called with dqoff_sem held
* MUST be called with dqptr_sem held
*/
static struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
{
......@@ -553,7 +553,7 @@ static int dqinit_needed(struct inode *inode, int type)
return 0;
}
/* This routine is guarded by dqoff_sem semaphore */
/* This routine is guarded by dqptr_sem semaphore */
static void add_dquot_ref(struct super_block *sb, int type)
{
struct list_head *p;
......@@ -586,7 +586,7 @@ static inline int dqput_blocks(struct dquot *dquot)
}
/* Remove references to dquots from inode - add dquot to list for freeing if needed */
/* We can't race with anybody because we hold dqoff_sem for writing... */
/* We can't race with anybody because we hold dqptr_sem for writing... */
int remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head)
{
struct dquot *dquot = inode->i_dquot[type];
......@@ -829,10 +829,10 @@ void dquot_initialize(struct inode *inode, int type)
unsigned int id = 0;
int cnt;
down_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
/* Having dqoff lock we know NOQUOTA flags can't be altered... */
down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
/* Having dqptr_sem we know NOQUOTA flags can't be altered... */
if (IS_NOQUOTA(inode)) {
up_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
return;
}
/* Build list of quotas to initialize... */
......@@ -853,7 +853,7 @@ void dquot_initialize(struct inode *inode, int type)
inode->i_flags |= S_QUOTA;
}
}
up_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
}
/*
......@@ -876,9 +876,9 @@ static void dquot_drop_nolock(struct inode *inode)
void dquot_drop(struct inode *inode)
{
down_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
dquot_drop_nolock(inode);
up_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
}
/*
......@@ -892,7 +892,7 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
warntype[cnt] = NOWARN;
down_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] == NODQUOT)
......@@ -910,7 +910,7 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
warn_put_all:
spin_unlock(&dq_data_lock);
flush_warnings(inode->i_dquot, warntype);
up_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
return ret;
}
......@@ -924,7 +924,7 @@ int dquot_alloc_inode(const struct inode *inode, unsigned long number)
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
warntype[cnt] = NOWARN;
down_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] == NODQUOT)
......@@ -942,7 +942,7 @@ int dquot_alloc_inode(const struct inode *inode, unsigned long number)
warn_put_all:
spin_unlock(&dq_data_lock);
flush_warnings((struct dquot **)inode->i_dquot, warntype);
up_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
return ret;
}
......@@ -953,7 +953,7 @@ void dquot_free_space(struct inode *inode, qsize_t number)
{
unsigned int cnt;
down_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] == NODQUOT)
......@@ -962,7 +962,7 @@ void dquot_free_space(struct inode *inode, qsize_t number)
}
inode_sub_bytes(inode, number);
spin_unlock(&dq_data_lock);
up_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
}
/*
......@@ -972,7 +972,7 @@ void dquot_free_inode(const struct inode *inode, unsigned long number)
{
unsigned int cnt;
down_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] == NODQUOT)
......@@ -980,7 +980,7 @@ void dquot_free_inode(const struct inode *inode, unsigned long number)
dquot_decr_inodes(inode->i_dquot[cnt], number);
}
spin_unlock(&dq_data_lock);
up_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
}
/*
......@@ -1002,7 +1002,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
transfer_to[cnt] = transfer_from[cnt] = NODQUOT;
warntype[cnt] = NOWARN;
}
down_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
if (IS_NOQUOTA(inode)) /* File without quota accounting? */
goto warn_put_all;
/* First build the transfer_to list - here we can block on reading of dquots... */
......@@ -1058,7 +1058,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
if (transfer_from[cnt] != NODQUOT)
dqput(transfer_from[cnt]);
up_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
return ret;
}
......@@ -1114,7 +1114,8 @@ int vfs_quota_off(struct super_block *sb, int type)
goto out;
/* We need to serialize quota_off() for device */
down_write(&dqopt->dqoff_sem);
down(&dqopt->dqonoff_sem);
down_write(&dqopt->dqptr_sem);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (type != -1 && cnt != type)
continue;
......@@ -1145,7 +1146,8 @@ int vfs_quota_off(struct super_block *sb, int type)
dqopt->info[cnt].dqi_bgrace = 0;
dqopt->ops[cnt] = NULL;
}
up_write(&dqopt->dqoff_sem);
up_write(&dqopt->dqptr_sem);
up(&dqopt->dqonoff_sem);
out:
return 0;
}
......@@ -1157,6 +1159,7 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
struct quota_info *dqopt = sb_dqopt(sb);
struct quota_format_type *fmt = find_quota_format(format_id);
int error;
unsigned int oldflags;
if (!fmt)
return -ESRCH;
......@@ -1176,15 +1179,17 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
if (!S_ISREG(inode->i_mode))
goto out_f;
down_write(&dqopt->dqoff_sem);
down(&dqopt->dqonoff_sem);
down_write(&dqopt->dqptr_sem);
if (sb_has_quota_enabled(sb, type)) {
error = -EBUSY;
goto out_lock;
}
oldflags = inode->i_flags;
dqopt->files[type] = f;
error = -EINVAL;
if (!fmt->qf_ops->check_quota_file(sb, type))
goto out_lock;
goto out_file_init;
/* We don't want quota on quota files */
dquot_drop_nolock(inode);
inode->i_flags |= S_NOQUOTA;
......@@ -1194,20 +1199,23 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
down(&dqopt->dqio_sem);
if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) {
up(&dqopt->dqio_sem);
goto out_lock;
goto out_file_init;
}
up(&dqopt->dqio_sem);
set_enable_flags(dqopt, type);
up_write(&dqopt->dqptr_sem);
add_dquot_ref(sb, type);
up(&dqopt->dqonoff_sem);
up_write(&dqopt->dqoff_sem);
return 0;
out_lock:
inode->i_flags &= ~S_NOQUOTA;
out_file_init:
inode->i_flags = oldflags;
dqopt->files[type] = NULL;
up_write(&dqopt->dqoff_sem);
out_lock:
up_write(&dqopt->dqptr_sem);
up(&dqopt->dqonoff_sem);
out_f:
filp_close(f, NULL);
out_fmt:
......@@ -1238,14 +1246,14 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
{
struct dquot *dquot;
down_read(&sb_dqopt(sb)->dqoff_sem);
down_read(&sb_dqopt(sb)->dqptr_sem);
if (!(dquot = dqget(sb, id, type))) {
up_read(&sb_dqopt(sb)->dqoff_sem);
up_read(&sb_dqopt(sb)->dqptr_sem);
return -ESRCH;
}
do_get_dqblk(dquot, di);
dqput(dquot);
up_read(&sb_dqopt(sb)->dqoff_sem);
up_read(&sb_dqopt(sb)->dqptr_sem);
return 0;
}
......@@ -1307,14 +1315,14 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
{
struct dquot *dquot;
down_read(&sb_dqopt(sb)->dqoff_sem);
down_read(&sb_dqopt(sb)->dqptr_sem);
if (!(dquot = dqget(sb, id, type))) {
up_read(&sb_dqopt(sb)->dqoff_sem);
up_read(&sb_dqopt(sb)->dqptr_sem);
return -ESRCH;
}
do_set_dqblk(dquot, di);
dqput(dquot);
up_read(&sb_dqopt(sb)->dqoff_sem);
up_read(&sb_dqopt(sb)->dqptr_sem);
return 0;
}
......@@ -1323,9 +1331,9 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
{
struct mem_dqinfo *mi;
down_read(&sb_dqopt(sb)->dqoff_sem);
down_read(&sb_dqopt(sb)->dqptr_sem);
if (!sb_has_quota_enabled(sb, type)) {
up_read(&sb_dqopt(sb)->dqoff_sem);
up_read(&sb_dqopt(sb)->dqptr_sem);
return -ESRCH;
}
mi = sb_dqopt(sb)->info + type;
......@@ -1335,7 +1343,7 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
ii->dqi_flags = mi->dqi_flags & DQF_MASK;
ii->dqi_valid = IIF_ALL;
spin_unlock(&dq_data_lock);
up_read(&sb_dqopt(sb)->dqoff_sem);
up_read(&sb_dqopt(sb)->dqptr_sem);
return 0;
}
......@@ -1344,9 +1352,9 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
{
struct mem_dqinfo *mi;
down_read(&sb_dqopt(sb)->dqoff_sem);
down_read(&sb_dqopt(sb)->dqptr_sem);
if (!sb_has_quota_enabled(sb, type)) {
up_read(&sb_dqopt(sb)->dqoff_sem);
up_read(&sb_dqopt(sb)->dqptr_sem);
return -ESRCH;
}
mi = sb_dqopt(sb)->info + type;
......@@ -1359,7 +1367,7 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK);
mark_info_dirty(mi);
spin_unlock(&dq_data_lock);
up_read(&sb_dqopt(sb)->dqoff_sem);
up_read(&sb_dqopt(sb)->dqptr_sem);
return 0;
}
......
......@@ -873,12 +873,10 @@ int prepare_binprm(struct linux_binprm *bprm)
void compute_creds(struct linux_binprm *bprm)
{
int do_unlock = 0;
task_lock(current);
if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
current->mm->dumpable = 0;
lock_kernel();
if (must_not_trace_exec(current)
|| atomic_read(&current->fs->count) > 1
|| atomic_read(&current->files->count) > 1
......@@ -888,14 +886,12 @@ void compute_creds(struct linux_binprm *bprm)
bprm->e_gid = current->gid;
}
}
do_unlock = 1;
}
current->suid = current->euid = current->fsuid = bprm->e_uid;
current->sgid = current->egid = current->fsgid = bprm->e_gid;
if(do_unlock)
unlock_kernel();
task_unlock(current);
security_bprm_compute_creds(bprm);
}
......
......@@ -334,22 +334,23 @@ int ext2_new_block (struct inode * inode, unsigned long goal,
if (!prealloc_count || *prealloc_count)
prealloc_goal = 0;
if (DQUOT_ALLOC_BLOCK(inode, 1)) {
*err = -EDQUOT;
if (DQUOT_ALLOC_BLOCK(inode, 1))
goto out;
}
while (prealloc_goal && DQUOT_PREALLOC_BLOCK(inode, prealloc_goal))
prealloc_goal--;
dq_alloc = prealloc_goal + 1;
*err = -ENOSPC;
lock_super (sb);
es_alloc = reserve_blocks(sb, dq_alloc);
if (!es_alloc)
if (!es_alloc) {
*err = -ENOSPC;
goto out_unlock;
}
ext2_debug ("goal=%lu.\n", goal);
......@@ -396,8 +397,10 @@ int ext2_new_block (struct inode * inode, unsigned long goal,
goto io_error;
group_alloc = group_reserve_blocks(desc, gdp_bh, es_alloc);
}
if (bit >= sbi->s_groups_count)
if (bit >= sbi->s_groups_count) {
*err = -ENOSPC;
goto out_release;
}
brelse(bitmap_bh);
bitmap_bh = read_block_bitmap(sb, group_no);
if (!bitmap_bh)
......@@ -409,7 +412,7 @@ int ext2_new_block (struct inode * inode, unsigned long goal,
"Free blocks count corrupted for block group %d",
group_no);
group_alloc = 0;
goto out_release;
goto io_error;
}
got_block:
......@@ -432,7 +435,7 @@ int ext2_new_block (struct inode * inode, unsigned long goal,
"block(%d) >= blocks count(%d) - "
"block_group = %d, es == %p ", ret_block,
le32_to_cpu(es->s_blocks_count), group_no, es);
goto out_release;
goto io_error;
}
block = target_block;
......@@ -470,10 +473,10 @@ int ext2_new_block (struct inode * inode, unsigned long goal,
ext2_debug ("allocating block %d. ", block);
*err = 0;
out_release:
group_release_blocks(desc, gdp_bh, group_alloc);
release_blocks(sb, es_alloc);
*err = 0;
out_unlock:
unlock_super (sb);
DQUOT_FREE_BLOCK(inode, dq_alloc);
......
......@@ -1239,6 +1239,12 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
error = inode_change_ok(inode, iattr);
if (error)
return error;
if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
(iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0;
if (error)
return error;
}
inode_setattr(inode, iattr);
if (iattr->ia_valid & ATTR_MODE)
error = ext2_acl_chmod(inode);
......
......@@ -67,6 +67,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
spin_lock(&inode_lock);
if ((inode->i_state & flags) != flags) {
const int was_dirty = inode->i_state & I_DIRTY;
struct address_space *mapping = inode->i_mapping;
inode->i_state |= flags;
......@@ -90,7 +91,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
* If the inode was already on s_dirty or s_io, don't
* reposition it (that would break s_dirty time-ordering).
*/
if (!mapping->dirtied_when) {
if (!was_dirty) {
mapping->dirtied_when = jiffies|1; /* 0 is special */
list_move(&inode->i_list, &sb->s_dirty);
}
......@@ -280,7 +281,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
__iget(inode);
__writeback_single_inode(inode, really_sync, wbc);
if (wbc->sync_mode == WB_SYNC_HOLD) {
mapping->dirtied_when = jiffies;
mapping->dirtied_when = jiffies|1;
list_move(&inode->i_list, &sb->s_dirty);
}
if (current_is_pdflush())
......
......@@ -176,6 +176,7 @@ void inode_init_once(struct inode *inode)
spin_lock_init(&inode->i_data.private_lock);
INIT_LIST_HEAD(&inode->i_data.i_mmap);
INIT_LIST_HEAD(&inode->i_data.i_mmap_shared);
spin_lock_init(&inode->i_lock);
}
static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
......
......@@ -689,11 +689,14 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, int force_copy)
* disk then we cannot do copy-out here. */
if (jh->b_jlist == BJ_Shadow) {
wait_queue_head_t *wqh;
JBUFFER_TRACE(jh, "on shadow: sleep");
spin_unlock(&journal_datalist_lock);
unlock_journal(journal);
/* commit wakes up all shadow buffers after IO */
sleep_on_buffer(jh2bh(jh));
wqh = bh_waitq_head(jh2bh(jh));
wait_event(*wqh, (jh->b_jlist != BJ_Shadow));
lock_journal(journal);
goto repeat;
}
......
......@@ -123,13 +123,13 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, cadd
case Q_GETFMT: {
__u32 fmt;
down_read(&sb_dqopt(sb)->dqoff_sem);
down_read(&sb_dqopt(sb)->dqptr_sem);
if (!sb_has_quota_enabled(sb, type)) {
up_read(&sb_dqopt(sb)->dqoff_sem);
up_read(&sb_dqopt(sb)->dqptr_sem);
return -ESRCH;
}
fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
up_read(&sb_dqopt(sb)->dqoff_sem);
up_read(&sb_dqopt(sb)->dqptr_sem);
if (copy_to_user(addr, &fmt, sizeof(fmt)))
return -EFAULT;
return 0;
......
......@@ -316,3 +316,45 @@ asmlinkage long sys_fstat64(unsigned long fd, struct stat64 * statbuf, long flag
}
#endif /* LFS-64 */
void inode_add_bytes(struct inode *inode, loff_t bytes)
{
spin_lock(&inode->i_lock);
inode->i_blocks += bytes >> 9;
bytes &= 511;
inode->i_bytes += bytes;
if (inode->i_bytes >= 512) {
inode->i_blocks++;
inode->i_bytes -= 512;
}
spin_unlock(&inode->i_lock);
}
void inode_sub_bytes(struct inode *inode, loff_t bytes)
{
spin_lock(&inode->i_lock);
inode->i_blocks -= bytes >> 9;
bytes &= 511;
if (inode->i_bytes < bytes) {
inode->i_blocks--;
inode->i_bytes += 512;
}
inode->i_bytes -= bytes;
spin_unlock(&inode->i_lock);
}
loff_t inode_get_bytes(struct inode *inode)
{
loff_t ret;
spin_lock(&inode->i_lock);
ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;
spin_unlock(&inode->i_lock);
return ret;
}
void inode_set_bytes(struct inode *inode, loff_t bytes)
{
inode->i_blocks = bytes >> 9;
inode->i_bytes = bytes & 511;
}
......@@ -71,7 +71,8 @@ static struct super_block *alloc_super(void)
atomic_set(&s->s_active, 1);
sema_init(&s->s_vfs_rename_sem,1);
sema_init(&s->s_dquot.dqio_sem, 1);
init_rwsem(&s->s_dquot.dqoff_sem);
sema_init(&s->s_dquot.dqonoff_sem, 1);
init_rwsem(&s->s_dquot.dqptr_sem);
s->s_maxbytes = MAX_NON_LFS;
s->dq_op = sb_dquot_ops;
s->s_qcop = sb_quotactl_ops;
......@@ -310,7 +311,7 @@ void sync_filesystems(int wait)
spin_lock(&sb_lock);
for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks);
sb = sb_entry(sb->s_list.next)) {
if (!sb->s_op->sync_fs);
if (!sb->s_op->sync_fs)
continue;
if (sb->s_flags & MS_RDONLY)
continue;
......
......@@ -13,18 +13,18 @@
} \
\
/* Kernel symbol table: Normal symbols */ \
__start___ksymtab = .; \
__ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
__start___ksymtab = .; \
*(__ksymtab) \
} \
__stop___ksymtab = .; \
} \
\
/* Kernel symbol table: GPL-only symbols */ \
__start___gpl_ksymtab = .; \
__gpl_ksymtab : AT(ADDR(__gpl_ksymtab) - LOAD_OFFSET) { \
__start___gpl_ksymtab = .; \
*(__gpl_ksymtab) \
} \
__stop___gpl_ksymtab = .; \
} \
\
/* Kernel symbol table: strings */ \
__ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
......
......@@ -89,8 +89,17 @@ static inline int pte_same(pte_t a, pte_t b)
}
#define pte_page(x) pfn_to_page(pte_pfn(x))
#define pte_none(x) (!(x).pte_low && !(x).pte_high)
#define pte_pfn(x) (((x).pte_low >> PAGE_SHIFT) | ((x).pte_high << (32 - PAGE_SHIFT)))
static inline int pte_none(pte_t pte)
{
return !pte.pte_low && !pte.pte_high;
}
static inline unsigned long pte_pfn(pte_t pte)
{
return (pte.pte_low >> PAGE_SHIFT) |
(pte.pte_high << (32 - PAGE_SHIFT));
}
static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
{
......
......@@ -242,7 +242,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
/* to find an entry in a page-table-directory. */
#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
#define __pgd_offset(address) pgd_index(address)
......
......@@ -287,8 +287,8 @@ extern unsigned long blk_max_low_pfn, blk_max_pfn;
* BLK_BOUNCE_ANY : don't bounce anything
* BLK_BOUNCE_ISA : bounce pages above ISA DMA boundary
*/
#define BLK_BOUNCE_HIGH (blk_max_low_pfn << PAGE_SHIFT)
#define BLK_BOUNCE_ANY (blk_max_pfn << PAGE_SHIFT)
#define BLK_BOUNCE_HIGH ((u64)blk_max_low_pfn << PAGE_SHIFT)
#define BLK_BOUNCE_ANY ((u64)blk_max_pfn << PAGE_SHIFT)
#define BLK_BOUNCE_ISA (ISA_DMA_THRESHOLD)
extern int init_emergency_isa_pool(void);
......
......@@ -10,6 +10,7 @@
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/linkage.h>
#include <linux/wait.h>
#include <asm/atomic.h>
enum bh_state_bits {
......@@ -154,7 +155,7 @@ void invalidate_bdev(struct block_device *, int);
void __invalidate_buffers(kdev_t dev, int);
int sync_blockdev(struct block_device *bdev);
void __wait_on_buffer(struct buffer_head *);
void sleep_on_buffer(struct buffer_head *bh);
wait_queue_head_t *bh_waitq_head(struct buffer_head *bh);
void wake_up_buffer(struct buffer_head *bh);
int fsync_bdev(struct block_device *);
int fsync_super(struct super_block *);
......
......@@ -371,9 +371,10 @@ struct inode {
struct timespec i_ctime;
unsigned int i_blkbits;
unsigned long i_blksize;
unsigned long i_blocks;
unsigned long i_version;
unsigned long i_blocks;
unsigned short i_bytes;
spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
struct semaphore i_sem;
struct inode_operations *i_op;
struct file_operations *i_fop; /* former ->i_op->default_file_ops */
......@@ -412,39 +413,6 @@ struct fown_struct {
void *security;
};
static inline void inode_add_bytes(struct inode *inode, loff_t bytes)
{
inode->i_blocks += bytes >> 9;
bytes &= 511;
inode->i_bytes += bytes;
if (inode->i_bytes >= 512) {
inode->i_blocks++;
inode->i_bytes -= 512;
}
}
static inline void inode_sub_bytes(struct inode *inode, loff_t bytes)
{
inode->i_blocks -= bytes >> 9;
bytes &= 511;
if (inode->i_bytes < bytes) {
inode->i_blocks--;
inode->i_bytes += 512;
}
inode->i_bytes -= bytes;
}
static inline loff_t inode_get_bytes(struct inode *inode)
{
return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;
}
static inline void inode_set_bytes(struct inode *inode, loff_t bytes)
{
inode->i_blocks = bytes >> 9;
inode->i_bytes = bytes & 511;
}
/*
* Track a single file's readahead state
*/
......@@ -1277,6 +1245,10 @@ extern int page_symlink(struct inode *inode, const char *symname, int len);
extern struct inode_operations page_symlink_inode_operations;
extern void generic_fillattr(struct inode *, struct kstat *);
extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
void inode_add_bytes(struct inode *inode, loff_t bytes);
void inode_sub_bytes(struct inode *inode, loff_t bytes);
loff_t inode_get_bytes(struct inode *inode);
void inode_set_bytes(struct inode *inode, loff_t bytes);
extern int vfs_readdir(struct file *, filldir_t, void *);
......
......@@ -344,7 +344,7 @@ static inline int module_text_address(unsigned long addr)
}
/* Get/put a kernel symbol (calls should be symmetric) */
#define symbol_get(x) (&(x))
#define symbol_get(x) ({ extern typeof(x) x __attribute__((weak)); &(x); })
#define symbol_put(x) do { } while(0)
#define symbol_put_addr(x) do { } while(0)
......
......@@ -280,7 +280,8 @@ struct quota_format_type {
struct quota_info {
unsigned int flags; /* Flags for diskquotas on this device */
struct semaphore dqio_sem; /* lock device while I/O in progress */
struct rw_semaphore dqoff_sem; /* serialize quota_off() and quota_on() on device and ops using quota_info struct, pointers from inode to dquots */
struct semaphore dqonoff_sem; /* Serialize quotaon & quotaoff */
struct rw_semaphore dqptr_sem; /* serialize ops using quota_info struct, pointers from inode to dquots */
struct file *files[MAXQUOTAS]; /* fp's to quotafiles */
struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */
struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */
......
......@@ -272,6 +272,10 @@ EXPORT_SYMBOL(vfs_fstat);
EXPORT_SYMBOL(vfs_stat);
EXPORT_SYMBOL(vfs_lstat);
EXPORT_SYMBOL(vfs_getattr);
EXPORT_SYMBOL(inode_add_bytes);
EXPORT_SYMBOL(inode_sub_bytes);
EXPORT_SYMBOL(inode_get_bytes);
EXPORT_SYMBOL(inode_set_bytes);
EXPORT_SYMBOL(lock_rename);
EXPORT_SYMBOL(unlock_rename);
EXPORT_SYMBOL(generic_read_dir);
......
......@@ -27,6 +27,22 @@
#define DEBUGP(fmt, a...)
#endif
static inline int dash2underscore(char c)
{
if (c == '-')
return '_';
return c;
}
static inline int parameq(const char *input, const char *paramname)
{
unsigned int i;
for (i = 0; dash2underscore(input[i]) == paramname[i]; i++)
if (input[i] == '\0')
return 1;
return 0;
}
static int parse_one(char *param,
char *val,
struct kernel_param *params,
......@@ -37,7 +53,7 @@ static int parse_one(char *param,
/* Find parameter */
for (i = 0; i < num_params; i++) {
if (strcmp(param, params[i].name) == 0) {
if (parameq(param, params[i].name)) {
DEBUGP("They are equal! Calling %p\n",
params[i].set);
return params[i].set(val, &params[i]);
......@@ -69,8 +85,6 @@ static char *next_arg(char *args, char **param, char **val)
if (equals == 0) {
if (args[i] == '=')
equals = i;
else if (args[i] == '-')
args[i] = '_';
}
if (args[i] == '"')
in_quote = !in_quote;
......
......@@ -2057,7 +2057,7 @@ static void show_task(task_t * p)
printk(" %016lx ", thread_saved_pc(p));
#endif
{
unsigned long * n = (unsigned long *) (p+1);
unsigned long * n = (unsigned long *) (p->thread_info+1);
while (!*n)
n++;
free = (unsigned long) n - (unsigned long)(p+1);
......@@ -2465,15 +2465,12 @@ void __preempt_spin_lock(spinlock_t *lock)
_raw_spin_lock(lock);
return;
}
while (!_raw_spin_trylock(lock)) {
if (need_resched()) {
preempt_enable_no_resched();
__cond_resched();
preempt_disable();
}
do {
preempt_enable();
while (spin_is_locked(lock))
cpu_relax();
}
preempt_disable();
} while (!_raw_spin_trylock(lock));
}
void __preempt_write_lock(rwlock_t *lock)
......@@ -2483,13 +2480,11 @@ void __preempt_write_lock(rwlock_t *lock)
return;
}
while (!_raw_write_trylock(lock)) {
if (need_resched()) {
preempt_enable_no_resched();
__cond_resched();
preempt_disable();
}
do {
preempt_enable();
while (rwlock_is_locked(lock))
cpu_relax();
}
preempt_disable();
} while (!_raw_write_trylock(lock));
}
#endif
......@@ -1306,11 +1306,13 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
return 0;
}
/*
* This is for filesystems which do not implement ->writepage.
*/
int generic_file_readonly_mmap(struct file *file, struct vm_area_struct *vma)
{
if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_WRITE))
if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
return -EINVAL;
vma->vm_flags &= ~VM_MAYWRITE;
return generic_file_mmap(file, vma);
}
#else
......
......@@ -1265,8 +1265,9 @@ void exit_mmap(struct mm_struct *mm)
tlb = tlb_gather_mmu(mm, 1);
flush_cache_mm(mm);
/* Use ~0UL here to ensure all VMAs in the mm are unmapped */
mm->map_count -= unmap_vmas(&tlb, mm, mm->mmap, 0,
TASK_SIZE, &nr_accounted);
~0UL, &nr_accounted);
vm_unacct_memory(nr_accounted);
BUG_ON(mm->map_count); /* This is just debugging */
clear_page_tables(tlb, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD);
......
......@@ -769,7 +769,7 @@ static void poison_obj(kmem_cache_t *cachep, void *addr, unsigned char val)
*(unsigned char *)(addr+size-1) = POISON_END;
}
static int check_poison_obj (kmem_cache_t *cachep, void *addr)
static void check_poison_obj(kmem_cache_t *cachep, void *addr)
{
int size = cachep->objsize;
void *end;
......@@ -779,8 +779,7 @@ static int check_poison_obj (kmem_cache_t *cachep, void *addr)
}
end = memchr(addr, POISON_END, size);
if (end != (addr+size-1))
return 1;
return 0;
slab_error(cachep, "object was modified after freeing");
}
#endif
......@@ -1420,6 +1419,8 @@ static int cache_grow (kmem_cache_t * cachep, int flags)
opps1:
kmem_freepages(cachep, objp);
failed:
if (local_flags & __GFP_WAIT)
local_irq_disable();
return 0;
}
......@@ -1628,8 +1629,7 @@ cache_alloc_debugcheck_after(kmem_cache_t *cachep,
if (!objp)
return objp;
if (cachep->flags & SLAB_POISON)
if (check_poison_obj(cachep, objp))
BUG();
check_poison_obj(cachep, objp);
if (cachep->flags & SLAB_RED_ZONE) {
/* Set alloc red-zone, and check old one. */
if (xchg((unsigned long *)objp, RED_ACTIVE) != RED_INACTIVE)
......
......@@ -120,17 +120,16 @@ void cap_bprm_compute_creds (struct linux_binprm *bprm)
{
/* Derived from fs/exec.c:compute_creds. */
kernel_cap_t new_permitted, working;
int do_unlock = 0;
new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
working = cap_intersect (bprm->cap_inheritable,
current->cap_inheritable);
new_permitted = cap_combine (new_permitted, working);
task_lock(current);
if (!cap_issubset (new_permitted, current->cap_permitted)) {
current->mm->dumpable = 0;
lock_kernel ();
if (must_not_trace_exec (current)
|| atomic_read (&current->fs->count) > 1
|| atomic_read (&current->files->count) > 1
......@@ -141,7 +140,6 @@ void cap_bprm_compute_creds (struct linux_binprm *bprm)
cap_permitted);
}
}
do_unlock = 1;
}
/* For init, we want to retain the capabilities set
......@@ -154,9 +152,7 @@ void cap_bprm_compute_creds (struct linux_binprm *bprm)
}
/* AUD: Audit candidate if current->cap_effective is set */
if (do_unlock)
unlock_kernel ();
task_unlock(current);
current->keep_capabilities = 0;
}
......
......@@ -668,7 +668,7 @@ static int ac97_read_mixer(struct ess_card *card, int mixer)
if (mixer == SOUND_MIXER_IGAIN) {
right = (right * 100) / mh->scale;
left = (left * 100) / mh->scale;
else {
} else {
right = 100 - ((right * 100) / mh->scale);
left = 100 - ((left * 100) / mh->scale);
}
......
#include <linux/vmalloc.h>
#define __KERNEL_SYSCALLS__
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/unistd.h>
#include <asm/uaccess.h>
static int do_mod_firmware_load(const char *fn, char **fp)
......
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