diff options
| author | Neil Brown <neilb@suse.de> | 2006-01-06 03:19:59 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:59 -0500 |
| commit | 9f708e40fe040e79f6c393a282f0701c9f8dc174 (patch) | |
| tree | e769b7b9088f03caf324923485ee1e5ef05e2292 /fs | |
| parent | a334de28665b14f0a33df82699fa9a78cfeedf31 (diff) | |
[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')
| -rw-r--r-- | fs/nfsd/vfs.c | 20 |
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: | |||
| 880 | return err; | 880 | return err; |
| 881 | } | 881 | } |
| 882 | 882 | ||
| 883 | static void kill_suid(struct dentry *dentry) | ||
| 884 | { | ||
| 885 | struct iattr ia; | ||
| 886 | ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID; | ||
| 887 | |||
| 888 | down(&dentry->d_inode->i_sem); | ||
| 889 | notify_change(dentry, &ia); | ||
| 890 | up(&dentry->d_inode->i_sem); | ||
| 891 | } | ||
| 892 | |||
| 883 | static inline int | 893 | static inline int |
| 884 | nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | 894 | nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, |
| 885 | loff_t offset, struct kvec *vec, int vlen, | 895 | 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, | |||
| 933 | } | 943 | } |
| 934 | 944 | ||
| 935 | /* clear setuid/setgid flag after write */ | 945 | /* clear setuid/setgid flag after write */ |
| 936 | if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) { | 946 | if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) |
| 937 | struct iattr ia; | 947 | kill_suid(dentry); |
| 938 | ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID; | ||
| 939 | |||
| 940 | down(&inode->i_sem); | ||
| 941 | notify_change(dentry, &ia); | ||
| 942 | up(&inode->i_sem); | ||
| 943 | } | ||
| 944 | 948 | ||
| 945 | if (err >= 0 && stable) { | 949 | if (err >= 0 && stable) { |
| 946 | static ino_t last_ino; | 950 | static ino_t last_ino; |
