1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * linux/fs/hpfs/inode.c 4 * 5 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999 6 * 7 * inode VFS functions 8 */ 9 10 #include <linux/slab.h> 11 #include <linux/user_namespace.h> 12 #include "hpfs_fn.h" 13 14 void hpfs_init_inode(struct inode *i) 15 { 16 struct super_block *sb = i->i_sb; 17 struct hpfs_inode_info *hpfs_inode = hpfs_i(i); 18 19 i->i_uid = hpfs_sb(sb)->sb_uid; 20 i->i_gid = hpfs_sb(sb)->sb_gid; 21 i->i_mode = hpfs_sb(sb)->sb_mode; 22 i->i_size = -1; 23 i->i_blocks = -1; 24 25 hpfs_inode->i_dno = 0; 26 hpfs_inode->i_n_secs = 0; 27 hpfs_inode->i_file_sec = 0; 28 hpfs_inode->i_disk_sec = 0; 29 hpfs_inode->i_dpos = 0; 30 hpfs_inode->i_dsubdno = 0; 31 hpfs_inode->i_ea_mode = 0; 32 hpfs_inode->i_ea_uid = 0; 33 hpfs_inode->i_ea_gid = 0; 34 hpfs_inode->i_ea_size = 0; 35 36 hpfs_inode->i_rddir_off = NULL; 37 hpfs_inode->i_dirty = 0; 38 39 inode_set_ctime(i, 0, 0); 40 inode_set_mtime(i, 0, 0); 41 inode_set_atime(i, 0, 0); 42 } 43 44 void hpfs_read_inode(struct inode *i) 45 { 46 struct buffer_head *bh; 47 struct fnode *fnode; 48 struct super_block *sb = i->i_sb; 49 struct hpfs_inode_info *hpfs_inode = hpfs_i(i); 50 void *ea; 51 int ea_size; 52 53 if (!(fnode = hpfs_map_fnode(sb, i->i_ino, &bh))) { 54 /*i->i_mode |= S_IFREG; 55 i->i_mode &= ~0111; 56 i->i_op = &hpfs_file_iops; 57 i->i_fop = &hpfs_file_ops; 58 clear_nlink(i);*/ 59 make_bad_inode(i); 60 return; 61 } 62 if (hpfs_sb(i->i_sb)->sb_eas) { 63 if ((ea = hpfs_get_ea(i->i_sb, fnode, "UID", &ea_size))) { 64 if (ea_size == 2) { 65 i_uid_write(i, le16_to_cpu(*(__le16*)ea)); 66 hpfs_inode->i_ea_uid = 1; 67 } 68 kfree(ea); 69 } 70 if ((ea = hpfs_get_ea(i->i_sb, fnode, "GID", &ea_size))) { 71 if (ea_size == 2) { 72 i_gid_write(i, le16_to_cpu(*(__le16*)ea)); 73 hpfs_inode->i_ea_gid = 1; 74 } 75 kfree(ea); 76 } 77 if ((ea = hpfs_get_ea(i->i_sb, fnode, "SYMLINK", &ea_size))) { 78 kfree(ea); 79 i->i_mode = S_IFLNK | 0777; 80 i->i_op = &page_symlink_inode_operations; 81 inode_nohighmem(i); 82 i->i_data.a_ops = &hpfs_symlink_aops; 83 set_nlink(i, 1); 84 i->i_size = ea_size; 85 i->i_blocks = 1; 86 brelse(bh); 87 return; 88 } 89 if ((ea = hpfs_get_ea(i->i_sb, fnode, "MODE", &ea_size))) { 90 int rdev = 0; 91 umode_t mode = hpfs_sb(sb)->sb_mode; 92 if (ea_size == 2) { 93 mode = le16_to_cpu(*(__le16*)ea); 94 hpfs_inode->i_ea_mode = 1; 95 } 96 kfree(ea); 97 i->i_mode = mode; 98 if (S_ISBLK(mode) || S_ISCHR(mode)) { 99 if ((ea = hpfs_get_ea(i->i_sb, fnode, "DEV", &ea_size))) { 100 if (ea_size == 4) 101 rdev = le32_to_cpu(*(__le32*)ea); 102 kfree(ea); 103 } 104 } 105 if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { 106 brelse(bh); 107 set_nlink(i, 1); 108 i->i_size = 0; 109 i->i_blocks = 1; 110 init_special_inode(i, mode, 111 new_decode_dev(rdev)); 112 return; 113 } 114 } 115 } 116 if (fnode_is_dir(fnode)) { 117 int n_dnodes, n_subdirs; 118 i->i_mode |= S_IFDIR; 119 i->i_op = &hpfs_dir_iops; 120 i->i_fop = &hpfs_dir_ops; 121 hpfs_inode->i_parent_dir = le32_to_cpu(fnode->up); 122 hpfs_inode->i_dno = le32_to_cpu(fnode->u.external[0].disk_secno); 123 if (hpfs_sb(sb)->sb_chk >= 2) { 124 struct buffer_head *bh0; 125 if (hpfs_map_fnode(sb, hpfs_inode->i_parent_dir, &bh0)) brelse(bh0); 126 } 127 n_dnodes = 0; n_subdirs = 0; 128 hpfs_count_dnodes(i->i_sb, hpfs_inode->i_dno, &n_dnodes, &n_subdirs, NULL); 129 i->i_blocks = 4 * n_dnodes; 130 i->i_size = 2048 * n_dnodes; 131 set_nlink(i, 2 + n_subdirs); 132 } else { 133 i->i_mode |= S_IFREG; 134 if (!hpfs_inode->i_ea_mode) i->i_mode &= ~0111; 135 i->i_op = &hpfs_file_iops; 136 i->i_fop = &hpfs_file_ops; 137 set_nlink(i, 1); 138 i->i_size = le32_to_cpu(fnode->file_size); 139 i->i_blocks = ((i->i_size + 511) >> 9) + 1; 140 i->i_data.a_ops = &hpfs_aops; 141 hpfs_i(i)->mmu_private = i->i_size; 142 } 143 brelse(bh); 144 } 145 146 static void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode) 147 { 148 struct hpfs_inode_info *hpfs_inode = hpfs_i(i); 149 /*if (le32_to_cpu(fnode->acl_size_l) || le16_to_cpu(fnode->acl_size_s)) { 150 Some unknown structures like ACL may be in fnode, 151 we'd better not overwrite them 152 hpfs_error(i->i_sb, "fnode %08x has some unknown HPFS386 structures", i->i_ino); 153 } else*/ if (hpfs_sb(i->i_sb)->sb_eas >= 2) { 154 __le32 ea; 155 if (!uid_eq(i->i_uid, hpfs_sb(i->i_sb)->sb_uid) || hpfs_inode->i_ea_uid) { 156 ea = cpu_to_le32(i_uid_read(i)); 157 hpfs_set_ea(i, fnode, "UID", (char*)&ea, 2); 158 hpfs_inode->i_ea_uid = 1; 159 } 160 if (!gid_eq(i->i_gid, hpfs_sb(i->i_sb)->sb_gid) || hpfs_inode->i_ea_gid) { 161 ea = cpu_to_le32(i_gid_read(i)); 162 hpfs_set_ea(i, fnode, "GID", (char *)&ea, 2); 163 hpfs_inode->i_ea_gid = 1; 164 } 165 if (!S_ISLNK(i->i_mode)) 166 if ((i->i_mode != ((hpfs_sb(i->i_sb)->sb_mode & ~(S_ISDIR(i->i_mode) ? 0 : 0111)) 167 | (S_ISDIR(i->i_mode) ? S_IFDIR : S_IFREG)) 168 && i->i_mode != ((hpfs_sb(i->i_sb)->sb_mode & ~(S_ISDIR(i->i_mode) ? 0222 : 0333)) 169 | (S_ISDIR(i->i_mode) ? S_IFDIR : S_IFREG))) || hpfs_inode->i_ea_mode) { 170 ea = cpu_to_le32(i->i_mode); 171 /* sick, but legal */ 172 hpfs_set_ea(i, fnode, "MODE", (char *)&ea, 2); 173 hpfs_inode->i_ea_mode = 1; 174 } 175 if (S_ISBLK(i->i_mode) || S_ISCHR(i->i_mode)) { 176 ea = cpu_to_le32(new_encode_dev(i->i_rdev)); 177 hpfs_set_ea(i, fnode, "DEV", (char *)&ea, 4); 178 } 179 } 180 } 181 182 void hpfs_write_inode(struct inode *i) 183 { 184 struct hpfs_inode_info *hpfs_inode = hpfs_i(i); 185 struct inode *parent; 186 if (i->i_ino == hpfs_sb(i->i_sb)->sb_root) return; 187 if (hpfs_inode->i_rddir_off && !atomic_read(&i->i_count)) { 188 if (*hpfs_inode->i_rddir_off) 189 pr_err("write_inode: some position still there\n"); 190 kfree(hpfs_inode->i_rddir_off); 191 hpfs_inode->i_rddir_off = NULL; 192 } 193 if (!i->i_nlink) { 194 return; 195 } 196 parent = iget_locked(i->i_sb, hpfs_inode->i_parent_dir); 197 if (parent) { 198 hpfs_inode->i_dirty = 0; 199 if (parent->i_state & I_NEW) { 200 hpfs_init_inode(parent); 201 hpfs_read_inode(parent); 202 unlock_new_inode(parent); 203 } 204 hpfs_write_inode_nolock(i); 205 iput(parent); 206 } 207 } 208 209 void hpfs_write_inode_nolock(struct inode *i) 210 { 211 struct hpfs_inode_info *hpfs_inode = hpfs_i(i); 212 struct buffer_head *bh; 213 struct fnode *fnode; 214 struct quad_buffer_head qbh; 215 struct hpfs_dirent *de; 216 if (i->i_ino == hpfs_sb(i->i_sb)->sb_root) return; 217 if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) return; 218 if (i->i_ino != hpfs_sb(i->i_sb)->sb_root && i->i_nlink) { 219 if (!(de = map_fnode_dirent(i->i_sb, i->i_ino, fnode, &qbh))) { 220 brelse(bh); 221 return; 222 } 223 } else de = NULL; 224 if (S_ISREG(i->i_mode)) { 225 fnode->file_size = cpu_to_le32(i->i_size); 226 if (de) de->file_size = cpu_to_le32(i->i_size); 227 } else if (S_ISDIR(i->i_mode)) { 228 fnode->file_size = cpu_to_le32(0); 229 if (de) de->file_size = cpu_to_le32(0); 230 } 231 hpfs_write_inode_ea(i, fnode); 232 if (de) { 233 de->write_date = cpu_to_le32(gmt_to_local(i->i_sb, inode_get_mtime_sec(i))); 234 de->read_date = cpu_to_le32(gmt_to_local(i->i_sb, inode_get_atime_sec(i))); 235 de->creation_date = cpu_to_le32(gmt_to_local(i->i_sb, inode_get_ctime_sec(i))); 236 de->read_only = !(i->i_mode & 0222); 237 de->ea_size = cpu_to_le32(hpfs_inode->i_ea_size); 238 hpfs_mark_4buffers_dirty(&qbh); 239 hpfs_brelse4(&qbh); 240 } 241 if (S_ISDIR(i->i_mode)) { 242 if ((de = map_dirent(i, hpfs_inode->i_dno, "\001\001", 2, NULL, &qbh))) { 243 de->write_date = cpu_to_le32(gmt_to_local(i->i_sb, inode_get_mtime_sec(i))); 244 de->read_date = cpu_to_le32(gmt_to_local(i->i_sb, inode_get_atime_sec(i))); 245 de->creation_date = cpu_to_le32(gmt_to_local(i->i_sb, inode_get_ctime_sec(i))); 246 de->read_only = !(i->i_mode & 0222); 247 de->ea_size = cpu_to_le32(/*hpfs_inode->i_ea_size*/0); 248 de->file_size = cpu_to_le32(0); 249 hpfs_mark_4buffers_dirty(&qbh); 250 hpfs_brelse4(&qbh); 251 } else 252 hpfs_error(i->i_sb, 253 "directory %08lx doesn't have '.' entry", 254 (unsigned long)i->i_ino); 255 } 256 mark_buffer_dirty(bh); 257 brelse(bh); 258 } 259 260 int hpfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, 261 struct iattr *attr) 262 { 263 struct inode *inode = d_inode(dentry); 264 int error = -EINVAL; 265 266 hpfs_lock(inode->i_sb); 267 if (inode->i_ino == hpfs_sb(inode->i_sb)->sb_root) 268 goto out_unlock; 269 if ((attr->ia_valid & ATTR_UID) && 270 from_kuid(&init_user_ns, attr->ia_uid) >= 0x10000) 271 goto out_unlock; 272 if ((attr->ia_valid & ATTR_GID) && 273 from_kgid(&init_user_ns, attr->ia_gid) >= 0x10000) 274 goto out_unlock; 275 if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size) 276 goto out_unlock; 277 278 error = setattr_prepare(&nop_mnt_idmap, dentry, attr); 279 if (error) 280 goto out_unlock; 281 282 if ((attr->ia_valid & ATTR_SIZE) && 283 attr->ia_size != i_size_read(inode)) { 284 error = inode_newsize_ok(inode, attr->ia_size); 285 if (error) 286 goto out_unlock; 287 288 truncate_setsize(inode, attr->ia_size); 289 hpfs_truncate(inode); 290 } 291 292 setattr_copy(&nop_mnt_idmap, inode, attr); 293 294 hpfs_write_inode(inode); 295 296 out_unlock: 297 hpfs_unlock(inode->i_sb); 298 return error; 299 } 300 301 void hpfs_write_if_changed(struct inode *inode) 302 { 303 struct hpfs_inode_info *hpfs_inode = hpfs_i(inode); 304 305 if (hpfs_inode->i_dirty) 306 hpfs_write_inode(inode); 307 } 308 309 void hpfs_evict_inode(struct inode *inode) 310 { 311 truncate_inode_pages_final(&inode->i_data); 312 clear_inode(inode); 313 if (!inode->i_nlink) { 314 hpfs_lock(inode->i_sb); 315 hpfs_remove_fnode(inode->i_sb, inode->i_ino); 316 hpfs_unlock(inode->i_sb); 317 } 318 } 319
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.