Messages in this thread Patch in this message | | | Subject | Re: Patch to implement getattr [patch] | From | Magnus Ahltorp <> | Date | 15 Jul 1999 19:00:03 +0200 |
| |
> > > 1. Having getattr is nice, but I'ld rather turned the old code into > > > generic_getattr() and let the filesystems refer to it. > > > [...] > > > 2. I think that having a wrapper around the thing (vfs_getattr()) would be > > > the right thing. Just look how arch/*/* stuff does stat() emulation for > > > personalities with different struct stat layout. set_fs();sys_stat();set_fs(); > > > and then reshuffle the stuff...<shudder>
We (I and Assar Westerlund <assar@sics.se>) produced a patch that should solved those issues. Comments?
--- fs/stat.c.orig Tue Jul 13 20:17:22 1999 +++ fs/stat.c Thu Jul 15 18:14:00 1999 @@ -24,56 +24,22 @@ } -#if !defined(__alpha__) && !defined(__sparc__) - -/* - * For backward compatibility? Maybe this should be moved - * into arch/i386 instead? - */ -static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf) -{ - static int warncount = 5; - struct __old_kernel_stat tmp; - - if (warncount) { - warncount--; - printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n", - current->comm); - } - - tmp.st_dev = kdev_t_to_nr(inode->i_dev); - tmp.st_ino = inode->i_ino; - tmp.st_mode = inode->i_mode; - tmp.st_nlink = inode->i_nlink; - tmp.st_uid = inode->i_uid; - tmp.st_gid = inode->i_gid; - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); - tmp.st_size = inode->i_size; - tmp.st_atime = inode->i_atime; - tmp.st_mtime = inode->i_mtime; - tmp.st_ctime = inode->i_ctime; - return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; -} - -#endif - -static int cp_new_stat(struct inode * inode, struct stat * statbuf) +int generic_getattr(struct inode * inode, struct stat * statbuf) { - struct stat tmp; unsigned int blocks, indirect; - memset(&tmp, 0, sizeof(tmp)); - tmp.st_dev = kdev_t_to_nr(inode->i_dev); - tmp.st_ino = inode->i_ino; - tmp.st_mode = inode->i_mode; - tmp.st_nlink = inode->i_nlink; - tmp.st_uid = inode->i_uid; - tmp.st_gid = inode->i_gid; - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); - tmp.st_size = inode->i_size; - tmp.st_atime = inode->i_atime; - tmp.st_mtime = inode->i_mtime; - tmp.st_ctime = inode->i_ctime; + memset(statbuf, 0, sizeof(*statbuf)); + statbuf->st_dev = kdev_t_to_nr(inode->i_dev); + statbuf->st_ino = inode->i_ino; + statbuf->st_mode = inode->i_mode; + statbuf->st_nlink = inode->i_nlink; + statbuf->st_uid = inode->i_uid; + statbuf->st_gid = inode->i_gid; + statbuf->st_rdev = kdev_t_to_nr(inode->i_rdev); + statbuf->st_size = inode->i_size; + statbuf->st_atime = inode->i_atime; + statbuf->st_mtime = inode->i_mtime; + statbuf->st_ctime = inode->i_ctime; /* * st_blocks and st_blksize are approximated with a simple algorithm if * they aren't supported directly by the filesystem. The minix and msdos @@ -87,13 +53,13 @@ * Use minix fs values for the number of direct and indirect blocks. The * count is now exact for the minix fs except that it counts zero blocks. * Everything is in units of BLOCK_SIZE until the assignment to - * tmp.st_blksize. + * statbuf->st_blksize. */ #define D_B 7 #define I_B (BLOCK_SIZE / sizeof(unsigned short)) if (!inode->i_blksize) { - blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE; + blocks = (statbuf->st_size + BLOCK_SIZE - 1) / BLOCK_SIZE; if (blocks > D_B) { indirect = (blocks - D_B + I_B - 1) / I_B; blocks += indirect; @@ -104,15 +70,72 @@ blocks++; } } - tmp.st_blocks = (BLOCK_SIZE / 512) * blocks; - tmp.st_blksize = BLOCK_SIZE; + statbuf->st_blocks = (BLOCK_SIZE / 512) * blocks; + statbuf->st_blksize = BLOCK_SIZE; } else { - tmp.st_blocks = inode->i_blocks; - tmp.st_blksize = inode->i_blksize; + statbuf->st_blocks = inode->i_blocks; + statbuf->st_blksize = inode->i_blksize; + } + return 0; +} + +int vfs_getattr(struct inode * inode, struct stat * statbuf) +{ + if (inode->i_op && inode->i_op->getattr) + return inode->i_op->getattr (inode, statbuf); + else + return generic_getattr (inode, statbuf); } + +#if !defined(__alpha__) && !defined(__sparc__) + +/* + * For backward compatibility? Maybe this should be moved + * into arch/i386 instead? + */ +static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf) +{ + static int warncount = 5; + struct __old_kernel_stat tmp; + struct stat new_tmp; + int ret; + + if (warncount) { + warncount--; + printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n", + current->comm); + } + + ret = vfs_getattr (inode, &new_tmp); + if (ret) + return ret; + tmp.st_dev = new_tmp.st_dev; + tmp.st_ino = new_tmp.st_ino; + tmp.st_mode = new_tmp.st_mode; + tmp.st_nlink = new_tmp.st_nlink; + tmp.st_uid = new_tmp.st_uid; + tmp.st_gid = new_tmp.st_gid; + tmp.st_rdev = new_tmp.st_rdev; + tmp.st_size = new_tmp.st_size; + tmp.st_atime = new_tmp.st_atime; + tmp.st_mtime = new_tmp.st_mtime; + tmp.st_ctime = new_tmp.st_ctime; + return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } +#endif + +static int cp_new_stat(struct inode * inode, struct stat * statbuf) +{ + struct stat tmp; + int ret; + + ret = vfs_getattr (inode, &tmp); + if (ret) + return ret; + return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; +} #if !defined(__alpha__) && !defined(__sparc__) /* --- include/linux/fs.h.orig Tue Jan 26 05:00:51 1999 +++ include/linux/fs.h Thu Jul 15 18:10:10 1999 @@ -613,6 +613,7 @@ int (*smap) (struct inode *,int); int (*updatepage) (struct file *, struct page *, unsigned long, unsigned int, int); int (*revalidate) (struct dentry *); + int (*getattr) (struct inode *, struct stat *); }; struct super_operations { @@ -876,6 +877,9 @@ extern int inode_change_ok(struct inode *, struct iattr *); extern void inode_setattr(struct inode *, struct iattr *); + +extern int generic_getattr(struct inode *, struct stat *); +extern int vfs_getattr(struct inode * inode, struct stat * statbuf); /* kludge to get SCSI modules working */ #include <linux/minix_fs.h>
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |