From: Oleg Drokin <green@linuxhacker.ru>
To: linux-fsdevel@vger.kernel.org
Subject: Attempt at "stat light" implementation
Date: Tue, 7 Apr 2009 10:23:56 +0400 [thread overview]
Message-ID: <20090407062356.GA1336463@fiona.linuxhacker.ru> (raw)
[-- Attachment #1: Type: text/plain, Size: 1151 bytes --]
Hello!
Just as we discussed earlier today, here is a simple version that should do everything we need.
I have separated stat fields into arbitrary categories based on my idea of how this needs to be done,
that could of course be refined in other ways if desired.
Only x86* syscall tables updated for now and no 64bit syscalls (probably we don't need them anyway, just
need to always return 64 bit structure).
I quickly realized that perhaps we can use just one extra syscall for fstat, and stat/lstat could be
implemented as statat with just current cwd, though I do not know how desirable that is.
Also I though that it would be kind of useful to allow the bitmask to be compatible with existing statat
flags usage so that we do not need a new statat.
Also perhaps the ->getattr just needs a prototype change to accept the flags argument and if the FS cares
about it - to use it, but I did not want to do this huge patch touching every FS right now if only to save
my time should this approach to be determined as undesirable for one reason or another, so
for now I add a ->getattr_light
Any comments?
Bye,
Oleg
[-- Attachment #2: stat_light.diff --]
[-- Type: text/plain, Size: 11379 bytes --]
--- ./arch/x86/ia32/ia32entry.S.orig 2009-04-07 01:49:27.000000000 -0400
+++ ./arch/x86/ia32/ia32entry.S 2009-04-07 01:52:44.000000000 -0400
@@ -828,4 +828,7 @@
.quad sys_dup3 /* 330 */
.quad sys_pipe2
.quad sys_inotify_init1
+ .quad sys_fstatlight
+ .quad sys_lstatlight
+ .quad sys_statlight
ia32_syscall_end:
--- ./arch/x86/include/asm/unistd_32.h.orig 2009-04-07 01:26:02.000000000 -0400
+++ ./arch/x86/include/asm/unistd_32.h 2009-04-07 01:38:39.000000000 -0400
@@ -338,6 +338,9 @@
#define __NR_dup3 330
#define __NR_pipe2 331
#define __NR_inotify_init1 332
+#define __NR_fstat_light 333
+#define __NR_lstat_light 334
+#define __NR_stat_light 335
#ifdef __KERNEL__
--- ./arch/x86/include/asm/unistd_64.h.orig 2009-04-07 01:26:12.000000000 -0400
+++ ./arch/x86/include/asm/unistd_64.h 2009-04-07 01:53:40.000000000 -0400
@@ -653,7 +653,12 @@
__SYSCALL(__NR_pipe2, sys_pipe2)
#define __NR_inotify_init1 294
__SYSCALL(__NR_inotify_init1, sys_inotify_init1)
-
+#define __NR_fstat_light 295
+__SYSCALL(__NR_fstat_light, sys_fstatlight)
+#define __NR_lstat_light 296
+__SYSCALL(__NR_lstat_light, sys_lstatlight)
+#define __NR_stat_light 297
+__SYSCALL(__NR_inotify_init1, sys_statlight)
#ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR
--- ./fs/stat.c.orig 2009-04-07 00:23:22.000000000 -0400
+++ ./fs/stat.c 2009-04-07 01:51:49.000000000 -0400
@@ -37,7 +37,8 @@
EXPORT_SYMBOL(generic_fillattr);
-int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat,
+ unsigned int flags)
{
struct inode *inode = dentry->d_inode;
int retval;
@@ -46,6 +47,9 @@
if (retval)
return retval;
+ if (inode->i_op->getattr_light)
+ return inode->i_op->getattr_light(mnt, dentry, stat, flags);
+
if (inode->i_op->getattr)
return inode->i_op->getattr(mnt, dentry, stat);
@@ -55,53 +59,56 @@
EXPORT_SYMBOL(vfs_getattr);
-int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
+int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat,
+ unsigned int flags)
{
struct path path;
int error;
error = user_path_at(dfd, name, LOOKUP_FOLLOW, &path);
if (!error) {
- error = vfs_getattr(path.mnt, path.dentry, stat);
+ error = vfs_getattr(path.mnt, path.dentry, stat, flags);
path_put(&path);
}
return error;
}
-int vfs_stat(char __user *name, struct kstat *stat)
+int vfs_stat(char __user *name, struct kstat *stat, unsigned int flags)
{
- return vfs_stat_fd(AT_FDCWD, name, stat);
+ return vfs_stat_fd(AT_FDCWD, name, stat, flags);
}
EXPORT_SYMBOL(vfs_stat);
-int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat)
+int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat,
+ unsigned int flags)
{
struct path path;
int error;
error = user_path_at(dfd, name, 0, &path);
if (!error) {
- error = vfs_getattr(path.mnt, path.dentry, stat);
+ error = vfs_getattr(path.mnt, path.dentry, stat, flags);
path_put(&path);
}
return error;
}
-int vfs_lstat(char __user *name, struct kstat *stat)
+int vfs_lstat(char __user *name, struct kstat *stat, unsigned int flags)
{
- return vfs_lstat_fd(AT_FDCWD, name, stat);
+ return vfs_lstat_fd(AT_FDCWD, name, stat, flags);
}
EXPORT_SYMBOL(vfs_lstat);
-int vfs_fstat(unsigned int fd, struct kstat *stat)
+int vfs_fstat(unsigned int fd, struct kstat *stat, unsigned int flags)
{
struct file *f = fget(fd);
int error = -EBADF;
if (f) {
- error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat);
+ error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat,
+ flags);
fput(f);
}
return error;
@@ -155,7 +162,7 @@
SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
{
struct kstat stat;
- int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
+ int error = vfs_stat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
if (!error)
error = cp_old_stat(&stat, statbuf);
@@ -166,7 +173,7 @@
SYSCALL_DEFINE2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
{
struct kstat stat;
- int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
+ int error = vfs_lstat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
if (!error)
error = cp_old_stat(&stat, statbuf);
@@ -177,7 +184,7 @@
SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)
{
struct kstat stat;
- int error = vfs_fstat(fd, &stat);
+ int error = vfs_fstat(fd, &stat, STAT_EVERYTHING);
if (!error)
error = cp_old_stat(&stat, statbuf);
@@ -240,7 +247,7 @@
SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf)
{
struct kstat stat;
- int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
+ int error = vfs_stat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
if (!error)
error = cp_new_stat(&stat, statbuf);
@@ -251,7 +258,7 @@
SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf)
{
struct kstat stat;
- int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
+ int error = vfs_lstat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
if (!error)
error = cp_new_stat(&stat, statbuf);
@@ -270,9 +277,9 @@
goto out;
if (flag & AT_SYMLINK_NOFOLLOW)
- error = vfs_lstat_fd(dfd, filename, &stat);
+ error = vfs_lstat_fd(dfd, filename, &stat, STAT_EVERYTHING);
else
- error = vfs_stat_fd(dfd, filename, &stat);
+ error = vfs_stat_fd(dfd, filename, &stat, STAT_EVERYTHING);
if (!error)
error = cp_new_stat(&stat, statbuf);
@@ -285,7 +292,43 @@
SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf)
{
struct kstat stat;
- int error = vfs_fstat(fd, &stat);
+ int error = vfs_fstat(fd, &stat, STAT_EVERYTHING);
+
+ if (!error)
+ error = cp_new_stat(&stat, statbuf);
+
+ return error;
+}
+
+SYSCALL_DEFINE3(statlight, char __user *, filename,
+ struct stat __user *, statbuf, unsigned int, flags)
+{
+ struct kstat stat;
+ int error = vfs_stat_fd(AT_FDCWD, filename, &stat, flags);
+
+ if (!error)
+ error = cp_new_stat(&stat, statbuf);
+
+ return error;
+}
+
+SYSCALL_DEFINE3(lstatlight, char __user *, filename,
+ struct stat __user *, statbuf, unsigned int, flags)
+{
+ struct kstat stat;
+ int error = vfs_lstat_fd(AT_FDCWD, filename, &stat, flags);
+
+ if (!error)
+ error = cp_new_stat(&stat, statbuf);
+
+ return error;
+}
+
+SYSCALL_DEFINE3(fstatlight, unsigned int, fd, struct stat __user *, statbuf,
+ unsigned int, flags)
+{
+ struct kstat stat;
+ int error = vfs_fstat(fd, &stat, flags);
if (!error)
error = cp_new_stat(&stat, statbuf);
@@ -370,7 +413,7 @@
SYSCALL_DEFINE2(stat64, char __user *, filename, struct stat64 __user *, statbuf)
{
struct kstat stat;
- int error = vfs_stat(filename, &stat);
+ int error = vfs_stat(filename, &stat, STAT_EVERYTHING);
if (!error)
error = cp_new_stat64(&stat, statbuf);
@@ -381,7 +424,7 @@
SYSCALL_DEFINE2(lstat64, char __user *, filename, struct stat64 __user *, statbuf)
{
struct kstat stat;
- int error = vfs_lstat(filename, &stat);
+ int error = vfs_lstat(filename, &stat, STAT_EVERYTHING);
if (!error)
error = cp_new_stat64(&stat, statbuf);
@@ -392,7 +435,7 @@
SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf)
{
struct kstat stat;
- int error = vfs_fstat(fd, &stat);
+ int error = vfs_fstat(fd, &stat, STAT_EVERYTHING);
if (!error)
error = cp_new_stat64(&stat, statbuf);
@@ -410,9 +453,9 @@
goto out;
if (flag & AT_SYMLINK_NOFOLLOW)
- error = vfs_lstat_fd(dfd, filename, &stat);
+ error = vfs_lstat_fd(dfd, filename, &stat, STAT_EVERYTHING);
else
- error = vfs_stat_fd(dfd, filename, &stat);
+ error = vfs_stat_fd(dfd, filename, &stat, STAT_EVERYTHING);
if (!error)
error = cp_new_stat64(&stat, statbuf);
--- ./include/linux/fcntl.h.orig 2009-04-07 00:31:36.000000000 -0400
+++ ./include/linux/fcntl.h 2009-04-07 00:44:41.000000000 -0400
@@ -40,6 +40,14 @@
unlinking file. */
#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */
+/* Bits to define what fields the "stat light" syscall must fill in struct stat,
+ * should not intersect with abovr AT_* bits */
+#define STAT_NLINK 0x01000 /* nlink */
+#define STAT_TIMES 0x02000 /* atime, mtime, ctime */
+#define STAT_SIZE 0x04000 /* File size and blocks */
+#define STAT_ACCESS 0x08000 /* mode, user, group */
+#define STAT_EVERYTHING 0x0f000 /* Just a normal stat */
+
#ifdef __KERNEL__
#ifndef force_o_largefile
--- ./include/linux/fs.h.orig 2009-04-07 00:30:52.000000000 -0400
+++ ./include/linux/fs.h 2009-04-07 01:03:58.000000000 -0400
@@ -1354,6 +1354,8 @@
int (*permission) (struct inode *, int);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
+ int (*getattr_light) (struct vfsmount *mnt, struct dentry *,
+ struct kstat *, unsigned int);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
@@ -2062,7 +2064,8 @@
extern const struct inode_operations page_symlink_inode_operations;
extern int generic_readlink(struct dentry *, char __user *, int);
extern void generic_fillattr(struct inode *, struct kstat *);
-extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *,
+ unsigned int);
void inode_add_bytes(struct inode *inode, loff_t bytes);
void inode_sub_bytes(struct inode *inode, loff_t bytes);
loff_t inode_get_bytes(struct inode *inode);
@@ -2070,11 +2073,11 @@
extern int vfs_readdir(struct file *, filldir_t, void *);
-extern int vfs_stat(char __user *, struct kstat *);
-extern int vfs_lstat(char __user *, struct kstat *);
-extern int vfs_stat_fd(int dfd, char __user *, struct kstat *);
-extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *);
-extern int vfs_fstat(unsigned int, struct kstat *);
+extern int vfs_stat(char __user *, struct kstat *, unsigned int);
+extern int vfs_lstat(char __user *, struct kstat *, unsigned int);
+extern int vfs_stat_fd(int dfd, char __user *, struct kstat *, unsigned int);
+extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *, unsigned int);
+extern int vfs_fstat(unsigned int, struct kstat *, unsigned int);
extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
unsigned long arg);
--- ./include/linux/syscalls.h.orig 2009-04-07 01:18:06.000000000 -0400
+++ ./include/linux/syscalls.h 2009-04-07 01:57:34.000000000 -0400
@@ -304,6 +304,13 @@
struct stat __user *statbuf);
asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf);
asmlinkage long sys_ustat(unsigned dev, struct ustat __user *ubuf);
+asmlinkage long sys_fstatlight(unsigned int fd,
+ struct stat __user *statbuf,
+ unsigned int);
+asmlinkage long sys_statlight(char __user *filename,
+ struct stat __user *statbuf, unsigned int);
+asmlinkage long sys_lstatlight(char __user *filename,
+ struct stat __user *statbuf, unsigned int);
#if BITS_PER_LONG == 32
asmlinkage long sys_stat64(char __user *filename,
struct stat64 __user *statbuf);
next reply other threads:[~2009-04-07 6:55 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-07 6:23 Oleg Drokin [this message]
2009-04-07 10:23 ` Attempt at "stat light" implementation Andreas Dilger
2009-04-07 14:54 ` Oleg Drokin
2009-04-07 17:52 ` Christoph Hellwig
2009-04-07 15:22 ` jim owens
2009-04-07 15:38 ` Oleg Drokin
2009-04-07 16:20 ` jim owens
2009-04-07 17:32 ` Jamie Lokier
2009-04-07 17:38 ` Jeff Garzik
2009-04-07 17:56 ` Jamie Lokier
2009-04-07 18:21 ` Andreas Dilger
2009-04-07 19:30 ` Ulrich Drepper
2009-04-12 20:55 ` Jamie Lokier
2009-04-07 17:41 ` Oleg Drokin
2009-04-07 17:54 ` Jamie Lokier
2009-04-07 18:00 ` Oleg Drokin
2009-04-07 18:18 ` Andreas Dilger
2009-04-07 18:31 ` Nicholas Miell
2009-04-07 17:49 ` Christoph Hellwig
2009-04-07 17:56 ` Oleg Drokin
2009-04-07 18:28 ` Andreas Dilger
2009-04-07 18:50 ` Jamie Lokier
2009-04-07 19:48 ` Jeff Garzik
2009-04-07 19:47 ` Jeff Garzik
2009-04-07 20:18 ` Evgeniy Polyakov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090407062356.GA1336463@fiona.linuxhacker.ru \
--to=green@linuxhacker.ru \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).