> Even if we assume, that the remote filesystem never changes, it is
> difficult to implement open-unlink-fstat semantics correctly in the
> client, without having this information.
>
> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
> ---
>
> Index: linux/fs/stat.c
> ===================================================================
> --- linux.orig/fs/stat.c 2007-10-24 11:59:46.000000000 +0200
> +++ linux/fs/stat.c 2007-10-24 11:59:47.000000000 +0200
> @@ -55,6 +55,33 @@ int vfs_getattr(struct vfsmount *mnt, st
>
> EXPORT_SYMBOL(vfs_getattr);
>
> +/*
> + * Perform getattr on an open file
> + *
> + * Fall back to i_op->getattr (or generic_fillattr) if the filesystem
> + * doesn't define an f_op->fgetattr operation.
> + */
> +static int vfs_fgetattr(struct file *file, struct kstat *stat)
> +{
> + struct vfsmount *mnt = file->f_path.mnt;
> + struct dentry *dentry = file->f_path.dentry;
> + struct inode *inode = dentry->d_inode;
> + int retval;
> +
> + retval = security_inode_getattr(mnt, dentry);
> + if (retval)
> + return retval;
> +
> + if (file->f_op && file->f_op->fgetattr) {
> + return file->f_op->fgetattr(file, stat);
> + } else if (inode->i_op->getattr) {
> + return inode->i_op->getattr(mnt, dentry, stat);
> + } else {
> + generic_fillattr(inode, stat);
> + return 0;
> + }
> +}
> +
> int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
> {
> struct nameidata nd;
> @@ -101,7 +128,7 @@ int vfs_fstat(unsigned int fd, struct ks
> int error = -EBADF;
>
> if (f) {
> - error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat);
> + error = vfs_fgetattr(f, stat);
> fput(f);
> }
> return error;
> Index: linux/include/linux/fs.h
> ===================================================================
> --- linux.orig/include/linux/fs.h 2007-10-24 11:59:46.000000000 +0200
> +++ linux/include/linux/fs.h 2007-10-24 11:59:47.000000000 +0200
> @@ -1195,6 +1195,7 @@ struct file_operations {
> 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 (*revoke)(struct file *, struct address_space *);
> + int (*fgetattr)(struct file *, struct kstat *);
> };
>
> struct inode_operations {
> Index: linux/fs/fuse/file.c
> ===================================================================
> --- linux.orig/fs/fuse/file.c 2007-10-24 11:59:46.000000000 +0200
> +++ linux/fs/fuse/file.c 2007-10-24 12:01:00.000000000 +0200
> @@ -871,6 +871,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;
> @@ -920,6 +931,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,
> };
>
> @@ -933,6 +945,7 @@ static const struct file_operations fuse
> .fsync = fuse_fsync,
> .lock = fuse_file_lock,
> .flock = fuse_file_flock,
> + .fgetattr = fuse_file_fgetattr,
> /* no mmap and splice_read */
> };
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to
majordomo@vger.kernel.org
> More majordomo info at
http://vger.kernel.org/majordomo-info.html
>