Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  linux/fs/hfs/attr.c
0004  *
0005  * (C) 2003 Ardis Technologies <roman@ardistech.com>
0006  *
0007  * Export hfs data via xattr
0008  */
0009 
0010 
0011 #include <linux/fs.h>
0012 #include <linux/xattr.h>
0013 
0014 #include "hfs_fs.h"
0015 #include "btree.h"
0016 
0017 enum hfs_xattr_type {
0018     HFS_TYPE,
0019     HFS_CREATOR,
0020 };
0021 
0022 static int __hfs_setxattr(struct inode *inode, enum hfs_xattr_type type,
0023               const void *value, size_t size, int flags)
0024 {
0025     struct hfs_find_data fd;
0026     hfs_cat_rec rec;
0027     struct hfs_cat_file *file;
0028     int res;
0029 
0030     if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))
0031         return -EOPNOTSUPP;
0032 
0033     res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);
0034     if (res)
0035         return res;
0036     fd.search_key->cat = HFS_I(inode)->cat_key;
0037     res = hfs_brec_find(&fd);
0038     if (res)
0039         goto out;
0040     hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
0041             sizeof(struct hfs_cat_file));
0042     file = &rec.file;
0043 
0044     switch (type) {
0045     case HFS_TYPE:
0046         if (size == 4)
0047             memcpy(&file->UsrWds.fdType, value, 4);
0048         else
0049             res = -ERANGE;
0050         break;
0051 
0052     case HFS_CREATOR:
0053         if (size == 4)
0054             memcpy(&file->UsrWds.fdCreator, value, 4);
0055         else
0056             res = -ERANGE;
0057         break;
0058     }
0059 
0060     if (!res)
0061         hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
0062                 sizeof(struct hfs_cat_file));
0063 out:
0064     hfs_find_exit(&fd);
0065     return res;
0066 }
0067 
0068 static ssize_t __hfs_getxattr(struct inode *inode, enum hfs_xattr_type type,
0069                   void *value, size_t size)
0070 {
0071     struct hfs_find_data fd;
0072     hfs_cat_rec rec;
0073     struct hfs_cat_file *file;
0074     ssize_t res = 0;
0075 
0076     if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))
0077         return -EOPNOTSUPP;
0078 
0079     if (size) {
0080         res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);
0081         if (res)
0082             return res;
0083         fd.search_key->cat = HFS_I(inode)->cat_key;
0084         res = hfs_brec_find(&fd);
0085         if (res)
0086             goto out;
0087         hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
0088                 sizeof(struct hfs_cat_file));
0089     }
0090     file = &rec.file;
0091 
0092     switch (type) {
0093     case HFS_TYPE:
0094         if (size >= 4) {
0095             memcpy(value, &file->UsrWds.fdType, 4);
0096             res = 4;
0097         } else
0098             res = size ? -ERANGE : 4;
0099         break;
0100 
0101     case HFS_CREATOR:
0102         if (size >= 4) {
0103             memcpy(value, &file->UsrWds.fdCreator, 4);
0104             res = 4;
0105         } else
0106             res = size ? -ERANGE : 4;
0107         break;
0108     }
0109 
0110 out:
0111     if (size)
0112         hfs_find_exit(&fd);
0113     return res;
0114 }
0115 
0116 static int hfs_xattr_get(const struct xattr_handler *handler,
0117              struct dentry *unused, struct inode *inode,
0118              const char *name, void *value, size_t size)
0119 {
0120     return __hfs_getxattr(inode, handler->flags, value, size);
0121 }
0122 
0123 static int hfs_xattr_set(const struct xattr_handler *handler,
0124              struct user_namespace *mnt_userns,
0125              struct dentry *unused, struct inode *inode,
0126              const char *name, const void *value, size_t size,
0127              int flags)
0128 {
0129     if (!value)
0130         return -EOPNOTSUPP;
0131 
0132     return __hfs_setxattr(inode, handler->flags, value, size, flags);
0133 }
0134 
0135 static const struct xattr_handler hfs_creator_handler = {
0136     .name = "hfs.creator",
0137     .flags = HFS_CREATOR,
0138     .get = hfs_xattr_get,
0139     .set = hfs_xattr_set,
0140 };
0141 
0142 static const struct xattr_handler hfs_type_handler = {
0143     .name = "hfs.type",
0144     .flags = HFS_TYPE,
0145     .get = hfs_xattr_get,
0146     .set = hfs_xattr_set,
0147 };
0148 
0149 const struct xattr_handler *hfs_xattr_handlers[] = {
0150     &hfs_creator_handler,
0151     &hfs_type_handler,
0152     NULL
0153 };