]> git.saurik.com Git - apple/hfs.git/blob - livefiles_hfs_plugin/lf_hfs_vnode.c
hfs-522.0.9.tar.gz
[apple/hfs.git] / livefiles_hfs_plugin / lf_hfs_vnode.c
1 /* Copyright © 2017-2018 Apple Inc. All rights reserved.
2 *
3 * lf_hfs_vnode.c
4 * livefiles_hfs
5 *
6 * Created by Or Haimovich on 20/3/18.
7 */
8
9 #include "lf_hfs_vnode.h"
10 #include "lf_hfs_utils.h"
11 #include "lf_hfs_vfsutils.h"
12 #include "lf_hfs_generic_buf.h"
13 #include "lf_hfs_fileops_handler.h"
14
15 int VTtoUVFS_tab[16] =
16 {
17 VNON,
18 /* 1 - 5 */
19 UVFS_FA_TYPE_FILE, UVFS_FA_TYPE_DIR, VNON, VNON, UVFS_FA_TYPE_SYMLINK,
20 /* 6 - 10 */
21 VNON, VNON, VNON, VNON, VNON
22 };
23
24 enum vtype iftovt_tab[16] =
25 {
26 VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
27 VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD,
28 };
29
30 int uvfsToVtype_tab[4] =
31 {
32 VNON,VREG,VDIR,VLNK,
33 };
34
35 mode_t vttoif_tab[9] =
36 {
37 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK,
38 S_IFSOCK, S_IFIFO, S_IFMT,
39 };
40
41 errno_t vnode_initialize(uint32_t size, void *data, vnode_t *vpp)
42 {
43 memset(*vpp,0,sizeof(struct vnode));
44 (*vpp)->cnode = NULL;
45 assert(size == sizeof((*vpp)->sFSParams));
46 memcpy((void *) &(*vpp)->sFSParams,data,size);
47
48 if ((*vpp)->sFSParams.vnfs_vtype == VDIR)
49 {
50 (*vpp)->sExtraData.sDirData.uDirVersion = 1;
51 }
52 return 0;
53 }
54
55 errno_t vnode_create(uint32_t size, void *data, vnode_t *vpp)
56 {
57 *vpp = hfs_malloc(sizeof(struct vnode));
58 if (*vpp == NULL)
59 {
60 return ENOMEM;
61 }
62
63 return (vnode_initialize(size, data, vpp));
64 }
65
66 void vnode_rele(vnode_t vp)
67 {
68 if (vp) {
69 lf_hfs_generic_buf_cache_LockBufCache();
70 lf_hfs_generic_buf_cache_remove_vnode(vp);
71 lf_hfs_generic_buf_cache_UnLockBufCache();
72 hfs_free(vp);
73 }
74 vp = NULL;
75 }
76
77 mount_t vnode_mount(vnode_t vp)
78 {
79 return (vp->sFSParams.vnfs_mp);
80 }
81
82 int vnode_issystem(vnode_t vp)
83 {
84 return (vp->sFSParams.vnfs_marksystem);
85 }
86
87 int vnode_isreg(vnode_t vp)
88 {
89 return (vp->sFSParams.vnfs_vtype == VREG);
90 }
91
92 int vnode_isdir(vnode_t vp)
93 {
94 return (vp->sFSParams.vnfs_vtype == VDIR);
95 }
96
97 int vnode_islnk(vnode_t vp)
98 {
99 return (vp->sFSParams.vnfs_vtype == VLNK);
100 }
101
102 /*!
103 @function vnode_update_identity
104 case:
105 VNODE_UPDATE_PARENT: set parent.
106 VNODE_UPDATE_NAME: set name.
107 VNODE_UPDATE_CACHE: flush cache entries for hard links associated with this file.
108
109
110 */
111 void vnode_update_identity(vnode_t vp, vnode_t dvp, const char *name, int name_len, uint32_t name_hashval, int flags)
112 {
113 if (flags & VNODE_UPDATE_PARENT)
114 {
115 vp->sFSParams.vnfs_dvp = dvp;
116 }
117
118 if (flags & VNODE_UPDATE_NAME)
119 {
120 if (!vp->sFSParams.vnfs_cnp) {
121 vp->sFSParams.vnfs_cnp = hfs_malloc(sizeof(struct componentname));
122 if (vp->sFSParams.vnfs_cnp == NULL) {
123 LFHFS_LOG(LEVEL_ERROR, "vnode_update_identity: failed to malloc vnfs_cnp\n");
124 assert(0);
125 }
126 }
127 vp->sFSParams.vnfs_cnp->cn_namelen = name_len;
128 if (vp->sFSParams.vnfs_cnp->cn_nameptr) {
129 hfs_free(vp->sFSParams.vnfs_cnp->cn_nameptr);
130 }
131 vp->sFSParams.vnfs_cnp->cn_nameptr = lf_hfs_utils_allocate_and_copy_string( (char*) name, name_len );
132 vp->sFSParams.vnfs_cnp->cn_hash = name_hashval;
133 }
134 }
135
136 void vnode_GetAttrInternal (vnode_t vp, UVFSFileAttributes *psOutAttr )
137 {
138 struct cnode *cp = VTOC(vp);
139 enum vtype v_type;
140
141 memset( psOutAttr, 0, sizeof(UVFSFileAttributes) );
142
143 psOutAttr->fa_validmask = VALID_OUT_ATTR_MASK;
144
145 psOutAttr->fa_gid = cp->c_gid;
146 psOutAttr->fa_uid = cp->c_uid;
147 psOutAttr->fa_mode = cp->c_mode & ALL_UVFS_MODES;
148
149 v_type = vp->sFSParams.vnfs_vtype;
150 psOutAttr->fa_type = VTOUVFS(v_type);
151
152 psOutAttr->fa_atime.tv_sec = cp->c_atime;
153 psOutAttr->fa_ctime.tv_sec = cp->c_ctime;
154 psOutAttr->fa_mtime.tv_sec = cp->c_mtime;
155 psOutAttr->fa_birthtime.tv_sec = cp->c_btime;
156
157 psOutAttr->fa_fileid = cp->c_fileid;
158 psOutAttr->fa_parentid = cp->c_parentcnid;
159 psOutAttr->fa_bsd_flags = cp->c_bsdflags;
160
161 if (v_type == VDIR)
162 {
163 psOutAttr->fa_allocsize = 0;
164 psOutAttr->fa_size = (cp->c_entries + 2) * AVERAGE_HFSDIRENTRY_SIZE;
165 psOutAttr->fa_nlink = cp->c_entries + 2;
166 }
167 else
168 {
169 psOutAttr->fa_allocsize = VCTOF(vp, cp)->ff_blocks * VTOHFS(vp)->blockSize;
170 psOutAttr->fa_size = VCTOF(vp, cp)->ff_size;
171 psOutAttr->fa_nlink = (cp->c_flag & C_HARDLINK)? cp->c_linkcount : 1;
172 }
173 }