static struct dentry *open_xa_dir(const struct inode *inode, int flags) { struct dentry *xaroot, *xadir; char namebuf[17]; xaroot = open_xa_root(inode->i_sb, flags); if (IS_ERR(xaroot)) return xaroot; snprintf(namebuf, sizeof(namebuf), "%X.%X", le32_to_cpu(INODE_PKEY(inode)->k_objectid), inode->i_generation); mutex_lock_nested(&xaroot->d_inode->i_mutex, I_MUTEX_XATTR); xadir = lookup_one_len(namebuf, xaroot, strlen(namebuf)); if (!IS_ERR(xadir) && !xadir->d_inode) { int err = -ENODATA; if (xattr_may_create(flags)) err = xattr_mkdir(xaroot->d_inode, xadir, 0700); if (err) { dput(xadir); xadir = ERR_PTR(err); } } mutex_unlock(&xaroot->d_inode->i_mutex); dput(xaroot); return xadir; }
static struct dentry *open_xa_root(struct super_block *sb, int flags) { struct dentry *privroot = REISERFS_SB(sb)->priv_root; struct dentry *xaroot; if (d_really_is_negative(privroot)) return ERR_PTR(-ENODATA); inode_lock_nested(d_inode(privroot), I_MUTEX_XATTR); xaroot = dget(REISERFS_SB(sb)->xattr_root); if (!xaroot) xaroot = ERR_PTR(-ENODATA); else if (d_really_is_negative(xaroot)) { int err = -ENODATA; if (xattr_may_create(flags)) err = xattr_mkdir(d_inode(privroot), xaroot, 0700); if (err) { dput(xaroot); xaroot = ERR_PTR(err); } } inode_unlock(d_inode(privroot)); return xaroot; }
static struct dentry *open_xa_root(struct super_block *sb, int flags) { struct dentry *privroot = REISERFS_SB(sb)->priv_root; struct dentry *xaroot; if (!privroot->d_inode) return ERR_PTR(-ENODATA); mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR); xaroot = dget(REISERFS_SB(sb)->xattr_root); if (!xaroot) xaroot = ERR_PTR(-ENODATA); else if (!xaroot->d_inode) { int err = -ENODATA; if (xattr_may_create(flags)) err = xattr_mkdir(privroot->d_inode, xaroot, 0700); if (err) { dput(xaroot); xaroot = ERR_PTR(err); } } mutex_unlock(&privroot->d_inode->i_mutex); return xaroot; }
/* * Inode operation listxattr() * * We totally ignore the generic listxattr here because it would be stupid * not to. Since the xattrs are organized in a directory, we can just * readdir to find them. */ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) { struct dentry *dir; int err = 0; loff_t pos = 0; struct listxattr_buf buf = { .dentry = dentry, .buf = buffer, .size = buffer ? size : 0, }; if (!dentry->d_inode) return -EINVAL; if (!dentry->d_sb->s_xattr || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) return -EOPNOTSUPP; dir = open_xa_dir(dentry->d_inode, XATTR_REPLACE); if (IS_ERR(dir)) { err = PTR_ERR(dir); if (err == -ENODATA) err = 0; /* Not an error if there aren't any xattrs */ goto out; } mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); err = reiserfs_readdir_dentry(dir, &buf, listxattr_filler, &pos); mutex_unlock(&dir->d_inode->i_mutex); if (!err) err = buf.pos; dput(dir); out: return err; } static int create_privroot(struct dentry *dentry) { int err; struct inode *inode = dentry->d_parent->d_inode; WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex)); err = xattr_mkdir(inode, dentry, 0700); if (err || !dentry->d_inode) { reiserfs_warning(dentry->d_sb, "jdm-20006", "xattrs/ACLs enabled and couldn't " "find/create .reiserfs_priv. " "Failing mount."); return -EOPNOTSUPP; } dentry->d_inode->i_flags |= S_PRIVATE; reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr " "storage.\n", PRIVROOT_NAME); return 0; }
/* * Inode operation listxattr() * * We totally ignore the generic listxattr here because it would be stupid * not to. Since the xattrs are organized in a directory, we can just * readdir to find them. */ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) { struct dentry *dir; int err = 0; loff_t pos = 0; struct listxattr_buf buf = { .dentry = dentry, .buf = buffer, .size = buffer ? size : 0, }; if (!dentry->d_inode) return -EINVAL; if (!dentry->d_sb->s_xattr || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) return -EOPNOTSUPP; dir = open_xa_dir(dentry->d_inode, XATTR_REPLACE); if (IS_ERR(dir)) { err = PTR_ERR(dir); if (err == -ENODATA) err = 0; /* Not an error if there aren't any xattrs */ goto out; } mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); err = reiserfs_readdir_dentry(dir, &buf, listxattr_filler, &pos); mutex_unlock(&dir->d_inode->i_mutex); if (!err) err = buf.pos; dput(dir); out: return err; } static int reiserfs_check_acl(struct inode *inode, int mask, unsigned int flags) { struct posix_acl *acl; int error = -EAGAIN; /* do regular unix permission checks by default */ if (flags & IPERM_FLAG_RCU) return -ECHILD; acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); if (acl) { if (!IS_ERR(acl)) { error = posix_acl_permission(inode, acl, mask); posix_acl_release(acl); } else if (PTR_ERR(acl) != -ENODATA) error = PTR_ERR(acl); } return error; } static int create_privroot(struct dentry *dentry) { int err; struct inode *inode = dentry->d_parent->d_inode; WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex)); err = xattr_mkdir(inode, dentry, 0700); if (err || !dentry->d_inode) { reiserfs_warning(dentry->d_sb, "jdm-20006", "xattrs/ACLs enabled and couldn't " "find/create .reiserfs_priv. " "Failing mount."); return -EOPNOTSUPP; } dentry->d_inode->i_flags |= S_PRIVATE; reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr " "storage.\n", PRIVROOT_NAME); return 0; }