summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/bmap.c23
-rw-r--r--fs/gfs2/rgrp.c2
-rw-r--r--fs/nfs/mount_clnt.c5
-rw-r--r--fs/nfs/super.c76
-rw-r--r--fs/nfs/write.c7
-rw-r--r--fs/select.c2
6 files changed, 62 insertions, 53 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index c19184f2e70..bec76b1c2bb 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -246,15 +246,11 @@ static void find_metapath(const struct gfs2_sbd *sdp, u64 block,
}
-static inline unsigned int zero_metapath_length(const struct metapath *mp,
- unsigned height)
+static inline unsigned int metapath_branch_start(const struct metapath *mp)
{
- unsigned int i;
- for (i = 0; i < height - 1; i++) {
- if (mp->mp_list[i] != 0)
- return i;
- }
- return height;
+ if (mp->mp_list[0] == 0)
+ return 2;
+ return 1;
}
/**
@@ -436,7 +432,7 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
struct gfs2_sbd *sdp = GFS2_SB(inode);
struct buffer_head *dibh = mp->mp_bh[0];
u64 bn, dblock = 0;
- unsigned n, i, blks, alloced = 0, iblks = 0, zmpl = 0;
+ unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0;
unsigned dblks = 0;
unsigned ptrs_per_blk;
const unsigned end_of_metadata = height - 1;
@@ -471,9 +467,8 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
/* Building up tree height */
state = ALLOC_GROW_HEIGHT;
iblks = height - ip->i_height;
- zmpl = zero_metapath_length(mp, height);
- iblks -= zmpl;
- iblks += height;
+ branch_start = metapath_branch_start(mp);
+ iblks += (height - branch_start);
}
}
@@ -509,13 +504,13 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
sizeof(struct gfs2_meta_header));
*ptr = zero_bn;
state = ALLOC_GROW_DEPTH;
- for(i = zmpl; i < height; i++) {
+ for(i = branch_start; i < height; i++) {
if (mp->mp_bh[i] == NULL)
break;
brelse(mp->mp_bh[i]);
mp->mp_bh[i] = NULL;
}
- i = zmpl;
+ i = branch_start;
}
if (n == 0)
break;
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 6387523a315..3401628d742 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -195,7 +195,7 @@ ulong_aligned:
depending on architecture. I've experimented with several ways
of writing this section such as using an else before the goto
but this one seems to be the fastest. */
- while ((unsigned char *)plong < end - 1) {
+ while ((unsigned char *)plong < end - sizeof(unsigned long)) {
prefetch(plong + 1);
if (((*plong) & LBITMASK) != lskipval)
break;
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 49c7cd0502c..779d2eb649c 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -130,10 +130,11 @@ static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
struct mnt_fhstatus *res)
{
struct nfs_fh *fh = res->fh;
+ unsigned size;
if ((res->status = ntohl(*p++)) == 0) {
- int size = ntohl(*p++);
- if (size <= NFS3_FHSIZE) {
+ size = ntohl(*p++);
+ if (size <= NFS3_FHSIZE && size != 0) {
fh->size = size;
memcpy(fh->data, p, size);
} else
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 2a4a024a4e7..614efeed543 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1216,8 +1216,6 @@ static int nfs_validate_mount_data(void *options,
{
struct nfs_mount_data *data = (struct nfs_mount_data *)options;
- memset(args, 0, sizeof(*args));
-
if (data == NULL)
goto out_no_data;
@@ -1251,13 +1249,13 @@ static int nfs_validate_mount_data(void *options,
case 5:
memset(data->context, 0, sizeof(data->context));
case 6:
- if (data->flags & NFS_MOUNT_VER3)
+ if (data->flags & NFS_MOUNT_VER3) {
+ if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
+ goto out_invalid_fh;
mntfh->size = data->root.size;
- else
+ } else
mntfh->size = NFS2_FHSIZE;
- if (mntfh->size > sizeof(mntfh->data))
- goto out_invalid_fh;
memcpy(mntfh->data, data->root.data, mntfh->size);
if (mntfh->size < sizeof(mntfh->data))
@@ -1585,24 +1583,29 @@ static int nfs_get_sb(struct file_system_type *fs_type,
{
struct nfs_server *server = NULL;
struct super_block *s;
- struct nfs_fh mntfh;
- struct nfs_parsed_mount_data data;
+ struct nfs_parsed_mount_data *data;
+ struct nfs_fh *mntfh;
struct dentry *mntroot;
int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
struct nfs_sb_mountdata sb_mntdata = {
.mntflags = flags,
};
- int error;
+ int error = -ENOMEM;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
+ if (data == NULL || mntfh == NULL)
+ goto out_free_fh;
- security_init_mnt_opts(&data.lsm_opts);
+ security_init_mnt_opts(&data->lsm_opts);
/* Validate the mount data */
- error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name);
+ error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
if (error < 0)
goto out;
/* Get a volume representation */
- server = nfs_create_server(&data, &mntfh);
+ server = nfs_create_server(data, mntfh);
if (IS_ERR(server)) {
error = PTR_ERR(server);
goto out;
@@ -1630,16 +1633,16 @@ static int nfs_get_sb(struct file_system_type *fs_type,
if (!s->s_root) {
/* initial superblock/root creation */
- nfs_fill_super(s, &data);
+ nfs_fill_super(s, data);
}
- mntroot = nfs_get_root(s, &mntfh);
+ mntroot = nfs_get_root(s, mntfh);
if (IS_ERR(mntroot)) {
error = PTR_ERR(mntroot);
goto error_splat_super;
}
- error = security_sb_set_mnt_opts(s, &data.lsm_opts);
+ error = security_sb_set_mnt_opts(s, &data->lsm_opts);
if (error)
goto error_splat_root;
@@ -1649,9 +1652,12 @@ static int nfs_get_sb(struct file_system_type *fs_type,
error = 0;
out:
- kfree(data.nfs_server.hostname);
- kfree(data.mount_server.hostname);
- security_free_mnt_opts(&data.lsm_opts);
+ kfree(data->nfs_server.hostname);
+ kfree(data->mount_server.hostname);
+ security_free_mnt_opts(&data->lsm_opts);
+out_free_fh:
+ kfree(mntfh);
+ kfree(data);
return error;
out_err_nosb:
@@ -1800,8 +1806,6 @@ static int nfs4_validate_mount_data(void *options,
struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
char *c;
- memset(args, 0, sizeof(*args));
-
if (data == NULL)
goto out_no_data;
@@ -1959,26 +1963,31 @@ out_no_client_address:
static int nfs4_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
{
- struct nfs_parsed_mount_data data;
+ struct nfs_parsed_mount_data *data;
struct super_block *s;
struct nfs_server *server;
- struct nfs_fh mntfh;
+ struct nfs_fh *mntfh;
struct dentry *mntroot;
int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
struct nfs_sb_mountdata sb_mntdata = {
.mntflags = flags,
};
- int error;
+ int error = -ENOMEM;
- security_init_mnt_opts(&data.lsm_opts);
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
+ if (data == NULL || mntfh == NULL)
+ goto out_free_fh;
+
+ security_init_mnt_opts(&data->lsm_opts);
/* Validate the mount data */
- error = nfs4_validate_mount_data(raw_data, &data, dev_name);
+ error = nfs4_validate_mount_data(raw_data, data, dev_name);
if (error < 0)
goto out;
/* Get a volume representation */
- server = nfs4_create_server(&data, &mntfh);
+ server = nfs4_create_server(data, mntfh);
if (IS_ERR(server)) {
error = PTR_ERR(server);
goto out;
@@ -2009,13 +2018,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
nfs4_fill_super(s);
}
- mntroot = nfs4_get_root(s, &mntfh);
+ mntroot = nfs4_get_root(s, mntfh);
if (IS_ERR(mntroot)) {
error = PTR_ERR(mntroot);
goto error_splat_super;
}
- error = security_sb_set_mnt_opts(s, &data.lsm_opts);
+ error = security_sb_set_mnt_opts(s, &data->lsm_opts);
if (error)
goto error_splat_root;
@@ -2025,10 +2034,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
error = 0;
out:
- kfree(data.client_address);
- kfree(data.nfs_server.export_path);
- kfree(data.nfs_server.hostname);
- security_free_mnt_opts(&data.lsm_opts);
+ kfree(data->client_address);
+ kfree(data->nfs_server.export_path);
+ kfree(data->nfs_server.hostname);
+ security_free_mnt_opts(&data->lsm_opts);
+out_free_fh:
+ kfree(mntfh);
+ kfree(data);
return error;
out_free:
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 6d8ace3e325..f333848fd3b 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -739,12 +739,13 @@ int nfs_updatepage(struct file *file, struct page *page,
}
status = nfs_writepage_setup(ctx, page, offset, count);
- __set_page_dirty_nobuffers(page);
+ if (status < 0)
+ nfs_set_pageerror(page);
+ else
+ __set_page_dirty_nobuffers(page);
dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n",
status, (long long)i_size_read(inode));
- if (status < 0)
- nfs_set_pageerror(page);
return status;
}
diff --git a/fs/select.c b/fs/select.c
index 8dda969614a..da0e88201c3 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -249,7 +249,6 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
retval++;
}
}
- cond_resched();
}
if (res_in)
*rinp = res_in;
@@ -257,6 +256,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
*routp = res_out;
if (res_ex)
*rexp = res_ex;
+ cond_resched();
}
wait = NULL;
if (retval || !*timeout || signal_pending(current))