aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-08-08 17:09:11 +1000
committerPaul Mackerras <paulus@samba.org>2006-08-08 17:09:11 +1000
commit32bc6e095d75233e7c87cc6fa0e07942b124d194 (patch)
tree8f83ef9a23d52d1305878b65dd98fc22b09b7f3e /fs
parent5cf13911b1e72707b6f0eb39b2d819ec6e343d76 (diff)
parent81b73dd92b97423b8f5324a59044da478c04f4c4 (diff)
Merge branch 'merge'
Diffstat (limited to 'fs')
-rw-r--r--fs/befs/linuxvfs.c11
-rw-r--r--fs/lockd/svclock.c12
-rw-r--r--fs/namei.c8
-rw-r--r--fs/nfs/namespace.c4
-rw-r--r--fs/nfs/read.c2
-rw-r--r--fs/nfs/write.c2
-rw-r--r--fs/reiserfs/file.c2
-rw-r--r--fs/reiserfs/inode.c26
-rw-r--r--fs/reiserfs/ioctl.c2
-rw-r--r--fs/udf/ialloc.c11
-rw-r--r--fs/ufs/balloc.c2
-rw-r--r--fs/ufs/util.c17
12 files changed, 54 insertions, 45 deletions
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index fcaeead9696..50cfca5c7ef 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -512,7 +512,11 @@ befs_utf2nls(struct super_block *sb, const char *in,
wchar_t uni;
int unilen, utflen;
char *result;
- int maxlen = in_len; /* The utf8->nls conversion can't make more chars */
+ /* The utf8->nls conversion won't make the final nls string bigger
+ * than the utf one, but if the string is pure ascii they'll have the
+ * same width and an extra char is needed to save the additional \0
+ */
+ int maxlen = in_len + 1;
befs_debug(sb, "---> utf2nls()");
@@ -588,7 +592,10 @@ befs_nls2utf(struct super_block *sb, const char *in,
wchar_t uni;
int unilen, utflen;
char *result;
- int maxlen = 3 * in_len;
+ /* There're nls characters that will translate to 3-chars-wide UTF-8
+ * characters, a additional byte is needed to save the final \0
+ * in special cases */
+ int maxlen = (3 * in_len) + 1;
befs_debug(sb, "---> nls2utf()\n");
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index baf5ae51348..c9d419703cf 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -638,9 +638,6 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
if (task->tk_status < 0) {
/* RPC error: Re-insert for retransmission */
timeout = 10 * HZ;
- } else if (block->b_done) {
- /* Block already removed, kill it for real */
- timeout = 0;
} else {
/* Call was successful, now wait for client callback */
timeout = 60 * HZ;
@@ -709,13 +706,10 @@ nlmsvc_retry_blocked(void)
break;
if (time_after(block->b_when,jiffies))
break;
- dprintk("nlmsvc_retry_blocked(%p, when=%ld, done=%d)\n",
- block, block->b_when, block->b_done);
+ dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
+ block, block->b_when);
kref_get(&block->b_count);
- if (block->b_done)
- nlmsvc_unlink_block(block);
- else
- nlmsvc_grant_blocked(block);
+ nlmsvc_grant_blocked(block);
nlmsvc_release_block(block);
}
diff --git a/fs/namei.c b/fs/namei.c
index e01070d7bf5..55a131230f9 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -159,7 +159,7 @@ char * getname(const char __user * filename)
#ifdef CONFIG_AUDITSYSCALL
void putname(const char *name)
{
- if (unlikely(current->audit_context))
+ if (unlikely(!audit_dummy_context()))
audit_putname(name);
else
__putname(name);
@@ -1125,7 +1125,7 @@ static int fastcall do_path_lookup(int dfd, const char *name,
retval = link_path_walk(name, nd);
out:
if (likely(retval == 0)) {
- if (unlikely(current->audit_context && nd && nd->dentry &&
+ if (unlikely(!audit_dummy_context() && nd && nd->dentry &&
nd->dentry->d_inode))
audit_inode(name, nd->dentry->d_inode);
}
@@ -1357,7 +1357,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
return -ENOENT;
BUG_ON(victim->d_parent->d_inode != dir);
- audit_inode_child(victim->d_name.name, victim->d_inode, dir->i_ino);
+ audit_inode_child(victim->d_name.name, victim->d_inode, dir);
error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
if (error)
@@ -1659,6 +1659,7 @@ do_last:
* It already exists.
*/
mutex_unlock(&dir->d_inode->i_mutex);
+ audit_inode_update(path.dentry->d_inode);
error = -EEXIST;
if (flag & O_EXCL)
@@ -1669,6 +1670,7 @@ do_last:
if (flag & O_NOFOLLOW)
goto exit_dput;
}
+
error = -ENOENT;
if (!path.dentry->d_inode)
goto exit_dput;
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 19b98ca468e..86b3169c8ca 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -51,7 +51,7 @@ char *nfs_path(const char *base, const struct dentry *dentry,
namelen = dentry->d_name.len;
buflen -= namelen + 1;
if (buflen < 0)
- goto Elong;
+ goto Elong_unlock;
end -= namelen;
memcpy(end, dentry->d_name.name, namelen);
*--end = '/';
@@ -68,6 +68,8 @@ char *nfs_path(const char *base, const struct dentry *dentry,
end -= namelen;
memcpy(end, base, namelen);
return end;
+Elong_unlock:
+ spin_unlock(&dcache_lock);
Elong:
return ERR_PTR(-ENAMETOOLONG);
}
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 52bf634260a..65c0c5b3235 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -63,7 +63,7 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
return p;
}
-void nfs_readdata_free(struct nfs_read_data *p)
+static void nfs_readdata_free(struct nfs_read_data *p)
{
if (p && (p->pagevec != &p->page_array[0]))
kfree(p->pagevec);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 86bac6a5008..50774991f8d 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -137,7 +137,7 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
return p;
}
-void nfs_writedata_free(struct nfs_write_data *p)
+static void nfs_writedata_free(struct nfs_write_data *p)
{
if (p && (p->pagevec != &p->page_array[0]))
kfree(p->pagevec);
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index f318b58510f..1627edd5081 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -48,8 +48,8 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
return 0;
}
- reiserfs_write_lock(inode->i_sb);
mutex_lock(&inode->i_mutex);
+ reiserfs_write_lock(inode->i_sb);
/* freeing preallocation only involves relogging blocks that
* are already in the current transaction. preallocation gets
* freed at the end of each transaction, so it is impossible for
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 12dfdcfbee3..52f1e213654 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -39,14 +39,10 @@ void reiserfs_delete_inode(struct inode *inode)
/* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
- mutex_lock(&inode->i_mutex);
-
reiserfs_delete_xattrs(inode);
- if (journal_begin(&th, inode->i_sb, jbegin_count)) {
- mutex_unlock(&inode->i_mutex);
+ if (journal_begin(&th, inode->i_sb, jbegin_count))
goto out;
- }
reiserfs_update_inode_transaction(inode);
err = reiserfs_delete_object(&th, inode);
@@ -57,12 +53,8 @@ void reiserfs_delete_inode(struct inode *inode)
if (!err)
DQUOT_FREE_INODE(inode);
- if (journal_end(&th, inode->i_sb, jbegin_count)) {
- mutex_unlock(&inode->i_mutex);
+ if (journal_end(&th, inode->i_sb, jbegin_count))
goto out;
- }
-
- mutex_unlock(&inode->i_mutex);
/* check return value from reiserfs_delete_object after
* ending the transaction
@@ -2348,6 +2340,7 @@ static int reiserfs_write_full_page(struct page *page,
unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
int error = 0;
unsigned long block;
+ sector_t last_block;
struct buffer_head *head, *bh;
int partial = 0;
int nr = 0;
@@ -2395,10 +2388,19 @@ static int reiserfs_write_full_page(struct page *page,
}
bh = head;
block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits);
+ last_block = (i_size_read(inode) - 1) >> inode->i_blkbits;
/* first map all the buffers, logging any direct items we find */
do {
- if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) ||
- (buffer_mapped(bh)
+ if (block > last_block) {
+ /*
+ * This can happen when the block size is less than
+ * the page size. The corresponding bytes in the page
+ * were zero filled above
+ */
+ clear_buffer_dirty(bh);
+ set_buffer_uptodate(bh);
+ } else if ((checked || buffer_dirty(bh)) &&
+ (!buffer_mapped(bh) || (buffer_mapped(bh)
&& bh->b_blocknr ==
0))) {
/* not mapped yet, or it points to a direct item, search
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index 745c8810089..a986b5e1e28 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -116,12 +116,12 @@ static int reiserfs_unpack(struct inode *inode, struct file *filp)
if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
return 0;
}
- reiserfs_write_lock(inode->i_sb);
/* we need to make sure nobody is changing the file size beneath
** us
*/
mutex_lock(&inode->i_mutex);
+ reiserfs_write_lock(inode->i_sb);
write_from = inode->i_size & (blocksize - 1);
/* if we are on a block boundary, we are already unpacked. */
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index 3873c672cb4..33323473e3c 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -75,6 +75,12 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
}
*err = -ENOSPC;
+ UDF_I_UNIQUE(inode) = 0;
+ UDF_I_LENEXTENTS(inode) = 0;
+ UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
+ UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
+ UDF_I_STRAT4096(inode) = 0;
+
block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum,
start, err);
if (*err)
@@ -84,11 +90,6 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
}
mutex_lock(&sbi->s_alloc_mutex);
- UDF_I_UNIQUE(inode) = 0;
- UDF_I_LENEXTENTS(inode) = 0;
- UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
- UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
- UDF_I_STRAT4096(inode) = 0;
if (UDF_SB_LVIDBH(sb))
{
struct logicalVolHeaderDesc *lvhd;
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index b01804baa12..b8238147577 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -248,7 +248,7 @@ static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk,
if (likely(cur_index != index)) {
page = ufs_get_locked_page(mapping, index);
- if (IS_ERR(page))
+ if (!page || IS_ERR(page)) /* it was truncated or EIO */
continue;
} else
page = locked_page;
diff --git a/fs/ufs/util.c b/fs/ufs/util.c
index 337cf2c46d1..22f820a9b15 100644
--- a/fs/ufs/util.c
+++ b/fs/ufs/util.c
@@ -251,12 +251,12 @@ struct page *ufs_get_locked_page(struct address_space *mapping,
{
struct page *page;
-try_again:
page = find_lock_page(mapping, index);
if (!page) {
page = read_cache_page(mapping, index,
(filler_t*)mapping->a_ops->readpage,
NULL);
+
if (IS_ERR(page)) {
printk(KERN_ERR "ufs_change_blocknr: "
"read_cache_page error: ino %lu, index: %lu\n",
@@ -266,6 +266,14 @@ try_again:
lock_page(page);
+ if (unlikely(page->mapping == NULL)) {
+ /* Truncate got there first */
+ unlock_page(page);
+ page_cache_release(page);
+ page = NULL;
+ goto out;
+ }
+
if (!PageUptodate(page) || PageError(page)) {
unlock_page(page);
page_cache_release(page);
@@ -275,15 +283,8 @@ try_again:
mapping->host->i_ino, index);
page = ERR_PTR(-EIO);
- goto out;
}
}
-
- if (unlikely(!page->mapping || !page_has_buffers(page))) {
- unlock_page(page);
- page_cache_release(page);
- goto try_again;/*we really need these buffers*/
- }
out:
return page;
}