root/fs/hfs/inode.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hfs_writepage
  2. hfs_readpage
  3. hfs_write_failed
  4. hfs_write_begin
  5. hfs_bmap
  6. hfs_releasepage
  7. hfs_direct_IO
  8. hfs_writepages
  9. hfs_new_inode
  10. hfs_delete_inode
  11. hfs_inode_read_fork
  12. hfs_test_inode
  13. hfs_read_inode
  14. hfs_iget
  15. hfs_inode_write_fork
  16. hfs_write_inode
  17. hfs_file_lookup
  18. hfs_evict_inode
  19. hfs_file_open
  20. hfs_file_release
  21. hfs_inode_setattr
  22. hfs_file_fsync

   1 /*
   2  *  linux/fs/hfs/inode.c
   3  *
   4  * Copyright (C) 1995-1997  Paul H. Hargrove
   5  * (C) 2003 Ardis Technologies <roman@ardistech.com>
   6  * This file may be distributed under the terms of the GNU General Public License.
   7  *
   8  * This file contains inode-related functions which do not depend on
   9  * which scheme is being used to represent forks.
  10  *
  11  * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds
  12  */
  13 
  14 #include <linux/pagemap.h>
  15 #include <linux/mpage.h>
  16 #include <linux/sched.h>
  17 #include <linux/cred.h>
  18 #include <linux/uio.h>
  19 #include <linux/xattr.h>
  20 
  21 #include "hfs_fs.h"
  22 #include "btree.h"
  23 
  24 static const struct file_operations hfs_file_operations;
  25 static const struct inode_operations hfs_file_inode_operations;
  26 
  27 /*================ Variable-like macros ================*/
  28 
  29 #define HFS_VALID_MODE_BITS  (S_IFREG | S_IFDIR | S_IRWXUGO)
  30 
  31 static int hfs_writepage(struct page *page, struct writeback_control *wbc)
  32 {
  33         return block_write_full_page(page, hfs_get_block, wbc);
  34 }
  35 
  36 static int hfs_readpage(struct file *file, struct page *page)
  37 {
  38         return block_read_full_page(page, hfs_get_block);
  39 }
  40 
  41 static void hfs_write_failed(struct address_space *mapping, loff_t to)
  42 {
  43         struct inode *inode = mapping->host;
  44 
  45         if (to > inode->i_size) {
  46                 truncate_pagecache(inode, inode->i_size);
  47                 hfs_file_truncate(inode);
  48         }
  49 }
  50 
  51 static int hfs_write_begin(struct file *file, struct address_space *mapping,
  52                         loff_t pos, unsigned len, unsigned flags,
  53                         struct page **pagep, void **fsdata)
  54 {
  55         int ret;
  56 
  57         *pagep = NULL;
  58         ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
  59                                 hfs_get_block,
  60                                 &HFS_I(mapping->host)->phys_size);
  61         if (unlikely(ret))
  62                 hfs_write_failed(mapping, pos + len);
  63 
  64         return ret;
  65 }
  66 
  67 static sector_t hfs_bmap(struct address_space *mapping, sector_t block)
  68 {
  69         return generic_block_bmap(mapping, block, hfs_get_block);
  70 }
  71 
  72 static int hfs_releasepage(struct page *page, gfp_t mask)
  73 {
  74         struct inode *inode = page->mapping->host;
  75         struct super_block *sb = inode->i_sb;
  76         struct hfs_btree *tree;
  77         struct hfs_bnode *node;
  78         u32 nidx;
  79         int i, res = 1;
  80 
  81         switch (inode->i_ino) {
  82         case HFS_EXT_CNID:
  83                 tree = HFS_SB(sb)->ext_tree;
  84                 break;
  85         case HFS_CAT_CNID:
  86                 tree = HFS_SB(sb)->cat_tree;
  87                 break;
  88         default:
  89                 BUG();
  90                 return 0;
  91         }
  92 
  93         if (!tree)
  94                 return 0;
  95 
  96         if (tree->node_size >= PAGE_SIZE) {
  97                 nidx = page->index >> (tree->node_size_shift - PAGE_SHIFT);
  98                 spin_lock(&tree->hash_lock);
  99                 node = hfs_bnode_findhash(tree, nidx);
 100                 if (!node)
 101                         ;
 102                 else if (atomic_read(&node->refcnt))
 103                         res = 0;
 104                 if (res && node) {
 105                         hfs_bnode_unhash(node);
 106                         hfs_bnode_free(node);
 107                 }
 108                 spin_unlock(&tree->hash_lock);
 109         } else {
 110                 nidx = page->index << (PAGE_SHIFT - tree->node_size_shift);
 111                 i = 1 << (PAGE_SHIFT - tree->node_size_shift);
 112                 spin_lock(&tree->hash_lock);
 113                 do {
 114                         node = hfs_bnode_findhash(tree, nidx++);
 115                         if (!node)
 116                                 continue;
 117                         if (atomic_read(&node->refcnt)) {
 118                                 res = 0;
 119                                 break;
 120                         }
 121                         hfs_bnode_unhash(node);
 122                         hfs_bnode_free(node);
 123                 } while (--i && nidx < tree->node_count);
 124                 spin_unlock(&tree->hash_lock);
 125         }
 126         return res ? try_to_free_buffers(page) : 0;
 127 }
 128 
 129 static ssize_t hfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 130 {
 131         struct file *file = iocb->ki_filp;
 132         struct address_space *mapping = file->f_mapping;
 133         struct inode *inode = mapping->host;
 134         size_t count = iov_iter_count(iter);
 135         ssize_t ret;
 136 
 137         ret = blockdev_direct_IO(iocb, inode, iter, hfs_get_block);
 138 
 139         /*
 140          * In case of error extending write may have instantiated a few
 141          * blocks outside i_size. Trim these off again.
 142          */
 143         if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) {
 144                 loff_t isize = i_size_read(inode);
 145                 loff_t end = iocb->ki_pos + count;
 146 
 147                 if (end > isize)
 148                         hfs_write_failed(mapping, end);
 149         }
 150 
 151         return ret;
 152 }
 153 
 154 static int hfs_writepages(struct address_space *mapping,
 155                           struct writeback_control *wbc)
 156 {
 157         return mpage_writepages(mapping, wbc, hfs_get_block);
 158 }
 159 
 160 const struct address_space_operations hfs_btree_aops = {
 161         .readpage       = hfs_readpage,
 162         .writepage      = hfs_writepage,
 163         .write_begin    = hfs_write_begin,
 164         .write_end      = generic_write_end,
 165         .bmap           = hfs_bmap,
 166         .releasepage    = hfs_releasepage,
 167 };
 168 
 169 const struct address_space_operations hfs_aops = {
 170         .readpage       = hfs_readpage,
 171         .writepage      = hfs_writepage,
 172         .write_begin    = hfs_write_begin,
 173         .write_end      = generic_write_end,
 174         .bmap           = hfs_bmap,
 175         .direct_IO      = hfs_direct_IO,
 176         .writepages     = hfs_writepages,
 177 };
 178 
 179 /*
 180  * hfs_new_inode
 181  */
 182 struct inode *hfs_new_inode(struct inode *dir, const struct qstr *name, umode_t mode)
 183 {
 184         struct super_block *sb = dir->i_sb;
 185         struct inode *inode = new_inode(sb);
 186         if (!inode)
 187                 return NULL;
 188 
 189         mutex_init(&HFS_I(inode)->extents_lock);
 190         INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list);
 191         spin_lock_init(&HFS_I(inode)->open_dir_lock);
 192         hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name);
 193         inode->i_ino = HFS_SB(sb)->next_id++;
 194         inode->i_mode = mode;
 195         inode->i_uid = current_fsuid();
 196         inode->i_gid = current_fsgid();
 197         set_nlink(inode, 1);
 198         inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
 199         HFS_I(inode)->flags = 0;
 200         HFS_I(inode)->rsrc_inode = NULL;
 201         HFS_I(inode)->fs_blocks = 0;
 202         if (S_ISDIR(mode)) {
 203                 inode->i_size = 2;
 204                 HFS_SB(sb)->folder_count++;
 205                 if (dir->i_ino == HFS_ROOT_CNID)
 206                         HFS_SB(sb)->root_dirs++;
 207                 inode->i_op = &hfs_dir_inode_operations;
 208                 inode->i_fop = &hfs_dir_operations;
 209                 inode->i_mode |= S_IRWXUGO;
 210                 inode->i_mode &= ~HFS_SB(inode->i_sb)->s_dir_umask;
 211         } else if (S_ISREG(mode)) {
 212                 HFS_I(inode)->clump_blocks = HFS_SB(sb)->clumpablks;
 213                 HFS_SB(sb)->file_count++;
 214                 if (dir->i_ino == HFS_ROOT_CNID)
 215                         HFS_SB(sb)->root_files++;
 216                 inode->i_op = &hfs_file_inode_operations;
 217                 inode->i_fop = &hfs_file_operations;
 218                 inode->i_mapping->a_ops = &hfs_aops;
 219                 inode->i_mode |= S_IRUGO|S_IXUGO;
 220                 if (mode & S_IWUSR)
 221                         inode->i_mode |= S_IWUGO;
 222                 inode->i_mode &= ~HFS_SB(inode->i_sb)->s_file_umask;
 223                 HFS_I(inode)->phys_size = 0;
 224                 HFS_I(inode)->alloc_blocks = 0;
 225                 HFS_I(inode)->first_blocks = 0;
 226                 HFS_I(inode)->cached_start = 0;
 227                 HFS_I(inode)->cached_blocks = 0;
 228                 memset(HFS_I(inode)->first_extents, 0, sizeof(hfs_extent_rec));
 229                 memset(HFS_I(inode)->cached_extents, 0, sizeof(hfs_extent_rec));
 230         }
 231         insert_inode_hash(inode);
 232         mark_inode_dirty(inode);
 233         set_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags);
 234         hfs_mark_mdb_dirty(sb);
 235 
 236         return inode;
 237 }
 238 
 239 void hfs_delete_inode(struct inode *inode)
 240 {
 241         struct super_block *sb = inode->i_sb;
 242 
 243         hfs_dbg(INODE, "delete_inode: %lu\n", inode->i_ino);
 244         if (S_ISDIR(inode->i_mode)) {
 245                 HFS_SB(sb)->folder_count--;
 246                 if (HFS_I(inode)->cat_key.ParID == cpu_to_be32(HFS_ROOT_CNID))
 247                         HFS_SB(sb)->root_dirs--;
 248                 set_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags);
 249                 hfs_mark_mdb_dirty(sb);
 250                 return;
 251         }
 252         HFS_SB(sb)->file_count--;
 253         if (HFS_I(inode)->cat_key.ParID == cpu_to_be32(HFS_ROOT_CNID))
 254                 HFS_SB(sb)->root_files--;
 255         if (S_ISREG(inode->i_mode)) {
 256                 if (!inode->i_nlink) {
 257                         inode->i_size = 0;
 258                         hfs_file_truncate(inode);
 259                 }
 260         }
 261         set_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags);
 262         hfs_mark_mdb_dirty(sb);
 263 }
 264 
 265 void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext,
 266                          __be32 __log_size, __be32 phys_size, u32 clump_size)
 267 {
 268         struct super_block *sb = inode->i_sb;
 269         u32 log_size = be32_to_cpu(__log_size);
 270         u16 count;
 271         int i;
 272 
 273         memcpy(HFS_I(inode)->first_extents, ext, sizeof(hfs_extent_rec));
 274         for (count = 0, i = 0; i < 3; i++)
 275                 count += be16_to_cpu(ext[i].count);
 276         HFS_I(inode)->first_blocks = count;
 277 
 278         inode->i_size = HFS_I(inode)->phys_size = log_size;
 279         HFS_I(inode)->fs_blocks = (log_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
 280         inode_set_bytes(inode, HFS_I(inode)->fs_blocks << sb->s_blocksize_bits);
 281         HFS_I(inode)->alloc_blocks = be32_to_cpu(phys_size) /
 282                                      HFS_SB(sb)->alloc_blksz;
 283         HFS_I(inode)->clump_blocks = clump_size / HFS_SB(sb)->alloc_blksz;
 284         if (!HFS_I(inode)->clump_blocks)
 285                 HFS_I(inode)->clump_blocks = HFS_SB(sb)->clumpablks;
 286 }
 287 
 288 struct hfs_iget_data {
 289         struct hfs_cat_key *key;
 290         hfs_cat_rec *rec;
 291 };
 292 
 293 static int hfs_test_inode(struct inode *inode, void *data)
 294 {
 295         struct hfs_iget_data *idata = data;
 296         hfs_cat_rec *rec;
 297 
 298         rec = idata->rec;
 299         switch (rec->type) {
 300         case HFS_CDR_DIR:
 301                 return inode->i_ino == be32_to_cpu(rec->dir.DirID);
 302         case HFS_CDR_FIL:
 303                 return inode->i_ino == be32_to_cpu(rec->file.FlNum);
 304         default:
 305                 BUG();
 306                 return 1;
 307         }
 308 }
 309 
 310 /*
 311  * hfs_read_inode
 312  */
 313 static int hfs_read_inode(struct inode *inode, void *data)
 314 {
 315         struct hfs_iget_data *idata = data;
 316         struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
 317         hfs_cat_rec *rec;
 318 
 319         HFS_I(inode)->flags = 0;
 320         HFS_I(inode)->rsrc_inode = NULL;
 321         mutex_init(&HFS_I(inode)->extents_lock);
 322         INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list);
 323         spin_lock_init(&HFS_I(inode)->open_dir_lock);
 324 
 325         /* Initialize the inode */
 326         inode->i_uid = hsb->s_uid;
 327         inode->i_gid = hsb->s_gid;
 328         set_nlink(inode, 1);
 329 
 330         if (idata->key)
 331                 HFS_I(inode)->cat_key = *idata->key;
 332         else
 333                 HFS_I(inode)->flags |= HFS_FLG_RSRC;
 334         HFS_I(inode)->tz_secondswest = sys_tz.tz_minuteswest * 60;
 335 
 336         rec = idata->rec;
 337         switch (rec->type) {
 338         case HFS_CDR_FIL:
 339                 if (!HFS_IS_RSRC(inode)) {
 340                         hfs_inode_read_fork(inode, rec->file.ExtRec, rec->file.LgLen,
 341                                             rec->file.PyLen, be16_to_cpu(rec->file.ClpSize));
 342                 } else {
 343                         hfs_inode_read_fork(inode, rec->file.RExtRec, rec->file.RLgLen,
 344                                             rec->file.RPyLen, be16_to_cpu(rec->file.ClpSize));
 345                 }
 346 
 347                 inode->i_ino = be32_to_cpu(rec->file.FlNum);
 348                 inode->i_mode = S_IRUGO | S_IXUGO;
 349                 if (!(rec->file.Flags & HFS_FIL_LOCK))
 350                         inode->i_mode |= S_IWUGO;
 351                 inode->i_mode &= ~hsb->s_file_umask;
 352                 inode->i_mode |= S_IFREG;
 353                 inode->i_ctime = inode->i_atime = inode->i_mtime =
 354                                 timespec_to_timespec64(hfs_m_to_utime(rec->file.MdDat));
 355                 inode->i_op = &hfs_file_inode_operations;
 356                 inode->i_fop = &hfs_file_operations;
 357                 inode->i_mapping->a_ops = &hfs_aops;
 358                 break;
 359         case HFS_CDR_DIR:
 360                 inode->i_ino = be32_to_cpu(rec->dir.DirID);
 361                 inode->i_size = be16_to_cpu(rec->dir.Val) + 2;
 362                 HFS_I(inode)->fs_blocks = 0;
 363                 inode->i_mode = S_IFDIR | (S_IRWXUGO & ~hsb->s_dir_umask);
 364                 inode->i_ctime = inode->i_atime = inode->i_mtime =
 365                                 timespec_to_timespec64(hfs_m_to_utime(rec->dir.MdDat));
 366                 inode->i_op = &hfs_dir_inode_operations;
 367                 inode->i_fop = &hfs_dir_operations;
 368                 break;
 369         default:
 370                 make_bad_inode(inode);
 371         }
 372         return 0;
 373 }
 374 
 375 /*
 376  * __hfs_iget()
 377  *
 378  * Given the MDB for a HFS filesystem, a 'key' and an 'entry' in
 379  * the catalog B-tree and the 'type' of the desired file return the
 380  * inode for that file/directory or NULL.  Note that 'type' indicates
 381  * whether we want the actual file or directory, or the corresponding
 382  * metadata (AppleDouble header file or CAP metadata file).
 383  */
 384 struct inode *hfs_iget(struct super_block *sb, struct hfs_cat_key *key, hfs_cat_rec *rec)
 385 {
 386         struct hfs_iget_data data = { key, rec };
 387         struct inode *inode;
 388         u32 cnid;
 389 
 390         switch (rec->type) {
 391         case HFS_CDR_DIR:
 392                 cnid = be32_to_cpu(rec->dir.DirID);
 393                 break;
 394         case HFS_CDR_FIL:
 395                 cnid = be32_to_cpu(rec->file.FlNum);
 396                 break;
 397         default:
 398                 return NULL;
 399         }
 400         inode = iget5_locked(sb, cnid, hfs_test_inode, hfs_read_inode, &data);
 401         if (inode && (inode->i_state & I_NEW))
 402                 unlock_new_inode(inode);
 403         return inode;
 404 }
 405 
 406 void hfs_inode_write_fork(struct inode *inode, struct hfs_extent *ext,
 407                           __be32 *log_size, __be32 *phys_size)
 408 {
 409         memcpy(ext, HFS_I(inode)->first_extents, sizeof(hfs_extent_rec));
 410 
 411         if (log_size)
 412                 *log_size = cpu_to_be32(inode->i_size);
 413         if (phys_size)
 414                 *phys_size = cpu_to_be32(HFS_I(inode)->alloc_blocks *
 415                                          HFS_SB(inode->i_sb)->alloc_blksz);
 416 }
 417 
 418 int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
 419 {
 420         struct inode *main_inode = inode;
 421         struct hfs_find_data fd;
 422         hfs_cat_rec rec;
 423         int res;
 424 
 425         hfs_dbg(INODE, "hfs_write_inode: %lu\n", inode->i_ino);
 426         res = hfs_ext_write_extent(inode);
 427         if (res)
 428                 return res;
 429 
 430         if (inode->i_ino < HFS_FIRSTUSER_CNID) {
 431                 switch (inode->i_ino) {
 432                 case HFS_ROOT_CNID:
 433                         break;
 434                 case HFS_EXT_CNID:
 435                         hfs_btree_write(HFS_SB(inode->i_sb)->ext_tree);
 436                         return 0;
 437                 case HFS_CAT_CNID:
 438                         hfs_btree_write(HFS_SB(inode->i_sb)->cat_tree);
 439                         return 0;
 440                 default:
 441                         BUG();
 442                         return -EIO;
 443                 }
 444         }
 445 
 446         if (HFS_IS_RSRC(inode))
 447                 main_inode = HFS_I(inode)->rsrc_inode;
 448 
 449         if (!main_inode->i_nlink)
 450                 return 0;
 451 
 452         if (hfs_find_init(HFS_SB(main_inode->i_sb)->cat_tree, &fd))
 453                 /* panic? */
 454                 return -EIO;
 455 
 456         fd.search_key->cat = HFS_I(main_inode)->cat_key;
 457         if (hfs_brec_find(&fd))
 458                 /* panic? */
 459                 goto out;
 460 
 461         if (S_ISDIR(main_inode->i_mode)) {
 462                 if (fd.entrylength < sizeof(struct hfs_cat_dir))
 463                         /* panic? */;
 464                 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
 465                            sizeof(struct hfs_cat_dir));
 466                 if (rec.type != HFS_CDR_DIR ||
 467                     be32_to_cpu(rec.dir.DirID) != inode->i_ino) {
 468                 }
 469 
 470                 rec.dir.MdDat = hfs_u_to_mtime(inode->i_mtime);
 471                 rec.dir.Val = cpu_to_be16(inode->i_size - 2);
 472 
 473                 hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
 474                             sizeof(struct hfs_cat_dir));
 475         } else if (HFS_IS_RSRC(inode)) {
 476                 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
 477                                sizeof(struct hfs_cat_file));
 478                 hfs_inode_write_fork(inode, rec.file.RExtRec,
 479                                      &rec.file.RLgLen, &rec.file.RPyLen);
 480                 hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
 481                                 sizeof(struct hfs_cat_file));
 482         } else {
 483                 if (fd.entrylength < sizeof(struct hfs_cat_file))
 484                         /* panic? */;
 485                 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
 486                            sizeof(struct hfs_cat_file));
 487                 if (rec.type != HFS_CDR_FIL ||
 488                     be32_to_cpu(rec.file.FlNum) != inode->i_ino) {
 489                 }
 490 
 491                 if (inode->i_mode & S_IWUSR)
 492                         rec.file.Flags &= ~HFS_FIL_LOCK;
 493                 else
 494                         rec.file.Flags |= HFS_FIL_LOCK;
 495                 hfs_inode_write_fork(inode, rec.file.ExtRec, &rec.file.LgLen, &rec.file.PyLen);
 496                 rec.file.MdDat = hfs_u_to_mtime(inode->i_mtime);
 497 
 498                 hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
 499                             sizeof(struct hfs_cat_file));
 500         }
 501 out:
 502         hfs_find_exit(&fd);
 503         return 0;
 504 }
 505 
 506 static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry,
 507                                       unsigned int flags)
 508 {
 509         struct inode *inode = NULL;
 510         hfs_cat_rec rec;
 511         struct hfs_find_data fd;
 512         int res;
 513 
 514         if (HFS_IS_RSRC(dir) || strcmp(dentry->d_name.name, "rsrc"))
 515                 goto out;
 516 
 517         inode = HFS_I(dir)->rsrc_inode;
 518         if (inode)
 519                 goto out;
 520 
 521         inode = new_inode(dir->i_sb);
 522         if (!inode)
 523                 return ERR_PTR(-ENOMEM);
 524 
 525         res = hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd);
 526         if (res) {
 527                 iput(inode);
 528                 return ERR_PTR(res);
 529         }
 530         fd.search_key->cat = HFS_I(dir)->cat_key;
 531         res = hfs_brec_read(&fd, &rec, sizeof(rec));
 532         if (!res) {
 533                 struct hfs_iget_data idata = { NULL, &rec };
 534                 hfs_read_inode(inode, &idata);
 535         }
 536         hfs_find_exit(&fd);
 537         if (res) {
 538                 iput(inode);
 539                 return ERR_PTR(res);
 540         }
 541         HFS_I(inode)->rsrc_inode = dir;
 542         HFS_I(dir)->rsrc_inode = inode;
 543         igrab(dir);
 544         inode_fake_hash(inode);
 545         mark_inode_dirty(inode);
 546         dont_mount(dentry);
 547 out:
 548         return d_splice_alias(inode, dentry);
 549 }
 550 
 551 void hfs_evict_inode(struct inode *inode)
 552 {
 553         truncate_inode_pages_final(&inode->i_data);
 554         clear_inode(inode);
 555         if (HFS_IS_RSRC(inode) && HFS_I(inode)->rsrc_inode) {
 556                 HFS_I(HFS_I(inode)->rsrc_inode)->rsrc_inode = NULL;
 557                 iput(HFS_I(inode)->rsrc_inode);
 558         }
 559 }
 560 
 561 static int hfs_file_open(struct inode *inode, struct file *file)
 562 {
 563         if (HFS_IS_RSRC(inode))
 564                 inode = HFS_I(inode)->rsrc_inode;
 565         atomic_inc(&HFS_I(inode)->opencnt);
 566         return 0;
 567 }
 568 
 569 static int hfs_file_release(struct inode *inode, struct file *file)
 570 {
 571         //struct super_block *sb = inode->i_sb;
 572 
 573         if (HFS_IS_RSRC(inode))
 574                 inode = HFS_I(inode)->rsrc_inode;
 575         if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) {
 576                 inode_lock(inode);
 577                 hfs_file_truncate(inode);
 578                 //if (inode->i_flags & S_DEAD) {
 579                 //      hfs_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
 580                 //      hfs_delete_inode(inode);
 581                 //}
 582                 inode_unlock(inode);
 583         }
 584         return 0;
 585 }
 586 
 587 /*
 588  * hfs_notify_change()
 589  *
 590  * Based very closely on fs/msdos/inode.c by Werner Almesberger
 591  *
 592  * This is the notify_change() field in the super_operations structure
 593  * for HFS file systems.  The purpose is to take that changes made to
 594  * an inode and apply then in a filesystem-dependent manner.  In this
 595  * case the process has a few of tasks to do:
 596  *  1) prevent changes to the i_uid and i_gid fields.
 597  *  2) map file permissions to the closest allowable permissions
 598  *  3) Since multiple Linux files can share the same on-disk inode under
 599  *     HFS (for instance the data and resource forks of a file) a change
 600  *     to permissions must be applied to all other in-core inodes which
 601  *     correspond to the same HFS file.
 602  */
 603 
 604 int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr)
 605 {
 606         struct inode *inode = d_inode(dentry);
 607         struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
 608         int error;
 609 
 610         error = setattr_prepare(dentry, attr); /* basic permission checks */
 611         if (error)
 612                 return error;
 613 
 614         /* no uig/gid changes and limit which mode bits can be set */
 615         if (((attr->ia_valid & ATTR_UID) &&
 616              (!uid_eq(attr->ia_uid, hsb->s_uid))) ||
 617             ((attr->ia_valid & ATTR_GID) &&
 618              (!gid_eq(attr->ia_gid, hsb->s_gid))) ||
 619             ((attr->ia_valid & ATTR_MODE) &&
 620              ((S_ISDIR(inode->i_mode) &&
 621                (attr->ia_mode != inode->i_mode)) ||
 622               (attr->ia_mode & ~HFS_VALID_MODE_BITS)))) {
 623                 return hsb->s_quiet ? 0 : error;
 624         }
 625 
 626         if (attr->ia_valid & ATTR_MODE) {
 627                 /* Only the 'w' bits can ever change and only all together. */
 628                 if (attr->ia_mode & S_IWUSR)
 629                         attr->ia_mode = inode->i_mode | S_IWUGO;
 630                 else
 631                         attr->ia_mode = inode->i_mode & ~S_IWUGO;
 632                 attr->ia_mode &= S_ISDIR(inode->i_mode) ? ~hsb->s_dir_umask: ~hsb->s_file_umask;
 633         }
 634 
 635         if ((attr->ia_valid & ATTR_SIZE) &&
 636             attr->ia_size != i_size_read(inode)) {
 637                 inode_dio_wait(inode);
 638 
 639                 error = inode_newsize_ok(inode, attr->ia_size);
 640                 if (error)
 641                         return error;
 642 
 643                 truncate_setsize(inode, attr->ia_size);
 644                 hfs_file_truncate(inode);
 645                 inode->i_atime = inode->i_mtime = inode->i_ctime =
 646                                                   current_time(inode);
 647         }
 648 
 649         setattr_copy(inode, attr);
 650         mark_inode_dirty(inode);
 651         return 0;
 652 }
 653 
 654 static int hfs_file_fsync(struct file *filp, loff_t start, loff_t end,
 655                           int datasync)
 656 {
 657         struct inode *inode = filp->f_mapping->host;
 658         struct super_block * sb;
 659         int ret, err;
 660 
 661         ret = file_write_and_wait_range(filp, start, end);
 662         if (ret)
 663                 return ret;
 664         inode_lock(inode);
 665 
 666         /* sync the inode to buffers */
 667         ret = write_inode_now(inode, 0);
 668 
 669         /* sync the superblock to buffers */
 670         sb = inode->i_sb;
 671         flush_delayed_work(&HFS_SB(sb)->mdb_work);
 672         /* .. finally sync the buffers to disk */
 673         err = sync_blockdev(sb->s_bdev);
 674         if (!ret)
 675                 ret = err;
 676         inode_unlock(inode);
 677         return ret;
 678 }
 679 
 680 static const struct file_operations hfs_file_operations = {
 681         .llseek         = generic_file_llseek,
 682         .read_iter      = generic_file_read_iter,
 683         .write_iter     = generic_file_write_iter,
 684         .mmap           = generic_file_mmap,
 685         .splice_read    = generic_file_splice_read,
 686         .fsync          = hfs_file_fsync,
 687         .open           = hfs_file_open,
 688         .release        = hfs_file_release,
 689 };
 690 
 691 static const struct inode_operations hfs_file_inode_operations = {
 692         .lookup         = hfs_file_lookup,
 693         .setattr        = hfs_inode_setattr,
 694         .listxattr      = generic_listxattr,
 695 };

/* [<][>][^][v][top][bottom][index][help] */