From f3d40e81c946bb81bb602abaf9e7bf7688145999 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:18:18 -0500 Subject: [PATCH] Import 2.2.3pre2 --- MAINTAINERS | 2 +- fs/buffer.c | 18 ++++----------- fs/nfs/dir.c | 28 +++++++---------------- fs/nfs/nfs2xdr.c | 1 + include/linux/mm.h | 30 +++++++++++++------------ include/linux/nfs.h | 1 + include/linux/sched.h | 52 +++++++++++++++++++++++++++++++++++++++++++ kernel/printk.c | 12 +++------- 8 files changed, 86 insertions(+), 58 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 836029aaa265..137de4bcd958 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -522,7 +522,7 @@ S: Maintained NETWORKING [IPv4/IPv6] P: David S. Miller -M: davem@dm.cobaltmicro.com +M: davem@redhat.com P: Andi Kleen M: ak@muc.de P: Alexey Kuznetsov diff --git a/fs/buffer.c b/fs/buffer.c index 1e5cc43c635c..bb916d8ff38f 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -74,7 +74,6 @@ static struct wait_queue * buffer_wait = NULL; static int nr_buffers = 0; static int nr_buffers_type[NR_LIST] = {0,}; -static int size_buffers_type[NR_LIST] = {0,}; static int nr_buffer_heads = 0; static int nr_unused_buffer_heads = 0; @@ -100,8 +99,7 @@ union bdflush_param{ each time we call refill */ int nref_dirt; /* Dirty buffer threshold for activating bdflush when trying to refill buffers. */ - int pct_dirt; /* Max %age of mem for dirty buffers before - activating bdflush */ + int dummy1; /* unused */ int age_buffer; /* Time for normal buffer to age before we flush it */ int age_super; /* Time for superblock to age before we @@ -482,7 +480,6 @@ static void remove_from_queues(struct buffer_head * bh) return; } nr_buffers_type[bh->b_list]--; - size_buffers_type[bh->b_list] -= bh->b_size; remove_from_hash_queue(bh); remove_from_lru_list(bh); } @@ -556,7 +553,6 @@ static void insert_into_queues(struct buffer_head * bh) (*bhp)->b_prev_free = bh; nr_buffers_type[bh->b_list]++; - size_buffers_type[bh->b_list] += bh->b_size; /* Put the buffer in new hash-queue if it has a device. */ bh->b_next = NULL; @@ -808,19 +804,13 @@ void refile_buffer(struct buffer_head * buf) file_buffer(buf, dispose); if(dispose == BUF_DIRTY) { int too_many = (nr_buffers * bdf_prm.b_un.nfract/100); - int too_large = (num_physpages * bdf_prm.b_un.pct_dirt/100); /* This buffer is dirty, maybe we need to start flushing. * If too high a percentage of the buffers are dirty... */ - if (nr_buffers_type[BUF_DIRTY] > too_many || - size_buffers_type[BUF_DIRTY]/PAGE_SIZE > too_large) { - if (nr_buffers_type[BUF_LOCKED] > 3 * bdf_prm.b_un.ndirty) - wakeup_bdflush(1); - else - wakeup_bdflush(0); - } - + if (nr_buffers_type[BUF_DIRTY] > too_many) + wakeup_bdflush(1); + /* If this is a loop device, and * more than half of the buffers are dirty... * (Prevents no-free-buffers deadlock with loop device.) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c71893476dba..0534e24b3e73 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -713,17 +713,6 @@ out: return error; } -/* - * To avoid retaining a stale inode reference, we check the dentry - * use count prior to the operation, and return EBUSY if it has - * multiple users. - * - * We update inode->i_nlink and free the inode prior to the operation - * to avoid possible races if the server reuses the inode. - * - * FIXME! We don't do it anymore (2.1.131) - it interacts badly with - * new rmdir(). -- AV - */ static int nfs_rmdir(struct inode *dir, struct dentry *dentry) { int error; @@ -735,10 +724,6 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry) if (dentry->d_name.len > NFS_MAXNAMLEN) goto out; - error = -EBUSY; - if (!list_empty(&dentry->d_hash)) - goto out; - #ifdef NFS_PARANOIA if (dentry->d_inode->i_count > 1) printk("nfs_rmdir: %s/%s inode busy?? i_count=%d, i_nlink=%d\n", @@ -746,14 +731,17 @@ dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_inode->i_count, dentry->d_inode->i_nlink); #endif - /* - * Update i_nlink and free the inode before unlinking. - */ - if (dentry->d_inode->i_nlink) - dentry->d_inode->i_nlink --; nfs_invalidate_dircache(dir); error = nfs_proc_rmdir(NFS_SERVER(dir), NFS_FH(dentry->d_parent), dentry->d_name.name); + + /* Update i_nlink and invalidate dentry. */ + if (!error) { + d_drop(dentry); + if (dentry->d_inode->i_nlink) + dentry->d_inode->i_nlink --; + } + out: return error; } diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 1c6a74a71799..a4c4e86d5db4 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -612,6 +612,7 @@ static struct { { NFSERR_FBIG, EFBIG }, { NFSERR_NOSPC, ENOSPC }, { NFSERR_ROFS, EROFS }, + { NFSERR_OPNOTSUPP, EOPNOTSUPP }, { NFSERR_NAMETOOLONG, ENAMETOOLONG }, { NFSERR_NOTEMPTY, ENOTEMPTY }, { NFSERR_DQUOT, EDQUOT }, diff --git a/include/linux/mm.h b/include/linux/mm.h index 7b6c6ec701f4..3e45b3b8bb87 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -177,10 +177,12 @@ typedef struct page { (test_and_clear_bit(PG_swap_cache, &(page)->flags)) /* - * page->reserved denotes a page which must never be accessed (which + * Various page->flags bits: + * + * PG_reserved is set for a page which must never be accessed (which * may not even be present). * - * page->dma is set for those pages which lie in the range of + * PG_DMA is set for those pages which lie in the range of * physical addresses capable of carrying DMA transfers. * * Multiple processes may "see" the same page. E.g. for untouched @@ -204,8 +206,8 @@ typedef struct page { * The following discussion applies only to them. * * A page may belong to an inode's memory mapping. In this case, - * page->inode is the inode, and page->offset is the file offset - * of the page (not necessarily a multiple of PAGE_SIZE). + * page->inode is the pointer to the inode, and page->offset is the + * file offset of the page (not necessarily a multiple of PAGE_SIZE). * * A page may have buffers allocated to it. In this case, * page->buffers is a circular list of these buffer heads. Else, @@ -219,7 +221,7 @@ typedef struct page { * fields are also used for freelist management when page->count==0.) * There is also a hash table mapping (inode,offset) to the page * in memory if present. The lists for this hash table use the fields - * page->next_hash and page->prev_hash. + * page->next_hash and page->pprev_hash. * * All process pages can do I/O: * - inode pages may need to be read from disk, @@ -227,18 +229,23 @@ typedef struct page { * to be written to disk, * - private pages which have been modified may need to be swapped out * to swap space and (later) to be read back into memory. - * During disk I/O, page->locked is true. This bit is set before I/O + * During disk I/O, PG_locked is used. This bit is set before I/O * and reset when I/O completes. page->wait is a wait queue of all * tasks waiting for the I/O on this page to complete. - * page->uptodate tells whether the page's contents is valid. + * PG_uptodate tells whether the page's contents is valid. * When a read completes, the page becomes uptodate, unless a disk I/O * error happened. - * When a write completes, and page->free_after is true, the page is + * When a write completes, and PG_free_after is set, the page is * freed without any further delay. * * For choosing which pages to swap out, inode pages carry a - * page->referenced bit, which is set any time the system accesses + * PG_referenced bit, which is set any time the system accesses * that page through the (inode,offset) hash table. + * + * PG_skip is used on sparc/sparc64 architectures to "skip" certain + * parts of the address space. + * + * PG_error is set to indicate that an I/O error occurred on this page. */ extern mem_map_t * mem_map; @@ -340,11 +347,6 @@ extern void put_cached_page(unsigned long); #define GFP_DMA __GFP_DMA -/* - * Decide if we should try to do some swapout.. - */ -extern int free_memory_available(void); - /* vma is the first one with address < vma->vm_end, * and even address < vma->vm_start. Have to extend vma. */ static inline int expand_stack(struct vm_area_struct * vma, unsigned long address) diff --git a/include/linux/nfs.h b/include/linux/nfs.h index c4aab89e1103..7936d5a71c61 100644 --- a/include/linux/nfs.h +++ b/include/linux/nfs.h @@ -41,6 +41,7 @@ enum nfs_stat { NFSERR_FBIG = 27, NFSERR_NOSPC = 28, NFSERR_ROFS = 30, + NFSERR_OPNOTSUPP = 45, NFSERR_NAMETOOLONG = 63, NFSERR_NOTEMPTY = 66, NFSERR_DQUOT = 69, diff --git a/include/linux/sched.h b/include/linux/sched.h index 9b97235c83d7..1e6c27a622ef 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -672,6 +672,58 @@ extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * write_unlock_irqrestore(&waitqueue_lock, flags); } +#define __wait_event(wq, condition) \ +do { \ + struct wait_queue __wait; \ + \ + __wait.task = current; \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + current->state = TASK_UNINTERRUPTIBLE; \ + if (condition) \ + break; \ + schedule(); \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#define wait_event(wq, condition) \ +do { \ + if (condition) \ + break; \ + __wait_event(wq, condition); \ +} while (0) + +#define __wait_event_interruptible(wq, condition, ret) \ +do { \ + struct wait_queue __wait; \ + \ + __wait.task = current; \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + current->state = TASK_INTERRUPTIBLE; \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + schedule(); \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#define wait_event_interruptible(wq, condition) \ +({ \ + int __ret = 0; \ + if (!(condition)) \ + __wait_event_interruptible(wq, condition, __ret); \ + __ret; \ +}) + #define REMOVE_LINKS(p) do { \ (p)->next_task->prev_task = (p)->prev_task; \ (p)->prev_task->next_task = (p)->next_task; \ diff --git a/kernel/printk.c b/kernel/printk.c index a333fe18ed5e..36414fcf3c6d 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -137,15 +137,9 @@ int do_syslog(int type, char * buf, int len) error = verify_area(VERIFY_WRITE,buf,len); if (error) goto out; - cli(); - error = -ERESTARTSYS; - while (!log_size) { - if (signal_pending(current)) { - sti(); - goto out; - } - interruptible_sleep_on(&log_wait); - } + error = wait_event_interruptible(log_wait, log_size); + if (error) + goto out; i = 0; while (log_size && i < len) { c = *((char *) log_buf+log_start); -- 2.39.5