^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) International Business Machines Corp., 2000-2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Portions Copyright (C) Christoph Hellwig, 2001-2002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/quotaops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/exportfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "jfs_incore.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "jfs_superblock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "jfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "jfs_dinode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "jfs_dmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "jfs_unicode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "jfs_metapage.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "jfs_xattr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "jfs_acl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "jfs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * forward references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) const struct dentry_operations jfs_ci_dentry_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static s64 commitZeroLink(tid_t, struct inode *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * NAME: free_ea_wmap(inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * FUNCTION: free uncommitted extended attributes from working map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static inline void free_ea_wmap(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) dxd_t *ea = &JFS_IP(inode)->ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (ea->flag & DXD_EXTENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* free EA pages from cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) invalidate_dxd_metapages(inode, *ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) dbFree(inode, addressDXD(ea), lengthDXD(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ea->flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * NAME: jfs_create(dip, dentry, mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * FUNCTION: create a regular file in the parent directory <dip>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * with name = <from dentry> and mode = <mode>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * PARAMETER: dip - parent directory vnode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * dentry - dentry of new file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * mode - create mode (rwxrwxrwx).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * nd- nd struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * RETURN: Errors from subroutines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) bool excl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) tid_t tid; /* transaction id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct inode *ip = NULL; /* child directory inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ino_t ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct component_name dname; /* child directory name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct btstack btstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct inode *iplist[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct tblock *tblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) jfs_info("jfs_create: dip:0x%p name:%pd", dip, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) rc = dquot_initialize(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * search parent directory for entry/freespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * (dtSearch() returns parent directory page pinned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if ((rc = get_UCSname(&dname, dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) goto out1;
^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) * Either iAlloc() or txBegin() may block. Deadlock can occur if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * block there while holding dtree page, so we allocate the inode &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * begin the transaction before we search the directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ip = ialloc(dip, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (IS_ERR(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) rc = PTR_ERR(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) tid = txBegin(dip->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) rc = jfs_init_acl(tid, ip, dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) txAbort(tid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) jfs_err("jfs_create: dtSearch returned %d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) txAbort(tid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) goto out3;
^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) tblk = tid_to_tblock(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) tblk->xflag |= COMMIT_CREATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) tblk->ino = ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) iplist[0] = dip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) iplist[1] = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * initialize the child XAD tree root in-line in inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) xtInitRoot(tid, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * create entry in parent directory for child directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * (dtInsert() releases parent directory page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ino = ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (rc == -EIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) jfs_err("jfs_create: dtInsert returned -EIO");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) txAbort(tid, 1); /* Marks Filesystem dirty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) txAbort(tid, 0); /* Filesystem full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ip->i_op = &jfs_file_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ip->i_fop = &jfs_file_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ip->i_mapping->a_ops = &jfs_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) mark_inode_dirty(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) dip->i_ctime = dip->i_mtime = current_time(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) mark_inode_dirty(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) rc = txCommit(tid, 2, &iplist[0], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) out3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) mutex_unlock(&JFS_IP(dip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) free_ea_wmap(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) clear_nlink(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) discard_new_inode(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) d_instantiate_new(dentry, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) free_UCSname(&dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) jfs_info("jfs_create: rc:%d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * NAME: jfs_mkdir(dip, dentry, mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * FUNCTION: create a child directory in the parent directory <dip>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * with name = <from dentry> and mode = <mode>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * PARAMETER: dip - parent directory vnode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * dentry - dentry of child directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * mode - create mode (rwxrwxrwx).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * RETURN: Errors from subroutines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * note:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * EACCES: user needs search+write permission on the parent directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) tid_t tid; /* transaction id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct inode *ip = NULL; /* child directory inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ino_t ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct component_name dname; /* child directory name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct btstack btstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct inode *iplist[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct tblock *tblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) jfs_info("jfs_mkdir: dip:0x%p name:%pd", dip, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) rc = dquot_initialize(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) goto out1;
^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) * search parent directory for entry/freespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * (dtSearch() returns parent directory page pinned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if ((rc = get_UCSname(&dname, dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) goto out1;
^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) * Either iAlloc() or txBegin() may block. Deadlock can occur if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * block there while holding dtree page, so we allocate the inode &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * begin the transaction before we search the directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ip = ialloc(dip, S_IFDIR | mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (IS_ERR(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) rc = PTR_ERR(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) tid = txBegin(dip->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) rc = jfs_init_acl(tid, ip, dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) txAbort(tid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) jfs_err("jfs_mkdir: dtSearch returned %d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) txAbort(tid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) goto out3;
^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) tblk = tid_to_tblock(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) tblk->xflag |= COMMIT_CREATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) tblk->ino = ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) iplist[0] = dip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) iplist[1] = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * initialize the child directory in-line in inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dtInitRoot(tid, ip, dip->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * create entry in parent directory for child directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * (dtInsert() releases parent directory page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ino = ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (rc == -EIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) jfs_err("jfs_mkdir: dtInsert returned -EIO");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) txAbort(tid, 1); /* Marks Filesystem dirty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) txAbort(tid, 0); /* Filesystem full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) set_nlink(ip, 2); /* for '.' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ip->i_op = &jfs_dir_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ip->i_fop = &jfs_dir_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) mark_inode_dirty(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* update parent directory inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) inc_nlink(dip); /* for '..' from child directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) dip->i_ctime = dip->i_mtime = current_time(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) mark_inode_dirty(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) rc = txCommit(tid, 2, &iplist[0], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) out3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) mutex_unlock(&JFS_IP(dip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) free_ea_wmap(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) clear_nlink(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) discard_new_inode(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) d_instantiate_new(dentry, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) free_UCSname(&dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) jfs_info("jfs_mkdir: rc:%d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * NAME: jfs_rmdir(dip, dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * FUNCTION: remove a link to child directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * PARAMETER: dip - parent inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * dentry - child directory dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * RETURN: -EINVAL - if name is . or ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * -EINVAL - if . or .. exist but are invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * errors from subroutines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * note:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * if other threads have the directory open when the last link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * is removed, the "." and ".." entries, if present, are removed before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * rmdir() returns and no new entries may be created in the directory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * but the directory is not removed until the last reference to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * the directory is released (cf.unlink() of regular file).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) tid_t tid; /* transaction id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct inode *ip = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ino_t ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct component_name dname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct inode *iplist[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct tblock *tblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) jfs_info("jfs_rmdir: dip:0x%p name:%pd", dip, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* Init inode for quota operations. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) rc = dquot_initialize(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) rc = dquot_initialize(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* directory must be empty to be removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (!dtEmpty(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) rc = -ENOTEMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if ((rc = get_UCSname(&dname, dentry))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) tid = txBegin(dip->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) iplist[0] = dip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) iplist[1] = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) tblk = tid_to_tblock(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) tblk->xflag |= COMMIT_DELETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) tblk->u.ip = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * delete the entry of target directory from parent directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ino = ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) jfs_err("jfs_rmdir: dtDelete returned %d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (rc == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) txAbort(tid, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) mutex_unlock(&JFS_IP(dip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* update parent directory's link count corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * to ".." entry of the target directory deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dip->i_ctime = dip->i_mtime = current_time(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) inode_dec_link_count(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * OS/2 could have created EA and/or ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* free EA from both persistent and working map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* free EA pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) JFS_IP(ip)->ea.flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* free ACL from both persistent and working map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* free ACL pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) JFS_IP(ip)->acl.flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* mark the target directory as deleted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) clear_nlink(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) mark_inode_dirty(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) rc = txCommit(tid, 2, &iplist[0], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) mutex_unlock(&JFS_IP(dip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * Truncating the directory index table is not guaranteed. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * may need to be done iteratively
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (test_cflag(COMMIT_Stale, dip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (dip->i_size > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) jfs_truncate_nolock(dip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) clear_cflag(COMMIT_Stale, dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) free_UCSname(&dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) jfs_info("jfs_rmdir: rc:%d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * NAME: jfs_unlink(dip, dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * FUNCTION: remove a link to object <vp> named by <name>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * from parent directory <dvp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * PARAMETER: dip - inode of parent directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * dentry - dentry of object to be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * RETURN: errors from subroutines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * note:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * temporary file: if one or more processes have the file open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * when the last link is removed, the link will be removed before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * unlink() returns, but the removal of the file contents will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * postponed until all references to the files are closed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * JFS does NOT support unlink() on directories.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int jfs_unlink(struct inode *dip, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) tid_t tid; /* transaction id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct inode *ip = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ino_t ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct component_name dname; /* object name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct inode *iplist[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct tblock *tblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) s64 new_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int commit_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) jfs_info("jfs_unlink: dip:0x%p name:%pd", dip, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* Init inode for quota operations. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) rc = dquot_initialize(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) rc = dquot_initialize(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if ((rc = get_UCSname(&dname, dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) IWRITE_LOCK(ip, RDWRLOCK_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) tid = txBegin(dip->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) iplist[0] = dip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) iplist[1] = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * delete the entry of target file from parent directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ino = ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) jfs_err("jfs_unlink: dtDelete returned %d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (rc == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) txAbort(tid, 1); /* Marks FS Dirty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) mutex_unlock(&JFS_IP(dip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) IWRITE_UNLOCK(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ASSERT(ip->i_nlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ip->i_ctime = dip->i_ctime = dip->i_mtime = current_time(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) mark_inode_dirty(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /* update target's inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) inode_dec_link_count(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * commit zero link count object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (ip->i_nlink == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) assert(!test_cflag(COMMIT_Nolink, ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* free block resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if ((new_size = commitZeroLink(tid, ip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) txAbort(tid, 1); /* Marks FS Dirty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) mutex_unlock(&JFS_IP(dip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) IWRITE_UNLOCK(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) rc = new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) tblk = tid_to_tblock(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) tblk->xflag |= COMMIT_DELETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) tblk->u.ip = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * Incomplete truncate of file data can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * result in timing problems unless we synchronously commit the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (new_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) commit_flag = COMMIT_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) commit_flag = 0;
^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) * If xtTruncate was incomplete, commit synchronously to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * timing complications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) rc = txCommit(tid, 2, &iplist[0], commit_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) mutex_unlock(&JFS_IP(dip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) while (new_size && (rc == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) tid = txBegin(dip->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) mutex_lock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) new_size = xtTruncate_pmap(tid, ip, new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (new_size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) txAbort(tid, 1); /* Marks FS Dirty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) rc = new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (ip->i_nlink == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) set_cflag(COMMIT_Nolink, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) IWRITE_UNLOCK(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * Truncating the directory index table is not guaranteed. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * may need to be done iteratively
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (test_cflag(COMMIT_Stale, dip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (dip->i_size > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) jfs_truncate_nolock(dip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) clear_cflag(COMMIT_Stale, dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) free_UCSname(&dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) jfs_info("jfs_unlink: rc:%d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * NAME: commitZeroLink()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * FUNCTION: for non-directory, called by jfs_remove(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * truncate a regular file, directory or symbolic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * link to zero length. return 0 if type is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * one of these.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * if the file is currently associated with a VM segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * only permanent disk and inode map resources are freed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * and neither the inode nor indirect blocks are modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * so that the resources can be later freed in the work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * map by ctrunc1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * if there is no VM segment on entry, the resources are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * freed in both work and permanent map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * (? for temporary file - memory object is cached even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * after no reference:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * reference count > 0 - )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * PARAMETERS: cd - pointer to commit data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * current inode is the one to truncate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * RETURN: Errors from subroutines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static s64 commitZeroLink(tid_t tid, struct inode *ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) int filetype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct tblock *tblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) jfs_info("commitZeroLink: tid = %d, ip = 0x%p", tid, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) filetype = ip->i_mode & S_IFMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) switch (filetype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) case S_IFREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) case S_IFLNK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) /* fast symbolic link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (ip->i_size < IDATASIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ip->i_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) assert(filetype != S_IFDIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) set_cflag(COMMIT_Freewmap, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* mark transaction of block map update type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) tblk = tid_to_tblock(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) tblk->xflag |= COMMIT_PMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * free EA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (JFS_IP(ip)->ea.flag & DXD_EXTENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /* acquire maplock on EA to be freed from block map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * free ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (JFS_IP(ip)->acl.flag & DXD_EXTENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /* acquire maplock on EA to be freed from block map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * free xtree/data (truncate to zero length):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * free xtree/data pages from cache if COMMIT_PWMAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * free xtree/data blocks from persistent block map, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * free xtree/data blocks from working block map if COMMIT_PWMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (ip->i_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return xtTruncate_pmap(tid, ip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * NAME: jfs_free_zero_link()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * FUNCTION: for non-directory, called by iClose(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * free resources of a file from cache and WORKING map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * for a file previously committed with zero link count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * while associated with a pager object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * PARAMETER: ip - pointer to inode of file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) void jfs_free_zero_link(struct inode *ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) jfs_info("jfs_free_zero_link: ip = 0x%p", ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /* return if not reg or symbolic link or if size is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * already ok.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) type = ip->i_mode & S_IFMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) case S_IFREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) case S_IFLNK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /* if its contained in inode nothing to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (ip->i_size < IDATASIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * free EA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) s64 xaddr = addressDXD(&JFS_IP(ip)->ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) int xlen = lengthDXD(&JFS_IP(ip)->ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct maplock maplock; /* maplock for COMMIT_WMAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) struct pxd_lock *pxdlock; /* maplock for COMMIT_WMAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* free EA pages from cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) invalidate_dxd_metapages(ip, JFS_IP(ip)->ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /* free EA extent from working block map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) maplock.index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) pxdlock = (struct pxd_lock *) & maplock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) pxdlock->flag = mlckFREEPXD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) PXDaddress(&pxdlock->pxd, xaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) PXDlength(&pxdlock->pxd, xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * free ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) s64 xaddr = addressDXD(&JFS_IP(ip)->acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int xlen = lengthDXD(&JFS_IP(ip)->acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) struct maplock maplock; /* maplock for COMMIT_WMAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct pxd_lock *pxdlock; /* maplock for COMMIT_WMAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) invalidate_dxd_metapages(ip, JFS_IP(ip)->acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /* free ACL extent from working block map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) maplock.index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) pxdlock = (struct pxd_lock *) & maplock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) pxdlock->flag = mlckFREEPXD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) PXDaddress(&pxdlock->pxd, xaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) PXDlength(&pxdlock->pxd, xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * free xtree/data (truncate to zero length):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * free xtree/data pages from cache, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * free xtree/data blocks from working block map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (ip->i_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) xtTruncate(0, ip, 0, COMMIT_WMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * NAME: jfs_link(vp, dvp, name, crp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * FUNCTION: create a link to <vp> by the name = <name>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * in the parent directory <dvp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * PARAMETER: vp - target object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * dvp - parent directory of new link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * name - name of new link to target object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * crp - credential
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * RETURN: Errors from subroutines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * note:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * JFS does NOT support link() on directories (to prevent circular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * path in the directory hierarchy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * EPERM: the target object is a directory, and either the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * does not have appropriate privileges or the implementation prohibits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * using link() on directories [XPG4.2].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * JFS does NOT support links between file systems:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * EXDEV: target object and new link are on different file systems and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * implementation does not support links between file systems [XPG4.2].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static int jfs_link(struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) tid_t tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct inode *ip = d_inode(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) ino_t ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) struct component_name dname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct btstack btstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct inode *iplist[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) jfs_info("jfs_link: %pd %pd", old_dentry, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) rc = dquot_initialize(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) tid = txBegin(ip->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * scan parent directory for entry/freespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if ((rc = get_UCSname(&dname, dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) goto out_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) goto free_dname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * create entry for new link in parent directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ino = ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) goto free_dname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* update object inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) inc_nlink(ip); /* for new link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) ip->i_ctime = current_time(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) dir->i_ctime = dir->i_mtime = current_time(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) mark_inode_dirty(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) ihold(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) iplist[0] = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) iplist[1] = dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) rc = txCommit(tid, 2, &iplist[0], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) drop_nlink(ip); /* never instantiated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) iput(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) d_instantiate(dentry, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) free_dname:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) free_UCSname(&dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) out_tx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) mutex_unlock(&JFS_IP(dir)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) jfs_info("jfs_link: rc:%d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * NAME: jfs_symlink(dip, dentry, name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * FUNCTION: creates a symbolic link to <symlink> by name <name>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * in directory <dip>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * PARAMETER: dip - parent directory vnode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * dentry - dentry of symbolic link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * name - the path name of the existing object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * that will be the source of the link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * RETURN: errors from subroutines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) * note:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * ENAMETOOLONG: pathname resolution of a symbolic link produced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * an intermediate result whose length exceeds PATH_MAX [XPG4.2]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) static int jfs_symlink(struct inode *dip, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) tid_t tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ino_t ino = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct component_name dname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) int ssize; /* source pathname size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct btstack btstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) struct inode *ip = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) s64 xlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) int bmask = 0, xsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) s64 xaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct super_block *sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct tblock *tblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) struct inode *iplist[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) jfs_info("jfs_symlink: dip:0x%p name:%s", dip, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) rc = dquot_initialize(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ssize = strlen(name) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * search parent directory for entry/freespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) * (dtSearch() returns parent directory page pinned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if ((rc = get_UCSname(&dname, dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * allocate on-disk/in-memory inode for symbolic link:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * (iAlloc() returns new, locked inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) ip = ialloc(dip, S_IFLNK | 0777);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (IS_ERR(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) rc = PTR_ERR(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) tid = txBegin(dip->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) tblk = tid_to_tblock(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) tblk->xflag |= COMMIT_CREATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) tblk->ino = ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /* fix symlink access permission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * (dir_create() ANDs in the u.u_cmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * but symlinks really need to be 777 access)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) ip->i_mode |= 0777;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * write symbolic link target path name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) xtInitRoot(tid, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) * write source path name inline in on-disk inode (fast symbolic link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (ssize <= IDATASIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ip->i_op = &jfs_fast_symlink_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) ip->i_link = JFS_IP(ip)->i_inline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) memcpy(ip->i_link, name, ssize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ip->i_size = ssize - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) * if symlink is > 128 bytes, we don't have the space to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * store inline extended attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (ssize > sizeof (JFS_IP(ip)->i_inline))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) JFS_IP(ip)->mode2 &= ~INLINEEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) jfs_info("jfs_symlink: fast symlink added ssize:%d name:%s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) ssize, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * write source path name in a single extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) jfs_info("jfs_symlink: allocate extent ip:0x%p", ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) ip->i_op = &jfs_symlink_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) inode_nohighmem(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) ip->i_mapping->a_ops = &jfs_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) * even though the data of symlink object (source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) * path name) is treated as non-journaled user data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) * it is read/written thru buffer cache for performance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) sb = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) bmask = JFS_SBI(sb)->bsize - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) xsize = (ssize + bmask) & ~bmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) xaddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) xlen = xsize >> JFS_SBI(sb)->l2bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) txAbort(tid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) ip->i_size = ssize - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) while (ssize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /* This is kind of silly since PATH_MAX == 4K */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) int copy_size = min(ssize, PSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) mp = get_metapage(ip, xaddr, PSIZE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (mp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) xtTruncate(tid, ip, 0, COMMIT_PWMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) txAbort(tid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) memcpy(mp->data, name, copy_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) flush_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ssize -= copy_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) name += copy_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) xaddr += JFS_SBI(sb)->nbperpage;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * create entry for symbolic link in parent directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) ino = ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) rc = dtInsert(tid, dip, &dname, &ino, &btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (xlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) xtTruncate(tid, ip, 0, COMMIT_PWMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) txAbort(tid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /* discard new inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) mark_inode_dirty(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) dip->i_ctime = dip->i_mtime = current_time(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) mark_inode_dirty(dip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * commit update of parent directory and link object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) iplist[0] = dip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) iplist[1] = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) rc = txCommit(tid, 2, &iplist[0], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) out3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) mutex_unlock(&JFS_IP(dip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) free_ea_wmap(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) clear_nlink(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) discard_new_inode(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) d_instantiate_new(dentry, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) free_UCSname(&dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) jfs_info("jfs_symlink: rc:%d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) * NAME: jfs_rename
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) * FUNCTION: rename a file or directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct inode *new_dir, struct dentry *new_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct btstack btstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) ino_t ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct component_name new_dname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct inode *new_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) struct component_name old_dname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) struct inode *old_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) tid_t tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) int ipcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct inode *iplist[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct tblock *tblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) s64 new_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) int commit_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (flags & ~RENAME_NOREPLACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) jfs_info("jfs_rename: %pd %pd", old_dentry, new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) rc = dquot_initialize(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) rc = dquot_initialize(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) old_ip = d_inode(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) new_ip = d_inode(new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if ((rc = get_UCSname(&old_dname, old_dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if ((rc = get_UCSname(&new_dname, new_dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * Make sure source inode number is what we think it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) rc = dtSearch(old_dir, &old_dname, &ino, &btstack, JFS_LOOKUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (rc || (ino != old_ip->i_ino)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * Make sure dest inode number (if any) is what we think it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) rc = dtSearch(new_dir, &new_dname, &ino, &btstack, JFS_LOOKUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if ((!new_ip) || (ino != new_ip->i_ino)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) rc = -ESTALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) } else if (rc != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) else if (new_ip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /* no entry exists, but one was expected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) rc = -ESTALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (S_ISDIR(old_ip->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (new_ip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (!dtEmpty(new_ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) rc = -ENOTEMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) } else if (new_ip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) /* Init inode for quota operations. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) rc = dquot_initialize(new_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * The real work starts here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) tid = txBegin(new_dir->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) * How do we know the locking is safe from deadlocks?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) * The vfs does the hard part for us. Any time we are taking nested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * commit_mutexes, the vfs already has i_mutex held on the parent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) * Here, the vfs has already taken i_mutex on both old_dir and new_dir.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) mutex_lock_nested(&JFS_IP(new_dir)->commit_mutex, COMMIT_MUTEX_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) mutex_lock_nested(&JFS_IP(old_ip)->commit_mutex, COMMIT_MUTEX_CHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (old_dir != new_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) mutex_lock_nested(&JFS_IP(old_dir)->commit_mutex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) COMMIT_MUTEX_SECOND_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (new_ip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) mutex_lock_nested(&JFS_IP(new_ip)->commit_mutex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) COMMIT_MUTEX_VICTIM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) * Change existing directory entry to new inode number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) ino = new_ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) rc = dtModify(tid, new_dir, &new_dname, &ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) old_ip->i_ino, JFS_RENAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) goto out_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) drop_nlink(new_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (S_ISDIR(new_ip->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) drop_nlink(new_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (new_ip->i_nlink) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (old_dir != new_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (!S_ISDIR(old_ip->i_mode) && new_ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) IWRITE_UNLOCK(new_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) jfs_error(new_ip->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) "new_ip->i_nlink != 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) tblk = tid_to_tblock(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) tblk->xflag |= COMMIT_DELETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) tblk->u.ip = new_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) } else if (new_ip->i_nlink == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) assert(!test_cflag(COMMIT_Nolink, new_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) /* free block resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if ((new_size = commitZeroLink(tid, new_ip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) txAbort(tid, 1); /* Marks FS Dirty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) rc = new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) goto out_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) tblk = tid_to_tblock(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) tblk->xflag |= COMMIT_DELETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) tblk->u.ip = new_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) new_ip->i_ctime = current_time(new_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) mark_inode_dirty(new_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * Add new directory entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) rc = dtSearch(new_dir, &new_dname, &ino, &btstack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) JFS_CREATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) jfs_err("jfs_rename didn't expect dtSearch to fail w/rc = %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) goto out_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) ino = old_ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (rc == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) jfs_err("jfs_rename: dtInsert returned -EIO");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) goto out_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (S_ISDIR(old_ip->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) inc_nlink(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * Remove old directory entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) ino = old_ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) jfs_err("jfs_rename did not expect dtDelete to return rc = %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) txAbort(tid, 1); /* Marks Filesystem dirty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) goto out_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (S_ISDIR(old_ip->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) drop_nlink(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (old_dir != new_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) * Change inode number of parent for moved directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) JFS_IP(old_ip)->i_dtroot.header.idotdot =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) cpu_to_le32(new_dir->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) /* Linelock header of dtree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) tlck = txLock(tid, old_ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) (struct metapage *) &JFS_IP(old_ip)->bxflag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) tlckDTREE | tlckBTROOT | tlckRELINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) ASSERT(dtlck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) * Update ctime on changed/moved inodes & mark dirty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) old_ip->i_ctime = current_time(old_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) mark_inode_dirty(old_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) new_dir->i_ctime = new_dir->i_mtime = current_time(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) mark_inode_dirty(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) /* Build list of inodes modified by this transaction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) ipcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) iplist[ipcount++] = old_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (new_ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) iplist[ipcount++] = new_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) iplist[ipcount++] = old_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (old_dir != new_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) iplist[ipcount++] = new_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) mark_inode_dirty(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) * Incomplete truncate of file data can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) * result in timing problems unless we synchronously commit the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) * transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (new_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) commit_flag = COMMIT_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) commit_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) rc = txCommit(tid, ipcount, iplist, commit_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) out_tx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (new_ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (old_dir != new_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) while (new_size && (rc == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) tid = txBegin(new_ip->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) mutex_lock(&JFS_IP(new_ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) new_size = xtTruncate_pmap(tid, new_ip, new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (new_size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) txAbort(tid, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) rc = new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (new_ip && (new_ip->i_nlink == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) set_cflag(COMMIT_Nolink, new_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) * Truncating the directory index table is not guaranteed. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * may need to be done iteratively
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (test_cflag(COMMIT_Stale, old_dir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (old_dir->i_size > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) jfs_truncate_nolock(old_dir, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) clear_cflag(COMMIT_Stale, old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (new_ip && !S_ISDIR(new_ip->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) IWRITE_UNLOCK(new_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) out3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) free_UCSname(&new_dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) free_UCSname(&old_dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) jfs_info("jfs_rename: returning %d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) * NAME: jfs_mknod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) * FUNCTION: Create a special file (device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) static int jfs_mknod(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) umode_t mode, dev_t rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) struct jfs_inode_info *jfs_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) struct btstack btstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) struct component_name dname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) ino_t ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) struct inode *ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) struct inode *iplist[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) tid_t tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) struct tblock *tblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) jfs_info("jfs_mknod: %pd", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) rc = dquot_initialize(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) if ((rc = get_UCSname(&dname, dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) ip = ialloc(dir, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (IS_ERR(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) rc = PTR_ERR(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) jfs_ip = JFS_IP(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) tid = txBegin(dir->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) rc = jfs_init_acl(tid, ip, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) rc = jfs_init_security(tid, ip, dir, &dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) txAbort(tid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) txAbort(tid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) tblk = tid_to_tblock(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) tblk->xflag |= COMMIT_CREATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) tblk->ino = ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) ino = ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) txAbort(tid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) ip->i_op = &jfs_file_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) jfs_ip->dev = new_encode_dev(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) init_special_inode(ip, ip->i_mode, rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) mark_inode_dirty(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) dir->i_ctime = dir->i_mtime = current_time(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) mark_inode_dirty(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) iplist[0] = dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) iplist[1] = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) rc = txCommit(tid, 2, iplist, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) out3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) mutex_unlock(&JFS_IP(dir)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) free_ea_wmap(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) clear_nlink(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) discard_new_inode(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) d_instantiate_new(dentry, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) free_UCSname(&dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) jfs_info("jfs_mknod: returning %d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) struct btstack btstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) ino_t inum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) struct inode *ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) struct component_name key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) jfs_info("jfs_lookup: name = %pd", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) if ((rc = get_UCSname(&key, dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) free_UCSname(&key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) if (rc == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) ip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) } else if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) jfs_err("jfs_lookup: dtSearch returned %d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) ip = ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) ip = jfs_iget(dip->i_sb, inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (IS_ERR(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) jfs_err("jfs_lookup: iget failed on inum %d", (uint)inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) return d_splice_alias(ip, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) static struct inode *jfs_nfs_get_inode(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) u64 ino, u32 generation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) if (ino == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) return ERR_PTR(-ESTALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) inode = jfs_iget(sb, ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) return ERR_CAST(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (generation && inode->i_generation != generation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) return ERR_PTR(-ESTALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) return inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) struct dentry *jfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) int fh_len, int fh_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) jfs_nfs_get_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) int fh_len, int fh_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) return generic_fh_to_parent(sb, fid, fh_len, fh_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) jfs_nfs_get_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) struct dentry *jfs_get_parent(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) unsigned long parent_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) parent_ino =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) le32_to_cpu(JFS_IP(d_inode(dentry))->i_dtroot.header.idotdot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) return d_obtain_alias(jfs_iget(dentry->d_sb, parent_ino));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) const struct inode_operations jfs_dir_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) .create = jfs_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) .lookup = jfs_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) .link = jfs_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) .unlink = jfs_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) .symlink = jfs_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) .mkdir = jfs_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) .rmdir = jfs_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) .mknod = jfs_mknod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) .rename = jfs_rename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) .listxattr = jfs_listxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) .setattr = jfs_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) #ifdef CONFIG_JFS_POSIX_ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) .get_acl = jfs_get_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) .set_acl = jfs_set_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) const struct file_operations jfs_dir_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) .read = generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) .iterate = jfs_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) .fsync = jfs_fsync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) .unlocked_ioctl = jfs_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) .compat_ioctl = jfs_compat_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) static int jfs_ci_hash(const struct dentry *dir, struct qstr *this)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) unsigned long hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) hash = init_name_hash(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) for (i=0; i < this->len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) hash = partial_name_hash(tolower(this->name[i]), hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) this->hash = end_name_hash(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) static int jfs_ci_compare(const struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) unsigned int len, const char *str, const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) int i, result = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) if (len != name->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) for (i=0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (tolower(str[i]) != tolower(name->name[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) static int jfs_ci_revalidate(struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) * This is not negative dentry. Always valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) * Note, rename() to existing directory entry will have ->d_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) * and will use existing name which isn't specified name by user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) * We may be able to drop this positive dentry here. But dropping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) * positive dentry isn't good idea. So it's unsupported like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) * rename("filename", "FILENAME") for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) if (d_really_is_positive(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) * This may be nfsd (or something), anyway, we can't see the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) * intent of this. So, since this can be for creation, drop it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) if (!flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * Drop the negative dentry, in order to make sure to use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) * case sensitive name which is specified by user if this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) * for creation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) const struct dentry_operations jfs_ci_dentry_operations =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) .d_hash = jfs_ci_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) .d_compare = jfs_ci_compare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) .d_revalidate = jfs_ci_revalidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) };