## Automatically generated incremental diff ## From: linux-2.4.22-bk37 ## To: linux-2.4.22-bk38 ## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $ diff -urN linux-2.4.22-bk37/Makefile linux-2.4.22-bk38/Makefile --- linux-2.4.22-bk37/Makefile 2003-10-21 02:49:29.000000000 -0700 +++ linux-2.4.22-bk38/Makefile 2003-10-21 02:49:32.000000000 -0700 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 22 -EXTRAVERSION = -bk37 +EXTRAVERSION = -bk38 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -urN linux-2.4.22-bk37/fs/lockd/svc4proc.c linux-2.4.22-bk38/fs/lockd/svc4proc.c --- linux-2.4.22-bk37/fs/lockd/svc4proc.c 2003-08-25 04:44:43.000000000 -0700 +++ linux-2.4.22-bk38/fs/lockd/svc4proc.c 2003-10-21 02:49:35.000000000 -0700 @@ -449,13 +449,11 @@ if (nlmsvc_ops != NULL) { struct svc_client *clnt; saddr.sin_addr.s_addr = argp->addr; - nlmsvc_ops->exp_readlock(); if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL && (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) { nlmsvc_free_host_resources(host); } nlm_release_host(host); - nlmsvc_ops->exp_unlock(); } return rpc_success; diff -urN linux-2.4.22-bk37/fs/lockd/svcproc.c linux-2.4.22-bk38/fs/lockd/svcproc.c --- linux-2.4.22-bk37/fs/lockd/svcproc.c 2003-08-25 04:44:43.000000000 -0700 +++ linux-2.4.22-bk38/fs/lockd/svcproc.c 2003-10-21 02:49:35.000000000 -0700 @@ -477,13 +477,11 @@ if (nlmsvc_ops != NULL) { struct svc_client *clnt; saddr.sin_addr.s_addr = argp->addr; - nlmsvc_ops->exp_readlock(); if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL && (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) { nlmsvc_free_host_resources(host); } nlm_release_host(host); - nlmsvc_ops->exp_unlock(); } return rpc_success; diff -urN linux-2.4.22-bk37/fs/ramfs/inode.c linux-2.4.22-bk38/fs/ramfs/inode.c --- linux-2.4.22-bk37/fs/ramfs/inode.c 2002-08-02 17:39:45.000000000 -0700 +++ linux-2.4.22-bk38/fs/ramfs/inode.c 2003-10-21 02:49:35.000000000 -0700 @@ -44,7 +44,7 @@ { buf->f_type = RAMFS_MAGIC; buf->f_bsize = PAGE_CACHE_SIZE; - buf->f_namelen = 255; + buf->f_namelen = NAME_MAX; return 0; } @@ -54,6 +54,8 @@ */ static struct dentry * ramfs_lookup(struct inode *dir, struct dentry *dentry) { + if (dentry->d_name.len > NAME_MAX) + return ERR_PTR(-ENAMETOOLONG); d_add(dentry, NULL); return NULL; } @@ -138,6 +140,11 @@ int error = -ENOSPC; if (inode) { + if (dir->i_mode & S_ISGID) { + inode->i_gid = dir->i_gid; + if (S_ISDIR(mode)) + inode->i_mode |= S_ISGID; + } d_instantiate(dentry, inode); dget(dentry); /* Extra count - pin the dentry in core */ error = 0; diff -urN linux-2.4.22-bk37/mm/shmem.c linux-2.4.22-bk38/mm/shmem.c --- linux-2.4.22-bk37/mm/shmem.c 2003-08-25 04:44:44.000000000 -0700 +++ linux-2.4.22-bk38/mm/shmem.c 2003-10-21 02:49:35.000000000 -0700 @@ -46,6 +46,10 @@ #define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT) +/* info->flags needs VM_flags to handle pagein/truncate race efficiently */ +#define SHMEM_PAGEIN VM_READ +#define SHMEM_TRUNCATE VM_WRITE + /* Pretend that each entry is of this size in directory's i_size */ #define BOGO_DIRENT_SIZE 20 @@ -364,8 +368,23 @@ while (index < info->next_index) freed += shmem_truncate_indirect(info, index); BUG_ON(info->swapped > info->next_index); - spin_unlock(&info->lock); + if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) { + /* + * Call truncate_inode_pages again: racing shmem_unuse_inode + * may have swizzled a page in from swap since vmtruncate or + * generic_delete_inode did it, before we lowered next_index. + * Also, though shmem_getpage checks i_size before adding to + * cache, no recheck after: so fix the narrow window there too. + */ + info->flags |= SHMEM_TRUNCATE; + spin_unlock(&info->lock); + truncate_inode_pages(inode->i_mapping, inode->i_size); + spin_lock(&info->lock); + info->flags &= ~SHMEM_TRUNCATE; + } + + spin_unlock(&info->lock); spin_lock(&sbinfo->stat_lock); sbinfo->free_blocks += freed; inode->i_blocks -= freed*BLOCKS_PER_PAGE; @@ -392,6 +411,19 @@ attr->ia_size>>PAGE_CACHE_SHIFT, &page, SGP_READ); } + /* + * Reset SHMEM_PAGEIN flag so that shmem_truncate can + * detect if any pages might have been added to cache + * after truncate_inode_pages. But we needn't bother + * if it's being fully truncated to zero-length: the + * nrpages check is efficient enough in that case. + */ + if (attr->ia_size) { + struct shmem_inode_info *info = SHMEM_I(inode); + spin_lock(&info->lock); + info->flags &= ~SHMEM_PAGEIN; + spin_unlock(&info->lock); + } } } @@ -439,7 +471,6 @@ struct address_space *mapping; swp_entry_t *ptr; unsigned long idx; - unsigned long limit; int offset; idx = 0; @@ -471,13 +502,9 @@ inode = info->inode; mapping = inode->i_mapping; delete_from_swap_cache(page); - - /* Racing against delete or truncate? Must leave out of page cache */ - limit = (inode->i_state & I_FREEING)? 0: - (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - - if (idx >= limit || add_to_page_cache_unique(page, + if (add_to_page_cache_unique(page, mapping, idx, page_hash(mapping, idx)) == 0) { + info->flags |= SHMEM_PAGEIN; ptr[offset].val = 0; info->swapped--; } else if (add_to_swap_cache(page, entry) != 0) @@ -529,21 +556,26 @@ BUG_ON(!PageLocked(page)); if (!PageLaunder(page)) - return fail_writepage(page); + goto fail; mapping = page->mapping; index = page->index; inode = mapping->host; info = SHMEM_I(inode); if (info->flags & VM_LOCKED) - return fail_writepage(page); + goto fail; getswap: swap = get_swap_page(); if (!swap.val) - return fail_writepage(page); + goto fail; spin_lock(&info->lock); - BUG_ON(index >= info->next_index); + if (index >= info->next_index) { + BUG_ON(!(info->flags & SHMEM_TRUNCATE)); + spin_unlock(&info->lock); + swap_free(swap); + goto fail; + } entry = shmem_swp_entry(info, index, NULL); BUG_ON(!entry); BUG_ON(entry->val); @@ -559,6 +591,7 @@ * Add page back to page cache, unref swap, try again. */ add_to_page_cache_locked(page, mapping, index); + info->flags |= SHMEM_PAGEIN; spin_unlock(&info->lock); swap_free(swap); goto getswap; @@ -571,6 +604,8 @@ set_page_dirty(page); UnlockPage(page); return 0; +fail: + return fail_writepage(page); } /* @@ -670,6 +705,7 @@ swap_free(swap); } else if (add_to_page_cache_unique(swappage, mapping, idx, page_hash(mapping, idx)) == 0) { + info->flags |= SHMEM_PAGEIN; entry->val = 0; info->swapped--; spin_unlock(&info->lock); @@ -735,6 +771,7 @@ goto failed; goto repeat; } + info->flags |= SHMEM_PAGEIN; } spin_unlock(&info->lock); @@ -1129,6 +1166,8 @@ */ static struct dentry *shmem_lookup(struct inode *dir, struct dentry *dentry) { + if (dentry->d_name.len > NAME_MAX) + return ERR_PTR(-ENAMETOOLONG); d_add(dentry, NULL); return NULL; } @@ -1142,6 +1181,11 @@ int error = -ENOSPC; if (inode) { + if (dir->i_mode & S_ISGID) { + inode->i_gid = dir->i_gid; + if (S_ISDIR(mode)) + inode->i_mode |= S_ISGID; + } dir->i_size += BOGO_DIRENT_SIZE; dir->i_ctime = dir->i_mtime = CURRENT_TIME; d_instantiate(dentry, inode); @@ -1308,6 +1352,8 @@ SetPageDirty(page); page_cache_release(page); } + if (dir->i_mode & S_ISGID) + inode->i_gid = dir->i_gid; dir->i_size += BOGO_DIRENT_SIZE; dir->i_ctime = dir->i_mtime = CURRENT_TIME; d_instantiate(dentry, inode); diff -urN linux-2.4.22-bk37/mm/vmscan.c linux-2.4.22-bk38/mm/vmscan.c --- linux-2.4.22-bk37/mm/vmscan.c 2003-10-21 02:49:31.000000000 -0700 +++ linux-2.4.22-bk38/mm/vmscan.c 2003-10-21 02:49:35.000000000 -0700 @@ -596,7 +596,7 @@ continue; } - nr_pages--; + ratio--; del_page_from_active_list(page); add_page_to_inactive_list(page);