summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2007-09-04 09:45:54 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2007-09-04 09:45:54 +0200
commitb1330031b76bf1c9dc23635e016625aa9edc069a (patch)
treee4f104e387fa249df7c1eb18b5a57a0cec6f727b /fs
parentMerge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/... (diff)
parentNFS: Fix a write request leak in nfs_invalidate_page() (diff)
downloadlinux-b1330031b76bf1c9dc23635e016625aa9edc069a.tar.xz
linux-b1330031b76bf1c9dc23635e016625aa9edc069a.zip
Merge branch 'for_linus' of git://git.linux-nfs.org/pub/linux/nfs-2.6
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/file.c2
-rw-r--r--fs/nfs/namespace.c2
-rw-r--r--fs/nfs/nfs4proc.c4
-rw-r--r--fs/nfs/super.c20
-rw-r--r--fs/nfs/write.c44
5 files changed, 58 insertions, 14 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index c87dc713b5d7..579cf8a7d4a7 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -316,7 +316,7 @@ static void nfs_invalidate_page(struct page *page, unsigned long offset)
if (offset != 0)
return;
/* Cancel any unstarted writes on this page */
- nfs_wb_page_priority(page->mapping->host, page, FLUSH_INVALIDATE);
+ nfs_wb_page_cancel(page->mapping->host, page);
}
static int nfs_release_page(struct page *page, gfp_t gfp)
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index aea76d0e5fbd..acfc56f9edc0 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -176,7 +176,7 @@ static void nfs_expire_automounts(struct work_struct *work)
void nfs_release_automount_timer(void)
{
if (list_empty(&nfs_automount_list))
- cancel_delayed_work_sync(&nfs_automount_task);
+ cancel_delayed_work(&nfs_automount_task);
}
/*
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 62b3ae280310..4b90e17555a9 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -646,7 +646,7 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
rcu_read_lock();
delegation = rcu_dereference(NFS_I(state->inode)->delegation);
if (delegation != NULL && (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) != 0)
- delegation_type = delegation->flags;
+ delegation_type = delegation->type;
rcu_read_unlock();
opendata->o_arg.u.delegation_type = delegation_type;
status = nfs4_open_recover(opendata, state);
@@ -1434,7 +1434,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
}
res = d_add_unique(dentry, igrab(state->inode));
if (res != NULL)
- dentry = res;
+ path.dentry = res;
nfs4_intent_set_file(nd, &path, state);
return res;
}
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 46139003ea0c..8ed593766f16 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -911,13 +911,13 @@ static int nfs_parse_mount_options(char *raw,
kfree(string);
switch (token) {
- case Opt_udp:
+ case Opt_xprt_udp:
mnt->flags &= ~NFS_MOUNT_TCP;
mnt->nfs_server.protocol = IPPROTO_UDP;
mnt->timeo = 7;
mnt->retrans = 5;
break;
- case Opt_tcp:
+ case Opt_xprt_tcp:
mnt->flags |= NFS_MOUNT_TCP;
mnt->nfs_server.protocol = IPPROTO_TCP;
mnt->timeo = 600;
@@ -936,10 +936,10 @@ static int nfs_parse_mount_options(char *raw,
kfree(string);
switch (token) {
- case Opt_udp:
+ case Opt_xprt_udp:
mnt->mount_server.protocol = IPPROTO_UDP;
break;
- case Opt_tcp:
+ case Opt_xprt_tcp:
mnt->mount_server.protocol = IPPROTO_TCP;
break;
default:
@@ -1153,20 +1153,20 @@ static int nfs_validate_mount_data(struct nfs_mount_data **options,
c = strchr(dev_name, ':');
if (c == NULL)
return -EINVAL;
- len = c - dev_name - 1;
+ len = c - dev_name;
if (len > sizeof(data->hostname))
- return -EINVAL;
+ return -ENAMETOOLONG;
strncpy(data->hostname, dev_name, len);
args.nfs_server.hostname = data->hostname;
c++;
if (strlen(c) > NFS_MAXPATHLEN)
- return -EINVAL;
+ return -ENAMETOOLONG;
args.nfs_server.export_path = c;
status = nfs_try_mount(&args, mntfh);
if (status)
- return -EINVAL;
+ return status;
/*
* Translate to nfs_mount_data, which nfs_fill_super
@@ -1677,7 +1677,7 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
/* while calculating len, pretend ':' is '\0' */
len = c - dev_name;
if (len > NFS4_MAXNAMLEN)
- return -EINVAL;
+ return -ENAMETOOLONG;
*hostname = kzalloc(len, GFP_KERNEL);
if (*hostname == NULL)
return -ENOMEM;
@@ -1686,7 +1686,7 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
c++; /* step over the ':' */
len = strlen(c);
if (len > NFS4_MAXPATHLEN)
- return -EINVAL;
+ return -ENAMETOOLONG;
*mntpath = kzalloc(len + 1, GFP_KERNEL);
if (*mntpath == NULL)
return -ENOMEM;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index ef97e0c0f5b1..0d7a77cc394b 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1396,6 +1396,50 @@ out:
return ret;
}
+int nfs_wb_page_cancel(struct inode *inode, struct page *page)
+{
+ struct nfs_page *req;
+ loff_t range_start = page_offset(page);
+ loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1);
+ struct writeback_control wbc = {
+ .bdi = page->mapping->backing_dev_info,
+ .sync_mode = WB_SYNC_ALL,
+ .nr_to_write = LONG_MAX,
+ .range_start = range_start,
+ .range_end = range_end,
+ };
+ int ret = 0;
+
+ BUG_ON(!PageLocked(page));
+ for (;;) {
+ req = nfs_page_find_request(page);
+ if (req == NULL)
+ goto out;
+ if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
+ nfs_release_request(req);
+ break;
+ }
+ if (nfs_lock_request_dontget(req)) {
+ nfs_inode_remove_request(req);
+ /*
+ * In case nfs_inode_remove_request has marked the
+ * page as being dirty
+ */
+ cancel_dirty_page(page, PAGE_CACHE_SIZE);
+ nfs_unlock_request(req);
+ break;
+ }
+ ret = nfs_wait_on_request(req);
+ if (ret < 0)
+ goto out;
+ }
+ if (!PagePrivate(page))
+ return 0;
+ ret = nfs_sync_mapping_wait(page->mapping, &wbc, FLUSH_INVALIDATE);
+out:
+ return ret;
+}
+
int nfs_wb_page_priority(struct inode *inode, struct page *page, int how)
{
loff_t range_start = page_offset(page);