diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-01-11 04:02:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-01-11 04:02:40 +0000 |
commit | e47f00743fc4776491344f2c618cc8dc2c23bcbc (patch) | |
tree | 13e03a113a82a184c51c19c209867cfd3a59b3b9 /fs | |
parent | b2ad5f821b1381492d792ca10b1eb7a107b48f14 (diff) |
Merge with Linux 2.4.0.
Diffstat (limited to 'fs')
-rw-r--r-- | fs/buffer.c | 74 | ||||
-rw-r--r-- | fs/dcache.c | 11 | ||||
-rw-r--r-- | fs/exec.c | 6 | ||||
-rw-r--r-- | fs/isofs/inode.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfsfh.c | 33 | ||||
-rw-r--r-- | fs/smbfs/smb_debug.h | 6 | ||||
-rw-r--r-- | fs/umsdos/mangle.c | 2 |
7 files changed, 60 insertions, 74 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index 601276bbc..0096524bf 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -118,8 +118,7 @@ union bdflush_param { wake-cycle */ int nrefill; /* Number of clean buffers to try to obtain each time we call refill */ - int nref_dirt; /* Dirty buffer threshold for activating bdflush - when trying to refill buffers. */ + int dummy1; /* unused */ int interval; /* jiffies delay between kupdate flushes */ int age_buffer; /* Time for normal buffer to age before we flush it */ int nfract_sync; /* Percentage of buffer cache dirty to @@ -128,7 +127,7 @@ union bdflush_param { int dummy3; /* unused */ } b_un; unsigned int data[N_PARAM]; -} bdf_prm = {{40, 500, 64, 256, 5*HZ, 30*HZ, 80, 0, 0}}; +} bdf_prm = {{30, 64, 64, 256, 5*HZ, 30*HZ, 60, 0, 0}}; /* These are the min and max parameter values that we will allow to be assigned */ int bdflush_min[N_PARAM] = { 0, 10, 5, 25, 0, 1*HZ, 0, 0, 0}; @@ -755,11 +754,15 @@ void set_blocksize(kdev_t dev, int size) /* * We used to try various strange things. Let's not. + * We'll just try to balance dirty buffers, and possibly + * launder some pages. */ static void refill_freelist(int size) { - if (!grow_buffers(size)) - wakeup_bdflush(1); /* Sets task->state to TASK_RUNNING */ + balance_dirty(NODEV); + if (free_shortage()) + page_launder(GFP_BUFFER, 0); + grow_buffers(size); } void init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private) @@ -1090,8 +1093,10 @@ void __mark_buffer_dirty(struct buffer_head *bh) void mark_buffer_dirty(struct buffer_head *bh) { - __mark_buffer_dirty(bh); - balance_dirty(bh->b_dev); + if (!atomic_set_buffer_dirty(bh)) { + __mark_dirty(bh); + balance_dirty(bh->b_dev); + } } /* @@ -2528,34 +2533,6 @@ void __init buffer_init(unsigned long mempages) * response to dirty buffers. Once this process is activated, we write back * a limited number of buffers to the disks and then go back to sleep again. */ -static DECLARE_WAIT_QUEUE_HEAD(bdflush_done); -struct task_struct *bdflush_tsk = 0; - -void wakeup_bdflush(int block) -{ - DECLARE_WAITQUEUE(wait, current); - - if (current == bdflush_tsk) - return; - - if (!block) { - wake_up_process(bdflush_tsk); - return; - } - - /* bdflush can wakeup us before we have a chance to - go to sleep so we must be smart in handling - this wakeup event from bdflush to avoid deadlocking in SMP - (we are not holding any lock anymore in these two paths). */ - __set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&bdflush_done, &wait); - - wake_up_process(bdflush_tsk); - schedule(); - - remove_wait_queue(&bdflush_done, &wait); - __set_current_state(TASK_RUNNING); -} /* This is the _only_ function that deals with flushing async writes to disk. @@ -2611,6 +2588,18 @@ static int flush_dirty_buffers(int check_flushtime) return flushed; } +struct task_struct *bdflush_tsk = 0; + +void wakeup_bdflush(int block) +{ + if (current != bdflush_tsk) { + wake_up_process(bdflush_tsk); + + if (block) + flush_dirty_buffers(0); + } +} + /* * Here we attempt to write back old buffers. We also try to flush inodes * and supers as well, since this function is essentially "update", and @@ -2725,23 +2714,14 @@ int bdflush(void *sem) flushed = flush_dirty_buffers(0); if (free_shortage()) - flushed += page_launder(GFP_BUFFER, 0); - - /* If wakeup_bdflush will wakeup us - after our bdflush_done wakeup, then - we must make sure to not sleep - in schedule_timeout otherwise - wakeup_bdflush may wait for our - bdflush_done wakeup that would never arrive - (as we would be sleeping) and so it would - deadlock in SMP. */ - __set_current_state(TASK_INTERRUPTIBLE); - wake_up_all(&bdflush_done); + flushed += page_launder(GFP_KERNEL, 0); + /* * If there are still a lot of dirty buffers around, * skip the sleep and flush some more. Otherwise, we * go to sleep waiting a wakeup. */ + set_current_state(TASK_INTERRUPTIBLE); if (!flushed || balance_dirty_state(NODEV) < 0) { run_task_queue(&tq_disk); schedule(); diff --git a/fs/dcache.c b/fs/dcache.c index 090bf1686..e0b170ad7 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -339,10 +339,18 @@ void prune_dcache(int count) if (tmp == &dentry_unused) break; - dentry_stat.nr_unused--; list_del_init(tmp); dentry = list_entry(tmp, struct dentry, d_lru); + /* If the dentry was recently referenced, don't free it. */ + if (dentry->d_flags & DCACHE_REFERENCED) { + dentry->d_flags &= ~DCACHE_REFERENCED; + list_add(&dentry->d_lru, &dentry_unused); + count--; + continue; + } + dentry_stat.nr_unused--; + /* Unused dentry with a count? */ if (atomic_read(&dentry->d_count)) BUG(); @@ -732,6 +740,7 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name) continue; } __dget_locked(dentry); + dentry->d_flags |= DCACHE_REFERENCED; spin_unlock(&dcache_lock); return dentry; } @@ -403,6 +403,12 @@ static int exec_mmap(void) mmdrop(mm); return -ENOMEM; } + + /* Add it to the list of mm's */ + spin_lock(&mmlist_lock); + list_add(&mm->mmlist, &init_mm.mmlist); + spin_unlock(&mmlist_lock); + task_lock(current); current->mm = mm; current->active_mm = mm; diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 5d50c37a6..757a87070 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -1264,7 +1264,7 @@ static void isofs_read_inode(struct inode * inode) (volume_seq_no != 0) && (volume_seq_no != 1)) { printk(KERN_WARNING "Multi-volume CD somehow got mounted.\n"); } else -#endif IGNORE_WRONG_MULTI_VOLUME_SPECS +#endif /*IGNORE_WRONG_MULTI_VOLUME_SPECS */ { if (S_ISREG(inode->i_mode)) { inode->i_fop = &generic_ro_fops; diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 7bf572e34..78c729c09 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -346,7 +346,7 @@ find_fh_dentry(struct super_block *sb, ino_t ino, int generation, ino_t dirino, struct dentry *dentry, *result = NULL; struct dentry *tmp; int found =0; - int err; + int err = -ESTALE; /* the sb->s_nfsd_free_path_sem semaphore is needed to make sure that only one unconnected (free) * dcache path ever exists, as otherwise two partial paths might get * joined together, which would be very confusing. @@ -360,19 +360,18 @@ find_fh_dentry(struct super_block *sb, ino_t ino, int generation, ino_t dirino, * Attempt to find the inode. */ retry: + down(&sb->s_nfsd_free_path_sem); result = nfsd_iget(sb, ino, generation); - err = PTR_ERR(result); - if (IS_ERR(result)) - goto err_out; - err = -ESTALE; - if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) - return result; - - /* result is now an anonymous dentry, which may be adequate as it stands, or else - * will get spliced into the dcache tree */ - - if (!S_ISDIR(result->d_inode->i_mode) && ! needpath) { - nfsdstats.fh_anon++; + if (IS_ERR(result) + || !(result->d_flags & DCACHE_NFSD_DISCONNECTED) + || (!S_ISDIR(result->d_inode->i_mode) && ! needpath)) { + up(&sb->s_nfsd_free_path_sem); + + err = PTR_ERR(result); + if (IS_ERR(result)) + goto err_out; + if ((result->d_flags & DCACHE_NFSD_DISCONNECTED)) + nfsdstats.fh_anon++; return result; } @@ -380,14 +379,6 @@ find_fh_dentry(struct super_block *sb, ino_t ino, int generation, ino_t dirino, * location in the tree. */ dprintk("nfs_fh: need to look harder for %d/%ld\n",sb->s_dev,ino); - down(&sb->s_nfsd_free_path_sem); - - /* claiming the semaphore might have allowed things to get fixed up */ - if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) { - up(&sb->s_nfsd_free_path_sem); - return result; - } - found = 0; if (!S_ISDIR(result->d_inode->i_mode)) { diff --git a/fs/smbfs/smb_debug.h b/fs/smbfs/smb_debug.h index a656c356e..746a99fe3 100644 --- a/fs/smbfs/smb_debug.h +++ b/fs/smbfs/smb_debug.h @@ -11,14 +11,14 @@ * these are normally enabled. */ #ifdef SMBFS_PARANOIA -#define PARANOIA(x...) printk(KERN_NOTICE __FUNCTION__ ": " ## x) +#define PARANOIA(x...) printk(KERN_NOTICE __FUNCTION__ ": " x) #else #define PARANOIA(x...) do { ; } while(0) #endif /* lots of debug messages */ #ifdef SMBFS_DEBUG_VERBOSE -#define VERBOSE(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x) +#define VERBOSE(x...) printk(KERN_DEBUG __FUNCTION__ ": " x) #else #define VERBOSE(x...) do { ; } while(0) #endif @@ -28,7 +28,7 @@ * too common name. */ #ifdef SMBFS_DEBUG -#define DEBUG1(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x) +#define DEBUG1(x...) printk(KERN_DEBUG __FUNCTION__ ": " x) #else #define DEBUG1(x...) do { ; } while(0) #endif diff --git a/fs/umsdos/mangle.c b/fs/umsdos/mangle.c index 08de621e7..a1feba0ea 100644 --- a/fs/umsdos/mangle.c +++ b/fs/umsdos/mangle.c @@ -435,7 +435,7 @@ struct MANG_TEST tb[] = "HELLO", 1, "hello", "Hello.1", 1, "hello.1", "Hello.c", 1, "hello.c", -#elseif +#else /* * I find the three examples below very unfortunate. I propose to * convert them to lower case in a quick preliminary pass, then test |