diff options
Diffstat (limited to 'ANDROID_3.4.5/fs/hfs/dir.c')
-rw-r--r-- | ANDROID_3.4.5/fs/hfs/dir.c | 316 |
1 files changed, 0 insertions, 316 deletions
diff --git a/ANDROID_3.4.5/fs/hfs/dir.c b/ANDROID_3.4.5/fs/hfs/dir.c deleted file mode 100644 index 62fc14ea..00000000 --- a/ANDROID_3.4.5/fs/hfs/dir.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * linux/fs/hfs/dir.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 directory-related functions independent of which - * scheme is being used to represent forks. - * - * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds - */ - -#include "hfs_fs.h" -#include "btree.h" - -/* - * hfs_lookup() - */ -static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry, - struct nameidata *nd) -{ - hfs_cat_rec rec; - struct hfs_find_data fd; - struct inode *inode = NULL; - int res; - - hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); - hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name); - res = hfs_brec_read(&fd, &rec, sizeof(rec)); - if (res) { - hfs_find_exit(&fd); - if (res == -ENOENT) { - /* No such entry */ - inode = NULL; - goto done; - } - return ERR_PTR(res); - } - inode = hfs_iget(dir->i_sb, &fd.search_key->cat, &rec); - hfs_find_exit(&fd); - if (!inode) - return ERR_PTR(-EACCES); -done: - d_add(dentry, inode); - return NULL; -} - -/* - * hfs_readdir - */ -static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) -{ - struct inode *inode = filp->f_path.dentry->d_inode; - struct super_block *sb = inode->i_sb; - int len, err; - char strbuf[HFS_MAX_NAMELEN]; - union hfs_cat_rec entry; - struct hfs_find_data fd; - struct hfs_readdir_data *rd; - u16 type; - - if (filp->f_pos >= inode->i_size) - return 0; - - hfs_find_init(HFS_SB(sb)->cat_tree, &fd); - hfs_cat_build_key(sb, fd.search_key, inode->i_ino, NULL); - err = hfs_brec_find(&fd); - if (err) - goto out; - - switch ((u32)filp->f_pos) { - case 0: - /* This is completely artificial... */ - if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR)) - goto out; - filp->f_pos++; - /* fall through */ - case 1: - if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { - err = -EIO; - goto out; - } - - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); - if (entry.type != HFS_CDR_THD) { - printk(KERN_ERR "hfs: bad catalog folder thread\n"); - err = -EIO; - goto out; - } - //if (fd.entrylength < HFS_MIN_THREAD_SZ) { - // printk(KERN_ERR "hfs: truncated catalog thread\n"); - // err = -EIO; - // goto out; - //} - if (filldir(dirent, "..", 2, 1, - be32_to_cpu(entry.thread.ParID), DT_DIR)) - goto out; - filp->f_pos++; - /* fall through */ - default: - if (filp->f_pos >= inode->i_size) - goto out; - err = hfs_brec_goto(&fd, filp->f_pos - 1); - if (err) - goto out; - } - - for (;;) { - if (be32_to_cpu(fd.key->cat.ParID) != inode->i_ino) { - printk(KERN_ERR "hfs: walked past end of dir\n"); - err = -EIO; - goto out; - } - - if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { - err = -EIO; - goto out; - } - - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); - type = entry.type; - len = hfs_mac2asc(sb, strbuf, &fd.key->cat.CName); - if (type == HFS_CDR_DIR) { - if (fd.entrylength < sizeof(struct hfs_cat_dir)) { - printk(KERN_ERR "hfs: small dir entry\n"); - err = -EIO; - goto out; - } - if (filldir(dirent, strbuf, len, filp->f_pos, - be32_to_cpu(entry.dir.DirID), DT_DIR)) - break; - } else if (type == HFS_CDR_FIL) { - if (fd.entrylength < sizeof(struct hfs_cat_file)) { - printk(KERN_ERR "hfs: small file entry\n"); - err = -EIO; - goto out; - } - if (filldir(dirent, strbuf, len, filp->f_pos, - be32_to_cpu(entry.file.FlNum), DT_REG)) - break; - } else { - printk(KERN_ERR "hfs: bad catalog entry type %d\n", type); - err = -EIO; - goto out; - } - filp->f_pos++; - if (filp->f_pos >= inode->i_size) - goto out; - err = hfs_brec_goto(&fd, 1); - if (err) - goto out; - } - rd = filp->private_data; - if (!rd) { - rd = kmalloc(sizeof(struct hfs_readdir_data), GFP_KERNEL); - if (!rd) { - err = -ENOMEM; - goto out; - } - filp->private_data = rd; - rd->file = filp; - list_add(&rd->list, &HFS_I(inode)->open_dir_list); - } - memcpy(&rd->key, &fd.key, sizeof(struct hfs_cat_key)); -out: - hfs_find_exit(&fd); - return err; -} - -static int hfs_dir_release(struct inode *inode, struct file *file) -{ - struct hfs_readdir_data *rd = file->private_data; - if (rd) { - list_del(&rd->list); - kfree(rd); - } - return 0; -} - -/* - * hfs_create() - * - * This is the create() entry in the inode_operations structure for - * regular HFS directories. The purpose is to create a new file in - * a directory and return a corresponding inode, given the inode for - * the directory and the name (and its length) of the new file. - */ -static int hfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - struct nameidata *nd) -{ - struct inode *inode; - int res; - - inode = hfs_new_inode(dir, &dentry->d_name, mode); - if (!inode) - return -ENOSPC; - - res = hfs_cat_create(inode->i_ino, dir, &dentry->d_name, inode); - if (res) { - clear_nlink(inode); - hfs_delete_inode(inode); - iput(inode); - return res; - } - d_instantiate(dentry, inode); - mark_inode_dirty(inode); - return 0; -} - -/* - * hfs_mkdir() - * - * This is the mkdir() entry in the inode_operations structure for - * regular HFS directories. The purpose is to create a new directory - * in a directory, given the inode for the parent directory and the - * name (and its length) of the new directory. - */ -static int hfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) -{ - struct inode *inode; - int res; - - inode = hfs_new_inode(dir, &dentry->d_name, S_IFDIR | mode); - if (!inode) - return -ENOSPC; - - res = hfs_cat_create(inode->i_ino, dir, &dentry->d_name, inode); - if (res) { - clear_nlink(inode); - hfs_delete_inode(inode); - iput(inode); - return res; - } - d_instantiate(dentry, inode); - mark_inode_dirty(inode); - return 0; -} - -/* - * hfs_remove() - * - * This serves as both unlink() and rmdir() in the inode_operations - * structure for regular HFS directories. The purpose is to delete - * an existing child, given the inode for the parent directory and - * the name (and its length) of the existing directory. - * - * HFS does not have hardlinks, so both rmdir and unlink set the - * link count to 0. The only difference is the emptiness check. - */ -static int hfs_remove(struct inode *dir, struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - int res; - - if (S_ISDIR(inode->i_mode) && inode->i_size != 2) - return -ENOTEMPTY; - res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); - if (res) - return res; - clear_nlink(inode); - inode->i_ctime = CURRENT_TIME_SEC; - hfs_delete_inode(inode); - mark_inode_dirty(inode); - return 0; -} - -/* - * hfs_rename() - * - * This is the rename() entry in the inode_operations structure for - * regular HFS directories. The purpose is to rename an existing - * file or directory, given the inode for the current directory and - * the name (and its length) of the existing file/directory and the - * inode for the new directory and the name (and its length) of the - * new file/directory. - * XXX: how do you handle must_be dir? - */ -static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) -{ - int res; - - /* Unlink destination if it already exists */ - if (new_dentry->d_inode) { - res = hfs_remove(new_dir, new_dentry); - if (res) - return res; - } - - res = hfs_cat_move(old_dentry->d_inode->i_ino, - old_dir, &old_dentry->d_name, - new_dir, &new_dentry->d_name); - if (!res) - hfs_cat_build_key(old_dir->i_sb, - (btree_key *)&HFS_I(old_dentry->d_inode)->cat_key, - new_dir->i_ino, &new_dentry->d_name); - return res; -} - -const struct file_operations hfs_dir_operations = { - .read = generic_read_dir, - .readdir = hfs_readdir, - .llseek = generic_file_llseek, - .release = hfs_dir_release, -}; - -const struct inode_operations hfs_dir_inode_operations = { - .create = hfs_create, - .lookup = hfs_lookup, - .unlink = hfs_remove, - .mkdir = hfs_mkdir, - .rmdir = hfs_remove, - .rename = hfs_rename, - .setattr = hfs_inode_setattr, -}; |