X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fzpl_inode.c;h=b7227675b55493986a594882ba17a5691c67d1bc;hb=6742abf9ec5a2c0ca132951efa0dee85698ff9b8;hp=e866dcd4d508117010dde8a79d281a0ba5ef7ae9;hpb=ee154f01bf0bdb5e85524c518c19964272d33cd9;p=zfs.git diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c index e866dcd..b722767 100644 --- a/module/zfs/zpl_inode.c +++ b/module/zfs/zpl_inode.c @@ -171,10 +171,33 @@ static int zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { cred_t *cr; + vattr_t *vap; + struct inode *ip; int error; + ip = dentry->d_inode; cr = (cred_t *)get_current_cred(); - error = -zfs_getattr(dentry->d_inode, stat, 0, cr); + vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP); + + error = -zfs_getattr(ip, vap, 0, cr); + if (error) + goto out; + + stat->ino = ip->i_ino; + stat->dev = 0; + stat->mode = vap->va_mode; + stat->nlink = vap->va_nlink; + stat->uid = vap->va_uid; + stat->gid = vap->va_gid; + stat->rdev = vap->va_rdev; + stat->size = vap->va_size; + stat->atime = vap->va_atime; + stat->mtime = vap->va_mtime; + stat->ctime = vap->va_ctime; + stat->blksize = vap->va_blksize; + stat->blocks = vap->va_nblocks; +out: + kmem_free(vap, sizeof(vattr_t)); put_cred(cr); ASSERT3S(error, <=, 0); @@ -182,21 +205,34 @@ zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) } static int -zpl_setattr(struct dentry *dentry, struct iattr *attr) +zpl_setattr(struct dentry *dentry, struct iattr *ia) { cred_t *cr; + vattr_t *vap; int error; - error = inode_change_ok(dentry->d_inode, attr); + error = inode_change_ok(dentry->d_inode, ia); if (error) return (error); cr = (cred_t *)get_current_cred(); - error = -zfs_setattr(dentry->d_inode, attr, 0, cr); + vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP); + vap->va_mask = ia->ia_valid & ATTR_IATTR_MASK; + vap->va_mode = ia->ia_mode; + vap->va_uid = ia->ia_uid; + vap->va_gid = ia->ia_gid; + vap->va_size = ia->ia_size; + vap->va_atime = ia->ia_atime; + vap->va_mtime = ia->ia_mtime; + vap->va_ctime = ia->ia_ctime; + + error = -zfs_setattr(dentry->d_inode, vap, 0, cr); + + kmem_free(vap, sizeof(vattr_t)); put_cred(cr); ASSERT3S(error, <=, 0); - return (-error); + return (error); } static int @@ -245,8 +281,33 @@ out: static void * zpl_follow_link(struct dentry *dentry, struct nameidata *nd) { - (void) zfs_follow_link(dentry, nd); - return NULL; + struct inode *ip = dentry->d_inode; + struct iovec iov; + uio_t uio; + char *link; + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + + iov.iov_len = MAXPATHLEN; + iov.iov_base = link = kmem_zalloc(MAXPATHLEN, KM_SLEEP); + + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_resid = (MAXPATHLEN - 1); + uio.uio_segflg = UIO_SYSSPACE; + + error = -zfs_readlink(ip, &uio, cr); + if (error) { + kmem_free(link, MAXPATHLEN); + nd_set_link(nd, ERR_PTR(error)); + } else { + nd_set_link(nd, link); + } + + put_cred(cr); + return (NULL); } static void @@ -256,7 +317,7 @@ zpl_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr) link = nd_get_link(nd); if (!IS_ERR(link)) - kmem_free(link, MAXPATHLEN + 1); + kmem_free(link, MAXPATHLEN); } static int @@ -288,7 +349,6 @@ out: } const struct inode_operations zpl_inode_operations = { - .check_acl = NULL, .create = zpl_create, .link = zpl_link, .unlink = zpl_unlink, @@ -306,7 +366,6 @@ const struct inode_operations zpl_inode_operations = { }; const struct inode_operations zpl_dir_inode_operations = { - .check_acl = NULL, .create = zpl_create, .lookup = zpl_lookup, .link = zpl_link, @@ -317,15 +376,24 @@ const struct inode_operations zpl_dir_inode_operations = { .mknod = zpl_mknod, .rename = zpl_rename, .setattr = zpl_setattr, + .getattr = zpl_getattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, + .removexattr = generic_removexattr, + .listxattr = zpl_xattr_list, }; const struct inode_operations zpl_symlink_inode_operations = { - .check_acl = NULL, .readlink = generic_readlink, .follow_link = zpl_follow_link, .put_link = zpl_put_link, }; const struct inode_operations zpl_special_inode_operations = { - .check_acl = NULL, + .setattr = zpl_setattr, + .getattr = zpl_getattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, + .removexattr = generic_removexattr, + .listxattr = zpl_xattr_list, };