aboutsummaryrefslogtreecommitdiffstats
path: root/fs/stat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/stat.c')
-rw-r--r--fs/stat.c105
1 files changed, 42 insertions, 63 deletions
diff --git a/fs/stat.c b/fs/stat.c
index 54711662b855..075694e31d8b 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -55,46 +55,6 @@ int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
55 55
56EXPORT_SYMBOL(vfs_getattr); 56EXPORT_SYMBOL(vfs_getattr);
57 57
58int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
59{
60 struct path path;
61 int error;
62
63 error = user_path_at(dfd, name, LOOKUP_FOLLOW, &path);
64 if (!error) {
65 error = vfs_getattr(path.mnt, path.dentry, stat);
66 path_put(&path);
67 }
68 return error;
69}
70
71int vfs_stat(char __user *name, struct kstat *stat)
72{
73 return vfs_stat_fd(AT_FDCWD, name, stat);
74}
75
76EXPORT_SYMBOL(vfs_stat);
77
78int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat)
79{
80 struct path path;
81 int error;
82
83 error = user_path_at(dfd, name, 0, &path);
84 if (!error) {
85 error = vfs_getattr(path.mnt, path.dentry, stat);
86 path_put(&path);
87 }
88 return error;
89}
90
91int vfs_lstat(char __user *name, struct kstat *stat)
92{
93 return vfs_lstat_fd(AT_FDCWD, name, stat);
94}
95
96EXPORT_SYMBOL(vfs_lstat);
97
98int vfs_fstat(unsigned int fd, struct kstat *stat) 58int vfs_fstat(unsigned int fd, struct kstat *stat)
99{ 59{
100 struct file *f = fget(fd); 60 struct file *f = fget(fd);
@@ -106,26 +66,43 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
106 } 66 }
107 return error; 67 return error;
108} 68}
109
110EXPORT_SYMBOL(vfs_fstat); 69EXPORT_SYMBOL(vfs_fstat);
111 70
112int vfs_fstatat(int dfd, char __user *filename, struct kstat *stat, int flag) 71int vfs_fstatat(int dfd, char __user *filename, struct kstat *stat, int flag)
113{ 72{
73 struct path path;
114 int error = -EINVAL; 74 int error = -EINVAL;
75 int lookup_flags = 0;
115 76
116 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) 77 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
117 goto out; 78 goto out;
118 79
119 if (flag & AT_SYMLINK_NOFOLLOW) 80 if (!(flag & AT_SYMLINK_NOFOLLOW))
120 error = vfs_lstat_fd(dfd, filename, stat); 81 lookup_flags |= LOOKUP_FOLLOW;
121 else 82
122 error = vfs_stat_fd(dfd, filename, stat); 83 error = user_path_at(dfd, filename, lookup_flags, &path);
84 if (error)
85 goto out;
86
87 error = vfs_getattr(path.mnt, path.dentry, stat);
88 path_put(&path);
123out: 89out:
124 return error; 90 return error;
125} 91}
126
127EXPORT_SYMBOL(vfs_fstatat); 92EXPORT_SYMBOL(vfs_fstatat);
128 93
94int vfs_stat(char __user *name, struct kstat *stat)
95{
96 return vfs_fstatat(AT_FDCWD, name, stat, 0);
97}
98EXPORT_SYMBOL(vfs_stat);
99
100int vfs_lstat(char __user *name, struct kstat *stat)
101{
102 return vfs_fstatat(AT_FDCWD, name, stat, AT_SYMLINK_NOFOLLOW);
103}
104EXPORT_SYMBOL(vfs_lstat);
105
129 106
130#ifdef __ARCH_WANT_OLD_STAT 107#ifdef __ARCH_WANT_OLD_STAT
131 108
@@ -173,23 +150,25 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta
173SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) 150SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
174{ 151{
175 struct kstat stat; 152 struct kstat stat;
176 int error = vfs_stat_fd(AT_FDCWD, filename, &stat); 153 int error;
177 154
178 if (!error) 155 error = vfs_stat(filename, &stat);
179 error = cp_old_stat(&stat, statbuf); 156 if (error)
157 return error;
180 158
181 return error; 159 return cp_old_stat(&stat, statbuf);
182} 160}
183 161
184SYSCALL_DEFINE2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) 162SYSCALL_DEFINE2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
185{ 163{
186 struct kstat stat; 164 struct kstat stat;
187 int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); 165 int error;
188 166
189 if (!error) 167 error = vfs_lstat(filename, &stat);
190 error = cp_old_stat(&stat, statbuf); 168 if (error)
169 return error;
191 170
192 return error; 171 return cp_old_stat(&stat, statbuf);
193} 172}
194 173
195SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf) 174SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)
@@ -258,23 +237,23 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
258SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf) 237SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf)
259{ 238{
260 struct kstat stat; 239 struct kstat stat;
261 int error = vfs_stat_fd(AT_FDCWD, filename, &stat); 240 int error = vfs_stat(filename, &stat);
262
263 if (!error)
264 error = cp_new_stat(&stat, statbuf);
265 241
266 return error; 242 if (error)
243 return error;
244 return cp_new_stat(&stat, statbuf);
267} 245}
268 246
269SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf) 247SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf)
270{ 248{
271 struct kstat stat; 249 struct kstat stat;
272 int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); 250 int error;
273 251
274 if (!error) 252 error = vfs_lstat(filename, &stat);
275 error = cp_new_stat(&stat, statbuf); 253 if (error)
254 return error;
276 255
277 return error; 256 return cp_new_stat(&stat, statbuf);
278} 257}
279 258
280#if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) 259#if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)