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