On Wed, 3 Jun 2009, Brian Molnar wrote: > There was some talk on this list a year or two ago about adding > f_op->fgetattr and f_op->fsetattr methods to the VFS file_operations > struct. For some reason or another, that was dropped on the floor, but > I'd like to pick that back up and discus it once again. > > In the file-system I'm working on, there is a distinction between > stat(2)s done against a pathname and fstat(2)s done against an open > file descriptor. The results of the two are expected to differ in some > circumstances. Moreover, I'm building this file-system in FUSE, and > while I've managed to hack the underlying fuse code to achieve this > behavior, it does so at a substantial performance cost. The more > 'correct' solution here would be to export an fgetattr/fsetattr > interface at VFS layer, then percolate that change up to the FUSE > interface. Can you tell us a bit more about your use case, and how you worked around the limitation? Attaching an untested patch that adds f_op->fgetattr(). Testing and comments are welcome. Thanks, Miklos Index: linux-2.6/include/linux/fs.h =================================================================== --- linux-2.6.orig/include/linux/fs.h 2009-06-02 15:55:18.000000000 +0200 +++ linux-2.6/include/linux/fs.h 2009-06-04 11:56:04.000000000 +0200 @@ -1508,6 +1508,7 @@ struct file_operations { ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock **); + int (*fgetattr)(struct file *, struct kstat *); }; struct inode_operations { Index: linux-2.6/fs/fuse/file.c =================================================================== --- linux-2.6.orig/fs/fuse/file.c 2009-06-04 11:42:10.000000000 +0200 +++ linux-2.6/fs/fuse/file.c 2009-06-04 12:02:48.000000000 +0200 @@ -1449,6 +1449,17 @@ static int fuse_file_flock(struct file * return err; } +static int fuse_file_fgetattr(struct file *file, struct kstat *stat) +{ + struct inode *inode = file->f_dentry->d_inode; + struct fuse_conn *fc = get_fuse_conn(inode); + + if (!fuse_allow_task(fc, current)) + return -EACCES; + + return fuse_update_attributes(inode, stat, file, NULL); +} + static sector_t fuse_bmap(struct address_space *mapping, sector_t block) { struct inode *inode = mapping->host; @@ -1927,6 +1938,7 @@ static const struct file_operations fuse .fsync = fuse_fsync, .lock = fuse_file_lock, .flock = fuse_file_flock, + .fgetattr = fuse_file_fgetattr, .splice_read = generic_file_splice_read, .unlocked_ioctl = fuse_file_ioctl, .compat_ioctl = fuse_file_compat_ioctl, @@ -1944,6 +1956,7 @@ static const struct file_operations fuse .fsync = fuse_fsync, .lock = fuse_file_lock, .flock = fuse_file_flock, + .fgetattr = fuse_file_fgetattr, .unlocked_ioctl = fuse_file_ioctl, .compat_ioctl = fuse_file_compat_ioctl, .poll = fuse_file_poll, Index: linux-2.6/fs/stat.c =================================================================== --- linux-2.6.orig/fs/stat.c 2009-05-20 14:11:59.000000000 +0200 +++ linux-2.6/fs/stat.c 2009-06-04 12:08:07.000000000 +0200 @@ -57,13 +57,33 @@ EXPORT_SYMBOL(vfs_getattr); int vfs_fstat(unsigned int fd, struct kstat *stat) { - struct file *f = fget(fd); - int error = -EBADF; + struct inode *inode; + struct vfsmount *mnt; + struct dentry *dentry; + struct file *f; + int error; - if (f) { - error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat); - fput(f); + f = fget(fd); + if (!f) + return -EBADF; + + mnt = f->f_path.mnt; + dentry = f->f_path.dentry; + inode = dentry->d_inode; + + error = security_inode_getattr(mnt, dentry); + if (!error) { + if (f->f_op && f->f_op->fgetattr) { + error = f->f_op->fgetattr(f, stat); + } else { + if (inode->i_op->getattr) + error = inode->i_op->getattr(mnt, dentry, stat); + else + generic_fillattr(inode, stat); + } } + fput(f); + return error; } EXPORT_SYMBOL(vfs_fstat); -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html