aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/aio.c20
-rw-r--r--fs/block_dev.c41
-rw-r--r--fs/cifs/CHANGES2
-rw-r--r--fs/cifs/cifsfs.c10
-rw-r--r--fs/cifs/file.c12
-rw-r--r--fs/cifs/readdir.c6
-rw-r--r--fs/cifs/smbdes.c10
-rw-r--r--fs/nfsd/nfsfh.c2
-rw-r--r--fs/proc/base.c12
9 files changed, 94 insertions, 21 deletions
diff --git a/fs/aio.c b/fs/aio.c
index ee20fc4240e0..55991e4132a7 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -298,17 +298,23 @@ static void wait_for_all_aios(struct kioctx *ctx)
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
+ spin_lock_irq(&ctx->ctx_lock);
if (!ctx->reqs_active)
- return;
+ goto out;
add_wait_queue(&ctx->wait, &wait);
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
while (ctx->reqs_active) {
+ spin_unlock_irq(&ctx->ctx_lock);
schedule();
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ spin_lock_irq(&ctx->ctx_lock);
}
__set_task_state(tsk, TASK_RUNNING);
remove_wait_queue(&ctx->wait, &wait);
+
+out:
+ spin_unlock_irq(&ctx->ctx_lock);
}
/* wait_on_sync_kiocb:
@@ -424,7 +430,6 @@ static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx)
ring = kmap_atomic(ctx->ring_info.ring_pages[0], KM_USER0);
if (ctx->reqs_active < aio_ring_avail(&ctx->ring_info, ring)) {
list_add(&req->ki_list, &ctx->active_reqs);
- get_ioctx(ctx);
ctx->reqs_active++;
okay = 1;
}
@@ -536,8 +541,6 @@ int fastcall aio_put_req(struct kiocb *req)
spin_lock_irq(&ctx->ctx_lock);
ret = __aio_put_req(ctx, req);
spin_unlock_irq(&ctx->ctx_lock);
- if (ret)
- put_ioctx(ctx);
return ret;
}
@@ -779,8 +782,7 @@ static int __aio_run_iocbs(struct kioctx *ctx)
*/
iocb->ki_users++; /* grab extra reference */
aio_run_iocb(iocb);
- if (__aio_put_req(ctx, iocb)) /* drop extra ref */
- put_ioctx(ctx);
+ __aio_put_req(ctx, iocb);
}
if (!list_empty(&ctx->run_list))
return 1;
@@ -997,14 +999,10 @@ put_rq:
/* everything turned out well, dispose of the aiocb. */
ret = __aio_put_req(ctx, iocb);
- spin_unlock_irqrestore(&ctx->ctx_lock, flags);
-
if (waitqueue_active(&ctx->wait))
wake_up(&ctx->wait);
- if (ret)
- put_ioctx(ctx);
-
+ spin_unlock_irqrestore(&ctx->ctx_lock, flags);
return ret;
}
diff --git a/fs/block_dev.c b/fs/block_dev.c
index d9bdf2b3ade2..fc7028b685f2 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -129,6 +129,46 @@ blkdev_get_block(struct inode *inode, sector_t iblock,
return 0;
}
+static int
+blkdev_get_blocks(struct inode *inode, sector_t iblock,
+ struct buffer_head *bh, int create)
+{
+ sector_t end_block = max_block(I_BDEV(inode));
+ unsigned long max_blocks = bh->b_size >> inode->i_blkbits;
+
+ if ((iblock + max_blocks) > end_block) {
+ max_blocks = end_block - iblock;
+ if ((long)max_blocks <= 0) {
+ if (create)
+ return -EIO; /* write fully beyond EOF */
+ /*
+ * It is a read which is fully beyond EOF. We return
+ * a !buffer_mapped buffer
+ */
+ max_blocks = 0;
+ }
+ }
+
+ bh->b_bdev = I_BDEV(inode);
+ bh->b_blocknr = iblock;
+ bh->b_size = max_blocks << inode->i_blkbits;
+ if (max_blocks)
+ set_buffer_mapped(bh);
+ return 0;
+}
+
+static ssize_t
+blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+ loff_t offset, unsigned long nr_segs)
+{
+ struct file *file = iocb->ki_filp;
+ struct inode *inode = file->f_mapping->host;
+
+ return blockdev_direct_IO_no_locking(rw, iocb, inode, I_BDEV(inode),
+ iov, offset, nr_segs, blkdev_get_blocks, NULL);
+}
+
+#if 0
static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error)
{
struct kiocb *iocb = bio->bi_private;
@@ -323,6 +363,7 @@ backout:
return PTR_ERR(page);
goto completion;
}
+#endif
static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
{
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index d04d2f7448d9..85e3850bf2c9 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,6 +1,8 @@
Version 1.47
------------
Fix oops in list_del during mount caused by unaligned string.
+Seek to SEEK_END forces check for update of file size for non-cached
+files.
Version 1.46
------------
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 10c90294cd18..93ef09971d2f 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -511,7 +511,15 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
{
/* origin == SEEK_END => we must revalidate the cached file length */
if (origin == SEEK_END) {
- int retval = cifs_revalidate(file->f_path.dentry);
+ int retval;
+
+ /* some applications poll for the file length in this strange
+ way so we must seek to end on non-oplocked files by
+ setting the revalidate time to zero */
+ if(file->f_path.dentry->d_inode)
+ CIFS_I(file->f_path.dentry->d_inode)->time = 0;
+
+ retval = cifs_revalidate(file->f_path.dentry);
if (retval < 0)
return (loff_t)retval;
}
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 8a49b2e77d37..e9dcf5ee29a2 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1146,7 +1146,7 @@ static int cifs_writepages(struct address_space *mapping,
pgoff_t end;
pgoff_t index;
int range_whole = 0;
- struct kvec iov[32];
+ struct kvec * iov;
int len;
int n_iov = 0;
pgoff_t next;
@@ -1171,15 +1171,21 @@ static int cifs_writepages(struct address_space *mapping,
if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
if(cifs_sb->tcon->ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- if(!experimEnabled)
+ if(!experimEnabled)
return generic_writepages(mapping, wbc);
+ iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL);
+ if(iov == NULL)
+ return generic_writepages(mapping, wbc);
+
+
/*
* BB: Is this meaningful for a non-block-device file system?
* If it is, we should test it again after we do I/O
*/
if (wbc->nonblocking && bdi_write_congested(bdi)) {
wbc->encountered_congestion = 1;
+ kfree(iov);
return 0;
}
@@ -1345,7 +1351,7 @@ retry:
mapping->writeback_index = index;
FreeXid(xid);
-
+ kfree(iov);
return rc;
}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 99dfb5337e31..782940be550f 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -156,9 +156,9 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
tmp_inode->i_atime = cnvrtDosUnixTm(
le16_to_cpu(pfindData->LastAccessDate),
le16_to_cpu(pfindData->LastAccessTime));
- tmp_inode->i_ctime = cnvrtDosUnixTm(
- le16_to_cpu(pfindData->LastWriteDate),
- le16_to_cpu(pfindData->LastWriteTime));
+ tmp_inode->i_ctime = cnvrtDosUnixTm(
+ le16_to_cpu(pfindData->LastWriteDate),
+ le16_to_cpu(pfindData->LastWriteTime));
AdjustForTZ(cifs_sb->tcon, tmp_inode);
attr = le16_to_cpu(pfindData->Attributes);
allocation_size = le32_to_cpu(pfindData->AllocationSize);
diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c
index 7a1b2b961ec8..1b1daf63f062 100644
--- a/fs/cifs/smbdes.c
+++ b/fs/cifs/smbdes.c
@@ -196,7 +196,7 @@ dohash(char *out, char *in, char *key, int forw)
char c[28];
char d[28];
char *cd;
- char ki[16][48];
+ char (*ki)[48];
char *pd1;
char l[32], r[32];
char *rl;
@@ -206,6 +206,12 @@ dohash(char *out, char *in, char *key, int forw)
if(pk1 == NULL)
return;
+ ki = kmalloc(16*48, GFP_KERNEL);
+ if(ki == NULL) {
+ kfree(pk1);
+ return;
+ }
+
cd = pk1 + 56;
pd1= cd + 56;
rl = pd1 + 64;
@@ -243,6 +249,7 @@ dohash(char *out, char *in, char *key, int forw)
er = kmalloc(48+48+32+32+32, GFP_KERNEL);
if(er == NULL) {
kfree(pk1);
+ kfree(ki);
return;
}
erk = er+48;
@@ -290,6 +297,7 @@ dohash(char *out, char *in, char *key, int forw)
permute(out, rl, perm6, 64);
kfree(pk1);
+ kfree(ki);
}
static void
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 98338a569dc0..c59d6fbb7a6b 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -269,7 +269,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
"acc=%x, error=%d\n",
dentry->d_parent->d_name.name,
dentry->d_name.name,
- access, (error >> 24));
+ access, ntohl(error));
}
out:
if (exp && !IS_ERR(exp))
diff --git a/fs/proc/base.c b/fs/proc/base.c
index ff7a66850602..1a979ea3b379 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2328,13 +2328,23 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
{
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode;
- struct task_struct *leader = get_proc_task(inode);
+ struct task_struct *leader = NULL;
struct task_struct *task;
int retval = -ENOENT;
ino_t ino;
int tid;
unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */
+ task = get_proc_task(inode);
+ if (!task)
+ goto out_no_task;
+ rcu_read_lock();
+ if (pid_alive(task)) {
+ leader = task->group_leader;
+ get_task_struct(leader);
+ }
+ rcu_read_unlock();
+ put_task_struct(task);
if (!leader)
goto out_no_task;
retval = 0;