^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * namei.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Inode name handling routines for the OSTA-UDF(tm) filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file is distributed under the terms of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * License (GPL). Copies of the GPL can be obtained from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * ftp://prep.ai.mit.edu/pub/gnu/GPL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Each contributing author retains all rights to their own work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * (C) 1998-2004 Ben Fennema
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * (C) 1999-2000 Stelias Computing Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * HISTORY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * 12/12/98 blf Created. Split out the lookup code from dir.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * 04/19/99 blf link, mknod, symlink support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "udfdecl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "udf_i.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "udf_sb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/crc-itu-t.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/exportfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/iversion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static inline int udf_match(int len1, const unsigned char *name1, int len2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) const unsigned char *name2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (len1 != len2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return !memcmp(name1, name2, len1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) uint8_t *impuse, uint8_t *fileident)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(struct tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) uint16_t crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) uint8_t lfi = cfi->lengthFileIdent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int padlen = fibh->eoffset - fibh->soffset - liu - lfi -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) sizeof(struct fileIdentDesc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int adinicb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) adinicb = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) offset = fibh->soffset + sizeof(struct fileIdentDesc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (impuse) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (adinicb || (offset + liu < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) memcpy((uint8_t *)sfi->impUse, impuse, liu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) } else if (offset >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) memcpy(fibh->ebh->b_data + offset, impuse, liu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) memcpy((uint8_t *)sfi->impUse, impuse, -offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) memcpy(fibh->ebh->b_data, impuse - offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) liu + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) offset += liu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (fileident) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (adinicb || (offset + lfi < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) memcpy((uint8_t *)sfi->fileIdent + liu, fileident, lfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) } else if (offset >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) memcpy(fibh->ebh->b_data + offset, fileident, lfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) memcpy((uint8_t *)sfi->fileIdent + liu, fileident,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) -offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) memcpy(fibh->ebh->b_data, fileident - offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) lfi + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) offset += lfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (adinicb || (offset + padlen < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) memset((uint8_t *)sfi->padding + liu + lfi, 0x00, padlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) } else if (offset >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) memset(fibh->ebh->b_data + offset, 0x00, padlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) memset((uint8_t *)sfi->padding + liu + lfi, 0x00, -offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) memset(fibh->ebh->b_data, 0x00, padlen + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(struct tag),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) sizeof(struct fileIdentDesc) - sizeof(struct tag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (fibh->sbh == fibh->ebh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) crc = crc_itu_t(crc, (uint8_t *)sfi->impUse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) crclen + sizeof(struct tag) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) sizeof(struct fileIdentDesc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) crc = crc_itu_t(crc, fibh->ebh->b_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) sizeof(struct fileIdentDesc) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) fibh->soffset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) crclen + sizeof(struct tag) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) sizeof(struct fileIdentDesc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) crc = crc_itu_t(crc, (uint8_t *)sfi->impUse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) -fibh->soffset - sizeof(struct fileIdentDesc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) crc = crc_itu_t(crc, fibh->ebh->b_data, fibh->eoffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) cfi->descTag.descCRC = cpu_to_le16(crc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) cfi->descTag.descCRCLength = cpu_to_le16(crclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) cfi->descTag.tagChecksum = udf_tag_checksum(&cfi->descTag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (adinicb || (sizeof(struct fileIdentDesc) <= -fibh->soffset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) memcpy((uint8_t *)sfi, (uint8_t *)cfi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) sizeof(struct fileIdentDesc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) memcpy((uint8_t *)sfi, (uint8_t *)cfi, -fibh->soffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) memcpy(fibh->ebh->b_data, (uint8_t *)cfi - fibh->soffset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) sizeof(struct fileIdentDesc) + fibh->soffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (adinicb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (fibh->sbh != fibh->ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) mark_buffer_dirty_inode(fibh->ebh, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) mark_buffer_dirty_inode(fibh->sbh, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) inode_inc_iversion(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * udf_find_entry - find entry in given directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * @dir: directory inode to search in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * @child: qstr of the name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * @fibh: buffer head / inode with file identifier descriptor we found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * @cfi: found file identifier descriptor with given name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * This function searches in the directory @dir for a file name @child. When
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * found, @fibh points to the buffer head(s) (bh is NULL for in ICB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * directories) containing the file identifier descriptor (FID). In that case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * the function returns pointer to the FID in the buffer or inode - but note
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * that FID may be split among two buffers (blocks) so accessing it via that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * pointer isn't easily possible. This pointer can be used only as an iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * for other directory manipulation functions. For inspection of the FID @cfi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * can be used - the found FID is copied there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Returns pointer to FID, NULL when nothing found, or error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static struct fileIdentDesc *udf_find_entry(struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) const struct qstr *child,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct udf_fileident_bh *fibh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct fileIdentDesc *cfi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct fileIdentDesc *fi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) loff_t f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) udf_pblk_t block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int flen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) unsigned char *fname = NULL, *copy_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) unsigned char *nameptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) uint8_t lfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) uint16_t liu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) loff_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct kernel_lb_addr eloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) uint32_t elen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) sector_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct extent_position epos = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct udf_inode_info *dinfo = UDF_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int isdotdot = child->len == 2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) child->name[0] == '.' && child->name[1] == '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) size = udf_ext0_offset(dir) + dir->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) f_pos = udf_ext0_offset(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) fibh->sbh = fibh->ebh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) fibh->soffset = fibh->eoffset = f_pos & (sb->s_blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (inode_bmap(dir, f_pos >> sb->s_blocksize_bits, &epos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) fi = ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) block = udf_get_lb_pblock(sb, &eloc, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if ((++offset << sb->s_blocksize_bits) < elen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) epos.offset -= sizeof(struct short_ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) epos.offset -= sizeof(struct long_ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) fibh->sbh = fibh->ebh = udf_tread(sb, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!fibh->sbh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) fi = ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) fname = kmalloc(UDF_NAME_LEN, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (!fname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) fi = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) while (f_pos < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) &elen, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (!fi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) fi = ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) liu = le16_to_cpu(cfi->lengthOfImpUse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) lfi = cfi->lengthFileIdent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (fibh->sbh == fibh->ebh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) nameptr = fi->fileIdent + liu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int poffset; /* Unpaded ending offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) poffset = fibh->soffset + sizeof(struct fileIdentDesc) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) liu + lfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (poffset >= lfi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) nameptr = (uint8_t *)(fibh->ebh->b_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) poffset - lfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!copy_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) copy_name = kmalloc(UDF_NAME_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!copy_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) fi = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) nameptr = copy_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) memcpy(nameptr, fi->fileIdent + liu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) lfi - poffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) memcpy(nameptr + lfi - poffset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) fibh->ebh->b_data, poffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNDELETE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if ((cfi->fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) isdotdot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) goto out_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (!lfi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) flen = udf_get_filename(sb, nameptr, lfi, fname, UDF_NAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (flen < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) fi = ERR_PTR(flen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (udf_match(flen, fname, child->len, child->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) goto out_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) fi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (fibh->sbh != fibh->ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) brelse(fibh->ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) brelse(fibh->sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) out_ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) brelse(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) kfree(fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) kfree(copy_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct inode *inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct fileIdentDesc cfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct udf_fileident_bh fibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct fileIdentDesc *fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (dentry->d_name.len > UDF_NAME_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (IS_ERR(fi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return ERR_CAST(fi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (fi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct kernel_lb_addr loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (fibh.sbh != fibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) brelse(fibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) brelse(fibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) loc = lelb_to_cpu(cfi.icb.extLocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) inode = udf_iget(dir->i_sb, &loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ERR_CAST(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static struct fileIdentDesc *udf_add_entry(struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct udf_fileident_bh *fibh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct fileIdentDesc *cfi, int *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct fileIdentDesc *fi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) unsigned char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) loff_t f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) loff_t size = udf_ext0_offset(dir) + dir->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) int nfidlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) udf_pblk_t block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct kernel_lb_addr eloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) uint32_t elen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) sector_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct extent_position epos = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct udf_inode_info *dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) fibh->sbh = fibh->ebh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) name = kmalloc(UDF_NAME_LEN_CS0, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (!name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) *err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (dentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (!dentry->d_name.len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) *err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) namelen = udf_put_filename(sb, dentry->d_name.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) dentry->d_name.len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) name, UDF_NAME_LEN_CS0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (!namelen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) *err = -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) namelen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) nfidlen = ALIGN(sizeof(struct fileIdentDesc) + namelen, UDF_NAME_PAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) f_pos = udf_ext0_offset(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) dinfo = UDF_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) block = udf_get_lb_pblock(dir->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) &dinfo->i_location, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) fibh->soffset = fibh->eoffset = sb->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) goto add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) block = udf_get_lb_pblock(dir->i_sb, &eloc, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) epos.offset -= sizeof(struct short_ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) epos.offset -= sizeof(struct long_ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (!fibh->sbh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) *err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) block = dinfo->i_location.logicalBlockNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) while (f_pos < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) &elen, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (!fi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) *err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (udf_dir_entry_len(cfi) == nfidlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) cfi->descTag.tagSerialNum = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) cfi->fileVersionNum = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) cfi->fileCharacteristics = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) cfi->lengthFileIdent = namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) cfi->lengthOfImpUse = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (!udf_write_fi(dir, cfi, fi, fibh, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) goto out_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) *err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) add:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) f_pos += nfidlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) sb->s_blocksize - fibh->eoffset < nfidlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) brelse(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) epos.bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) fibh->soffset -= udf_ext0_offset(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) fibh->eoffset -= udf_ext0_offset(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) f_pos -= udf_ext0_offset(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (fibh->sbh != fibh->ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) brelse(fibh->ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) brelse(fibh->sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) fibh->sbh = fibh->ebh =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) udf_expand_dir_adinicb(dir, &block, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (!fibh->sbh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) epos.block = dinfo->i_location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) epos.offset = udf_file_entry_alloc_offset(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /* Load extent udf_expand_dir_adinicb() has created */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) udf_current_aext(dir, &epos, &eloc, &elen, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* Entry fits into current block? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (sb->s_blocksize - fibh->eoffset >= nfidlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) fibh->soffset = fibh->eoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) fibh->eoffset += nfidlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (fibh->sbh != fibh->ebh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) brelse(fibh->sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) fibh->sbh = fibh->ebh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) block = dinfo->i_location.logicalBlockNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) fi = (struct fileIdentDesc *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) (dinfo->i_data + fibh->soffset -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) udf_ext0_offset(dir) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) dinfo->i_lenEAttr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) block = eloc.logicalBlockNum +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ((elen - 1) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) dir->i_sb->s_blocksize_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) fi = (struct fileIdentDesc *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) (fibh->sbh->b_data + fibh->soffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* Round up last extent in the file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) epos.offset -= sizeof(struct short_ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) epos.offset -= sizeof(struct long_ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) udf_write_aext(dir, &epos, &eloc, elen, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) dinfo->i_lenExtents = (dinfo->i_lenExtents + sb->s_blocksize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) - 1) & ~(sb->s_blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) fibh->soffset = fibh->eoffset - sb->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) fibh->eoffset += nfidlen - sb->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (fibh->sbh != fibh->ebh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) brelse(fibh->sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) fibh->sbh = fibh->ebh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) block = eloc.logicalBlockNum + ((elen - 1) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) dir->i_sb->s_blocksize_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) fibh->ebh = udf_bread(dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) f_pos >> dir->i_sb->s_blocksize_bits, 1, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (!fibh->ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /* Extents could have been merged, invalidate our position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) brelse(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) epos.bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) epos.block = dinfo->i_location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) epos.offset = udf_file_entry_alloc_offset(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (!fibh->soffset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* Find the freshly allocated block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) while (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) (EXT_RECORDED_ALLOCATED >> 30))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) block = eloc.logicalBlockNum + ((elen - 1) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) dir->i_sb->s_blocksize_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) brelse(fibh->sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) fibh->sbh = fibh->ebh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) fi = (struct fileIdentDesc *)(fibh->sbh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) fi = (struct fileIdentDesc *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) (fibh->sbh->b_data + sb->s_blocksize +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) fibh->soffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) memset(cfi, 0, sizeof(struct fileIdentDesc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (UDF_SB(sb)->s_udfrev >= 0x0200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) sizeof(struct tag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) sizeof(struct tag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) cfi->fileVersionNum = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) cfi->lengthFileIdent = namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) cfi->lengthOfImpUse = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) dir->i_size += nfidlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) dinfo->i_lenAlloc += nfidlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /* Find the last extent and truncate it to proper size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) while (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) (EXT_RECORDED_ALLOCATED >> 30))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) elen -= dinfo->i_lenExtents - dir->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) epos.offset -= sizeof(struct short_ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) epos.offset -= sizeof(struct long_ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) udf_write_aext(dir, &epos, &eloc, elen, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) dinfo->i_lenExtents = dir->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) mark_inode_dirty(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) goto out_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) *err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) fi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (fibh->sbh != fibh->ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) brelse(fibh->ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) brelse(fibh->sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) out_ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) brelse(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct udf_fileident_bh *fibh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct fileIdentDesc *cfi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) memset(&(cfi->icb), 0x00, sizeof(struct long_ad));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static int udf_add_nondir(struct dentry *dentry, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct udf_inode_info *iinfo = UDF_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct inode *dir = d_inode(dentry->d_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct udf_fileident_bh fibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct fileIdentDesc cfi, *fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (unlikely(!fi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) inode_dec_link_count(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) discard_new_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) dir->i_ctime = dir->i_mtime = current_time(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) mark_inode_dirty(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (fibh.sbh != fibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) brelse(fibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) brelse(fibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) d_instantiate_new(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) bool excl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct inode *inode = udf_new_inode(dir, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) inode->i_data.a_ops = &udf_adinicb_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) inode->i_data.a_ops = &udf_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) inode->i_op = &udf_file_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) inode->i_fop = &udf_file_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return udf_add_nondir(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct inode *inode = udf_new_inode(dir, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) inode->i_data.a_ops = &udf_adinicb_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) inode->i_data.a_ops = &udf_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) inode->i_op = &udf_file_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) inode->i_fop = &udf_file_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) d_tmpfile(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) unlock_new_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dev_t rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (!old_valid_dev(rdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) inode = udf_new_inode(dir, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) init_special_inode(inode, mode, rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return udf_add_nondir(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct udf_fileident_bh fibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct fileIdentDesc cfi, *fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct udf_inode_info *dinfo = UDF_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct udf_inode_info *iinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) inode = udf_new_inode(dir, S_IFDIR | mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) iinfo = UDF_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) inode->i_op = &udf_dir_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) inode->i_fop = &udf_dir_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (!fi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) inode_dec_link_count(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) discard_new_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) set_nlink(inode, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) cfi.icb.extLocation = cpu_to_lelb(dinfo->i_location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) cpu_to_le32(dinfo->i_unique & 0x00000000FFFFFFFFUL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) cfi.fileCharacteristics =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) brelse(fibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (!fi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) clear_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) discard_new_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) inc_nlink(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dir->i_ctime = dir->i_mtime = current_time(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) mark_inode_dirty(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) d_instantiate_new(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (fibh.sbh != fibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) brelse(fibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) brelse(fibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static int empty_dir(struct inode *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct fileIdentDesc *fi, cfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct udf_fileident_bh fibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) loff_t f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) loff_t size = udf_ext0_offset(dir) + dir->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) udf_pblk_t block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct kernel_lb_addr eloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) uint32_t elen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) sector_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct extent_position epos = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) struct udf_inode_info *dinfo = UDF_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) f_pos = udf_ext0_offset(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) fibh.soffset = fibh.eoffset = f_pos & (dir->i_sb->s_blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) fibh.sbh = fibh.ebh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) &epos, &eloc, &elen, &offset) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) (EXT_RECORDED_ALLOCATED >> 30)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) block = udf_get_lb_pblock(dir->i_sb, &eloc, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) epos.offset -= sizeof(struct short_ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) epos.offset -= sizeof(struct long_ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (!fibh.sbh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) brelse(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) brelse(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) while (f_pos < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) &elen, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (!fi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (fibh.sbh != fibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) brelse(fibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) brelse(fibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) brelse(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (cfi.lengthFileIdent &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (fibh.sbh != fibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) brelse(fibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) brelse(fibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) brelse(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (fibh.sbh != fibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) brelse(fibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) brelse(fibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) brelse(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static int udf_rmdir(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct udf_fileident_bh fibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct fileIdentDesc *fi, cfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct kernel_lb_addr tloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) retval = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (IS_ERR_OR_NULL(fi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (fi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) retval = PTR_ERR(fi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) tloc = lelb_to_cpu(cfi.icb.extLocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) goto end_rmdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) retval = -ENOTEMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (!empty_dir(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) goto end_rmdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) retval = udf_delete_entry(dir, fi, &fibh, &cfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) goto end_rmdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (inode->i_nlink != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) udf_warn(inode->i_sb, "empty directory has nlink != 2 (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) inode->i_nlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) clear_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) inode->i_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) inode_dec_link_count(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) inode->i_ctime = dir->i_ctime = dir->i_mtime =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) mark_inode_dirty(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) end_rmdir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (fibh.sbh != fibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) brelse(fibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) brelse(fibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static int udf_unlink(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) struct udf_fileident_bh fibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) struct fileIdentDesc *fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) struct fileIdentDesc cfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) struct kernel_lb_addr tloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) retval = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (IS_ERR_OR_NULL(fi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (fi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) retval = PTR_ERR(fi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) tloc = lelb_to_cpu(cfi.icb.extLocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) goto end_unlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (!inode->i_nlink) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) udf_debug("Deleting nonexistent file (%lu), %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) inode->i_ino, inode->i_nlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) set_nlink(inode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) retval = udf_delete_entry(dir, fi, &fibh, &cfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) goto end_unlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) dir->i_ctime = dir->i_mtime = current_time(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) mark_inode_dirty(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) inode_dec_link_count(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) inode->i_ctime = dir->i_ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) end_unlink:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (fibh.sbh != fibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) brelse(fibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) brelse(fibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static int udf_symlink(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct inode *inode = udf_new_inode(dir, S_IFLNK | 0777);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) struct pathComponent *pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) const char *compstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct extent_position epos = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) int eoffset, elen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) uint8_t *ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) udf_pblk_t block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) unsigned char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) int namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct udf_inode_info *iinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) iinfo = UDF_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) down_write(&iinfo->i_data_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) name = kmalloc(UDF_NAME_LEN_CS0, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (!name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) goto out_no_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) inode->i_data.a_ops = &udf_symlink_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) inode->i_op = &udf_symlink_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) inode_nohighmem(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) struct kernel_lb_addr eloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) uint32_t bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) block = udf_new_block(sb, inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) iinfo->i_location.partitionReferenceNum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) iinfo->i_location.logicalBlockNum, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (!block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) goto out_no_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) epos.block = iinfo->i_location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) epos.offset = udf_file_entry_alloc_offset(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) epos.bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) eloc.logicalBlockNum = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) eloc.partitionReferenceNum =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) iinfo->i_location.partitionReferenceNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) bsize = sb->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) iinfo->i_lenExtents = bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) udf_add_aext(inode, &epos, &eloc, bsize, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) brelse(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) block = udf_get_pblock(sb, block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) iinfo->i_location.partitionReferenceNum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) epos.bh = udf_tgetblk(sb, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (unlikely(!epos.bh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) goto out_no_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) lock_buffer(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) memset(epos.bh->b_data, 0x00, bsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) set_buffer_uptodate(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) unlock_buffer(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) mark_buffer_dirty_inode(epos.bh, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) ea = epos.bh->b_data + udf_ext0_offset(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) ea = iinfo->i_data + iinfo->i_lenEAttr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) eoffset = sb->s_blocksize - udf_ext0_offset(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) pc = (struct pathComponent *)ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (*symname == '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) symname++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) } while (*symname == '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) pc->componentType = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) pc->lengthComponentIdent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) pc->componentFileVersionNum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) elen += sizeof(struct pathComponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) err = -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) while (*symname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (elen + sizeof(struct pathComponent) > eoffset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) goto out_no_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) pc = (struct pathComponent *)(ea + elen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) compstart = symname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) symname++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) } while (*symname && *symname != '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) pc->componentType = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) pc->lengthComponentIdent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) pc->componentFileVersionNum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (compstart[0] == '.') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if ((symname - compstart) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) pc->componentType = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) else if ((symname - compstart) == 2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) compstart[1] == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) pc->componentType = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (pc->componentType == 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) namelen = udf_put_filename(sb, compstart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) symname - compstart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) name, UDF_NAME_LEN_CS0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (!namelen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) goto out_no_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (elen + sizeof(struct pathComponent) + namelen >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) eoffset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) goto out_no_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) pc->lengthComponentIdent = namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) memcpy(pc->componentIdent, name, namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (*symname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) symname++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) } while (*symname == '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) brelse(epos.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) inode->i_size = elen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) iinfo->i_lenAlloc = inode->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) udf_truncate_tail_extent(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) up_write(&iinfo->i_data_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) err = udf_add_nondir(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) out_no_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) up_write(&iinfo->i_data_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) inode_dec_link_count(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) discard_new_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) static int udf_link(struct dentry *old_dentry, struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) struct inode *inode = d_inode(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) struct udf_fileident_bh fibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) struct fileIdentDesc cfi, *fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (!fi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (UDF_SB(inode->i_sb)->s_lvid_bh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) cpu_to_le32(lvid_get_unique_id(inode->i_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) mark_inode_dirty(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (fibh.sbh != fibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) brelse(fibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) brelse(fibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) inc_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) inode->i_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) dir->i_ctime = dir->i_mtime = current_time(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) mark_inode_dirty(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) ihold(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) d_instantiate(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) /* Anybody can rename anything with this: the permission checks are left to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) * higher-level routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct inode *new_dir, struct dentry *new_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) struct inode *old_inode = d_inode(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct inode *new_inode = d_inode(new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct udf_fileident_bh ofibh, nfibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) struct fileIdentDesc ocfi, ncfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct buffer_head *dir_bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) int retval = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) struct kernel_lb_addr tloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) struct udf_inode_info *old_iinfo = UDF_I(old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (flags & ~RENAME_NOREPLACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (IS_ERR(ofi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) retval = PTR_ERR(ofi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) goto end_rename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (ofibh.sbh != ofibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) brelse(ofibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) brelse(ofibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) tloc = lelb_to_cpu(ocfi.icb.extLocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (!ofi || udf_get_lb_pblock(old_dir->i_sb, &tloc, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) != old_inode->i_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) goto end_rename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) nfi = udf_find_entry(new_dir, &new_dentry->d_name, &nfibh, &ncfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (IS_ERR(nfi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) retval = PTR_ERR(nfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) goto end_rename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (nfi && !new_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (nfibh.sbh != nfibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) brelse(nfibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) brelse(nfibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) nfi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (S_ISDIR(old_inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) int offset = udf_ext0_offset(old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (new_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) retval = -ENOTEMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (!empty_dir(new_inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) goto end_rename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) dir_fi = udf_get_fileident(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) old_iinfo->i_data -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) (old_iinfo->i_efe ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) sizeof(struct extendedFileEntry) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) sizeof(struct fileEntry)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) old_inode->i_sb->s_blocksize, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) dir_bh = udf_bread(old_inode, 0, 0, &retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (!dir_bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) goto end_rename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) dir_fi = udf_get_fileident(dir_bh->b_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) old_inode->i_sb->s_blocksize, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (!dir_fi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) goto end_rename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) tloc = lelb_to_cpu(dir_fi->icb.extLocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) old_dir->i_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) goto end_rename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (!nfi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) &retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (!nfi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) goto end_rename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) * Like most other Unix systems, set the ctime for inodes on a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) * rename.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) old_inode->i_ctime = current_time(old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) mark_inode_dirty(old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) * ok, that's it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) ncfi.fileVersionNum = ocfi.fileVersionNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) ncfi.fileCharacteristics = ocfi.fileCharacteristics;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(ocfi.icb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /* The old fid may have moved - find it again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) udf_delete_entry(old_dir, ofi, &ofibh, &ocfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (new_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) new_inode->i_ctime = current_time(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) inode_dec_link_count(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) new_dir->i_ctime = new_dir->i_mtime = current_time(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) mark_inode_dirty(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) mark_inode_dirty(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) if (dir_fi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) dir_fi->icb.extLocation = cpu_to_lelb(UDF_I(new_dir)->i_location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) udf_update_tag((char *)dir_fi, udf_dir_entry_len(dir_fi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) mark_inode_dirty(old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) mark_buffer_dirty_inode(dir_bh, old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) inode_dec_link_count(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (new_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) inode_dec_link_count(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) inc_nlink(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) mark_inode_dirty(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (ofi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (ofibh.sbh != ofibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) brelse(ofibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) brelse(ofibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) end_rename:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) brelse(dir_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (nfi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (nfibh.sbh != nfibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) brelse(nfibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) brelse(nfibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static struct dentry *udf_get_parent(struct dentry *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct kernel_lb_addr tloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) struct inode *inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) struct qstr dotdot = QSTR_INIT("..", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) struct fileIdentDesc cfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) struct udf_fileident_bh fibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (!udf_find_entry(d_inode(child), &dotdot, &fibh, &cfi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) return ERR_PTR(-EACCES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (fibh.sbh != fibh.ebh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) brelse(fibh.ebh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) brelse(fibh.sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) tloc = lelb_to_cpu(cfi.icb.extLocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) inode = udf_iget(child->d_sb, &tloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return ERR_CAST(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return d_obtain_alias(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) u16 partref, __u32 generation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) struct kernel_lb_addr loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (block == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return ERR_PTR(-ESTALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) loc.logicalBlockNum = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) loc.partitionReferenceNum = partref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) inode = udf_iget(sb, &loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return ERR_CAST(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (generation && inode->i_generation != generation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return ERR_PTR(-ESTALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return d_obtain_alias(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) static struct dentry *udf_fh_to_dentry(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) struct fid *fid, int fh_len, int fh_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (fh_len < 3 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) (fh_type != FILEID_UDF_WITH_PARENT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) fh_type != FILEID_UDF_WITHOUT_PARENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) return udf_nfs_get_inode(sb, fid->udf.block, fid->udf.partref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) fid->udf.generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) static struct dentry *udf_fh_to_parent(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct fid *fid, int fh_len, int fh_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (fh_len < 5 || fh_type != FILEID_UDF_WITH_PARENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return udf_nfs_get_inode(sb, fid->udf.parent_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) fid->udf.parent_partref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) fid->udf.parent_generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) static int udf_encode_fh(struct inode *inode, __u32 *fh, int *lenp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) struct inode *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) int len = *lenp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) struct kernel_lb_addr location = UDF_I(inode)->i_location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) struct fid *fid = (struct fid *)fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) int type = FILEID_UDF_WITHOUT_PARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (parent && (len < 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) *lenp = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return FILEID_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) } else if (len < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) *lenp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return FILEID_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) *lenp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) fid->udf.block = location.logicalBlockNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) fid->udf.partref = location.partitionReferenceNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) fid->udf.parent_partref = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) fid->udf.generation = inode->i_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) location = UDF_I(parent)->i_location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) fid->udf.parent_block = location.logicalBlockNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) fid->udf.parent_partref = location.partitionReferenceNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) fid->udf.parent_generation = inode->i_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) *lenp = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) type = FILEID_UDF_WITH_PARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) const struct export_operations udf_export_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) .encode_fh = udf_encode_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) .fh_to_dentry = udf_fh_to_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) .fh_to_parent = udf_fh_to_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) .get_parent = udf_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) const struct inode_operations udf_dir_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) .lookup = udf_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) .create = udf_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) .link = udf_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) .unlink = udf_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) .symlink = udf_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) .mkdir = udf_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) .rmdir = udf_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) .mknod = udf_mknod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) .rename = udf_rename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) .tmpfile = udf_tmpfile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) };