summaryrefslogtreecommitdiff
path: root/fs/nfsd
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2006-01-06 00:19:59 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 08:33:59 -0800
commit9f708e40fe040e79f6c393a282f0701c9f8dc174 (patch)
treee769b7b9088f03caf324923485ee1e5ef05e2292 /fs/nfsd
parenta334de28665b14f0a33df82699fa9a78cfeedf31 (diff)
downloadlwn-9f708e40fe040e79f6c393a282f0701c9f8dc174.tar.gz
lwn-9f708e40fe040e79f6c393a282f0701c9f8dc174.zip
[PATCH] knfsd: reduce stack consumption
A typical nfsd call trace is nfsd -> svc_process -> nfsd_dispatch -> nfsd3_proc_write -> nfsd_write ->nfsd_vfs_write -> vfs_writev These add up to over 300 bytes on the stack. Looking at each of these, I see that nfsd_write (which includes nfsd_vfs_write) contributes 0x8c to stack usage itself!! It turns out this is because it puts a 'struct iattr' on the stack so it can kill suid if needed. The following patch saves about 50 bytes off the stack in this call path. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/vfs.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index f83ab4cf4265..df4019f04560 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -880,6 +880,16 @@ out:
return err;
}
+static void kill_suid(struct dentry *dentry)
+{
+ struct iattr ia;
+ ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
+
+ down(&dentry->d_inode->i_sem);
+ notify_change(dentry, &ia);
+ up(&dentry->d_inode->i_sem);
+}
+
static inline int
nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
loff_t offset, struct kvec *vec, int vlen,
@@ -933,14 +943,8 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
}
/* clear setuid/setgid flag after write */
- if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) {
- struct iattr ia;
- ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
-
- down(&inode->i_sem);
- notify_change(dentry, &ia);
- up(&inode->i_sem);
- }
+ if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
+ kill_suid(dentry);
if (err >= 0 && stable) {
static ino_t last_ino;