* [PATCH 00/24] Reduce the stack foot print of the NFS client
@ 2010-04-16 20:30 Trond Myklebust
2010-04-16 20:30 ` [PATCH 01/24] NFS: Add helper functions for allocating filehandles and fattr structs Trond Myklebust
2010-04-19 21:43 ` [PATCH 00/24] Reduce the stack foot print of the NFS client Chuck Lever
0 siblings, 2 replies; 29+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:30 UTC (permalink / raw)
To: linux-nfs
The following patch series aims to significantly reduce the stack foot
print of the NFS client by dynamically allocating the struct nfs_fattr
and struct nfs_fh.
Cheers
Trond
Trond Myklebust (24):
NFS: Add helper functions for allocating filehandles and fattr
structs
NFSv4: Eliminate nfs4_path_walk()
NFS: Reduce the stack footprint of nfs_follow_mountpoint()
NFS: Reduce the stack footprint of nfs_create_server
NFSv4: Reduce the stack footprint of try_location()
NFS: Reduce the stack footprint of nfs_lookup
NFS: Reduce the stack footprint of nfs_follow_remote_path()
NFSv4: Reduce stack footprint of nfs4_get_root()
NFSv4: Reduce the stack footprint of nfs4_remote_referral_get_sb
NFSv4: Reduce stack footprint of nfs4_proc_access() and
nfs3_proc_access()
NFS: Reduce stack footprint of nfs_revalidate_inode()
NFS: Reduce stack footprint of nfs3_proc_rename() and
nfs4_proc_rename()
NFS: Reduce stack footprint of nfs_readdir()
NFS: Reduce the stack footprint of nfs_link()
NFS: Reduce stack footprint of nfs3_proc_readlink()
NFS: Reduce stack footprint of nfs_proc_remove()
NFS: Reduce the stack footprint of nfs_rmdir
NFS: Reduce the stack footprint of nfs_proc_create
NFS: Reduce the stack footprint of nfs_proc_symlink()
NFS: Reduce stack footprint of nfs4_proc_create()
NFS: Reduce stack footprint of nfs_setattr()
NFS: Reduce stack footprint of nfs_statfs()
NFS: Reduce stack footprint of nfs3_proc_getacl() and
nfs3_proc_setacl()
NFS: Prevent the mount code from looping forever on broken exports
fs/nfs/client.c | 54 ++++++++++---
fs/nfs/dir.c | 62 +++++++++++----
fs/nfs/getroot.c | 191 +++++++++++++++++------------------------------
fs/nfs/inode.c | 46 ++++++++++--
fs/nfs/internal.h | 4 +-
fs/nfs/namespace.c | 20 ++++--
fs/nfs/nfs3acl.c | 23 ++++--
fs/nfs/nfs3proc.c | 128 +++++++++++++++++++------------
fs/nfs/nfs3xdr.c | 2 +-
fs/nfs/nfs4namespace.c | 10 ++-
fs/nfs/nfs4proc.c | 81 ++++++++++++--------
fs/nfs/nfs4xdr.c | 2 +-
fs/nfs/proc.c | 144 ++++++++++++++++++++---------------
fs/nfs/super.c | 121 ++++++++++++++++++++++++++----
fs/nfs/unlink.c | 4 +-
include/linux/nfs_fs.h | 14 ++++
include/linux/nfs_xdr.h | 2 +-
17 files changed, 566 insertions(+), 342 deletions(-)
^ permalink raw reply [flat|nested] 29+ messages in thread* [PATCH 01/24] NFS: Add helper functions for allocating filehandles and fattr structs 2010-04-16 20:30 [PATCH 00/24] Reduce the stack foot print of the NFS client Trond Myklebust @ 2010-04-16 20:30 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 02/24] NFSv4: Eliminate nfs4_path_walk() Trond Myklebust 2010-04-19 21:43 ` [PATCH 00/24] Reduce the stack foot print of the NFS client Chuck Lever 1 sibling, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:30 UTC (permalink / raw) To: linux-nfs NFS Filehandles and struct fattr are really too large to be allocated on the stack. This patch adds in a couple of helper functions to allocate them dynamically instead. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/inode.c | 20 ++++++++++++++++++++ include/linux/nfs_fs.h | 14 ++++++++++++++ 2 files changed, 34 insertions(+), 0 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 50a56ed..6e257c3 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -916,6 +916,26 @@ void nfs_fattr_init(struct nfs_fattr *fattr) fattr->gencount = nfs_inc_attr_generation_counter(); } +struct nfs_fattr *nfs_alloc_fattr(void) +{ + struct nfs_fattr *fattr; + + fattr = kmalloc(sizeof(*fattr), GFP_KERNEL); + if (fattr != NULL) + nfs_fattr_init(fattr); + return fattr; +} + +struct nfs_fh *nfs_alloc_fhandle(void) +{ + struct nfs_fh *fh; + + fh = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL); + if (fh != NULL) + fh->size = 0; + return fh; +} + /** * nfs_inode_attrs_need_update - check if the inode attributes need updating * @inode - pointer to inode diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 1a0b85a..8f65903 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -355,6 +355,20 @@ extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struc extern u64 nfs_compat_user_ino64(u64 fileid); extern void nfs_fattr_init(struct nfs_fattr *fattr); +extern struct nfs_fattr *nfs_alloc_fattr(void); + +static inline void nfs_free_fattr(const struct nfs_fattr *fattr) +{ + kfree(fattr); +} + +extern struct nfs_fh *nfs_alloc_fhandle(void); + +static inline void nfs_free_fhandle(const struct nfs_fh *fh) +{ + kfree(fh); +} + /* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */ extern __be32 root_nfs_parse_addr(char *name); /*__init*/ extern unsigned long nfs_inc_attr_generation_counter(void); -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 02/24] NFSv4: Eliminate nfs4_path_walk() 2010-04-16 20:30 ` [PATCH 01/24] NFS: Add helper functions for allocating filehandles and fattr structs Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 03/24] NFS: Reduce the stack footprint of nfs_follow_mountpoint() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs All we really want is the ability to retrieve the root file handle. We no longer need the ability to walk down the path, since that is now done in nfs_follow_remote_path(). Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/client.c | 4 +- fs/nfs/getroot.c | 115 ++++++++++------------------------------------------ fs/nfs/internal.h | 4 +- 3 files changed, 25 insertions(+), 98 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index a8766c4..48fc680 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -1362,7 +1362,7 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, goto error; /* Probe the root fh to retrieve its FSID */ - error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path); + error = nfs4_get_rootfh(server, mntfh); if (error < 0) goto error; @@ -1441,7 +1441,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); /* Probe the root fh to retrieve its FSID and filehandle */ - error = nfs4_path_walk(server, mntfh, data->mnt_path); + error = nfs4_get_rootfh(server, mntfh); if (error < 0) goto error; diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index b35d2a6..ada369a 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c @@ -122,115 +122,44 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh) #ifdef CONFIG_NFS_V4 -/* - * Do a simple pathwalk from the root FH of the server to the nominated target - * of the mountpoint - * - give error on symlinks - * - give error on ".." occurring in the path - * - follow traversals - */ -int nfs4_path_walk(struct nfs_server *server, - struct nfs_fh *mntfh, - const char *path) +int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh) { struct nfs_fsinfo fsinfo; - struct nfs_fattr fattr; - struct nfs_fh lastfh; - struct qstr name; - int ret; + int ret = -ENOMEM; - dprintk("--> nfs4_path_walk(,,%s)\n", path); + dprintk("--> nfs4_get_rootfh()\n"); - fsinfo.fattr = &fattr; - nfs_fattr_init(&fattr); - - /* Eat leading slashes */ - while (*path == '/') - path++; + fsinfo.fattr = nfs_alloc_fattr(); + if (fsinfo.fattr == NULL) + goto out; /* Start by getting the root filehandle from the server */ ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo); if (ret < 0) { - dprintk("nfs4_get_root: getroot error = %d\n", -ret); - return ret; + dprintk("nfs4_get_rootfh: getroot error = %d\n", -ret); + goto out; } - if (!S_ISDIR(fattr.mode)) { - printk(KERN_ERR "nfs4_get_root:" + if (!(fsinfo.fattr->valid & NFS_ATTR_FATTR_MODE) + || !S_ISDIR(fsinfo.fattr->mode)) { + printk(KERN_ERR "nfs4_get_rootfh:" " getroot encountered non-directory\n"); - return -ENOTDIR; + ret = -ENOTDIR; + goto out; } - /* FIXME: It is quite valid for the server to return a referral here */ - if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) { - printk(KERN_ERR "nfs4_get_root:" + if (fsinfo.fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) { + printk(KERN_ERR "nfs4_get_rootfh:" " getroot obtained referral\n"); - return -EREMOTE; + ret = -EREMOTE; + goto out; } -next_component: - dprintk("Next: %s\n", path); - - /* extract the next bit of the path */ - if (!*path) - goto path_walk_complete; - - name.name = path; - while (*path && *path != '/') - path++; - name.len = path - (const char *) name.name; - - if (name.len > NFS4_MAXNAMLEN) - return -ENAMETOOLONG; - -eat_dot_dir: - while (*path == '/') - path++; - - if (path[0] == '.' && (path[1] == '/' || !path[1])) { - path += 2; - goto eat_dot_dir; - } - - /* FIXME: Why shouldn't the user be able to use ".." in the path? */ - if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || !path[2]) - ) { - printk(KERN_ERR "nfs4_get_root:" - " Mount path contains reference to \"..\"\n"); - return -EINVAL; - } - - /* lookup the next FH in the sequence */ - memcpy(&lastfh, mntfh, sizeof(lastfh)); - - dprintk("LookupFH: %*.*s [%s]\n", name.len, name.len, name.name, path); - - ret = server->nfs_client->rpc_ops->lookupfh(server, &lastfh, &name, - mntfh, &fattr); - if (ret < 0) { - dprintk("nfs4_get_root: getroot error = %d\n", -ret); - return ret; - } - - if (!S_ISDIR(fattr.mode)) { - printk(KERN_ERR "nfs4_get_root:" - " lookupfh encountered non-directory\n"); - return -ENOTDIR; - } - - /* FIXME: Referrals are quite valid here too */ - if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) { - printk(KERN_ERR "nfs4_get_root:" - " lookupfh obtained referral\n"); - return -EREMOTE; - } - - goto next_component; - -path_walk_complete: - memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid)); - dprintk("<-- nfs4_path_walk() = 0\n"); - return 0; + memcpy(&server->fsid, &fsinfo.fattr->fsid, sizeof(server->fsid)); +out: + nfs_free_fattr(fsinfo.fattr); + dprintk("<-- nfs4_get_rootfh() = %d\n", ret); + return ret; } /* diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 11f82f0..d8bd619 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -244,9 +244,7 @@ extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *); #ifdef CONFIG_NFS_V4 extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *); -extern int nfs4_path_walk(struct nfs_server *server, - struct nfs_fh *mntfh, - const char *path); +extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh); #endif /* read.c */ -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 03/24] NFS: Reduce the stack footprint of nfs_follow_mountpoint() 2010-04-16 20:31 ` [PATCH 02/24] NFSv4: Eliminate nfs4_path_walk() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 04/24] NFS: Reduce the stack footprint of nfs_create_server Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/namespace.c | 20 ++++++++++++++------ 1 files changed, 14 insertions(+), 6 deletions(-) diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 7888cf3..db6aa36 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -105,8 +105,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) struct vfsmount *mnt; struct nfs_server *server = NFS_SERVER(dentry->d_inode); struct dentry *parent; - struct nfs_fh fh; - struct nfs_fattr fattr; + struct nfs_fh *fh = NULL; + struct nfs_fattr *fattr = NULL; int err; dprintk("--> nfs_follow_mountpoint()\n"); @@ -115,6 +115,12 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) if (IS_ROOT(dentry)) goto out_err; + err = -ENOMEM; + fh = nfs_alloc_fhandle(); + fattr = nfs_alloc_fattr(); + if (fh == NULL || fattr == NULL) + goto out_err; + dprintk("%s: enter\n", __func__); dput(nd->path.dentry); nd->path.dentry = dget(dentry); @@ -123,16 +129,16 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) parent = dget_parent(nd->path.dentry); err = server->nfs_client->rpc_ops->lookup(parent->d_inode, &nd->path.dentry->d_name, - &fh, &fattr); + fh, fattr); dput(parent); if (err != 0) goto out_err; - if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) + if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry); else - mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, &fh, - &fattr); + mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, fh, + fattr); err = PTR_ERR(mnt); if (IS_ERR(mnt)) goto out_err; @@ -151,6 +157,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) nd->path.dentry = dget(mnt->mnt_root); schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); out: + nfs_free_fattr(fattr); + nfs_free_fhandle(fh); dprintk("%s: done, returned %d\n", __func__, err); dprintk("<-- nfs_follow_mountpoint() = %d\n", err); -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 04/24] NFS: Reduce the stack footprint of nfs_create_server 2010-04-16 20:31 ` [PATCH 03/24] NFS: Reduce the stack footprint of nfs_follow_mountpoint() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 05/24] NFSv4: Reduce the stack footprint of try_location() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/client.c | 50 +++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 39 insertions(+), 11 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 48fc680..dc242fa 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -1045,13 +1045,18 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data, struct nfs_fh *mntfh) { struct nfs_server *server; - struct nfs_fattr fattr; + struct nfs_fattr *fattr; int error; server = nfs_alloc_server(); if (!server) return ERR_PTR(-ENOMEM); + error = -ENOMEM; + fattr = nfs_alloc_fattr(); + if (fattr == NULL) + goto error; + /* Get a client representation */ error = nfs_init_server(server, data); if (error < 0) @@ -1062,7 +1067,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data, BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); /* Probe the root fh to retrieve its FSID */ - error = nfs_probe_fsinfo(server, mntfh, &fattr); + error = nfs_probe_fsinfo(server, mntfh, fattr); if (error < 0) goto error; if (server->nfs_client->rpc_ops->version == 3) { @@ -1075,14 +1080,14 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data, server->namelen = NFS2_MAXNAMLEN; } - if (!(fattr.valid & NFS_ATTR_FATTR)) { - error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr); + if (!(fattr->valid & NFS_ATTR_FATTR)) { + error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr); if (error < 0) { dprintk("nfs_create_server: getattr error = %d\n", -error); goto error; } } - memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid)); + memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid)); dprintk("Server FSID: %llx:%llx\n", (unsigned long long) server->fsid.major, @@ -1094,9 +1099,11 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data, spin_unlock(&nfs_client_lock); server->mount_time = jiffies; + nfs_free_fattr(fattr); return server; error: + nfs_free_fattr(fattr); nfs_free_server(server); return ERR_PTR(error); } @@ -1338,7 +1345,7 @@ error: struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, struct nfs_fh *mntfh) { - struct nfs_fattr fattr; + struct nfs_fattr *fattr; struct nfs_server *server; int error; @@ -1348,6 +1355,11 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, if (!server) return ERR_PTR(-ENOMEM); + error = -ENOMEM; + fattr = nfs_alloc_fattr(); + if (fattr == NULL) + goto error; + /* set up the general RPC client */ error = nfs4_init_server(server, data); if (error < 0) @@ -1373,7 +1385,7 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, nfs4_session_set_rwsize(server); - error = nfs_probe_fsinfo(server, mntfh, &fattr); + error = nfs_probe_fsinfo(server, mntfh, fattr); if (error < 0) goto error; @@ -1387,9 +1399,11 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, server->mount_time = jiffies; dprintk("<-- nfs4_create_server() = %p\n", server); + nfs_free_fattr(fattr); return server; error: + nfs_free_fattr(fattr); nfs_free_server(server); dprintk("<-- nfs4_create_server() = error %d\n", error); return ERR_PTR(error); @@ -1403,7 +1417,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, { struct nfs_client *parent_client; struct nfs_server *server, *parent_server; - struct nfs_fattr fattr; + struct nfs_fattr *fattr; int error; dprintk("--> nfs4_create_referral_server()\n"); @@ -1412,6 +1426,11 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, if (!server) return ERR_PTR(-ENOMEM); + error = -ENOMEM; + fattr = nfs_alloc_fattr(); + if (fattr == NULL) + goto error; + parent_server = NFS_SB(data->sb); parent_client = parent_server->nfs_client; @@ -1446,7 +1465,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, goto error; /* probe the filesystem info for this server filesystem */ - error = nfs_probe_fsinfo(server, mntfh, &fattr); + error = nfs_probe_fsinfo(server, mntfh, fattr); if (error < 0) goto error; @@ -1464,10 +1483,12 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, server->mount_time = jiffies; + nfs_free_fattr(fattr); dprintk("<-- nfs_create_referral_server() = %p\n", server); return server; error: + nfs_free_fattr(fattr); nfs_free_server(server); dprintk("<-- nfs4_create_referral_server() = error %d\n", error); return ERR_PTR(error); @@ -1483,7 +1504,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, struct nfs_fattr *fattr) { struct nfs_server *server; - struct nfs_fattr fattr_fsinfo; + struct nfs_fattr *fattr_fsinfo; int error; dprintk("--> nfs_clone_server(,%llx:%llx,)\n", @@ -1494,6 +1515,11 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, if (!server) return ERR_PTR(-ENOMEM); + error = -ENOMEM; + fattr_fsinfo = nfs_alloc_fattr(); + if (fattr_fsinfo == NULL) + goto out_free_server; + /* Copy data from the source */ server->nfs_client = source->nfs_client; atomic_inc(&server->nfs_client->cl_count); @@ -1510,7 +1536,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, nfs_init_server_aclclient(server); /* probe the filesystem info for this server filesystem */ - error = nfs_probe_fsinfo(server, fh, &fattr_fsinfo); + error = nfs_probe_fsinfo(server, fh, fattr_fsinfo); if (error < 0) goto out_free_server; @@ -1532,10 +1558,12 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, server->mount_time = jiffies; + nfs_free_fattr(fattr_fsinfo); dprintk("<-- nfs_clone_server() = %p\n", server); return server; out_free_server: + nfs_free_fattr(fattr_fsinfo); nfs_free_server(server); dprintk("<-- nfs_clone_server() = error %d\n", error); return ERR_PTR(error); -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 05/24] NFSv4: Reduce the stack footprint of try_location() 2010-04-16 20:31 ` [PATCH 04/24] NFS: Reduce the stack footprint of nfs_create_server Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 06/24] NFS: Reduce the stack footprint of nfs_lookup Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/nfs4namespace.c | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index f071d12..832f9b5 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c @@ -115,6 +115,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, char *page, char *page2, const struct nfs4_fs_location *location) { + const size_t addr_bufsize = sizeof(struct sockaddr_storage); struct vfsmount *mnt = ERR_PTR(-ENOENT); char *mnt_path; unsigned int maxbuflen; @@ -126,9 +127,12 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, mountdata->mnt_path = mnt_path; maxbuflen = mnt_path - 1 - page2; + mountdata->addr = kmalloc(addr_bufsize, GFP_KERNEL); + if (mountdata->addr == NULL) + return ERR_PTR(-ENOMEM); + for (s = 0; s < location->nservers; s++) { const struct nfs4_string *buf = &location->servers[s]; - struct sockaddr_storage addr; if (buf->len <= 0 || buf->len >= maxbuflen) continue; @@ -137,11 +141,10 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, continue; mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len, - (struct sockaddr *)&addr, sizeof(addr)); + mountdata->addr, addr_bufsize); if (mountdata->addrlen == 0) continue; - mountdata->addr = (struct sockaddr *)&addr; rpc_set_port(mountdata->addr, NFS_PORT); memcpy(page2, buf->data, buf->len); @@ -156,6 +159,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, if (!IS_ERR(mnt)) break; } + kfree(mountdata->addr); return mnt; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 06/24] NFS: Reduce the stack footprint of nfs_lookup 2010-04-16 20:31 ` [PATCH 05/24] NFSv4: Reduce the stack footprint of try_location() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 07/24] NFS: Reduce the stack footprint of nfs_follow_remote_path() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/dir.c | 45 +++++++++++++++++++++++++++++++++++---------- fs/nfs/nfs3proc.c | 10 ++++++---- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index be46f26..4da45ab 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -776,9 +776,9 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) struct inode *dir; struct inode *inode; struct dentry *parent; + struct nfs_fh *fhandle = NULL; + struct nfs_fattr *fattr = NULL; int error; - struct nfs_fh fhandle; - struct nfs_fattr fattr; parent = dget_parent(dentry); dir = parent->d_inode; @@ -811,14 +811,22 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) if (NFS_STALE(inode)) goto out_bad; - error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); + error = -ENOMEM; + fhandle = nfs_alloc_fhandle(); + fattr = nfs_alloc_fattr(); + if (fhandle == NULL || fattr == NULL) + goto out_error; + + error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); if (error) goto out_bad; - if (nfs_compare_fh(NFS_FH(inode), &fhandle)) + if (nfs_compare_fh(NFS_FH(inode), fhandle)) goto out_bad; - if ((error = nfs_refresh_inode(inode, &fattr)) != 0) + if ((error = nfs_refresh_inode(inode, fattr)) != 0) goto out_bad; + nfs_free_fattr(fattr); + nfs_free_fhandle(fhandle); out_set_verifier: nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); out_valid: @@ -840,11 +848,21 @@ out_zap_parent: shrink_dcache_parent(dentry); } d_drop(dentry); + nfs_free_fattr(fattr); + nfs_free_fhandle(fhandle); dput(parent); dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", __func__, dentry->d_parent->d_name.name, dentry->d_name.name); return 0; +out_error: + nfs_free_fattr(fattr); + nfs_free_fhandle(fhandle); + dput(parent); + dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) lookup returned error %d\n", + __func__, dentry->d_parent->d_name.name, + dentry->d_name.name, error); + return error; } /* @@ -909,9 +927,9 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru struct dentry *res; struct dentry *parent; struct inode *inode = NULL; + struct nfs_fh *fhandle = NULL; + struct nfs_fattr *fattr = NULL; int error; - struct nfs_fh fhandle; - struct nfs_fattr fattr; dfprintk(VFS, "NFS: lookup(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); @@ -921,7 +939,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru if (dentry->d_name.len > NFS_SERVER(dir)->namelen) goto out; - res = ERR_PTR(-ENOMEM); dentry->d_op = NFS_PROTO(dir)->dentry_ops; /* @@ -934,17 +951,23 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru goto out; } + res = ERR_PTR(-ENOMEM); + fhandle = nfs_alloc_fhandle(); + fattr = nfs_alloc_fattr(); + if (fhandle == NULL || fattr == NULL) + goto out; + parent = dentry->d_parent; /* Protect against concurrent sillydeletes */ nfs_block_sillyrename(parent); - error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); + error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); if (error == -ENOENT) goto no_entry; if (error < 0) { res = ERR_PTR(error); goto out_unblock_sillyrename; } - inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr); + inode = nfs_fhget(dentry->d_sb, fhandle, fattr); res = (struct dentry *)inode; if (IS_ERR(res)) goto out_unblock_sillyrename; @@ -960,6 +983,8 @@ no_entry: out_unblock_sillyrename: nfs_unblock_sillyrename(parent); out: + nfs_free_fattr(fattr); + nfs_free_fhandle(fhandle); return res; } diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index e701002..72334c1 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -144,14 +144,12 @@ static int nfs3_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr) { - struct nfs_fattr dir_attr; struct nfs3_diropargs arg = { .fh = NFS_FH(dir), .name = name->name, .len = name->len }; struct nfs3_diropres res = { - .dir_attr = &dir_attr, .fh = fhandle, .fattr = fattr }; @@ -163,16 +161,20 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name, int status; dprintk("NFS call lookup %s\n", name->name); - nfs_fattr_init(&dir_attr); + res.dir_attr = nfs_alloc_fattr(); + if (res.dir_attr == NULL) + return -ENOMEM; + nfs_fattr_init(fattr); status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); - nfs_refresh_inode(dir, &dir_attr); + nfs_refresh_inode(dir, res.dir_attr); if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) { msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; msg.rpc_argp = fhandle; msg.rpc_resp = fattr; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); } + nfs_free_fattr(res.dir_attr); dprintk("NFS reply lookup: %d\n", status); return status; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 07/24] NFS: Reduce the stack footprint of nfs_follow_remote_path() 2010-04-16 20:31 ` [PATCH 06/24] NFS: Reduce the stack footprint of nfs_lookup Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 08/24] NFSv4: Reduce stack footprint of nfs4_get_root() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/super.c | 18 ++++++++++++------ 1 files changed, 12 insertions(+), 6 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index e016372..ef2102f 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2671,38 +2671,44 @@ out_freepage: static int nfs_follow_remote_path(struct vfsmount *root_mnt, const char *export_path, struct vfsmount *mnt_target) { + struct nameidata *nd = NULL; struct mnt_namespace *ns_private; - struct nameidata nd; struct super_block *s; int ret; + nd = kmalloc(sizeof(*nd), GFP_KERNEL); + if (nd == NULL) + return -ENOMEM; + ns_private = create_mnt_ns(root_mnt); ret = PTR_ERR(ns_private); if (IS_ERR(ns_private)) goto out_mntput; ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt, - export_path, LOOKUP_FOLLOW, &nd); + export_path, LOOKUP_FOLLOW, nd); put_mnt_ns(ns_private); if (ret != 0) goto out_err; - s = nd.path.mnt->mnt_sb; + s = nd->path.mnt->mnt_sb; atomic_inc(&s->s_active); mnt_target->mnt_sb = s; - mnt_target->mnt_root = dget(nd.path.dentry); + mnt_target->mnt_root = dget(nd->path.dentry); /* Correct the device pathname */ - nfs_fix_devname(&nd.path, mnt_target); + nfs_fix_devname(&nd->path, mnt_target); - path_put(&nd.path); + path_put(&nd->path); + kfree(nd); down_write(&s->s_umount); return 0; out_mntput: mntput(root_mnt); out_err: + kfree(nd); return ret; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 08/24] NFSv4: Reduce stack footprint of nfs4_get_root() 2010-04-16 20:31 ` [PATCH 07/24] NFS: Reduce the stack footprint of nfs_follow_remote_path() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 09/24] NFSv4: Reduce the stack footprint of nfs4_remote_referral_get_sb Trond Myklebust 2010-04-19 21:03 ` [PATCH 08/24] NFSv4: Reduce stack footprint of nfs4_get_root() Chuck Lever 0 siblings, 2 replies; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/getroot.c | 76 ++++++++++++++++++++++++++++++++--------------------- 1 files changed, 46 insertions(+), 30 deletions(-) diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index ada369a..7428f7d 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c @@ -78,46 +78,52 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh) { struct nfs_server *server = NFS_SB(sb); struct nfs_fsinfo fsinfo; - struct nfs_fattr fattr; - struct dentry *mntroot; + struct dentry *ret; struct inode *inode; int error; /* get the actual root for this mount */ - fsinfo.fattr = &fattr; + fsinfo.fattr = nfs_alloc_fattr(); + if (fsinfo.fattr == NULL) + return ERR_PTR(-ENOMEM); error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo); if (error < 0) { dprintk("nfs_get_root: getattr error = %d\n", -error); - return ERR_PTR(error); + ret = ERR_PTR(error); + goto out; } inode = nfs_fhget(sb, mntfh, fsinfo.fattr); if (IS_ERR(inode)) { dprintk("nfs_get_root: get root inode failed\n"); - return ERR_CAST(inode); + ret = ERR_CAST(inode); + goto out; } error = nfs_superblock_set_dummy_root(sb, inode); - if (error != 0) - return ERR_PTR(error); + if (error != 0) { + ret = ERR_PTR(error); + goto out; + } /* root dentries normally start off anonymous and get spliced in later * if the dentry tree reaches them; however if the dentry already * exists, we'll pick it up at this point and use it as the root */ - mntroot = d_obtain_alias(inode); - if (IS_ERR(mntroot)) { + ret = d_obtain_alias(inode); + if (IS_ERR(ret)) { dprintk("nfs_get_root: get root dentry failed\n"); - return mntroot; + goto out; } - security_d_instantiate(mntroot, inode); + security_d_instantiate(ret, inode); - if (!mntroot->d_op) - mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops; - - return mntroot; + if (ret->d_op == NULL) + ret->d_op = server->nfs_client->rpc_ops->dentry_ops; +out: + nfs_free_fattr(fsinfo.fattr); + return ret; } #ifdef CONFIG_NFS_V4 @@ -168,8 +174,8 @@ out: struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh) { struct nfs_server *server = NFS_SB(sb); - struct nfs_fattr fattr; - struct dentry *mntroot; + struct nfs_fattr *fattr = NULL; + struct dentry *ret; struct inode *inode; int error; @@ -183,40 +189,50 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh) return ERR_PTR(error); } + fattr = nfs_alloc_fattr(); + if (fattr == NULL) + return ERR_PTR(-ENOMEM);; + /* get the actual root for this mount */ - error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr); + error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr); if (error < 0) { dprintk("nfs_get_root: getattr error = %d\n", -error); - return ERR_PTR(error); + ret = ERR_PTR(error); + goto out; } - inode = nfs_fhget(sb, mntfh, &fattr); + inode = nfs_fhget(sb, mntfh, fattr); if (IS_ERR(inode)) { dprintk("nfs_get_root: get root inode failed\n"); - return ERR_CAST(inode); + ret = ERR_CAST(inode); + goto out; } error = nfs_superblock_set_dummy_root(sb, inode); - if (error != 0) - return ERR_PTR(error); + if (error != 0) { + ret = ERR_PTR(error); + goto out; + } /* root dentries normally start off anonymous and get spliced in later * if the dentry tree reaches them; however if the dentry already * exists, we'll pick it up at this point and use it as the root */ - mntroot = d_obtain_alias(inode); - if (IS_ERR(mntroot)) { + ret = d_obtain_alias(inode); + if (IS_ERR(ret)) { dprintk("nfs_get_root: get root dentry failed\n"); - return mntroot; + goto out; } - security_d_instantiate(mntroot, inode); + security_d_instantiate(ret, inode); - if (!mntroot->d_op) - mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops; + if (ret->d_op == NULL) + ret->d_op = server->nfs_client->rpc_ops->dentry_ops; +out: + nfs_free_fattr(fattr); dprintk("<-- nfs4_get_root()\n"); - return mntroot; + return ret; } #endif /* CONFIG_NFS_V4 */ -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 09/24] NFSv4: Reduce the stack footprint of nfs4_remote_referral_get_sb 2010-04-16 20:31 ` [PATCH 08/24] NFSv4: Reduce stack footprint of nfs4_get_root() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 10/24] NFSv4: Reduce stack footprint of nfs4_proc_access() and nfs3_proc_access() Trond Myklebust 2010-04-19 21:03 ` [PATCH 08/24] NFSv4: Reduce stack footprint of nfs4_get_root() Chuck Lever 1 sibling, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/super.c | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ef2102f..3e9047f 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2879,17 +2879,21 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type, struct super_block *s; struct nfs_server *server; struct dentry *mntroot; - struct nfs_fh mntfh; + struct nfs_fh *mntfh; int (*compare_super)(struct super_block *, void *) = nfs_compare_super; struct nfs_sb_mountdata sb_mntdata = { .mntflags = flags, }; - int error; + int error = -ENOMEM; dprintk("--> nfs4_referral_get_sb()\n"); + mntfh = nfs_alloc_fhandle(); + if (mntfh == NULL) + goto out_err_nofh; + /* create a new volume representation */ - server = nfs4_create_referral_server(data, &mntfh); + server = nfs4_create_referral_server(data, mntfh); if (IS_ERR(server)) { error = PTR_ERR(server); goto out_err_noserver; @@ -2921,7 +2925,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type, nfs_fscache_get_super_cookie(s, NULL, data); } - mntroot = nfs4_get_root(s, &mntfh); + mntroot = nfs4_get_root(s, mntfh); if (IS_ERR(mntroot)) { error = PTR_ERR(mntroot); goto error_splat_super; @@ -2938,12 +2942,15 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type, security_sb_clone_mnt_opts(data->sb, s); + nfs_free_fhandle(mntfh); dprintk("<-- nfs4_referral_get_sb() = 0\n"); return 0; out_err_nosb: nfs_free_server(server); out_err_noserver: + nfs_free_fhandle(mntfh); +out_err_nofh: dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error); return error; @@ -2952,6 +2959,7 @@ error_splat_super: bdi_unregister(&server->backing_dev_info); error_splat_bdi: deactivate_locked_super(s); + nfs_free_fhandle(mntfh); dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error); return error; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 10/24] NFSv4: Reduce stack footprint of nfs4_proc_access() and nfs3_proc_access() 2010-04-16 20:31 ` [PATCH 09/24] NFSv4: Reduce the stack footprint of nfs4_remote_referral_get_sb Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 11/24] NFS: Reduce stack footprint of nfs_revalidate_inode() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/nfs3proc.c | 17 ++++++++++------- fs/nfs/nfs4proc.c | 11 +++++++---- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 72334c1..9d5d02f 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -181,13 +181,10 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name, static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) { - struct nfs_fattr fattr; struct nfs3_accessargs arg = { .fh = NFS_FH(inode), }; - struct nfs3_accessres res = { - .fattr = &fattr, - }; + struct nfs3_accessres res; struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS], .rpc_argp = &arg, @@ -195,7 +192,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) .rpc_cred = entry->cred, }; int mode = entry->mask; - int status; + int status = -ENOMEM; dprintk("NFS call access\n"); @@ -212,9 +209,13 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) if (mode & MAY_EXEC) arg.access |= NFS3_ACCESS_EXECUTE; } - nfs_fattr_init(&fattr); + + res.fattr = nfs_alloc_fattr(); + if (res.fattr == NULL) + goto out; + status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); - nfs_refresh_inode(inode, &fattr); + nfs_refresh_inode(inode, res.fattr); if (status == 0) { entry->mask = 0; if (res.access & NFS3_ACCESS_READ) @@ -224,6 +225,8 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE)) entry->mask |= MAY_EXEC; } + nfs_free_fattr(res.fattr); +out: dprintk("NFS reply access: %d\n", status); return status; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6380670..3acce87 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2404,14 +2404,12 @@ static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) { struct nfs_server *server = NFS_SERVER(inode); - struct nfs_fattr fattr; struct nfs4_accessargs args = { .fh = NFS_FH(inode), .bitmask = server->attr_bitmask, }; struct nfs4_accessres res = { .server = server, - .fattr = &fattr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS], @@ -2438,7 +2436,11 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry if (mode & MAY_EXEC) args.access |= NFS4_ACCESS_EXECUTE; } - nfs_fattr_init(&fattr); + + res.fattr = nfs_alloc_fattr(); + if (res.fattr == NULL) + return -ENOMEM; + status = nfs4_call_sync(server, &msg, &args, &res, 0); if (!status) { entry->mask = 0; @@ -2448,8 +2450,9 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry entry->mask |= MAY_WRITE; if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE)) entry->mask |= MAY_EXEC; - nfs_refresh_inode(inode, &fattr); + nfs_refresh_inode(inode, res.fattr); } + nfs_free_fattr(res.fattr); return status; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 11/24] NFS: Reduce stack footprint of nfs_revalidate_inode() 2010-04-16 20:31 ` [PATCH 10/24] NFSv4: Reduce stack footprint of nfs4_proc_access() and nfs3_proc_access() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 12/24] NFS: Reduce stack footprint of nfs3_proc_rename() and nfs4_proc_rename() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/inode.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 6e257c3..e20acdd 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -682,7 +682,7 @@ int __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) { int status = -ESTALE; - struct nfs_fattr fattr; + struct nfs_fattr *fattr = NULL; struct nfs_inode *nfsi = NFS_I(inode); dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", @@ -693,8 +693,13 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) if (NFS_STALE(inode)) goto out; + status = -ENOMEM; + fattr = nfs_alloc_fattr(); + if (fattr == NULL) + goto out; + nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); - status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); + status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr); if (status != 0) { dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", inode->i_sb->s_id, @@ -707,7 +712,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) goto out; } - status = nfs_refresh_inode(inode, &fattr); + status = nfs_refresh_inode(inode, fattr); if (status) { dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", inode->i_sb->s_id, @@ -723,6 +728,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) (long long)NFS_FILEID(inode)); out: + nfs_free_fattr(fattr); return status; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 12/24] NFS: Reduce stack footprint of nfs3_proc_rename() and nfs4_proc_rename() 2010-04-16 20:31 ` [PATCH 11/24] NFS: Reduce stack footprint of nfs_revalidate_inode() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 13/24] NFS: Reduce stack footprint of nfs_readdir() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/nfs3proc.c | 23 +++++++++++++---------- fs/nfs/nfs4proc.c | 16 +++++++++------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 9d5d02f..c252fc9 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -432,7 +432,6 @@ static int nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, struct inode *new_dir, struct qstr *new_name) { - struct nfs_fattr old_dir_attr, new_dir_attr; struct nfs3_renameargs arg = { .fromfh = NFS_FH(old_dir), .fromname = old_name->name, @@ -441,23 +440,27 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, .toname = new_name->name, .tolen = new_name->len }; - struct nfs3_renameres res = { - .fromattr = &old_dir_attr, - .toattr = &new_dir_attr - }; + struct nfs3_renameres res; struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_RENAME], .rpc_argp = &arg, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name); - nfs_fattr_init(&old_dir_attr); - nfs_fattr_init(&new_dir_attr); + + res.fromattr = nfs_alloc_fattr(); + res.toattr = nfs_alloc_fattr(); + if (res.fromattr == NULL || res.toattr == NULL) + goto out; + status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0); - nfs_post_op_update_inode(old_dir, &old_dir_attr); - nfs_post_op_update_inode(new_dir, &new_dir_attr); + nfs_post_op_update_inode(old_dir, res.fromattr); + nfs_post_op_update_inode(new_dir, res.toattr); +out: + nfs_free_fattr(res.toattr); + nfs_free_fattr(res.fromattr); dprintk("NFS reply rename: %d\n", status); return status; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 3acce87..e027fdb 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2656,29 +2656,31 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name, .new_name = new_name, .bitmask = server->attr_bitmask, }; - struct nfs_fattr old_fattr, new_fattr; struct nfs4_rename_res res = { .server = server, - .old_fattr = &old_fattr, - .new_fattr = &new_fattr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME], .rpc_argp = &arg, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; - nfs_fattr_init(res.old_fattr); - nfs_fattr_init(res.new_fattr); - status = nfs4_call_sync(server, &msg, &arg, &res, 1); + res.old_fattr = nfs_alloc_fattr(); + res.new_fattr = nfs_alloc_fattr(); + if (res.old_fattr == NULL || res.new_fattr == NULL) + goto out; + status = nfs4_call_sync(server, &msg, &arg, &res, 1); if (!status) { update_changeattr(old_dir, &res.old_cinfo); nfs_post_op_update_inode(old_dir, res.old_fattr); update_changeattr(new_dir, &res.new_cinfo); nfs_post_op_update_inode(new_dir, res.new_fattr); } +out: + nfs_free_fattr(res.new_fattr); + nfs_free_fattr(res.old_fattr); return status; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 13/24] NFS: Reduce stack footprint of nfs_readdir() 2010-04-16 20:31 ` [PATCH 12/24] NFS: Reduce stack footprint of nfs3_proc_rename() and nfs4_proc_rename() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 14/24] NFS: Reduce the stack footprint of nfs_link() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/dir.c | 17 ++++++++++------- fs/nfs/nfs3proc.c | 13 ++++++++----- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 4da45ab..dd94f83 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -530,9 +530,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) nfs_readdir_descriptor_t my_desc, *desc = &my_desc; struct nfs_entry my_entry; - struct nfs_fh fh; - struct nfs_fattr fattr; - long res; + int res = -ENOMEM; dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", dentry->d_parent->d_name.name, dentry->d_name.name, @@ -554,9 +552,11 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) my_entry.cookie = my_entry.prev_cookie = 0; my_entry.eof = 0; - my_entry.fh = &fh; - my_entry.fattr = &fattr; - nfs_fattr_init(&fattr); + my_entry.fh = nfs_alloc_fhandle(); + my_entry.fattr = nfs_alloc_fattr(); + if (my_entry.fh == NULL || my_entry.fattr == NULL) + goto out_alloc_failed; + desc->entry = &my_entry; nfs_block_sillyrename(dentry); @@ -598,7 +598,10 @@ out: nfs_unblock_sillyrename(dentry); if (res > 0) res = 0; - dfprintk(FILE, "NFS: readdir(%s/%s) returns %ld\n", +out_alloc_failed: + nfs_free_fattr(my_entry.fattr); + nfs_free_fhandle(my_entry.fh); + dfprintk(FILE, "NFS: readdir(%s/%s) returns %d\n", dentry->d_parent->d_name.name, dentry->d_name.name, res); return res; diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index c252fc9..1c5bfb3 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -597,7 +597,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, u64 cookie, struct page *page, unsigned int count, int plus) { struct inode *dir = dentry->d_inode; - struct nfs_fattr dir_attr; __be32 *verf = NFS_COOKIEVERF(dir); struct nfs3_readdirargs arg = { .fh = NFS_FH(dir), @@ -608,7 +607,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, .pages = &page }; struct nfs3_readdirres res = { - .dir_attr = &dir_attr, .verf = verf, .plus = plus }; @@ -618,7 +616,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, .rpc_resp = &res, .rpc_cred = cred }; - int status; + int status = -ENOMEM; if (plus) msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; @@ -626,12 +624,17 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, dprintk("NFS call readdir%s %d\n", plus? "plus" : "", (unsigned int) cookie); - nfs_fattr_init(&dir_attr); + res.dir_attr = nfs_alloc_fattr(); + if (res.dir_attr == NULL) + goto out; + status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); nfs_invalidate_atime(dir); + nfs_refresh_inode(dir, res.dir_attr); - nfs_refresh_inode(dir, &dir_attr); + nfs_free_fattr(res.dir_attr); +out: dprintk("NFS reply readdir: %d\n", status); return status; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 14/24] NFS: Reduce the stack footprint of nfs_link() 2010-04-16 20:31 ` [PATCH 13/24] NFS: Reduce stack footprint of nfs_readdir() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 15/24] NFS: Reduce stack footprint of nfs3_proc_readlink() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/nfs3proc.c | 22 ++++++++++++---------- fs/nfs/nfs4proc.c | 16 +++++++++------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 1c5bfb3..982a81b 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -468,30 +468,32 @@ out: static int nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) { - struct nfs_fattr dir_attr, fattr; struct nfs3_linkargs arg = { .fromfh = NFS_FH(inode), .tofh = NFS_FH(dir), .toname = name->name, .tolen = name->len }; - struct nfs3_linkres res = { - .dir_attr = &dir_attr, - .fattr = &fattr - }; + struct nfs3_linkres res; struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_LINK], .rpc_argp = &arg, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; dprintk("NFS call link %s\n", name->name); - nfs_fattr_init(&dir_attr); - nfs_fattr_init(&fattr); + res.fattr = nfs_alloc_fattr(); + res.dir_attr = nfs_alloc_fattr(); + if (res.fattr == NULL || res.dir_attr == NULL) + goto out; + status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); - nfs_post_op_update_inode(dir, &dir_attr); - nfs_post_op_update_inode(inode, &fattr); + nfs_post_op_update_inode(dir, res.dir_attr); + nfs_post_op_update_inode(inode, res.fattr); +out: + nfs_free_fattr(res.dir_attr); + nfs_free_fattr(res.fattr); dprintk("NFS reply link: %d\n", status); return status; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index e027fdb..345b6f9 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2707,28 +2707,30 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr * .name = name, .bitmask = server->attr_bitmask, }; - struct nfs_fattr fattr, dir_attr; struct nfs4_link_res res = { .server = server, - .fattr = &fattr, - .dir_attr = &dir_attr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK], .rpc_argp = &arg, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; + + res.fattr = nfs_alloc_fattr(); + res.dir_attr = nfs_alloc_fattr(); + if (res.fattr == NULL || res.dir_attr == NULL) + goto out; - nfs_fattr_init(res.fattr); - nfs_fattr_init(res.dir_attr); status = nfs4_call_sync(server, &msg, &arg, &res, 1); if (!status) { update_changeattr(dir, &res.cinfo); nfs_post_op_update_inode(dir, res.dir_attr); nfs_post_op_update_inode(inode, res.fattr); } - +out: + nfs_free_fattr(res.dir_attr); + nfs_free_fattr(res.fattr); return status; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 15/24] NFS: Reduce stack footprint of nfs3_proc_readlink() 2010-04-16 20:31 ` [PATCH 14/24] NFS: Reduce the stack footprint of nfs_link() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 16/24] NFS: Reduce stack footprint of nfs_proc_remove() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/nfs3proc.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 982a81b..088dceb 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -234,7 +234,7 @@ out: static int nfs3_proc_readlink(struct inode *inode, struct page *page, unsigned int pgbase, unsigned int pglen) { - struct nfs_fattr fattr; + struct nfs_fattr *fattr; struct nfs3_readlinkargs args = { .fh = NFS_FH(inode), .pgbase = pgbase, @@ -244,14 +244,19 @@ static int nfs3_proc_readlink(struct inode *inode, struct page *page, struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_READLINK], .rpc_argp = &args, - .rpc_resp = &fattr, }; - int status; + int status = -ENOMEM; dprintk("NFS call readlink\n"); - nfs_fattr_init(&fattr); + fattr = nfs_alloc_fattr(); + if (fattr == NULL) + goto out; + msg.rpc_resp = fattr; + status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); - nfs_refresh_inode(inode, &fattr); + nfs_refresh_inode(inode, fattr); + nfs_free_fattr(fattr); +out: dprintk("NFS reply readlink: %d\n", status); return status; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 16/24] NFS: Reduce stack footprint of nfs_proc_remove() 2010-04-16 20:31 ` [PATCH 15/24] NFS: Reduce stack footprint of nfs3_proc_readlink() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 17/24] NFS: Reduce the stack footprint of nfs_rmdir Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/nfs3proc.c | 13 +++++++++---- fs/nfs/nfs3xdr.c | 2 +- fs/nfs/nfs4proc.c | 13 +++++++++---- fs/nfs/nfs4xdr.c | 2 +- fs/nfs/unlink.c | 4 +++- include/linux/nfs_xdr.h | 2 +- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 088dceb..80378d1 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -406,12 +406,17 @@ nfs3_proc_remove(struct inode *dir, struct qstr *name) .rpc_argp = &arg, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; dprintk("NFS call remove %s\n", name->name); - nfs_fattr_init(&res.dir_attr); + res.dir_attr = nfs_alloc_fattr(); + if (res.dir_attr == NULL) + goto out; + status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); - nfs_post_op_update_inode(dir, &res.dir_attr); + nfs_post_op_update_inode(dir, res.dir_attr); + nfs_free_fattr(res.dir_attr); +out: dprintk("NFS reply remove: %d\n", status); return status; } @@ -429,7 +434,7 @@ nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir) if (nfs3_async_handle_jukebox(task, dir)) return 0; res = task->tk_msg.rpc_resp; - nfs_post_op_update_inode(dir, &res->dir_attr); + nfs_post_op_update_inode(dir, res->dir_attr); return 1; } diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 56a86f6..75dcfc7 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -762,7 +762,7 @@ nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) static int nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res) { - return nfs3_xdr_wccstat(req, p, &res->dir_attr); + return nfs3_xdr_wccstat(req, p, res->dir_attr); } /* diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 345b6f9..f09a7b9 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2599,14 +2599,19 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) .rpc_argp = &args, .rpc_resp = &res, }; - int status; + int status = -ENOMEM; + + res.dir_attr = nfs_alloc_fattr(); + if (res.dir_attr == NULL) + goto out; - nfs_fattr_init(&res.dir_attr); status = nfs4_call_sync(server, &msg, &args, &res, 1); if (status == 0) { update_changeattr(dir, &res.cinfo); - nfs_post_op_update_inode(dir, &res.dir_attr); + nfs_post_op_update_inode(dir, res.dir_attr); } + nfs_free_fattr(res.dir_attr); +out: return status; } @@ -2641,7 +2646,7 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) return 0; update_changeattr(dir, &res->cinfo); - nfs_post_op_update_inode(dir, &res->dir_attr); + nfs_post_op_update_inode(dir, res->dir_attr); return 1; } diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 38f3b58..8905806 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -4815,7 +4815,7 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_rem goto out; if ((status = decode_remove(&xdr, &res->cinfo)) != 0) goto out; - decode_getfattr(&xdr, &res->dir_attr, res->server, + decode_getfattr(&xdr, res->dir_attr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 6da3d3f..a2242af 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -23,6 +23,7 @@ struct nfs_unlinkdata { struct nfs_removeres res; struct inode *dir; struct rpc_cred *cred; + struct nfs_fattr dir_attr; }; /** @@ -169,7 +170,7 @@ static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct n } nfs_sb_active(dir->i_sb); data->args.fh = NFS_FH(dir); - nfs_fattr_init(&data->res.dir_attr); + nfs_fattr_init(data->res.dir_attr); NFS_PROTO(dir)->unlink_setup(&msg, dir); @@ -259,6 +260,7 @@ nfs_async_unlink(struct inode *dir, struct dentry *dentry) goto out_free; } data->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE; + data->res.dir_attr = &data->dir_attr; status = -EBUSY; spin_lock(&dentry->d_lock); diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 89b2881..76e11c6 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -386,8 +386,8 @@ struct nfs_removeargs { struct nfs_removeres { const struct nfs_server *server; + struct nfs_fattr *dir_attr; struct nfs4_change_info cinfo; - struct nfs_fattr dir_attr; struct nfs4_sequence_res seq_res; }; -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 17/24] NFS: Reduce the stack footprint of nfs_rmdir 2010-04-16 20:31 ` [PATCH 16/24] NFS: Reduce stack footprint of nfs_proc_remove() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 18/24] NFS: Reduce the stack footprint of nfs_proc_create Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/nfs3proc.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 80378d1..fabb4f2 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -574,7 +574,7 @@ out: static int nfs3_proc_rmdir(struct inode *dir, struct qstr *name) { - struct nfs_fattr dir_attr; + struct nfs_fattr *dir_attr; struct nfs3_diropargs arg = { .fh = NFS_FH(dir), .name = name->name, @@ -583,14 +583,19 @@ nfs3_proc_rmdir(struct inode *dir, struct qstr *name) struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_RMDIR], .rpc_argp = &arg, - .rpc_resp = &dir_attr, }; - int status; + int status = -ENOMEM; dprintk("NFS call rmdir %s\n", name->name); - nfs_fattr_init(&dir_attr); + dir_attr = nfs_alloc_fattr(); + if (dir_attr == NULL) + goto out; + + msg.rpc_resp = dir_attr; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); - nfs_post_op_update_inode(dir, &dir_attr); + nfs_post_op_update_inode(dir, dir_attr); + nfs_free_fattr(dir_attr); +out: dprintk("NFS reply rmdir: %d\n", status); return status; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 18/24] NFS: Reduce the stack footprint of nfs_proc_create 2010-04-16 20:31 ` [PATCH 17/24] NFS: Reduce the stack footprint of nfs_rmdir Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 19/24] NFS: Reduce the stack footprint of nfs_proc_symlink() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/proc.c | 118 ++++++++++++++++++++++++++++++++------------------------- 1 files changed, 66 insertions(+), 52 deletions(-) diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 0288be8..aa61f2c 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -224,35 +224,60 @@ static int nfs_proc_readlink(struct inode *inode, struct page *page, return status; } +struct nfs_createdata { + struct nfs_createargs arg; + struct nfs_diropok res; + struct nfs_fh fhandle; + struct nfs_fattr fattr; +}; + +static struct nfs_createdata *nfs_alloc_createdata(struct inode *dir, + struct dentry *dentry, struct iattr *sattr) +{ + struct nfs_createdata *data; + + data = kmalloc(sizeof(*data), GFP_KERNEL); + + if (data != NULL) { + data->arg.fh = NFS_FH(dir); + data->arg.name = dentry->d_name.name; + data->arg.len = dentry->d_name.len; + data->arg.sattr = sattr; + nfs_fattr_init(&data->fattr); + data->fhandle.size = 0; + data->res.fh = &data->fhandle; + data->res.fattr = &data->fattr; + } + return data; +}; + +static void nfs_free_createdata(const struct nfs_createdata *data) +{ + kfree(data); +} + static int nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, int flags, struct nameidata *nd) { - struct nfs_fh fhandle; - struct nfs_fattr fattr; - struct nfs_createargs arg = { - .fh = NFS_FH(dir), - .name = dentry->d_name.name, - .len = dentry->d_name.len, - .sattr = sattr - }; - struct nfs_diropok res = { - .fh = &fhandle, - .fattr = &fattr - }; + struct nfs_createdata *data; struct rpc_message msg = { .rpc_proc = &nfs_procedures[NFSPROC_CREATE], - .rpc_argp = &arg, - .rpc_resp = &res, }; - int status; + int status = -ENOMEM; - nfs_fattr_init(&fattr); dprintk("NFS call create %s\n", dentry->d_name.name); + data = nfs_alloc_createdata(dir, dentry, sattr); + if (data == NULL) + goto out; + msg.rpc_argp = &data->arg; + msg.rpc_resp = &data->res; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); nfs_mark_for_revalidate(dir); if (status == 0) - status = nfs_instantiate(dentry, &fhandle, &fattr); + status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); + nfs_free_createdata(data); +out: dprintk("NFS reply create: %d\n", status); return status; } @@ -264,24 +289,12 @@ static int nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, dev_t rdev) { - struct nfs_fh fhandle; - struct nfs_fattr fattr; - struct nfs_createargs arg = { - .fh = NFS_FH(dir), - .name = dentry->d_name.name, - .len = dentry->d_name.len, - .sattr = sattr - }; - struct nfs_diropok res = { - .fh = &fhandle, - .fattr = &fattr - }; + struct nfs_createdata *data; struct rpc_message msg = { .rpc_proc = &nfs_procedures[NFSPROC_CREATE], - .rpc_argp = &arg, - .rpc_resp = &res, }; - int status, mode; + umode_t mode; + int status = -ENOMEM; dprintk("NFS call mknod %s\n", dentry->d_name.name); @@ -294,17 +307,24 @@ nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, sattr->ia_size = new_encode_dev(rdev);/* get out your barf bag */ } - nfs_fattr_init(&fattr); + data = nfs_alloc_createdata(dir, dentry, sattr); + if (data == NULL) + goto out; + msg.rpc_argp = &data->arg; + msg.rpc_resp = &data->res; + status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); nfs_mark_for_revalidate(dir); if (status == -EINVAL && S_ISFIFO(mode)) { sattr->ia_mode = mode; - nfs_fattr_init(&fattr); + nfs_fattr_init(data->res.fattr); status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); } if (status == 0) - status = nfs_instantiate(dentry, &fhandle, &fattr); + status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); + nfs_free_createdata(data); +out: dprintk("NFS reply mknod: %d\n", status); return status; } @@ -440,31 +460,25 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, static int nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) { - struct nfs_fh fhandle; - struct nfs_fattr fattr; - struct nfs_createargs arg = { - .fh = NFS_FH(dir), - .name = dentry->d_name.name, - .len = dentry->d_name.len, - .sattr = sattr - }; - struct nfs_diropok res = { - .fh = &fhandle, - .fattr = &fattr - }; + struct nfs_createdata *data; struct rpc_message msg = { .rpc_proc = &nfs_procedures[NFSPROC_MKDIR], - .rpc_argp = &arg, - .rpc_resp = &res, }; - int status; + int status = -ENOMEM; dprintk("NFS call mkdir %s\n", dentry->d_name.name); - nfs_fattr_init(&fattr); + data = nfs_alloc_createdata(dir, dentry, sattr); + if (data == NULL) + goto out; + msg.rpc_argp = &data->arg; + msg.rpc_resp = &data->res; + status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); nfs_mark_for_revalidate(dir); if (status == 0) - status = nfs_instantiate(dentry, &fhandle, &fattr); + status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); + nfs_free_createdata(data); +out: dprintk("NFS reply mkdir: %d\n", status); return status; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 19/24] NFS: Reduce the stack footprint of nfs_proc_symlink() 2010-04-16 20:31 ` [PATCH 18/24] NFS: Reduce the stack footprint of nfs_proc_create Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 20/24] NFS: Reduce stack footprint of nfs4_proc_create() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/proc.c | 26 ++++++++++++++++---------- 1 files changed, 16 insertions(+), 10 deletions(-) diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index aa61f2c..611bec2 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -418,8 +418,8 @@ static int nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, unsigned int len, struct iattr *sattr) { - struct nfs_fh fhandle; - struct nfs_fattr fattr; + struct nfs_fh *fh; + struct nfs_fattr *fattr; struct nfs_symlinkargs arg = { .fromfh = NFS_FH(dir), .fromname = dentry->d_name.name, @@ -432,12 +432,18 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, .rpc_proc = &nfs_procedures[NFSPROC_SYMLINK], .rpc_argp = &arg, }; - int status; + int status = -ENAMETOOLONG; + + dprintk("NFS call symlink %s\n", dentry->d_name.name); if (len > NFS2_MAXPATHLEN) - return -ENAMETOOLONG; + goto out; - dprintk("NFS call symlink %s\n", dentry->d_name.name); + fh = nfs_alloc_fhandle(); + fattr = nfs_alloc_fattr(); + status = -ENOMEM; + if (fh == NULL || fattr == NULL) + goto out; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); nfs_mark_for_revalidate(dir); @@ -447,12 +453,12 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, * filehandle size to zero indicates to nfs_instantiate that it * should fill in the data with a LOOKUP call on the wire. */ - if (status == 0) { - nfs_fattr_init(&fattr); - fhandle.size = 0; - status = nfs_instantiate(dentry, &fhandle, &fattr); - } + if (status == 0) + status = nfs_instantiate(dentry, fh, fattr); + nfs_free_fattr(fattr); + nfs_free_fhandle(fh); +out: dprintk("NFS reply symlink: %d\n", status); return status; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 20/24] NFS: Reduce stack footprint of nfs4_proc_create() 2010-04-16 20:31 ` [PATCH 19/24] NFS: Reduce the stack footprint of nfs_proc_symlink() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 21/24] NFS: Reduce stack footprint of nfs_setattr() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Move the O_EXCL open handling into _nfs4_do_open() where it belongs. Doing so also allows us to reuse the struct fattr from the opendata. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/nfs4proc.c | 25 +++++++++++++++---------- 1 files changed, 15 insertions(+), 10 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f09a7b9..d46305a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -70,6 +70,9 @@ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); +static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, + struct nfs_fattr *fattr, struct iattr *sattr, + struct nfs4_state *state); /* Prevent leaks of NFSv4 errors into userland */ static int nfs4_map_errors(int err) @@ -1659,15 +1662,24 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in if (status != 0) goto err_opendata_put; - if (opendata->o_arg.open_flags & O_EXCL) - nfs4_exclusive_attrset(opendata, sattr); - state = nfs4_opendata_to_nfs4_state(opendata); status = PTR_ERR(state); if (IS_ERR(state)) goto err_opendata_put; if (server->caps & NFS_CAP_POSIX_LOCK) set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); + + if (opendata->o_arg.open_flags & O_EXCL) { + nfs4_exclusive_attrset(opendata, sattr); + + nfs_fattr_init(opendata->o_res.f_attr); + status = nfs4_do_setattr(state->inode, cred, + opendata->o_res.f_attr, sattr, + state); + if (status == 0) + nfs_setattr_update_inode(state->inode, sattr); + nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); + } nfs4_opendata_put(opendata); nfs4_put_state_owner(sp); *res = state; @@ -2565,13 +2577,6 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, } d_add(dentry, igrab(state->inode)); nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); - if (flags & O_EXCL) { - struct nfs_fattr fattr; - status = nfs4_do_setattr(state->inode, cred, &fattr, sattr, state); - if (status == 0) - nfs_setattr_update_inode(state->inode, sattr); - nfs_post_op_update_inode(state->inode, &fattr); - } if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) status = nfs4_intent_set_file(nd, &path, state, fmode); else -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 21/24] NFS: Reduce stack footprint of nfs_setattr() 2010-04-16 20:31 ` [PATCH 20/24] NFS: Reduce stack footprint of nfs4_proc_create() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 22/24] NFS: Reduce stack footprint of nfs_statfs() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/inode.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index e20acdd..f132059 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -393,8 +393,8 @@ int nfs_setattr(struct dentry *dentry, struct iattr *attr) { struct inode *inode = dentry->d_inode; - struct nfs_fattr fattr; - int error; + struct nfs_fattr *fattr; + int error = -ENOMEM; nfs_inc_stats(inode, NFSIOS_VFSSETATTR); @@ -417,14 +417,20 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) filemap_write_and_wait(inode->i_mapping); nfs_wb_all(inode); } + + fattr = nfs_alloc_fattr(); + if (fattr == NULL) + goto out; /* * Return any delegations if we're going to change ACLs */ if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) nfs_inode_return_delegation(inode); - error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr); + error = NFS_PROTO(inode)->setattr(dentry, fattr, attr); if (error == 0) - nfs_refresh_inode(inode, &fattr); + nfs_refresh_inode(inode, fattr); + nfs_free_fattr(fattr); +out: return error; } -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 22/24] NFS: Reduce stack footprint of nfs_statfs() 2010-04-16 20:31 ` [PATCH 21/24] NFS: Reduce stack footprint of nfs_setattr() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 23/24] NFS: Reduce stack footprint of nfs3_proc_getacl() and nfs3_proc_setacl() Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/super.c | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 3e9047f..cb196eb 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -423,15 +423,19 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) unsigned char blockbits; unsigned long blockres; struct nfs_fh *fh = NFS_FH(dentry->d_inode); - struct nfs_fattr fattr; - struct nfs_fsstat res = { - .fattr = &fattr, - }; - int error; + struct nfs_fsstat res; + int error = -ENOMEM; + + res.fattr = nfs_alloc_fattr(); + if (res.fattr == NULL) + goto out_err; error = server->nfs_client->rpc_ops->statfs(server, fh, &res); + + nfs_free_fattr(res.fattr); if (error < 0) goto out_err; + buf->f_type = NFS_SUPER_MAGIC; /* -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 23/24] NFS: Reduce stack footprint of nfs3_proc_getacl() and nfs3_proc_setacl() 2010-04-16 20:31 ` [PATCH 22/24] NFS: Reduce stack footprint of nfs_statfs() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 2010-04-16 20:31 ` [PATCH 24/24] NFS: Prevent the mount code from looping forever on broken exports Trond Myklebust 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/nfs3acl.c | 23 ++++++++++++++++------- 1 files changed, 16 insertions(+), 7 deletions(-) diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index d150ae0..9f88c5f 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c @@ -185,7 +185,6 @@ static void nfs3_cache_acls(struct inode *inode, struct posix_acl *acl, struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type) { struct nfs_server *server = NFS_SERVER(inode); - struct nfs_fattr fattr; struct page *pages[NFSACL_MAXPAGES] = { }; struct nfs3_getaclargs args = { .fh = NFS_FH(inode), @@ -193,7 +192,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type) .pages = pages, }; struct nfs3_getaclres res = { - .fattr = &fattr, + 0 }; struct rpc_message msg = { .rpc_argp = &args, @@ -228,7 +227,10 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type) dprintk("NFS call getacl\n"); msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_GETACL]; - nfs_fattr_init(&fattr); + res.fattr = nfs_alloc_fattr(); + if (res.fattr == NULL) + return ERR_PTR(-ENOMEM); + status = rpc_call_sync(server->client_acl, &msg, 0); dprintk("NFS reply getacl: %d\n", status); @@ -238,7 +240,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type) switch (status) { case 0: - status = nfs_refresh_inode(inode, &fattr); + status = nfs_refresh_inode(inode, res.fattr); break; case -EPFNOSUPPORT: case -EPROTONOSUPPORT: @@ -278,6 +280,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type) getout: posix_acl_release(res.acl_access); posix_acl_release(res.acl_default); + nfs_free_fattr(res.fattr); if (status != 0) { posix_acl_release(acl); @@ -290,7 +293,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, struct posix_acl *dfacl) { struct nfs_server *server = NFS_SERVER(inode); - struct nfs_fattr fattr; + struct nfs_fattr *fattr; struct page *pages[NFSACL_MAXPAGES]; struct nfs3_setaclargs args = { .inode = inode, @@ -335,8 +338,13 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, } dprintk("NFS call setacl\n"); + status = -ENOMEM; + fattr = nfs_alloc_fattr(); + if (fattr == NULL) + goto out_freepages; + msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL]; - nfs_fattr_init(&fattr); + msg.rpc_resp = fattr; status = rpc_call_sync(server->client_acl, &msg, 0); nfs_access_zap_cache(inode); nfs_zap_acl_cache(inode); @@ -344,7 +352,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, switch (status) { case 0: - status = nfs_refresh_inode(inode, &fattr); + status = nfs_refresh_inode(inode, fattr); nfs3_cache_acls(inode, acl, dfacl); break; case -EPFNOSUPPORT: @@ -355,6 +363,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, case -ENOTSUPP: status = -EOPNOTSUPP; } + nfs_free_fattr(fattr); out_freepages: while (args.npages != 0) { args.npages--; -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 24/24] NFS: Prevent the mount code from looping forever on broken exports 2010-04-16 20:31 ` [PATCH 23/24] NFS: Reduce stack footprint of nfs3_proc_getacl() and nfs3_proc_setacl() Trond Myklebust @ 2010-04-16 20:31 ` Trond Myklebust 0 siblings, 0 replies; 29+ messages in thread From: Trond Myklebust @ 2010-04-16 20:31 UTC (permalink / raw) To: linux-nfs Keep a global count of how many referrals that the current task has traversed on a path lookup. Return ELOOP if the count exceeds MAX_NESTED_LINKS. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/super.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 73 insertions(+), 0 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index cb196eb..33f355f 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2672,6 +2672,72 @@ out_freepage: free_page((unsigned long)page); } +struct nfs_referral_count { + struct list_head list; + const struct task_struct *task; + unsigned int referral_count; +}; + +static LIST_HEAD(nfs_referral_count_list); +static DEFINE_SPINLOCK(nfs_referral_count_list_lock); + +static struct nfs_referral_count *nfs_find_referral_count(void) +{ + struct nfs_referral_count *p; + + list_for_each_entry(p, &nfs_referral_count_list, list) { + if (p->task == current) + return p; + } + return NULL; +} + +#define NFS_MAX_NESTED_REFERRALS 2 + +static int nfs_referral_loop_protect(void) +{ + struct nfs_referral_count *p, *new; + int ret = -ENOMEM; + + new = kmalloc(sizeof(*new), GFP_KERNEL); + if (!new) + goto out; + new->task = current; + new->referral_count = 1; + + ret = 0; + spin_lock(&nfs_referral_count_list_lock); + p = nfs_find_referral_count(); + if (p != NULL) { + if (p->referral_count >= NFS_MAX_NESTED_REFERRALS) + ret = -ELOOP; + else + p->referral_count++; + } else { + list_add(&new->list, &nfs_referral_count_list); + new = NULL; + } + spin_unlock(&nfs_referral_count_list_lock); + kfree(new); +out: + return ret; +} + +static void nfs_referral_loop_unprotect(void) +{ + struct nfs_referral_count *p; + + spin_lock(&nfs_referral_count_list_lock); + p = nfs_find_referral_count(); + p->referral_count--; + if (p->referral_count == 0) + list_del(&p->list); + else + p = NULL; + spin_unlock(&nfs_referral_count_list_lock); + kfree(p); +} + static int nfs_follow_remote_path(struct vfsmount *root_mnt, const char *export_path, struct vfsmount *mnt_target) { @@ -2689,9 +2755,14 @@ static int nfs_follow_remote_path(struct vfsmount *root_mnt, if (IS_ERR(ns_private)) goto out_mntput; + ret = nfs_referral_loop_protect(); + if (ret != 0) + goto out_put_mnt_ns; + ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt, export_path, LOOKUP_FOLLOW, nd); + nfs_referral_loop_unprotect(); put_mnt_ns(ns_private); if (ret != 0) @@ -2709,6 +2780,8 @@ static int nfs_follow_remote_path(struct vfsmount *root_mnt, kfree(nd); down_write(&s->s_umount); return 0; +out_put_mnt_ns: + put_mnt_ns(ns_private); out_mntput: mntput(root_mnt); out_err: -- 1.6.6.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH 08/24] NFSv4: Reduce stack footprint of nfs4_get_root() 2010-04-16 20:31 ` [PATCH 08/24] NFSv4: Reduce stack footprint of nfs4_get_root() Trond Myklebust 2010-04-16 20:31 ` [PATCH 09/24] NFSv4: Reduce the stack footprint of nfs4_remote_referral_get_sb Trond Myklebust @ 2010-04-19 21:03 ` Chuck Lever 1 sibling, 0 replies; 29+ messages in thread From: Chuck Lever @ 2010-04-19 21:03 UTC (permalink / raw) To: Trond Myklebust; +Cc: linux-nfs On 04/16/2010 04:31 PM, Trond Myklebust wrote: > Signed-off-by: Trond Myklebust<Trond.Myklebust@netapp.com> > --- > fs/nfs/getroot.c | 76 ++++++++++++++++++++++++++++++++--------------------- > 1 files changed, 46 insertions(+), 30 deletions(-) > > diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c > index ada369a..7428f7d 100644 > --- a/fs/nfs/getroot.c > +++ b/fs/nfs/getroot.c > @@ -78,46 +78,52 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh) > { > struct nfs_server *server = NFS_SB(sb); > struct nfs_fsinfo fsinfo; fsinfo is 48 bytes on 64-bit systems. Perhaps it's also a candidate for dynamic allocation? > - struct nfs_fattr fattr; > - struct dentry *mntroot; > + struct dentry *ret; > struct inode *inode; > int error; > > /* get the actual root for this mount */ NIT: this comment actually goes with the next paragraph, as it does in nfs4_get_root(). > - fsinfo.fattr =&fattr; > + fsinfo.fattr = nfs_alloc_fattr(); > + if (fsinfo.fattr == NULL) > + return ERR_PTR(-ENOMEM); > > error = server->nfs_client->rpc_ops->getroot(server, mntfh,&fsinfo); > if (error< 0) { > dprintk("nfs_get_root: getattr error = %d\n", -error); > - return ERR_PTR(error); > + ret = ERR_PTR(error); > + goto out; > } > > inode = nfs_fhget(sb, mntfh, fsinfo.fattr); > if (IS_ERR(inode)) { > dprintk("nfs_get_root: get root inode failed\n"); > - return ERR_CAST(inode); > + ret = ERR_CAST(inode); > + goto out; > } > > error = nfs_superblock_set_dummy_root(sb, inode); > - if (error != 0) > - return ERR_PTR(error); > + if (error != 0) { > + ret = ERR_PTR(error); > + goto out; > + } > > /* root dentries normally start off anonymous and get spliced in later > * if the dentry tree reaches them; however if the dentry already > * exists, we'll pick it up at this point and use it as the root > */ > - mntroot = d_obtain_alias(inode); > - if (IS_ERR(mntroot)) { > + ret = d_obtain_alias(inode); > + if (IS_ERR(ret)) { > dprintk("nfs_get_root: get root dentry failed\n"); > - return mntroot; > + goto out; > } > > - security_d_instantiate(mntroot, inode); > + security_d_instantiate(ret, inode); > > - if (!mntroot->d_op) > - mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops; > - > - return mntroot; > + if (ret->d_op == NULL) > + ret->d_op = server->nfs_client->rpc_ops->dentry_ops; > +out: > + nfs_free_fattr(fsinfo.fattr); > + return ret; > } > > #ifdef CONFIG_NFS_V4 > @@ -168,8 +174,8 @@ out: > struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh) > { > struct nfs_server *server = NFS_SB(sb); > - struct nfs_fattr fattr; > - struct dentry *mntroot; > + struct nfs_fattr *fattr = NULL; > + struct dentry *ret; > struct inode *inode; > int error; > > @@ -183,40 +189,50 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh) > return ERR_PTR(error); > } > > + fattr = nfs_alloc_fattr(); > + if (fattr == NULL) > + return ERR_PTR(-ENOMEM);; > + > /* get the actual root for this mount */ > - error = server->nfs_client->rpc_ops->getattr(server, mntfh,&fattr); > + error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr); > if (error< 0) { > dprintk("nfs_get_root: getattr error = %d\n", -error); > - return ERR_PTR(error); > + ret = ERR_PTR(error); > + goto out; > } > > - inode = nfs_fhget(sb, mntfh,&fattr); > + inode = nfs_fhget(sb, mntfh, fattr); > if (IS_ERR(inode)) { > dprintk("nfs_get_root: get root inode failed\n"); > - return ERR_CAST(inode); > + ret = ERR_CAST(inode); > + goto out; > } > > error = nfs_superblock_set_dummy_root(sb, inode); > - if (error != 0) > - return ERR_PTR(error); > + if (error != 0) { > + ret = ERR_PTR(error); > + goto out; > + } > > /* root dentries normally start off anonymous and get spliced in later > * if the dentry tree reaches them; however if the dentry already > * exists, we'll pick it up at this point and use it as the root > */ > - mntroot = d_obtain_alias(inode); > - if (IS_ERR(mntroot)) { > + ret = d_obtain_alias(inode); > + if (IS_ERR(ret)) { > dprintk("nfs_get_root: get root dentry failed\n"); > - return mntroot; > + goto out; > } > > - security_d_instantiate(mntroot, inode); > + security_d_instantiate(ret, inode); > > - if (!mntroot->d_op) > - mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops; > + if (ret->d_op == NULL) > + ret->d_op = server->nfs_client->rpc_ops->dentry_ops; > > +out: > + nfs_free_fattr(fattr); > dprintk("<-- nfs4_get_root()\n"); > - return mntroot; > + return ret; > } > > #endif /* CONFIG_NFS_V4 */ -- chuck[dot]lever[at]oracle[dot]com ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 00/24] Reduce the stack foot print of the NFS client 2010-04-16 20:30 [PATCH 00/24] Reduce the stack foot print of the NFS client Trond Myklebust 2010-04-16 20:30 ` [PATCH 01/24] NFS: Add helper functions for allocating filehandles and fattr structs Trond Myklebust @ 2010-04-19 21:43 ` Chuck Lever 2010-04-19 23:29 ` Trond Myklebust 1 sibling, 1 reply; 29+ messages in thread From: Chuck Lever @ 2010-04-19 21:43 UTC (permalink / raw) To: Trond Myklebust; +Cc: linux-nfs On 04/16/2010 04:30 PM, Trond Myklebust wrote: > The following patch series aims to significantly reduce the stack foot > print of the NFS client by dynamically allocating the struct nfs_fattr > and struct nfs_fh. Random comments: 1. There's an open-coded kzalloc of an nfs_fh in nfs_get_sb. This can be replaced with nfs_alloc_fh(). 2. root_nfs_get_handle allocates an nfs_fh on the stack. This can be replaced with nfs_alloc_fh(). 3. There is an unneeded nfs_fattr_init() call in nfs_probe_fsinfo(). I didn't look for others that are similarly made obsolete. 4. Where ever you have "if (fattr == NULL) goto out;" (and similarly for filehandles) you could add "unlikely()" to improve branch prediction slightly. 5. The documenting comment before nfs_do_refmount() is out of date. > Cheers > Trond > > Trond Myklebust (24): > NFS: Add helper functions for allocating filehandles and fattr > structs > NFSv4: Eliminate nfs4_path_walk() > NFS: Reduce the stack footprint of nfs_follow_mountpoint() > NFS: Reduce the stack footprint of nfs_create_server > NFSv4: Reduce the stack footprint of try_location() > NFS: Reduce the stack footprint of nfs_lookup > NFS: Reduce the stack footprint of nfs_follow_remote_path() > NFSv4: Reduce stack footprint of nfs4_get_root() > NFSv4: Reduce the stack footprint of nfs4_remote_referral_get_sb > NFSv4: Reduce stack footprint of nfs4_proc_access() and > nfs3_proc_access() > NFS: Reduce stack footprint of nfs_revalidate_inode() > NFS: Reduce stack footprint of nfs3_proc_rename() and > nfs4_proc_rename() > NFS: Reduce stack footprint of nfs_readdir() > NFS: Reduce the stack footprint of nfs_link() > NFS: Reduce stack footprint of nfs3_proc_readlink() > NFS: Reduce stack footprint of nfs_proc_remove() > NFS: Reduce the stack footprint of nfs_rmdir > NFS: Reduce the stack footprint of nfs_proc_create > NFS: Reduce the stack footprint of nfs_proc_symlink() > NFS: Reduce stack footprint of nfs4_proc_create() > NFS: Reduce stack footprint of nfs_setattr() > NFS: Reduce stack footprint of nfs_statfs() > NFS: Reduce stack footprint of nfs3_proc_getacl() and > nfs3_proc_setacl() > NFS: Prevent the mount code from looping forever on broken exports > > fs/nfs/client.c | 54 ++++++++++--- > fs/nfs/dir.c | 62 +++++++++++---- > fs/nfs/getroot.c | 191 +++++++++++++++++------------------------------ > fs/nfs/inode.c | 46 ++++++++++-- > fs/nfs/internal.h | 4 +- > fs/nfs/namespace.c | 20 ++++-- > fs/nfs/nfs3acl.c | 23 ++++-- > fs/nfs/nfs3proc.c | 128 +++++++++++++++++++------------ > fs/nfs/nfs3xdr.c | 2 +- > fs/nfs/nfs4namespace.c | 10 ++- > fs/nfs/nfs4proc.c | 81 ++++++++++++-------- > fs/nfs/nfs4xdr.c | 2 +- > fs/nfs/proc.c | 144 ++++++++++++++++++++--------------- > fs/nfs/super.c | 121 ++++++++++++++++++++++++++---- > fs/nfs/unlink.c | 4 +- > include/linux/nfs_fs.h | 14 ++++ > include/linux/nfs_xdr.h | 2 +- > 17 files changed, 566 insertions(+), 342 deletions(-) > > -- > To unsubscribe from this list: send the line "unsubscribe linux-nfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- chuck[dot]lever[at]oracle[dot]com ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 00/24] Reduce the stack foot print of the NFS client 2010-04-19 21:43 ` [PATCH 00/24] Reduce the stack foot print of the NFS client Chuck Lever @ 2010-04-19 23:29 ` Trond Myklebust [not found] ` <1271719778.25129.73.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org> 0 siblings, 1 reply; 29+ messages in thread From: Trond Myklebust @ 2010-04-19 23:29 UTC (permalink / raw) To: Chuck Lever; +Cc: linux-nfs On Mon, 2010-04-19 at 17:43 -0400, Chuck Lever wrote: > On 04/16/2010 04:30 PM, Trond Myklebust wrote: > > The following patch series aims to significantly reduce the stack foot > > print of the NFS client by dynamically allocating the struct nfs_fattr > > and struct nfs_fh. > > Random comments: > > 1. There's an open-coded kzalloc of an nfs_fh in nfs_get_sb. This can > be replaced with nfs_alloc_fh(). Added a clean up patch to do this. > 2. root_nfs_get_handle allocates an nfs_fh on the stack. This can be > replaced with nfs_alloc_fh(). I suppose, although there will never be any danger of anyone calling this function from any unexpected contexts. Anyhow, added a patch. > 3. There is an unneeded nfs_fattr_init() call in nfs_probe_fsinfo(). I > didn't look for others that are similarly made obsolete. Fixed. > 4. Where ever you have "if (fattr == NULL) goto out;" (and similarly > for filehandles) you could add "unlikely()" to improve branch prediction > slightly. No. While I agree that it is unlikely to fail, I prefer _not_ to have to wade through all these likely()/unlikely() markups in order to read the code. A quick perusal of other examples shows that I'm not alone in that preference. > 5. The documenting comment before nfs_do_refmount() is out of date. Fixed. Cheers Trond ^ permalink raw reply [flat|nested] 29+ messages in thread
[parent not found: <1271719778.25129.73.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>]
* Re: [PATCH 00/24] Reduce the stack foot print of the NFS client [not found] ` <1271719778.25129.73.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org> @ 2010-04-19 23:37 ` Chuck Lever 0 siblings, 0 replies; 29+ messages in thread From: Chuck Lever @ 2010-04-19 23:37 UTC (permalink / raw) To: Trond Myklebust; +Cc: linux-nfs On 04/19/2010 07:29 PM, Trond Myklebust wrote: > On Mon, 2010-04-19 at 17:43 -0400, Chuck Lever wrote: >> On 04/16/2010 04:30 PM, Trond Myklebust wrote: >>> The following patch series aims to significantly reduce the stack foot >>> print of the NFS client by dynamically allocating the struct nfs_fattr >>> and struct nfs_fh. >> >> Random comments: >> >> 1. There's an open-coded kzalloc of an nfs_fh in nfs_get_sb. This can >> be replaced with nfs_alloc_fh(). > > Added a clean up patch to do this. > >> 2. root_nfs_get_handle allocates an nfs_fh on the stack. This can be >> replaced with nfs_alloc_fh(). > > I suppose, although there will never be any danger of anyone calling > this function from any unexpected contexts. Anyhow, added a patch. > >> 3. There is an unneeded nfs_fattr_init() call in nfs_probe_fsinfo(). I >> didn't look for others that are similarly made obsolete. > > Fixed. > >> 4. Where ever you have "if (fattr == NULL) goto out;" (and similarly >> for filehandles) you could add "unlikely()" to improve branch prediction >> slightly. > > No. While I agree that it is unlikely to fail, I prefer _not_ to have to > wade through all these likely()/unlikely() markups in order to read the > code. A quick perusal of other examples shows that I'm not alone in that > preference. > >> 5. The documenting comment before nfs_do_refmount() is out of date. > > Fixed. I forgot to add this in my reply to the cover letter of the original series: Reviewed-by: Chuck Lever <chuck.lever@oracle.com> and/or Tested-by: Chuck Lever <chuck.lever@oracle.com> -- chuck[dot]lever[at]oracle[dot]com ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2010-04-19 23:39 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-16 20:30 [PATCH 00/24] Reduce the stack foot print of the NFS client Trond Myklebust
2010-04-16 20:30 ` [PATCH 01/24] NFS: Add helper functions for allocating filehandles and fattr structs Trond Myklebust
2010-04-16 20:31 ` [PATCH 02/24] NFSv4: Eliminate nfs4_path_walk() Trond Myklebust
2010-04-16 20:31 ` [PATCH 03/24] NFS: Reduce the stack footprint of nfs_follow_mountpoint() Trond Myklebust
2010-04-16 20:31 ` [PATCH 04/24] NFS: Reduce the stack footprint of nfs_create_server Trond Myklebust
2010-04-16 20:31 ` [PATCH 05/24] NFSv4: Reduce the stack footprint of try_location() Trond Myklebust
2010-04-16 20:31 ` [PATCH 06/24] NFS: Reduce the stack footprint of nfs_lookup Trond Myklebust
2010-04-16 20:31 ` [PATCH 07/24] NFS: Reduce the stack footprint of nfs_follow_remote_path() Trond Myklebust
2010-04-16 20:31 ` [PATCH 08/24] NFSv4: Reduce stack footprint of nfs4_get_root() Trond Myklebust
2010-04-16 20:31 ` [PATCH 09/24] NFSv4: Reduce the stack footprint of nfs4_remote_referral_get_sb Trond Myklebust
2010-04-16 20:31 ` [PATCH 10/24] NFSv4: Reduce stack footprint of nfs4_proc_access() and nfs3_proc_access() Trond Myklebust
2010-04-16 20:31 ` [PATCH 11/24] NFS: Reduce stack footprint of nfs_revalidate_inode() Trond Myklebust
2010-04-16 20:31 ` [PATCH 12/24] NFS: Reduce stack footprint of nfs3_proc_rename() and nfs4_proc_rename() Trond Myklebust
2010-04-16 20:31 ` [PATCH 13/24] NFS: Reduce stack footprint of nfs_readdir() Trond Myklebust
2010-04-16 20:31 ` [PATCH 14/24] NFS: Reduce the stack footprint of nfs_link() Trond Myklebust
2010-04-16 20:31 ` [PATCH 15/24] NFS: Reduce stack footprint of nfs3_proc_readlink() Trond Myklebust
2010-04-16 20:31 ` [PATCH 16/24] NFS: Reduce stack footprint of nfs_proc_remove() Trond Myklebust
2010-04-16 20:31 ` [PATCH 17/24] NFS: Reduce the stack footprint of nfs_rmdir Trond Myklebust
2010-04-16 20:31 ` [PATCH 18/24] NFS: Reduce the stack footprint of nfs_proc_create Trond Myklebust
2010-04-16 20:31 ` [PATCH 19/24] NFS: Reduce the stack footprint of nfs_proc_symlink() Trond Myklebust
2010-04-16 20:31 ` [PATCH 20/24] NFS: Reduce stack footprint of nfs4_proc_create() Trond Myklebust
2010-04-16 20:31 ` [PATCH 21/24] NFS: Reduce stack footprint of nfs_setattr() Trond Myklebust
2010-04-16 20:31 ` [PATCH 22/24] NFS: Reduce stack footprint of nfs_statfs() Trond Myklebust
2010-04-16 20:31 ` [PATCH 23/24] NFS: Reduce stack footprint of nfs3_proc_getacl() and nfs3_proc_setacl() Trond Myklebust
2010-04-16 20:31 ` [PATCH 24/24] NFS: Prevent the mount code from looping forever on broken exports Trond Myklebust
2010-04-19 21:03 ` [PATCH 08/24] NFSv4: Reduce stack footprint of nfs4_get_root() Chuck Lever
2010-04-19 21:43 ` [PATCH 00/24] Reduce the stack foot print of the NFS client Chuck Lever
2010-04-19 23:29 ` Trond Myklebust
[not found] ` <1271719778.25129.73.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2010-04-19 23:37 ` Chuck Lever
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox