// SPDX-License-Identifier: GPL-2.0 /* * linux/fs/ext2/dir.c * * Copyright (C) 1992, 1993, 1994, 1995 * Remy Card ([email protected]) * Laboratoire MASI - Institut Blaise Pascal * Universite Pierre et Marie Curie (Paris VI) * * from * * linux/fs/minix/dir.c * * Copyright (C) 1991, 1992 Linus Torvalds * * ext2 directory handling functions * * Big-endian to little-endian byte-swapping/bitmaps by * David S. Miller ([email protected]), 1995 * * All code that works with directory layout had been switched to pagecache * and moved here. AV */ #include "ext2.h" #include <linux/buffer_head.h> #include <linux/pagemap.h> #include <linux/swap.h> #include <linux/iversion.h> ext2_dirent; /* * Tests against MAX_REC_LEN etc were put in place for 64k block * sizes; if that is not possible on this arch, we can skip * those tests and speed things up. */ static inline unsigned ext2_rec_len_from_disk(__le16 dlen) { … } static inline __le16 ext2_rec_len_to_disk(unsigned len) { … } /* * ext2 uses block-sized chunks. Arguably, sector-sized ones would be * more robust, but we have what we have */ static inline unsigned ext2_chunk_size(struct inode *inode) { … } /* * Return the offset into page `page_nr' of the last valid * byte in that page, plus one. */ static unsigned ext2_last_byte(struct inode *inode, unsigned long page_nr) { … } static void ext2_commit_chunk(struct folio *folio, loff_t pos, unsigned len) { … } static bool ext2_check_folio(struct folio *folio, int quiet, char *kaddr) { … } /* * Calls to ext2_get_folio()/folio_release_kmap() must be nested according * to the rules documented in kmap_local_folio()/kunmap_local(). * * NOTE: ext2_find_entry() and ext2_dotdot() act as a call * to folio_release_kmap() and should be treated as a call to * folio_release_kmap() for nesting purposes. */ static void *ext2_get_folio(struct inode *dir, unsigned long n, int quiet, struct folio **foliop) { … } /* * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure. * * len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller. */ static inline int ext2_match (int len, const char * const name, struct ext2_dir_entry_2 * de) { … } /* * p is at least 6 bytes before the end of page */ static inline ext2_dirent *ext2_next_entry(ext2_dirent *p) { … } static inline unsigned ext2_validate_entry(char *base, unsigned offset, unsigned mask) { … } static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode) { … } static int ext2_readdir(struct file *file, struct dir_context *ctx) { … } /* * ext2_find_entry() * * finds an entry in the specified directory with the wanted name. It * returns the page in which the entry was found (as a parameter - res_page), * and the entry itself. Page is returned mapped and unlocked. * Entry is guaranteed to be valid. * * On Success folio_release_kmap() should be called on *foliop. * * NOTE: Calls to ext2_get_folio()/folio_release_kmap() must be nested * according to the rules documented in kmap_local_folio()/kunmap_local(). * * ext2_find_entry() and ext2_dotdot() act as a call to ext2_get_folio() * and should be treated as a call to ext2_get_folio() for nesting * purposes. */ struct ext2_dir_entry_2 *ext2_find_entry (struct inode *dir, const struct qstr *child, struct folio **foliop) { … } /* * Return the '..' directory entry and the page in which the entry was found * (as a parameter - p). * * On Success folio_release_kmap() should be called on *foliop. * * NOTE: Calls to ext2_get_folio()/folio_release_kmap() must be nested * according to the rules documented in kmap_local_folio()/kunmap_local(). * * ext2_find_entry() and ext2_dotdot() act as a call to ext2_get_folio() * and should be treated as a call to ext2_get_folio() for nesting * purposes. */ struct ext2_dir_entry_2 *ext2_dotdot(struct inode *dir, struct folio **foliop) { … } int ext2_inode_by_name(struct inode *dir, const struct qstr *child, ino_t *ino) { … } static int ext2_prepare_chunk(struct folio *folio, loff_t pos, unsigned len) { … } static int ext2_handle_dirsync(struct inode *dir) { … } int ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, struct folio *folio, struct inode *inode, bool update_times) { … } /* * Parent is locked. */ int ext2_add_link (struct dentry *dentry, struct inode *inode) { … } /* * ext2_delete_entry deletes a directory entry by merging it with the * previous entry. Page is up-to-date. */ int ext2_delete_entry(struct ext2_dir_entry_2 *dir, struct folio *folio) { … } /* * Set the first fragment of directory. */ int ext2_make_empty(struct inode *inode, struct inode *parent) { … } /* * routine to check that the specified directory is empty (for rmdir) */ int ext2_empty_dir(struct inode *inode) { … } const struct file_operations ext2_dir_operations = …;