aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Drokin <green@linuxhacker.ru>2009-04-08 12:05:42 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2009-04-20 23:02:51 -0400
commit0112fc2229847feb6c4eb011e6833d8f1742a375 (patch)
treec5bda0b4f5a5f942478faf2fb5961df7fbd15546
parentfd56d242b3b80b6f2ca174272b20029aae61df75 (diff)
Separate out common fstatat code into vfs_fstatat
This is a version incorporating Christoph's suggestion. Separate out common *fstatat functionality into a single function instead of duplicating it all over the code. Signed-off-by: Oleg Drokin <green@linuxhacker.ru> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c19
-rw-r--r--arch/s390/kernel/compat_linux.c18
-rw-r--r--arch/sparc/kernel/sys_sparc32.c19
-rw-r--r--arch/x86/ia32/sys_ia32.c19
-rw-r--r--fs/compat.c19
-rw-r--r--fs/stat.c56
-rw-r--r--include/linux/fs.h1
7 files changed, 54 insertions, 97 deletions
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index e04173c7e62..d59a0cd537f 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -177,21 +177,12 @@ asmlinkage long sys_oabi_fstatat64(int dfd,
177 int flag) 177 int flag)
178{ 178{
179 struct kstat stat; 179 struct kstat stat;
180 int error = -EINVAL; 180 int error;
181 181
182 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) 182 error = vfs_fstatat(dfd, filename, &stat, flag);
183 goto out; 183 if (error)
184 184 return error;
185 if (flag & AT_SYMLINK_NOFOLLOW) 185 return cp_oldabi_stat64(&stat, statbuf);
186 error = vfs_lstat_fd(dfd, filename, &stat);
187 else
188 error = vfs_stat_fd(dfd, filename, &stat);
189
190 if (!error)
191 error = cp_oldabi_stat64(&stat, statbuf);
192
193out:
194 return error;
195} 186}
196 187
197struct oabi_flock64 { 188struct oabi_flock64 {
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 6cc87d8c868..002c70d3cb7 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -702,20 +702,12 @@ asmlinkage long sys32_fstatat64(unsigned int dfd, char __user *filename,
702 struct stat64_emu31 __user* statbuf, int flag) 702 struct stat64_emu31 __user* statbuf, int flag)
703{ 703{
704 struct kstat stat; 704 struct kstat stat;
705 int error = -EINVAL; 705 int error;
706
707 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
708 goto out;
709
710 if (flag & AT_SYMLINK_NOFOLLOW)
711 error = vfs_lstat_fd(dfd, filename, &stat);
712 else
713 error = vfs_stat_fd(dfd, filename, &stat);
714 706
715 if (!error) 707 error = vfs_fstatat(dfd, filename, &stat, flag);
716 error = cp_stat64(statbuf, &stat); 708 if (error)
717out: 709 return error;
718 return error; 710 return cp_stat64(statbuf, &stat);
719} 711}
720 712
721/* 713/*
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c
index e800503879e..f5000a460c0 100644
--- a/arch/sparc/kernel/sys_sparc32.c
+++ b/arch/sparc/kernel/sys_sparc32.c
@@ -206,21 +206,12 @@ asmlinkage long compat_sys_fstatat64(unsigned int dfd, char __user *filename,
206 struct compat_stat64 __user * statbuf, int flag) 206 struct compat_stat64 __user * statbuf, int flag)
207{ 207{
208 struct kstat stat; 208 struct kstat stat;
209 int error = -EINVAL; 209 int error;
210
211 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
212 goto out;
213
214 if (flag & AT_SYMLINK_NOFOLLOW)
215 error = vfs_lstat_fd(dfd, filename, &stat);
216 else
217 error = vfs_stat_fd(dfd, filename, &stat);
218
219 if (!error)
220 error = cp_compat_stat64(&stat, statbuf);
221 210
222out: 211 error = vfs_fstatat(dfd, filename, &stat, flag);
223 return error; 212 if (error)
213 return error;
214 return cp_compat_stat64(&stat, statbuf);
224} 215}
225 216
226asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2) 217asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2)
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index efac92fd1ef..085a8c35f14 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -129,21 +129,12 @@ asmlinkage long sys32_fstatat(unsigned int dfd, char __user *filename,
129 struct stat64 __user *statbuf, int flag) 129 struct stat64 __user *statbuf, int flag)
130{ 130{
131 struct kstat stat; 131 struct kstat stat;
132 int error = -EINVAL; 132 int error;
133 133
134 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) 134 error = vfs_fstatat(dfd, filename, &stat, flag);
135 goto out; 135 if (error)
136 136 return error;
137 if (flag & AT_SYMLINK_NOFOLLOW) 137 return cp_stat64(statbuf, &stat);
138 error = vfs_lstat_fd(dfd, filename, &stat);
139 else
140 error = vfs_stat_fd(dfd, filename, &stat);
141
142 if (!error)
143 error = cp_stat64(statbuf, &stat);
144
145out:
146 return error;
147} 138}
148 139
149/* 140/*
diff --git a/fs/compat.c b/fs/compat.c
index 3f84d5f1588..dda72e26709 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -204,21 +204,12 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename,
204 struct compat_stat __user *statbuf, int flag) 204 struct compat_stat __user *statbuf, int flag)
205{ 205{
206 struct kstat stat; 206 struct kstat stat;
207 int error = -EINVAL; 207 int error;
208
209 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
210 goto out;
211
212 if (flag & AT_SYMLINK_NOFOLLOW)
213 error = vfs_lstat_fd(dfd, filename, &stat);
214 else
215 error = vfs_stat_fd(dfd, filename, &stat);
216
217 if (!error)
218 error = cp_compat_stat(&stat, statbuf);
219 208
220out: 209 error = vfs_fstatat(dfd, filename, &stat, flag);
221 return error; 210 if (error)
211 return error;
212 return cp_compat_stat(&stat, statbuf);
222} 213}
223#endif 214#endif
224 215
diff --git a/fs/stat.c b/fs/stat.c
index 2db740a0cfb..54711662b85 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -109,6 +109,24 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
109 109
110EXPORT_SYMBOL(vfs_fstat); 110EXPORT_SYMBOL(vfs_fstat);
111 111
112int vfs_fstatat(int dfd, char __user *filename, struct kstat *stat, int flag)
113{
114 int error = -EINVAL;
115
116 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
117 goto out;
118
119 if (flag & AT_SYMLINK_NOFOLLOW)
120 error = vfs_lstat_fd(dfd, filename, stat);
121 else
122 error = vfs_stat_fd(dfd, filename, stat);
123out:
124 return error;
125}
126
127EXPORT_SYMBOL(vfs_fstatat);
128
129
112#ifdef __ARCH_WANT_OLD_STAT 130#ifdef __ARCH_WANT_OLD_STAT
113 131
114/* 132/*
@@ -264,21 +282,12 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, char __user *, filename,
264 struct stat __user *, statbuf, int, flag) 282 struct stat __user *, statbuf, int, flag)
265{ 283{
266 struct kstat stat; 284 struct kstat stat;
267 int error = -EINVAL; 285 int error;
268
269 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
270 goto out;
271
272 if (flag & AT_SYMLINK_NOFOLLOW)
273 error = vfs_lstat_fd(dfd, filename, &stat);
274 else
275 error = vfs_stat_fd(dfd, filename, &stat);
276
277 if (!error)
278 error = cp_new_stat(&stat, statbuf);
279 286
280out: 287 error = vfs_fstatat(dfd, filename, &stat, flag);
281 return error; 288 if (error)
289 return error;
290 return cp_new_stat(&stat, statbuf);
282} 291}
283#endif 292#endif
284 293
@@ -404,21 +413,12 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, char __user *, filename,
404 struct stat64 __user *, statbuf, int, flag) 413 struct stat64 __user *, statbuf, int, flag)
405{ 414{
406 struct kstat stat; 415 struct kstat stat;
407 int error = -EINVAL; 416 int error;
408
409 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
410 goto out;
411
412 if (flag & AT_SYMLINK_NOFOLLOW)
413 error = vfs_lstat_fd(dfd, filename, &stat);
414 else
415 error = vfs_stat_fd(dfd, filename, &stat);
416
417 if (!error)
418 error = cp_new_stat64(&stat, statbuf);
419 417
420out: 418 error = vfs_fstatat(dfd, filename, &stat, flag);
421 return error; 419 if (error)
420 return error;
421 return cp_new_stat64(&stat, statbuf);
422} 422}
423#endif /* __ARCH_WANT_STAT64 */ 423#endif /* __ARCH_WANT_STAT64 */
424 424
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e766be0d432..257f4d37ad2 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2302,6 +2302,7 @@ extern int vfs_lstat(char __user *, struct kstat *);
2302extern int vfs_stat_fd(int dfd, char __user *, struct kstat *); 2302extern int vfs_stat_fd(int dfd, char __user *, struct kstat *);
2303extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *); 2303extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *);
2304extern int vfs_fstat(unsigned int, struct kstat *); 2304extern int vfs_fstat(unsigned int, struct kstat *);
2305extern int vfs_fstatat(int , char __user *, struct kstat *, int);
2305 2306
2306extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, 2307extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
2307 unsigned long arg); 2308 unsigned long arg);