/* * linux/fs/hfs/inode.c * * Copyright (C) 1995-1997 Paul H. Hargrove * (C) 2003 Ardis Technologies <roman@ardistech.com> * This file may be distributed under the terms of the GNU General Public License. * * This file contains inode-related functions which do not depend on * which scheme is being used to represent forks. * * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds
*/
switch (inode->i_ino) { case HFS_EXT_CNID:
tree = HFS_SB(sb)->ext_tree; break; case HFS_CAT_CNID:
tree = HFS_SB(sb)->cat_tree; break; default:
BUG(); returnfalse;
}
if (!tree) returnfalse;
if (tree->node_size >= PAGE_SIZE) {
nidx = folio->index >> (tree->node_size_shift - PAGE_SHIFT);
spin_lock(&tree->hash_lock);
node = hfs_bnode_findhash(tree, nidx); if (!node)
; elseif (atomic_read(&node->refcnt))
res = false; if (res && node) {
hfs_bnode_unhash(node);
hfs_bnode_free(node);
}
spin_unlock(&tree->hash_lock);
} else {
nidx = folio->index << (PAGE_SHIFT - tree->node_size_shift);
i = 1 << (PAGE_SHIFT - tree->node_size_shift);
spin_lock(&tree->hash_lock); do {
node = hfs_bnode_findhash(tree, nidx++); if (!node) continue; if (atomic_read(&node->refcnt)) {
res = false; break;
}
hfs_bnode_unhash(node);
hfs_bnode_free(node);
} while (--i && nidx < tree->node_count);
spin_unlock(&tree->hash_lock);
} return res ? try_to_free_buffers(folio) : false;
}
ret = blockdev_direct_IO(iocb, inode, iter, hfs_get_block);
/* * In case of error extending write may have instantiated a few * blocks outside i_size. Trim these off again.
*/ if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) {
loff_t isize = i_size_read(inode);
loff_t end = iocb->ki_pos + count;
if (end > isize)
hfs_write_failed(mapping, end);
}
/* * __hfs_iget() * * Given the MDB for a HFS filesystem, a 'key' and an 'entry' in * the catalog B-tree and the 'type' of the desired file return the * inode for that file/directory or NULL. Note that 'type' indicates * whether we want the actual file or directory, or the corresponding * metadata (AppleDouble header file or CAP metadata file).
*/ struct inode *hfs_iget(struct super_block *sb, struct hfs_cat_key *key, hfs_cat_rec *rec)
{ struct hfs_iget_data data = { key, rec }; struct inode *inode;
u32 cnid;
/* * hfs_notify_change() * * Based very closely on fs/msdos/inode.c by Werner Almesberger * * This is the notify_change() field in the super_operations structure * for HFS file systems. The purpose is to take that changes made to * an inode and apply then in a filesystem-dependent manner. In this * case the process has a few of tasks to do: * 1) prevent changes to the i_uid and i_gid fields. * 2) map file permissions to the closest allowable permissions * 3) Since multiple Linux files can share the same on-disk inode under * HFS (for instance the data and resource forks of a file) a change * to permissions must be applied to all other in-core inodes which * correspond to the same HFS file.
*/
/* no uig/gid changes and limit which mode bits can be set */ if (((attr->ia_valid & ATTR_UID) &&
(!uid_eq(attr->ia_uid, hsb->s_uid))) ||
((attr->ia_valid & ATTR_GID) &&
(!gid_eq(attr->ia_gid, hsb->s_gid))) ||
((attr->ia_valid & ATTR_MODE) &&
((S_ISDIR(inode->i_mode) &&
(attr->ia_mode != inode->i_mode)) ||
(attr->ia_mode & ~HFS_VALID_MODE_BITS)))) { return hsb->s_quiet ? 0 : error;
}
if (attr->ia_valid & ATTR_MODE) { /* Only the 'w' bits can ever change and only all together. */ if (attr->ia_mode & S_IWUSR)
attr->ia_mode = inode->i_mode | S_IWUGO; else
attr->ia_mode = inode->i_mode & ~S_IWUGO;
attr->ia_mode &= S_ISDIR(inode->i_mode) ? ~hsb->s_dir_umask: ~hsb->s_file_umask;
}
if ((attr->ia_valid & ATTR_SIZE) &&
attr->ia_size != i_size_read(inode)) {
inode_dio_wait(inode);
error = inode_newsize_ok(inode, attr->ia_size); if (error) return error;
ret = file_write_and_wait_range(filp, start, end); if (ret) return ret;
inode_lock(inode);
/* sync the inode to buffers */
ret = write_inode_now(inode, 0);
/* sync the superblock to buffers */
sb = inode->i_sb;
flush_delayed_work(&HFS_SB(sb)->mdb_work); /* .. finally sync the buffers to disk */
err = sync_blockdev(sb->s_bdev); if (!ret)
ret = err;
inode_unlock(inode); return ret;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.11Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.