diff options
Diffstat (limited to 'fs')
58 files changed, 489 insertions, 384 deletions
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 672a31924f3..e172180a1d8 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c @@ -47,7 +47,7 @@ static struct file_operations bad_file_ops = .get_unmapped_area = EIO_ERROR, }; -struct inode_operations bad_inode_ops = +static struct inode_operations bad_inode_ops = { .create = EIO_ERROR, .lookup = EIO_ERROR, diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index ce9423bb2de..c374be51b04 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -251,7 +251,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec, } /* Populate argv and envp */ - p = current->mm->arg_start; + p = current->mm->arg_end = current->mm->arg_start; while (argc-- > 0) { size_t len; __put_user((elf_addr_t)p, argv++); @@ -1301,7 +1301,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, struct mm_struct *mm) { - int i, len; + unsigned int i, len; /* first copy the parameters from user space */ memset(psinfo, 0, sizeof(struct elf_prpsinfo)); diff --git a/fs/block_dev.c b/fs/block_dev.c index d19d07c49ad..c0cbd1bc1a0 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -530,7 +530,7 @@ int check_disk_change(struct block_device *bdev) if (!bdops->media_changed(bdev->bd_disk)) return 0; - if (__invalidate_device(bdev, 0)) + if (__invalidate_device(bdev)) printk("VFS: busy inodes on changed media.\n"); if (bdops->revalidate_disk) diff --git a/fs/buffer.c b/fs/buffer.c index 5f525b3c6d9..7e9e409feaa 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1210,7 +1210,7 @@ grow_buffers(struct block_device *bdev, sector_t block, int size) return 1; } -struct buffer_head * +static struct buffer_head * __getblk_slow(struct block_device *bdev, sector_t block, int size) { /* Size must be multiple of hard sectorsize */ @@ -1809,7 +1809,6 @@ static int __block_write_full_page(struct inode *inode, struct page *page, } while (bh != head); do { - get_bh(bh); if (!buffer_mapped(bh)) continue; /* @@ -1838,7 +1837,6 @@ static int __block_write_full_page(struct inode *inode, struct page *page, */ BUG_ON(PageWriteback(page)); set_page_writeback(page); - unlock_page(page); do { struct buffer_head *next = bh->b_this_page; @@ -1846,9 +1844,9 @@ static int __block_write_full_page(struct inode *inode, struct page *page, submit_bh(WRITE, bh); nr_underway++; } - put_bh(bh); bh = next; } while (bh != head); + unlock_page(page); err = 0; done: @@ -1887,7 +1885,6 @@ recover: bh = head; /* Recovery: lock and submit the mapped buffers */ do { - get_bh(bh); if (buffer_mapped(bh) && buffer_dirty(bh)) { lock_buffer(bh); mark_buffer_async_write(bh); @@ -1910,7 +1907,6 @@ recover: submit_bh(WRITE, bh); nr_underway++; } - put_bh(bh); bh = next; } while (bh != head); goto done; @@ -1953,7 +1949,7 @@ static int __block_prepare_write(struct inode *inode, struct page *page, if (!buffer_mapped(bh)) { err = get_block(inode, block, bh, 1); if (err) - goto out; + break; if (buffer_new(bh)) { clear_buffer_new(bh); unmap_underlying_metadata(bh->b_bdev, @@ -1995,10 +1991,12 @@ static int __block_prepare_write(struct inode *inode, struct page *page, while(wait_bh > wait) { wait_on_buffer(*--wait_bh); if (!buffer_uptodate(*wait_bh)) - return -EIO; + err = -EIO; } - return 0; -out: + if (!err) + return err; + + /* Error case: */ /* * Zero out any newly allocated blocks to avoid exposing stale * data. If BH_New is set, we know that the block was newly @@ -2096,9 +2094,12 @@ int block_read_full_page(struct page *page, get_block_t *get_block) continue; if (!buffer_mapped(bh)) { + int err = 0; + fully_mapped = 0; if (iblock < lblock) { - if (get_block(inode, iblock, bh, 0)) + err = get_block(inode, iblock, bh, 0); + if (err) SetPageError(page); } if (!buffer_mapped(bh)) { @@ -2106,7 +2107,8 @@ int block_read_full_page(struct page *page, get_block_t *get_block) memset(kaddr + i * blocksize, 0, blocksize); flush_dcache_page(page); kunmap_atomic(kaddr, KM_USER0); - set_buffer_uptodate(bh); + if (!err) + set_buffer_uptodate(bh); continue; } /* @@ -3115,7 +3117,7 @@ void __init buffer_init(void) bh_cachep = kmem_cache_create("buffer_head", sizeof(struct buffer_head), 0, - SLAB_PANIC, init_buffer_head, NULL); + SLAB_RECLAIM_ACCOUNT|SLAB_PANIC, init_buffer_head, NULL); /* * Limit the bh occupancy to 10% of ZONE_NORMAL diff --git a/fs/char_dev.c b/fs/char_dev.c index a745b1d9e54..c1e3537909f 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -328,7 +328,7 @@ void cd_forget(struct inode *inode) spin_unlock(&cdev_lock); } -void cdev_purge(struct cdev *cdev) +static void cdev_purge(struct cdev *cdev) { spin_lock(&cdev_lock); while (!list_empty(&cdev->list)) { diff --git a/fs/cifs/README b/fs/cifs/README index 7b4ac096cd1..34b0cf7111f 100644 --- a/fs/cifs/README +++ b/fs/cifs/README @@ -32,9 +32,9 @@ the cifs download to your kernel build directory e.g. 6) make modules (or "make" if CIFS VFS not to be built as a module) For Linux 2.6: -1) Download the kernel (e.g. from http://www.kernel.org or from bitkeeper -at bk://linux.bkbits.net/linux-2.5) and change directory into the top -of the kernel directory tree (e.g. /usr/src/linux-2.5.73) +1) Download the kernel (e.g. from http://www.kernel.org) +and change directory into the top of the kernel directory tree +(e.g. /usr/src/linux-2.5.73) 2) make menuconfig (or make xconfig) 3) select cifs from within the network filesystem choices 4) save and exit @@ -371,7 +371,7 @@ A partial list of the supported mount options follows: on newly created files, directories, and devices (create, mkdir, mknod) which will result in the server setting the uid and gid to the default (usually the server uid of the - usern who mounted the share). Letting the server (rather than + user who mounted the share). Letting the server (rather than the client) set the uid and gid is the default. This parameter has no effect if the CIFS Unix Extensions are not negotiated. @@ -384,7 +384,7 @@ A partial list of the supported mount options follows: client (e.g. when the application is doing large sequential reads bigger than page size without rereading the same data) this can provide better performance than the default - behavior which caches reads (reaadahead) and writes + behavior which caches reads (readahead) and writes (writebehind) through the local Linux client pagecache if oplock (caching token) is granted and held. Note that direct allows write operations larger than page size diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 0010511083f..ea239dea571 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -228,7 +228,7 @@ extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, const struct nls_table *nls_codepage, int remap_special_chars); #endif /* CONFIG_CIFS_EXPERIMENTAL */ -extern int cifs_convertUCSpath(char *target, const __u16 *source, int maxlen, +extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen, const struct nls_table * codepage); extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen, const struct nls_table * cp, int mapChars); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 741ff0c69f3..3c628bf667a 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -567,7 +567,7 @@ DelFileRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->fileName, fileName, + cifsConvertToUCS((__le16 *) pSMB->fileName, fileName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -665,7 +665,7 @@ MkDirRetry: return rc; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { - name_len = cifsConvertToUCS((__u16 *) pSMB->DirName, name, + name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -719,7 +719,7 @@ openRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { count = 1; /* account for one byte pad to word boundary */ name_len = - cifsConvertToUCS((__u16 *) (pSMB->fileName + 1), + cifsConvertToUCS((__le16 *) (pSMB->fileName + 1), fileName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -1141,7 +1141,7 @@ renameRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, + cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -1149,7 +1149,7 @@ renameRetry: /* protocol requires ASCII signature byte on Unicode string */ pSMB->OldFileName[name_len + 1] = 0x00; name_len2 = - cifsConvertToUCS((__u16 *) &pSMB->OldFileName[name_len + 2], + cifsConvertToUCS((__le16 *) &pSMB->OldFileName[name_len + 2], toName, PATH_MAX, nls_codepage, remap); name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; name_len2 *= 2; /* convert to bytes */ @@ -1236,10 +1236,10 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, /* unicode only call */ if(target_name == NULL) { sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid); - len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name, + len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name, dummy_string, 24, nls_codepage, remap); } else { - len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name, + len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name, target_name, PATH_MAX, nls_codepage, remap); } rename_info->target_name_len = cpu_to_le32(2 * len_of_str); @@ -1296,7 +1296,7 @@ copyRetry: pSMB->Flags = cpu_to_le16(flags & COPY_TREE); if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { - name_len = cifsConvertToUCS((__u16 *) pSMB->OldFileName, + name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ @@ -1304,7 +1304,7 @@ copyRetry: pSMB->OldFileName[name_len] = 0x04; /* pad */ /* protocol requires ASCII signature byte on Unicode string */ pSMB->OldFileName[name_len + 1] = 0x00; - name_len2 = cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], + name_len2 = cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], toName, PATH_MAX, nls_codepage, remap); name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; name_len2 *= 2; /* convert to bytes */ @@ -1453,7 +1453,7 @@ createHardLinkRetry: return rc; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { - name_len = cifsConvertToUCS((__u16 *) pSMB->FileName, toName, + name_len = cifsConvertToUCS((__le16 *) pSMB->FileName, toName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -1476,7 +1476,7 @@ createHardLinkRetry: data_offset = (char *) (&pSMB->hdr.Protocol) + offset; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len_target = - cifsConvertToUCS((__u16 *) data_offset, fromName, PATH_MAX, + cifsConvertToUCS((__le16 *) data_offset, fromName, PATH_MAX, nls_codepage, remap); name_len_target++; /* trailing null */ name_len_target *= 2; @@ -1546,14 +1546,14 @@ winCreateHardLinkRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, + cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; pSMB->OldFileName[name_len] = 0; /* pad */ pSMB->OldFileName[name_len + 1] = 0x04; name_len2 = - cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], + cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], toName, PATH_MAX, nls_codepage, remap); name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; name_len2 *= 2; /* convert to bytes */ @@ -1939,7 +1939,7 @@ queryAclRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, + cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -2024,7 +2024,7 @@ setAclRetry: return rc; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, + cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -2188,7 +2188,7 @@ QPathInfoRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, + cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -2269,7 +2269,7 @@ UnixQPathInfoRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, + cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -2350,7 +2350,7 @@ findUniqueRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX + cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX /* find define for this maxpathcomponent */ , nls_codepage); name_len++; /* trailing null */ @@ -2435,7 +2435,7 @@ findFirstRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->FileName,searchName, + cifsConvertToUCS((__le16 *) pSMB->FileName,searchName, PATH_MAX, nls_codepage, remap); /* We can not add the asterik earlier in case it got remapped to 0xF03A as if it were part of the @@ -2726,7 +2726,7 @@ GetInodeNumberRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, + cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX,nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -2837,7 +2837,7 @@ getDFSRetry: if (ses->capabilities & CAP_UNICODE) { pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; name_len = - cifsConvertToUCS((__u16 *) pSMB->RequestFileName, + cifsConvertToUCS((__le16 *) pSMB->RequestFileName, searchName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -3369,7 +3369,7 @@ SetEOFRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, + cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -3627,7 +3627,7 @@ SetTimesRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, + cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -3708,7 +3708,7 @@ SetAttrLgcyRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - ConvertToUCS((wchar_t *) pSMB->fileName, fileName, + ConvertToUCS((__le16 *) pSMB->fileName, fileName, PATH_MAX, nls_codepage); name_len++; /* trailing null */ name_len *= 2; @@ -3759,7 +3759,7 @@ setPermsRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, + cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -3904,7 +3904,7 @@ QAllEAsRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, + cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -4047,7 +4047,7 @@ QEARetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, + cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -4194,7 +4194,7 @@ SetEARetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, + cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index e3137aa48cd..3f3538d4a1f 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -392,7 +392,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name rc = 0; d_add(direntry, NULL); } else { - cERROR(1,("Error 0x%x or on cifs_get_inode_info in lookup",rc)); + cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", + rc,full_path)); /* BB special case check for Access Denied - watch security exposure of returning dir info implicitly via different rc if file exists or not but no access BB */ diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 67094728826..b8b78cbb34c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -422,7 +422,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (!rc) { - direntry->d_inode->i_nlink--; + if(direntry->d_inode) + direntry->d_inode->i_nlink--; } else if (rc == -ENOENT) { d_drop(direntry); } else if (rc == -ETXTBSY) { @@ -440,7 +441,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); CIFSSMBClose(xid, pTcon, netfid); - direntry->d_inode->i_nlink--; + if(direntry->d_inode) + direntry->d_inode->i_nlink--; } } else if (rc == -EACCES) { /* try only if r/o attribute set in local lookup data? */ @@ -494,7 +496,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (!rc) { - direntry->d_inode->i_nlink--; + if(direntry->d_inode) + direntry->d_inode->i_nlink--; } else if (rc == -ETXTBSY) { int oplock = FALSE; __u16 netfid; @@ -514,17 +517,20 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); CIFSSMBClose(xid, pTcon, netfid); - direntry->d_inode->i_nlink--; + if(direntry->d_inode) + direntry->d_inode->i_nlink--; } /* BB if rc = -ETXTBUSY goto the rename logic BB */ } } } - cifsInode = CIFS_I(direntry->d_inode); - cifsInode->time = 0; /* will force revalidate to get info when - needed */ - direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = - current_fs_time(inode->i_sb); + if(direntry->d_inode) { + cifsInode = CIFS_I(direntry->d_inode); + cifsInode->time = 0; /* will force revalidate to get info + when needed */ + direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); + } + inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); cifsInode = CIFS_I(inode); cifsInode->time = 0; /* force revalidate of dir as well */ diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index db14b503d89..072b4ee8c53 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -571,6 +571,7 @@ cifs_convertUCSpath(char *target, const __le16 * source, int maxlen, break; case UNI_LESSTHAN: target[j] = '<'; + break; default: len = cp->uni2char(src_char, &target[j], NLS_MAX_CHARSET_SIZE); diff --git a/fs/dcache.c b/fs/dcache.c index 496a4e08369..3aa8a7e980d 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -39,7 +39,7 @@ int sysctl_vfs_cache_pressure = 100; EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); -seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED; +static seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED; EXPORT_SYMBOL(dcache_lock); diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 05b966cd6f7..9900e333655 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -320,7 +320,7 @@ static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type, /* * This semaphore is used to serialize ep_free() and eventpoll_release_file(). */ -struct semaphore epsem; +static struct semaphore epsem; /* Safe wake up implementation */ static struct poll_safewake psw; diff --git a/fs/exec.c b/fs/exec.c index a8394499926..e56ee243702 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -197,7 +197,8 @@ static int count(char __user * __user * argv, int max) * memory to free pages in kernel mem. These are in a format ready * to be put directly into the top of new user memory. */ -int copy_strings(int argc,char __user * __user * argv, struct linux_binprm *bprm) +static int copy_strings(int argc, char __user * __user * argv, + struct linux_binprm *bprm) { struct page *kmapped_page = NULL; char *kaddr = NULL; @@ -868,9 +869,11 @@ int flush_old_exec(struct linux_binprm * bprm) if (current->euid == current->uid && current->egid == current->gid) current->mm->dumpable = 1; name = bprm->filename; + + /* Copies the binary name from after last slash */ for (i=0; (ch = *(name++)) != '\0';) { if (ch == '/') - i = 0; + i = 0; /* overwrite what we wrote */ else if (i < (sizeof(tcomm) - 1)) tcomm[i++] = ch; diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index ea5888688f9..0d5fa73b18d 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -844,12 +844,6 @@ get_block: return ret; } -static int ext3_writepages_get_block(struct inode *inode, sector_t iblock, - struct buffer_head *bh, int create) -{ - return ext3_direct_io_get_blocks(inode, iblock, 1, bh, create); -} - /* * `handle' can be NULL if create is zero */ @@ -1323,45 +1317,6 @@ out_fail: return ret; } -static int -ext3_writeback_writepage_helper(struct page *page, - struct writeback_control *wbc) -{ - return block_write_full_page(page, ext3_get_block, wbc); -} - -static int -ext3_writeback_writepages(struct address_space *mapping, - struct writeback_control *wbc) -{ - struct inode *inode = mapping->host; - handle_t *handle = NULL; - int err, ret = 0; - - if (!mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) - return ret; - - handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode)); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - return ret; - } - - ret = __mpage_writepages(mapping, wbc, ext3_writepages_get_block, - ext3_writeback_writepage_helper); - - /* - * Need to reaquire the handle since ext3_writepages_get_block() - * can restart the handle - */ - handle = journal_current_handle(); - - err = ext3_journal_stop(handle); - if (!ret) - ret = err; - return ret; -} - static int ext3_writeback_writepage(struct page *page, struct writeback_control *wbc) { @@ -1599,7 +1554,6 @@ static struct address_space_operations ext3_writeback_aops = { .readpage = ext3_readpage, .readpages = ext3_readpages, .writepage = ext3_writeback_writepage, - .writepages = ext3_writeback_writepages, .sync_page = block_sync_page, .prepare_write = ext3_prepare_write, .commit_write = ext3_writeback_commit_write, diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 545b440a2d2..981ccb233ef 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -225,8 +225,16 @@ void __ext3_std_error (struct super_block * sb, const char * function, int errno) { char nbuf[16]; - const char *errstr = ext3_decode_error(sb, errno, nbuf); + const char *errstr; + + /* Special case: if the error is EROFS, and we're not already + * inside a transaction, then there's really no point in logging + * an error. */ + if (errno == -EROFS && journal_current_handle() == NULL && + (sb->s_flags & MS_RDONLY)) + return; + errstr = ext3_decode_error(sb, errno, nbuf); printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n", sb->s_id, function, errstr); diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index e6c63d9cac7..4bf43ea87c4 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -23,7 +23,6 @@ #include "kern_util.h" #include "kern.h" #include "user_util.h" -#include "2_5compat.h" #include "init.h" struct hostfs_inode_info { @@ -991,13 +990,17 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) goto out_put; err = read_inode(root_inode); - if(err) - goto out_put; + if(err){ + /* No iput in this case because the dput does that for us */ + dput(sb->s_root); + sb->s_root = NULL; + goto out_free; + } return(0); out_put: - iput(root_inode); + iput(root_inode); out_free: kfree(name); out: diff --git a/fs/inode.c b/fs/inode.c index af8fd78d209..801fe7f3628 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -26,7 +26,6 @@ * This is needed for the following functions: * - inode_has_buffers * - invalidate_inode_buffers - * - fsync_bdev * - invalidate_bdev * * FIXME: remove all knowledge of the buffer layer from this file @@ -332,14 +331,6 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose) return busy; } -/* - * This is a two-stage process. First we collect all - * offending inodes onto the throw-away list, and in - * the second stage we actually dispose of them. This - * is because we don't want to sleep while messing - * with the global lists.. - */ - /** * invalidate_inodes - discard the inodes on a device * @sb: superblock @@ -366,16 +357,11 @@ int invalidate_inodes(struct super_block * sb) EXPORT_SYMBOL(invalidate_inodes); -int __invalidate_device(struct block_device *bdev, int do_sync) +int __invalidate_device(struct block_device *bdev) { - struct super_block *sb; - int res; + struct super_block *sb = get_super(bdev); + int res = 0; - if (do_sync) - fsync_bdev(bdev); - - res = 0; - sb = get_super(bdev); if (sb) { /* * no need to lock the super, get_super holds the @@ -390,7 +376,6 @@ int __invalidate_device(struct block_device *bdev, int do_sync) invalidate_bdev(bdev, 0); return res; } - EXPORT_SYMBOL(__invalidate_device); static int can_unuse(struct inode *inode) @@ -1336,7 +1321,7 @@ void __init inode_init(unsigned long mempages) /* inode slab cache */ inode_cachep = kmem_cache_create("inode_cache", sizeof(struct inode), - 0, SLAB_PANIC, init_once, NULL); + 0, SLAB_RECLAIM_ACCOUNT|SLAB_PANIC, init_once, NULL); set_shrinker(DEFAULT_SEEKS, shrink_icache_memory); /* Hash may have been set up in inode_init_early */ diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c index 450d6624181..09422388fb9 100644 --- a/fs/jffs2/compr_rubin.c +++ b/fs/jffs2/compr_rubin.c @@ -228,8 +228,10 @@ int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); } #endif -int jffs2_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t *sourcelen, uint32_t *dstlen, void *model) +static int jffs2_dynrubin_compress(unsigned char *data_in, + unsigned char *cpage_out, + uint32_t *sourcelen, uint32_t *dstlen, + void *model) { int bits[8]; unsigned char histo[256]; @@ -306,15 +308,19 @@ static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata } -int jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t sourcelen, uint32_t dstlen, void *model) +static int jffs2_rubinmips_decompress(unsigned char *data_in, + unsigned char *cpage_out, + uint32_t sourcelen, uint32_t dstlen, + void *model) { rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); return 0; } -int jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t sourcelen, uint32_t dstlen, void *model) +static int jffs2_dynrubin_decompress(unsigned char *data_in, + unsigned char *cpage_out, + uint32_t sourcelen, uint32_t dstlen, + void *model) { int bits[8]; int c; diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c index 9f9932c22ad..078a30e406b 100644 --- a/fs/jffs2/compr_zlib.c +++ b/fs/jffs2/compr_zlib.c @@ -69,8 +69,10 @@ static void free_workspaces(void) #define free_workspaces() do { } while(0) #endif /* __KERNEL__ */ -int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t *sourcelen, uint32_t *dstlen, void *model) +static int jffs2_zlib_compress(unsigned char *data_in, + unsigned char *cpage_out, + uint32_t *sourcelen, uint32_t *dstlen, + void *model) { int ret; @@ -135,8 +137,10 @@ int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, return ret; } -int jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t srclen, uint32_t destlen, void *model) +static int jffs2_zlib_decompress(unsigned char *data_in, + unsigned char *cpage_out, + uint32_t srclen, uint32_t destlen, + void *model) { int ret; int wbits = MAX_WBITS; diff --git a/fs/locks.c b/fs/locks.c index 1792ce547af..3fa6a7ce57a 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -406,12 +406,12 @@ static void lease_release_private_callback(struct file_lock *fl) fl->fl_file->f_owner.signum = 0; } -int lease_mylease_callback(struct file_lock *fl, struct file_lock *try) +static int lease_mylease_callback(struct file_lock *fl, struct file_lock *try) { return fl->fl_file == try->fl_file; } -struct lock_manager_operations lease_manager_ops = { +static struct lock_manager_operations lease_manager_ops = { .fl_break = lease_break_callback, .fl_release_private = lease_release_private_callback, .fl_mylease = lease_mylease_callback, @@ -1274,7 +1274,7 @@ int fcntl_getlease(struct file *filp) * * Called with kernel lock held. */ -int __setlease(struct file *filp, long arg, struct file_lock **flp) +static int __setlease(struct file *filp, long arg, struct file_lock **flp) { struct file_lock *fl, **before, **my_before = NULL, *lease = *flp; struct dentry *dentry = filp->f_dentry; diff --git a/fs/mbcache.c b/fs/mbcache.c index f9e4d2700cd..c7170b9221a 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -57,7 +57,7 @@ #define MB_CACHE_WRITER ((unsigned short)~0U >> 1) -DECLARE_WAIT_QUEUE_HEAD(mb_cache_queue); +static DECLARE_WAIT_QUEUE_HEAD(mb_cache_queue); MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>"); MODULE_DESCRIPTION("Meta block cache (for extended attributes)"); diff --git a/fs/mpage.c b/fs/mpage.c index 32c7c8fcfce..b92c0e64aef 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -87,7 +87,7 @@ static int mpage_end_io_write(struct bio *bio, unsigned int bytes_done, int err) return 0; } -struct bio *mpage_bio_submit(int rw, struct bio *bio) +static struct bio *mpage_bio_submit(int rw, struct bio *bio) { bio->bi_end_io = mpage_end_io_read; if (rw == WRITE) @@ -627,15 +627,6 @@ int mpage_writepages(struct address_space *mapping, struct writeback_control *wbc, get_block_t get_block) { - return __mpage_writepages(mapping, wbc, get_block, - mapping->a_ops->writepage); -} - -int -__mpage_writepages(struct address_space *mapping, - struct writeback_control *wbc, get_block_t get_block, - writepage_t writepage_fn) -{ struct backing_dev_info *bdi = mapping->backing_dev_info; struct bio *bio = NULL; sector_t last_block_in_bio = 0; @@ -725,7 +716,7 @@ retry: } else { bio = __mpage_writepage(bio, page, get_block, &last_block_in_bio, &ret, wbc, - writepage_fn); + page->mapping->a_ops->writepage); } if (unlikely(ret == WRITEPAGE_ACTIVATE)) unlock_page(page); @@ -755,7 +746,6 @@ retry: return ret; } EXPORT_SYMBOL(mpage_writepages); -EXPORT_SYMBOL(__mpage_writepages); int mpage_writepage(struct page *page, get_block_t get_block, struct writeback_control *wbc) diff --git a/fs/namei.c b/fs/namei.c index 0f76fd75591..dd78f01b6de 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1580,6 +1580,7 @@ enoent: fail: return dentry; } +EXPORT_SYMBOL_GPL(lookup_create); int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { @@ -2071,8 +2072,8 @@ exit: * ->i_sem on parents, which works but leads to some truely excessive * locking]. */ -int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) +static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) { int error = 0; struct inode *target; @@ -2116,8 +2117,8 @@ int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, return error; } -int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) +static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) { struct inode *target; int error; diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index b74c4e3a64e..87f4f9aeac8 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -79,7 +79,7 @@ static ssize_t idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *, char __user *, size_t); static ssize_t idmap_pipe_downcall(struct file *, const char __user *, size_t); -void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); +static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); static unsigned int fnvhash32(const void *, size_t); @@ -434,7 +434,7 @@ out: return ret; } -void +static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg) { struct idmap_msg *im = msg->data; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 6345f26e87e..f2317f3e29f 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1904,7 +1904,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) } } -int nfs_init_inodecache(void) +static int nfs_init_inodecache(void) { nfs_inode_cachep = kmem_cache_create("nfs_inode_cache", sizeof(struct nfs_inode), @@ -1916,7 +1916,7 @@ int nfs_init_inodecache(void) return 0; } -void nfs_destroy_inodecache(void) +static void nfs_destroy_inodecache(void) { if (kmem_cache_destroy(nfs_inode_cachep)) printk(KERN_INFO "nfs_inode_cache: not all structures were freed\n"); diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index 897512796ed..a912debcd20 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -243,7 +243,7 @@ void unload_nls(struct nls_table *nls) module_put(nls->owner); } -wchar_t charset2uni[256] = { +static wchar_t charset2uni[256] = { /* 0x00*/ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 17ee1b4ff08..584a27b2bbd 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -114,9 +114,6 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev, */ for (i=0; i<4; i++, p++) { u32 offs, size, next; - - if (SYS_IND(p) == 0) - continue; if (!NR_SECTS(p) || is_extended_partition(p)) continue; @@ -433,8 +430,6 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) for (slot = 1 ; slot <= 4 ; slot++, p++) { u32 start = START_SECT(p)*sector_size; u32 size = NR_SECTS(p)*sector_size; - if (SYS_IND(p) == 0) - continue; if (!size) continue; if (is_extended_partition(p)) { diff --git a/fs/proc/mmu.c b/fs/proc/mmu.c index a7041038ad5..25d2d9c6e32 100644 --- a/fs/proc/mmu.c +++ b/fs/proc/mmu.c @@ -50,13 +50,23 @@ void get_vmalloc_info(struct vmalloc_info *vmi) read_lock(&vmlist_lock); for (vma = vmlist; vma; vma = vma->next) { + unsigned long addr = (unsigned long) vma->addr; + + /* + * Some archs keep another range for modules in vmlist + */ + if (addr < VMALLOC_START) + continue; + if (addr >= VMALLOC_END) + break; + vmi->used += vma->size; - free_area_size = (unsigned long) vma->addr - prev_end; + free_area_size = addr - prev_end; if (vmi->largest_chunk < free_area_size) vmi->largest_chunk = free_area_size; - prev_end = vma->size + (unsigned long) vma->addr; + prev_end = vma->size + addr; } if (VMALLOC_END - prev_end > vmi->largest_chunk) diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index 67423c696c0..6fd57f15419 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c @@ -12,15 +12,8 @@ #include <asm/uaccess.h> #ifndef HAVE_ARCH_DEVTREE_FIXUPS -static inline void set_node_proc_entry(struct device_node *np, struct proc_dir_entry *de) -{ -} - -static void inline set_node_name_link(struct device_node *np, struct proc_dir_entry *de) -{ -} - -static void inline set_node_addr_link(struct device_node *np, struct proc_dir_entry *de) +static inline void set_node_proc_entry(struct device_node *np, + struct proc_dir_entry *de) { } #endif @@ -58,89 +51,67 @@ static int property_read_proc(char *page, char **start, off_t off, /* * Process a node, adding entries for its children and its properties. */ -void proc_device_tree_add_node(struct device_node *np, struct proc_dir_entry *de) +void proc_device_tree_add_node(struct device_node *np, + struct proc_dir_entry *de) { struct property *pp; struct proc_dir_entry *ent; - struct device_node *child, *sib; - const char *p, *at; - int l; - struct proc_dir_entry *list, **lastp, *al; + struct device_node *child; + struct proc_dir_entry *list = NULL, **lastp; + const char *p; set_node_proc_entry(np, de); lastp = &list; - for (pp = np->properties; pp != 0; pp = pp->next) { - /* - * Unfortunately proc_register puts each new entry - * at the beginning of the list. So we rearrange them. - */ - ent = create_proc_read_entry(pp->name, strncmp(pp->name, "security-", 9) ? - S_IRUGO : S_IRUSR, de, property_read_proc, pp); - if (ent == 0) - break; - if (!strncmp(pp->name, "security-", 9)) - ent->size = 0; /* don't leak number of password chars */ - else - ent->size = pp->length; - *lastp = ent; - lastp = &ent->next; - } - child = NULL; - while ((child = of_get_next_child(np, child))) { + for (child = NULL; (child = of_get_next_child(np, child));) { p = strrchr(child->full_name, '/'); if (!p) p = child->full_name; else ++p; - /* chop off '@0' if the name ends with that */ - l = strlen(p); - if (l > 2 && p[l-2] == '@' && p[l-1] == '0') - l -= 2; ent = proc_mkdir(p, de); if (ent == 0) break; *lastp = ent; + ent->next = NULL; lastp = &ent->next; proc_device_tree_add_node(child, ent); - - /* - * If we left the address part on the name, consider - * adding symlinks from the name and address parts. - */ - if (p[l] != 0 || (at = strchr(p, '@')) == 0) - continue; - + } + of_node_put(child); + for (pp = np->properties; pp != 0; pp = pp->next) { /* - * If this is the first node with a given name property, - * add a symlink with the name property as its name. + * Yet another Apple device-tree bogosity: on some machines, + * they have properties & nodes with the same name. Those + * properties are quite unimportant for us though, thus we + * simply "skip" them here, but we do have to check. */ - sib = NULL; - while ((sib = of_get_next_child(np, sib)) && sib != child) - if (sib->name && strcmp(sib->name, child->name) == 0) - break; - if (sib == child && strncmp(p, child->name, l) != 0) { - al = proc_symlink(child->name, de, ent->name); - if (al == 0) { - of_node_put(sib); + for (ent = list; ent != NULL; ent = ent->next) + if (!strcmp(ent->name, pp->name)) break; - } - set_node_name_link(child, al); - *lastp = al; - lastp = &al->next; + if (ent != NULL) { + printk(KERN_WARNING "device-tree: property \"%s\" name" + " conflicts with node in %s\n", pp->name, + np->full_name); + continue; } - of_node_put(sib); + /* - * Add another directory with the @address part as its name. + * Unfortunately proc_register puts each new entry + * at the beginning of the list. So we rearrange them. */ - al = proc_symlink(at, de, ent->name); - if (al == 0) + ent = create_proc_read_entry(pp->name, + strncmp(pp->name, "security-", 9) + ? S_IRUGO : S_IRUSR, de, + property_read_proc, pp); + if (ent == 0) break; - set_node_addr_link(child, al); - *lastp = al; - lastp = &al->next; + if (!strncmp(pp->name, "security-", 9)) + ent->size = 0; /* don't leak number of password chars */ + else + ent->size = pp->length; + ent->next = NULL; + *lastp = ent; + lastp = &ent->next; } - of_node_put(child); - *lastp = NULL; de->subdir = list; } diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 80e92d9b81c..7d4dc5f5aa8 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -608,7 +608,7 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode, goto out_failed; } - retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode); + retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode); if (retval) goto out_failed; diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index da23ba75f3d..c47f8fd31a2 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c @@ -230,7 +230,6 @@ const struct reiserfs_key MAX_KEY = { __constant_cpu_to_le32(0xffffffff)},} }; -const struct in_core_key MAX_IN_CORE_KEY = {~0U, ~0U, ~0ULL>>4, 15}; /* Get delimiting key of the buffer by looking for it in the buffers in the path, starting from the bottom of the path, and going upwards. We must check the path's validity at each step. If the key is not in diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 31e75125f48..b35b8774498 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -164,7 +164,9 @@ static int finish_unfinished (struct super_block * s) /* compose key to look for "save" links */ max_cpu_key.version = KEY_FORMAT_3_5; - max_cpu_key.on_disk_key = MAX_IN_CORE_KEY; + max_cpu_key.on_disk_key.k_dir_id = ~0U; + max_cpu_key.on_disk_key.k_objectid = ~0U; + set_cpu_key_k_offset (&max_cpu_key, ~0U); max_cpu_key.key_length = 3; #ifdef CONFIG_QUOTA diff --git a/fs/select.c b/fs/select.c index 25b1ccac2f2..b80e7eb0ac0 100644 --- a/fs/select.c +++ b/fs/select.c @@ -55,7 +55,8 @@ struct poll_table_page { * as all select/poll functions have to call it to add an entry to the * poll table. */ -void __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p); +static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, + poll_table *p); void poll_initwait(struct poll_wqueues *pwq) { @@ -87,7 +88,8 @@ void poll_freewait(struct poll_wqueues *pwq) EXPORT_SYMBOL(poll_freewait); -void __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *_p) +static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, + poll_table *_p) { struct poll_wqueues *p = container_of(_p, struct poll_wqueues, pt); struct poll_table_page *table = p->table; diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c index c2634bda6b5..85d8dbe843f 100644 --- a/fs/udf/udftime.c +++ b/fs/udf/udftime.c @@ -46,7 +46,7 @@ #endif /* How many days come before each month (0-12). */ -const unsigned short int __mon_yday[2][13] = +static const unsigned short int __mon_yday[2][13] = { /* Normal years. */ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, @@ -103,7 +103,7 @@ udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src) offset = 0; if ((src.year < EPOCH_YEAR) || - (src.year > EPOCH_YEAR+MAX_YEAR_SECONDS)) + (src.year >= EPOCH_YEAR+MAX_YEAR_SECONDS)) { *dest = -1; *dest_usec = -1; diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 554e4a18c15..d3ff7835463 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -49,7 +49,7 @@ ifeq ($(CONFIG_XFS_TRACE),y) EXTRA_CFLAGS += -DXFS_LOG_TRACE EXTRA_CFLAGS += -DXFS_RW_TRACE EXTRA_CFLAGS += -DPAGEBUF_TRACE - # EXTRA_CFLAGS += -DXFS_VNODE_TRACE + EXTRA_CFLAGS += -DXFS_VNODE_TRACE endif obj-$(CONFIG_XFS_FS) += xfs.o diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 76a84758073..93ce257cd14 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -558,7 +558,8 @@ xfs_submit_page( int i; BUG_ON(PageWriteback(page)); - set_page_writeback(page); + if (bh_count) + set_page_writeback(page); if (clear_dirty) clear_page_dirty(page); unlock_page(page); @@ -578,9 +579,6 @@ xfs_submit_page( if (probed_page && clear_dirty) wbc->nr_to_write--; /* Wrote an "extra" page */ - } else { - end_page_writeback(page); - wbc->pages_skipped++; /* We didn't write this page */ } } @@ -602,21 +600,26 @@ xfs_convert_page( { struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head; xfs_iomap_t *mp = iomapp, *tmp; - unsigned long end, offset; - pgoff_t end_index; - int i = 0, index = 0; + unsigned long offset, end_offset; + int index = 0; int bbits = inode->i_blkbits; + int len, page_dirty; - end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT; - if (page->index < end_index) { - end = PAGE_CACHE_SIZE; - } else { - end = i_size_read(inode) & (PAGE_CACHE_SIZE-1); - } + end_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1)); + + /* + * page_dirty is initially a count of buffers on the page before + * EOF and is decrememted as we move each into a cleanable state. + */ + len = 1 << inode->i_blkbits; + end_offset = max(end_offset, PAGE_CACHE_SIZE); + end_offset = roundup(end_offset, len); + page_dirty = end_offset / len; + + offset = 0; bh = head = page_buffers(page); do { - offset = i << bbits; - if (offset >= end) + if (offset >= end_offset) break; if (!(PageUptodate(page) || buffer_uptodate(bh))) continue; @@ -625,6 +628,7 @@ xfs_convert_page( if (startio) { lock_buffer(bh); bh_arr[index++] = bh; + page_dirty--; } continue; } @@ -657,10 +661,11 @@ xfs_convert_page( unlock_buffer(bh); mark_buffer_dirty(bh); } - } while (i++, (bh = bh->b_this_page) != head); + page_dirty--; + } while (offset += len, (bh = bh->b_this_page) != head); - if (startio) { - xfs_submit_page(page, wbc, bh_arr, index, 1, index == i); + if (startio && index) { + xfs_submit_page(page, wbc, bh_arr, index, 1, !page_dirty); } else { unlock_page(page); } @@ -725,8 +730,11 @@ xfs_page_state_convert( __uint64_t end_offset; pgoff_t end_index, last_index, tlast; int len, err, i, cnt = 0, uptodate = 1; - int flags = startio ? 0 : BMAPI_TRYLOCK; - int page_dirty, delalloc = 0; + int flags; + int page_dirty; + + /* wait for other IO threads? */ + flags = (startio && wbc->sync_mode != WB_SYNC_NONE) ? 0 : BMAPI_TRYLOCK; /* Is this page beyond the end of the file? */ offset = i_size_read(inode); @@ -740,19 +748,22 @@ xfs_page_state_convert( } } - offset = (loff_t)page->index << PAGE_CACHE_SHIFT; end_offset = min_t(unsigned long long, - offset + PAGE_CACHE_SIZE, i_size_read(inode)); - - bh = head = page_buffers(page); - iomp = NULL; + (loff_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset); + offset = (loff_t)page->index << PAGE_CACHE_SHIFT; /* - * page_dirty is initially a count of buffers on the page and - * is decrememted as we move each into a cleanable state. + * page_dirty is initially a count of buffers on the page before + * EOF and is decrememted as we move each into a cleanable state. */ - len = bh->b_size; - page_dirty = PAGE_CACHE_SIZE / len; + len = 1 << inode->i_blkbits; + p_offset = max(p_offset, PAGE_CACHE_SIZE); + p_offset = roundup(p_offset, len); + page_dirty = p_offset / len; + + iomp = NULL; + p_offset = 0; + bh = head = page_buffers(page); do { if (offset >= end_offset) @@ -804,7 +815,6 @@ xfs_page_state_convert( */ } else if (buffer_delay(bh)) { if (!iomp) { - delalloc = 1; err = xfs_map_blocks(inode, offset, len, &iomap, BMAPI_ALLOCATE | flags); if (err) { @@ -875,14 +885,14 @@ xfs_page_state_convert( if (uptodate && bh == head) SetPageUptodate(page); - if (startio) - xfs_submit_page(page, wbc, bh_arr, cnt, 0, 1); + if (startio) { + xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty); + } if (iomp) { - tlast = (iomp->iomap_offset + iomp->iomap_bsize - 1) >> + offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >> PAGE_CACHE_SHIFT; - if (delalloc && (tlast > last_index)) - tlast = last_index; + tlast = min_t(pgoff_t, offset, last_index); xfs_cluster_write(inode, page->index + 1, iomp, wbc, startio, unmapped, tlast); } diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 23e0eb67fc2..997963e5362 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1746,13 +1746,15 @@ STATIC DECLARE_COMPLETION(pagebuf_daemon_done); STATIC struct task_struct *pagebuf_daemon_task; STATIC int pagebuf_daemon_active; STATIC int force_flush; - +STATIC int force_sleep; STATIC int pagebuf_daemon_wakeup( int priority, unsigned int mask) { + if (force_sleep) + return 0; force_flush = 1; barrier(); wake_up_process(pagebuf_daemon_task); @@ -1778,7 +1780,12 @@ pagebuf_daemon( INIT_LIST_HEAD(&tmp); do { - try_to_freeze(PF_FREEZE); + if (unlikely(current->flags & PF_FREEZE)) { + force_sleep = 1; + refrigerator(PF_FREEZE); + } else { + force_sleep = 0; + } set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((xfs_buf_timer_centisecs * HZ) / 100); diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 9f057a4a5b0..24fa3b101b9 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -515,10 +515,49 @@ open_exec_out: } #endif /* HAVE_FOP_OPEN_EXEC */ +/* + * Temporary workaround to the AIO direct IO write problem. + * This code can go and we can revert to do_sync_write once + * the writepage(s) rework is merged. + */ +STATIC ssize_t +linvfs_write( + struct file *filp, + const char __user *buf, + size_t len, + loff_t *ppos) +{ + struct kiocb kiocb; + ssize_t ret; + + init_sync_kiocb(&kiocb, filp); + kiocb.ki_pos = *ppos; + ret = __linvfs_write(&kiocb, buf, 0, len, kiocb.ki_pos); + *ppos = kiocb.ki_pos; + return ret; +} +STATIC ssize_t +linvfs_write_invis( + struct file *filp, + const char __user *buf, + size_t len, + loff_t *ppos) +{ + struct kiocb kiocb; + ssize_t ret; + + init_sync_kiocb(&kiocb, filp); + kiocb.ki_pos = *ppos; + ret = __linvfs_write(&kiocb, buf, IO_INVIS, len, kiocb.ki_pos); + *ppos = kiocb.ki_pos; + return ret; +} + + struct file_operations linvfs_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, - .write = do_sync_write, + .write = linvfs_write, .readv = linvfs_readv, .writev = linvfs_writev, .aio_read = linvfs_aio_read, @@ -526,7 +565,7 @@ struct file_operations linvfs_file_operations = { .sendfile = linvfs_sendfile, .unlocked_ioctl = linvfs_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = xfs_compat_ioctl, + .compat_ioctl = linvfs_compat_ioctl, #endif .mmap = linvfs_file_mmap, .open = linvfs_open, @@ -540,7 +579,7 @@ struct file_operations linvfs_file_operations = { struct file_operations linvfs_invis_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, - .write = do_sync_write, + .write = linvfs_write_invis, .readv = linvfs_readv_invis, .writev = linvfs_writev_invis, .aio_read = linvfs_aio_read_invis, @@ -548,7 +587,7 @@ struct file_operations linvfs_invis_file_operations = { .sendfile = linvfs_sendfile, .unlocked_ioctl = linvfs_ioctl_invis, #ifdef CONFIG_COMPAT - .compat_ioctl = xfs_compat_invis_ioctl, + .compat_ioctl = linvfs_compat_invis_ioctl, #endif .mmap = linvfs_file_mmap, .open = linvfs_open, @@ -561,6 +600,9 @@ struct file_operations linvfs_dir_operations = { .read = generic_read_dir, .readdir = linvfs_readdir, .unlocked_ioctl = linvfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = linvfs_compat_ioctl, +#endif .fsync = linvfs_fsync, }; diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index 7a12c83184f..0f8f1384eb3 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -58,8 +58,9 @@ typedef struct xfs_fsop_bulkreq32 { __s32 ocount; /* output count pointer */ } xfs_fsop_bulkreq32_t; -static unsigned long -xfs_ioctl32_bulkstat(unsigned long arg) +STATIC unsigned long +xfs_ioctl32_bulkstat( + unsigned long arg) { xfs_fsop_bulkreq32_t __user *p32 = (void __user *)arg; xfs_fsop_bulkreq_t __user *p = compat_alloc_user_space(sizeof(*p)); @@ -78,11 +79,11 @@ xfs_ioctl32_bulkstat(unsigned long arg) } #endif -static long -__xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) +STATIC long +__linvfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) { int error; - struct inode *inode = f->f_dentry->d_inode; + struct inode *inode = f->f_dentry->d_inode; vnode_t *vp = LINVFS_GET_VP(inode); switch (cmd) { @@ -152,12 +153,20 @@ __xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) return error; } -long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg) +long +linvfs_compat_ioctl( + struct file *f, + unsigned cmd, + unsigned long arg) { - return __xfs_compat_ioctl(0, f, cmd, arg); + return __linvfs_compat_ioctl(0, f, cmd, arg); } -long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg) +long +linvfs_compat_invis_ioctl( + struct file *f, + unsigned cmd, + unsigned long arg) { - return __xfs_compat_ioctl(IO_INVIS, f, cmd, arg); + return __linvfs_compat_ioctl(IO_INVIS, f, cmd, arg); } diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.h b/fs/xfs/linux-2.6/xfs_ioctl32.h index 779f69a4811..c874793a1dc 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.h +++ b/fs/xfs/linux-2.6/xfs_ioctl32.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -30,5 +30,5 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg); -long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg); +long linvfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg); +long linvfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg); diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index ff145fd0d1a..aa9daaea6c3 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -683,6 +683,9 @@ xfs_write( (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? mp->m_rtdev_targp : mp->m_ddev_targp; + if (ioflags & IO_ISAIO) + return XFS_ERROR(-ENOSYS); + if ((pos & target->pbr_smask) || (count & target->pbr_smask)) return XFS_ERROR(-EINVAL); diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 53dc658cafa..455e2b2fb96 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -66,7 +66,6 @@ #include "xfs_buf_item.h" #include "xfs_utils.h" #include "xfs_version.h" -#include "xfs_ioctl32.h" #include <linux/namei.h> #include <linux/init.h> diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c index 849c61c74f3..a832d165f24 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.c +++ b/fs/xfs/linux-2.6/xfs_vnode.c @@ -156,7 +156,6 @@ vn_initialize( #ifdef XFS_VNODE_TRACE vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP); - printk("Allocated VNODE_TRACE at 0x%p\n", vp->v_trace); #endif /* XFS_VNODE_TRACE */ vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address); @@ -424,13 +423,13 @@ vn_remove( * Vnode tracing code. */ void -vn_trace_entry(vnode_t *vp, char *func, inst_t *ra) +vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra) { KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra); } void -vn_trace_exit(vnode_t *vp, char *func, inst_t *ra) +vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra) { KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra); } diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index da76c1f1e11..00466c3194a 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h @@ -86,10 +86,11 @@ typedef struct vnode { vnumber_t v_number; /* in-core vnode number */ vn_bhv_head_t v_bh; /* behavior head */ spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ - struct inode v_inode; /* Linux inode */ #ifdef XFS_VNODE_TRACE struct ktrace *v_trace; /* trace header structure */ #endif + struct inode v_inode; /* Linux inode */ + /* inode MUST be last */ } vnode_t; #define v_fbhv v_bh.bh_first /* first behavior */ @@ -409,7 +410,7 @@ typedef struct vattr { int va_mask; /* bit-mask of attributes present */ enum vtype va_type; /* vnode type (for create) */ mode_t va_mode; /* file access mode and type */ - nlink_t va_nlink; /* number of references to file */ + xfs_nlink_t va_nlink; /* number of references to file */ uid_t va_uid; /* owner user id */ gid_t va_gid; /* owner group id */ xfs_ino_t va_nodeid; /* file id */ @@ -625,6 +626,7 @@ static inline int VN_BAD(struct vnode *vp) #define ATTR_DMI 0x08 /* invocation from a DMI function */ #define ATTR_LAZY 0x80 /* set/get attributes lazily */ #define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */ +#define ATTR_NOLOCK 0x200 /* Don't grab any conflicting locks */ /* * Flags to VOP_FSYNC and VOP_RECLAIM. @@ -646,8 +648,8 @@ static inline int VN_BAD(struct vnode *vp) #define VNODE_KTRACE_REF 4 #define VNODE_KTRACE_RELE 5 -extern void vn_trace_entry(struct vnode *, char *, inst_t *); -extern void vn_trace_exit(struct vnode *, char *, inst_t *); +extern void vn_trace_entry(struct vnode *, const char *, inst_t *); +extern void vn_trace_exit(struct vnode *, const char *, inst_t *); extern void vn_trace_hold(struct vnode *, char *, int, inst_t *); extern void vn_trace_ref(struct vnode *, char *, int, inst_t *); extern void vn_trace_rele(struct vnode *, char *, int, inst_t *); diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 08d551a1734..63abdc2ac7f 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c @@ -182,7 +182,7 @@ xfs_swapext( if (VN_CACHED(tvp) != 0) xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore), - (loff_t)0, 0, 0); + (xfs_off_t)0, 0, 0); /* Verify O_DIRECT for ftmp */ if (VN_CACHED(tvp) != 0) { diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 3a0ba1dfd0e..d3da00045f2 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -136,6 +136,40 @@ xfs_chash_free(xfs_mount_t *mp) } /* + * Try to move an inode to the front of its hash list if possible + * (and if its not there already). Called right after obtaining + * the list version number and then dropping the read_lock on the + * hash list in question (which is done right after looking up the + * inode in question...). + */ +STATIC void +xfs_ihash_promote( + xfs_ihash_t *ih, + xfs_inode_t *ip, + ulong version) +{ + xfs_inode_t *iq; + + if ((ip->i_prevp != &ih->ih_next) && write_trylock(&ih->ih_lock)) { + if (likely(version == ih->ih_version)) { + /* remove from list */ + if ((iq = ip->i_next)) { + iq->i_prevp = ip->i_prevp; + } + *ip->i_prevp = iq; + + /* insert at list head */ + iq = ih->ih_next; + iq->i_prevp = &ip->i_next; + ip->i_next = iq; + ip->i_prevp = &ih->ih_next; + ih->ih_next = ip; + } + write_unlock(&ih->ih_lock); + } +} + +/* * Look up an inode by number in the given file system. * The inode is looked up in the hash table for the file system * represented by the mount point parameter mp. Each bucket of @@ -229,7 +263,9 @@ again: XFS_STATS_INC(xs_ig_found); ip->i_flags &= ~XFS_IRECLAIMABLE; + version = ih->ih_version; read_unlock(&ih->ih_lock); + xfs_ihash_promote(ih, ip, version); XFS_MOUNT_ILOCK(mp); list_del_init(&ip->i_reclaim); @@ -259,8 +295,15 @@ again: inode_vp, vp); } + /* + * Inode cache hit: if ip is not at the front of + * its hash chain, move it there now. + * Do this with the lock held for update, but + * do statistics after releasing the lock. + */ + version = ih->ih_version; read_unlock(&ih->ih_lock); - + xfs_ihash_promote(ih, ip, version); XFS_STATS_INC(xs_ig_found); finish_inode: @@ -547,6 +590,7 @@ xfs_inode_incore(xfs_mount_t *mp, { xfs_ihash_t *ih; xfs_inode_t *ip; + ulong version; ih = XFS_IHASH(mp, ino); read_lock(&ih->ih_lock); @@ -554,11 +598,15 @@ xfs_inode_incore(xfs_mount_t *mp, if (ip->i_ino == ino) { /* * If we find it and tp matches, return it. + * Also move it to the front of the hash list + * if we find it and it is not already there. * Otherwise break from the loop and return * NULL. */ if (ip->i_transp == tp) { + version = ih->ih_version; read_unlock(&ih->ih_lock); + xfs_ihash_promote(ih, ip, version); return (ip); } break; @@ -685,6 +733,7 @@ xfs_iextract( iq->i_prevp = ip->i_prevp; } *ip->i_prevp = iq; + ih->ih_version++; write_unlock(&ih->ih_lock); /* diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 43c632ab86a..bc8c8c7f903 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1130,7 +1130,7 @@ xfs_ialloc( xfs_trans_t *tp, xfs_inode_t *pip, mode_t mode, - nlink_t nlink, + xfs_nlink_t nlink, xfs_dev_t rdev, cred_t *cr, xfs_prid_t prid, diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index a53b1ccf607..37e1c316f3b 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -495,9 +495,9 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *, int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, xfs_inode_t **, xfs_daddr_t); int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int); -int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, nlink_t, - xfs_dev_t, struct cred *, xfs_prid_t, int, - struct xfs_buf **, boolean_t *, xfs_inode_t **); +int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, + xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, + int, struct xfs_buf **, boolean_t *, xfs_inode_t **); void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *, int); uint xfs_ip2xflags(struct xfs_inode *); diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 3826e8f0e28..469e1a7939d 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -278,7 +278,9 @@ phase2: switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) { case BMAPI_WRITE: /* If we found an extent, return it */ - if (nimaps && (imap.br_startblock != HOLESTARTBLOCK)) { + if (nimaps && + (imap.br_startblock != HOLESTARTBLOCK) && + (imap.br_startblock != DELAYSTARTBLOCK)) { xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io, offset, count, iomapp, &imap, flags); break; @@ -308,7 +310,8 @@ phase2: break; } - error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps); + error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, + &imap, &nimaps); break; case BMAPI_UNWRITTEN: lockmode = 0; @@ -365,7 +368,7 @@ xfs_flush_space( int xfs_iomap_write_direct( xfs_inode_t *ip, - loff_t offset, + xfs_off_t offset, size_t count, int flags, xfs_bmbt_irec_t *ret_imap, @@ -541,7 +544,7 @@ error_out: int xfs_iomap_write_delay( xfs_inode_t *ip, - loff_t offset, + xfs_off_t offset, size_t count, int ioflag, xfs_bmbt_irec_t *ret_imap, @@ -746,6 +749,8 @@ write_map: int xfs_iomap_write_allocate( xfs_inode_t *ip, + xfs_off_t offset, + size_t count, xfs_bmbt_irec_t *map, int *retmap) { @@ -770,9 +775,9 @@ xfs_iomap_write_allocate( if ((error = XFS_QM_DQATTACH(mp, ip, 0))) return XFS_ERROR(error); - offset_fsb = map->br_startoff; + offset_fsb = XFS_B_TO_FSBT(mp, offset); count_fsb = map->br_blockcount; - map_start_fsb = offset_fsb; + map_start_fsb = map->br_startoff; XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); @@ -868,9 +873,9 @@ xfs_iomap_write_allocate( imap[i].br_startoff, imap[i].br_blockcount,imap[i].br_state); } - if ((map->br_startoff >= imap[i].br_startoff) && - (map->br_startoff < (imap[i].br_startoff + - imap[i].br_blockcount))) { + if ((offset_fsb >= imap[i].br_startoff) && + (offset_fsb < (imap[i].br_startoff + + imap[i].br_blockcount))) { *map = imap[i]; *retmap = 1; XFS_STATS_INC(xs_xstrat_quick); @@ -883,9 +888,8 @@ xfs_iomap_write_allocate( * file, just surrounding data, try again. */ nimaps--; - offset_fsb = imap[nimaps].br_startoff + - imap[nimaps].br_blockcount; - map_start_fsb = offset_fsb; + map_start_fsb = imap[nimaps].br_startoff + + imap[nimaps].br_blockcount; } trans_cancel: @@ -899,7 +903,7 @@ error0: int xfs_iomap_write_unwritten( xfs_inode_t *ip, - loff_t offset, + xfs_off_t offset, size_t count) { xfs_mount_t *mp = ip->i_mount; diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index 31c91087cb3..4daaa521210 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003,2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2003-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -29,9 +29,6 @@ * * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ - - - #ifndef __XFS_IOMAP_H__ #define __XFS_IOMAP_H__ @@ -56,7 +53,7 @@ typedef enum { BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */ /* modifiers */ BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ - BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ + BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */ BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */ @@ -67,13 +64,13 @@ typedef enum { /* * xfs_iomap_t: File system I/O map * - * The iomap_bn field is expressed in 512-byte blocks, and is where the + * The iomap_bn field is expressed in 512-byte blocks, and is where the * mapping starts on disk. * * The iomap_offset, iomap_bsize and iomap_delta fields are in bytes. * iomap_offset is the offset of the mapping in the file itself. - * iomap_bsize is the size of the mapping, iomap_delta is the - * desired data's offset into the mapping, given the offset supplied + * iomap_bsize is the size of the mapping, iomap_delta is the + * desired data's offset into the mapping, given the offset supplied * to the file I/O map routine. * * When a request is made to read beyond the logical end of the object, @@ -84,8 +81,8 @@ typedef enum { typedef struct xfs_iomap { xfs_daddr_t iomap_bn; /* first 512b blk of mapping */ xfs_buftarg_t *iomap_target; - loff_t iomap_offset; /* offset of mapping, bytes */ - loff_t iomap_bsize; /* size of mapping, bytes */ + xfs_off_t iomap_offset; /* offset of mapping, bytes */ + xfs_off_t iomap_bsize; /* size of mapping, bytes */ size_t iomap_delta; /* offset into mapping, bytes */ iomap_flags_t iomap_flags; } xfs_iomap_t; @@ -96,12 +93,12 @@ struct xfs_bmbt_irec; extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int, struct xfs_iomap *, int *); -extern int xfs_iomap_write_direct(struct xfs_inode *, loff_t, size_t, +extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, int, struct xfs_bmbt_irec *, int *, int); -extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t, int, +extern int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, int, struct xfs_bmbt_irec *, int *); -extern int xfs_iomap_write_allocate(struct xfs_inode *, +extern int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t, struct xfs_bmbt_irec *, int *); -extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t); +extern int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, size_t); #endif /* __XFS_IOMAP_H__*/ diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index b57423caef9..2ec967d93e5 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -301,6 +301,15 @@ xfs_mount_validate_sb( } /* + * Version 1 directory format has never worked on Linux. + */ + if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) { + cmn_err(CE_WARN, + "XFS: Attempted to mount file system using version 1 directory format"); + return XFS_ERROR(ENOSYS); + } + + /* * Until this is fixed only page-sized or smaller data blocks work. */ if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) { diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 5fc6201dd8e..30dd08fb9f5 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -210,15 +210,16 @@ typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, struct xfs_bmap_free *); typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); typedef int (*xfs_iomap_write_direct_t)( - void *, loff_t, size_t, int, + void *, xfs_off_t, size_t, int, struct xfs_bmbt_irec *, int *, int); typedef int (*xfs_iomap_write_delay_t)( - void *, loff_t, size_t, int, + void *, xfs_off_t, size_t, int, struct xfs_bmbt_irec *, int *); typedef int (*xfs_iomap_write_allocate_t)( - void *, struct xfs_bmbt_irec *, int *); + void *, xfs_off_t, size_t, + struct xfs_bmbt_irec *, int *); typedef int (*xfs_iomap_write_unwritten_t)( - void *, loff_t, size_t); + void *, xfs_off_t, size_t); typedef uint (*xfs_lck_map_shared_t)(void *); typedef void (*xfs_lock_t)(void *, uint); typedef void (*xfs_lock_demote_t)(void *, uint); @@ -258,9 +259,9 @@ typedef struct xfs_ioops { #define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \ (*(mp)->m_io_ops.xfs_iomap_write_delay) \ ((io)->io_obj, offset, count, flags, mval, nmap) -#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, mval, nmap) \ +#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, mval, nmap) \ (*(mp)->m_io_ops.xfs_iomap_write_allocate) \ - ((io)->io_obj, mval, nmap) + ((io)->io_obj, offset, count, mval, nmap) #define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \ (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \ ((io)->io_obj, offset, count) @@ -428,10 +429,10 @@ typedef struct xfs_mount { #define XFS_WRITEIO_LOG_LARGE 16 /* - * Max and min values for UIO and mount-option defined I/O sizes; - * min value can't be less than a page. Currently unused. + * Max and min values for mount-option defined I/O + * preallocation sizes. */ -#define XFS_MAX_IO_LOG 16 /* 64K */ +#define XFS_MAX_IO_LOG 30 /* 1G */ #define XFS_MIN_IO_LOG PAGE_SHIFT /* diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index 04609d27ea5..e4bf711e48f 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h @@ -63,6 +63,7 @@ typedef __u64 xfs_ino_t; /* <inode> type */ typedef __s64 xfs_daddr_t; /* <disk address> type */ typedef char * xfs_caddr_t; /* <core address> type */ typedef __u32 xfs_dev_t; +typedef __u32 xfs_nlink_t; /* __psint_t is the same size as a pointer */ #if (BITS_PER_LONG == 32) diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 816b945fa0e..d1f8146a06e 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c @@ -147,7 +147,7 @@ xfs_dir_ialloc( xfs_inode_t *dp, /* directory within whose allocate the inode. */ mode_t mode, - nlink_t nlink, + xfs_nlink_t nlink, xfs_dev_t rdev, cred_t *credp, prid_t prid, /* project id */ diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h index e1ed6a58800..01d98b4b7af 100644 --- a/fs/xfs/xfs_utils.h +++ b/fs/xfs/xfs_utils.h @@ -42,7 +42,7 @@ extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **); extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *, xfs_inode_t **); extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); -extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, nlink_t, +extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, xfs_dev_t, cred_t *, prid_t, int, xfs_inode_t **, int *); extern int xfs_droplink (xfs_trans_t *, xfs_inode_t *); diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 00aae9c6a90..b5373665010 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -1649,6 +1649,7 @@ xfs_vget( #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ +#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ #define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */ #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ #define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */ @@ -1657,6 +1658,28 @@ xfs_vget( #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ +STATIC unsigned long +suffix_strtoul(const char *cp, char **endp, unsigned int base) +{ + int last, shift_left_factor = 0; + char *value = (char *)cp; + + last = strlen(value) - 1; + if (value[last] == 'K' || value[last] == 'k') { + shift_left_factor = 10; + value[last] = '\0'; + } + if (value[last] == 'M' || value[last] == 'm') { + shift_left_factor = 20; + value[last] = '\0'; + } + if (value[last] == 'G' || value[last] == 'g') { + shift_left_factor = 30; + value[last] = '\0'; + } + + return simple_strtoul(cp, endp, base) << shift_left_factor; +} int xfs_parseargs( @@ -1688,60 +1711,60 @@ xfs_parseargs( if (!strcmp(this_char, MNTOPT_LOGBUFS)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_LOGBUFS); + this_char); return EINVAL; } args->logbufs = simple_strtoul(value, &eov, 10); } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { - int last, in_kilobytes = 0; - if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_LOGBSIZE); + this_char); return EINVAL; } - last = strlen(value) - 1; - if (value[last] == 'K' || value[last] == 'k') { - in_kilobytes = 1; - value[last] = '\0'; - } - args->logbufsize = simple_strtoul(value, &eov, 10); - if (in_kilobytes) - args->logbufsize <<= 10; + args->logbufsize = suffix_strtoul(value, &eov, 10); } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_LOGDEV); + this_char); return EINVAL; } strncpy(args->logname, value, MAXNAMELEN); } else if (!strcmp(this_char, MNTOPT_MTPT)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_MTPT); + this_char); return EINVAL; } strncpy(args->mtpt, value, MAXNAMELEN); } else if (!strcmp(this_char, MNTOPT_RTDEV)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_RTDEV); + this_char); return EINVAL; } strncpy(args->rtname, value, MAXNAMELEN); } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_BIOSIZE); + this_char); return EINVAL; } iosize = simple_strtoul(value, &eov, 10); args->flags |= XFSMNT_IOSIZE; args->iosizelog = (uint8_t) iosize; + } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { + if (!value || !*value) { + printk("XFS: %s option requires an argument\n", + this_char); + return EINVAL; + } + iosize = suffix_strtoul(value, &eov, 10); + args->flags |= XFSMNT_IOSIZE; + args->iosizelog = ffs(iosize) - 1; } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - this_char); + this_char); return EINVAL; } args->flags |= XFSMNT_IHASHSIZE; @@ -1756,7 +1779,7 @@ xfs_parseargs( args->flags |= XFSMNT_INO64; #if !XFS_BIG_INUMS printk("XFS: %s option not allowed on this system\n", - MNTOPT_INO64); + this_char); return EINVAL; #endif } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { @@ -1766,14 +1789,14 @@ xfs_parseargs( } else if (!strcmp(this_char, MNTOPT_SUNIT)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_SUNIT); + this_char); return EINVAL; } dsunit = simple_strtoul(value, &eov, 10); } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_SWIDTH); + this_char); return EINVAL; } dswidth = simple_strtoul(value, &eov, 10); @@ -1781,7 +1804,7 @@ xfs_parseargs( args->flags &= ~XFSMNT_32BITINODES; #if !XFS_BIG_INUMS printk("XFS: %s option not allowed on this system\n", - MNTOPT_64BITINODE); + this_char); return EINVAL; #endif } else if (!strcmp(this_char, MNTOPT_NOUUID)) { @@ -1877,7 +1900,7 @@ xfs_showargs( seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize); if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) - seq_printf(m, "," MNTOPT_BIOSIZE "=%d", mp->m_writeio_log); + seq_printf(m, "," MNTOPT_ALLOCSIZE "=%d", 1<<mp->m_writeio_log); if (mp->m_logbufs > 0) seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 70092963ca9..25a526629b1 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -305,7 +305,7 @@ xfs_setattr( int mandlock_before, mandlock_after; struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; int file_owner; - int need_iolock = (flags & ATTR_DMI) == 0; + int need_iolock = 1; vp = BHV_TO_VNODE(bdp); vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); @@ -384,6 +384,9 @@ xfs_setattr( */ tp = NULL; lock_flags = XFS_ILOCK_EXCL; + ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1); + if (flags & ATTR_NOLOCK) + need_iolock = 0; if (!(mask & XFS_AT_SIZE)) { if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) || (mp->m_flags & XFS_MOUNT_WSYNC)) { @@ -4320,7 +4323,7 @@ xfs_free_file_space( int rt; xfs_fileoff_t startoffset_fsb; xfs_trans_t *tp; - int need_iolock = (attr_flags & ATTR_DMI) == 0; + int need_iolock = 1; vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); mp = ip->i_mount; @@ -4348,8 +4351,12 @@ xfs_free_file_space( return(error); } + ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1); + if (attr_flags & ATTR_NOLOCK) + need_iolock = 0; if (need_iolock) xfs_ilock(ip, XFS_IOLOCK_EXCL); + rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog), (__uint8_t)NBPP); ilen = len + (offset & (rounding - 1)); |