1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2274dcf55SMike Marshall /* 3274dcf55SMike Marshall * (C) 2001 Clemson University and The University of Chicago 4274dcf55SMike Marshall * 5274dcf55SMike Marshall * See COPYING in top-level directory. 6274dcf55SMike Marshall */ 7274dcf55SMike Marshall 8274dcf55SMike Marshall /* 9274dcf55SMike Marshall * Linux VFS namei operations. 10274dcf55SMike Marshall */ 11274dcf55SMike Marshall 12274dcf55SMike Marshall #include "protocol.h" 13575e9461SMike Marshall #include "orangefs-kernel.h" 14274dcf55SMike Marshall 15274dcf55SMike Marshall /* 16274dcf55SMike Marshall * Get a newly allocated inode to go with a negative dentry. 17274dcf55SMike Marshall */ 188bb8aefdSYi Liu static int orangefs_create(struct inode *dir, 19274dcf55SMike Marshall struct dentry *dentry, 20274dcf55SMike Marshall umode_t mode, 21274dcf55SMike Marshall bool exclusive) 22274dcf55SMike Marshall { 238bb8aefdSYi Liu struct orangefs_inode_s *parent = ORANGEFS_I(dir); 248bb8aefdSYi Liu struct orangefs_kernel_op_s *new_op; 25db0267e7SMartin Brandenburg struct orangefs_object_kref ref; 26274dcf55SMike Marshall struct inode *inode; 27a55f2d86SMartin Brandenburg struct iattr iattr; 28274dcf55SMike Marshall int ret; 29274dcf55SMike Marshall 30f66debf1SAl Viro gossip_debug(GOSSIP_NAME_DEBUG, "%s: %pd\n", 315253487eSMike Marshall __func__, 32f66debf1SAl Viro dentry); 33274dcf55SMike Marshall 348bb8aefdSYi Liu new_op = op_alloc(ORANGEFS_VFS_OP_CREATE); 35274dcf55SMike Marshall if (!new_op) 36274dcf55SMike Marshall return -ENOMEM; 37274dcf55SMike Marshall 38274dcf55SMike Marshall new_op->upcall.req.create.parent_refn = parent->refn; 39274dcf55SMike Marshall 40274dcf55SMike Marshall fill_default_sys_attrs(new_op->upcall.req.create.attributes, 418bb8aefdSYi Liu ORANGEFS_TYPE_METAFILE, mode); 42274dcf55SMike Marshall 43274dcf55SMike Marshall strncpy(new_op->upcall.req.create.d_name, 446bdfb48dSXiongfeng Wang dentry->d_name.name, ORANGEFS_NAME_MAX - 1); 45274dcf55SMike Marshall 46274dcf55SMike Marshall ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 47274dcf55SMike Marshall 48274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 49f66debf1SAl Viro "%s: %pd: handle:%pU: fsid:%d: new_op:%p: ret:%d:\n", 505253487eSMike Marshall __func__, 51f66debf1SAl Viro dentry, 52274dcf55SMike Marshall &new_op->downcall.resp.create.refn.khandle, 535253487eSMike Marshall new_op->downcall.resp.create.refn.fs_id, 545253487eSMike Marshall new_op, 555253487eSMike Marshall ret); 56274dcf55SMike Marshall 575253487eSMike Marshall if (ret < 0) 58274dcf55SMike Marshall goto out; 59274dcf55SMike Marshall 60db0267e7SMartin Brandenburg ref = new_op->downcall.resp.create.refn; 61db0267e7SMartin Brandenburg op_release(new_op); 62db0267e7SMartin Brandenburg 63db0267e7SMartin Brandenburg inode = orangefs_new_inode(dir->i_sb, dir, S_IFREG | mode, 0, &ref); 64274dcf55SMike Marshall if (IS_ERR(inode)) { 65f66debf1SAl Viro gossip_err("%s: Failed to allocate inode for file :%pd:\n", 665253487eSMike Marshall __func__, 67f66debf1SAl Viro dentry); 68274dcf55SMike Marshall ret = PTR_ERR(inode); 69274dcf55SMike Marshall goto out; 70274dcf55SMike Marshall } 71274dcf55SMike Marshall 72274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 73f66debf1SAl Viro "%s: Assigned inode :%pU: for file :%pd:\n", 745253487eSMike Marshall __func__, 755253487eSMike Marshall get_khandle_from_ino(inode), 76f66debf1SAl Viro dentry); 77274dcf55SMike Marshall 781e2e547aSAl Viro d_instantiate_new(dentry, inode); 79804b1737SMiklos Szeredi orangefs_set_timeout(dentry); 808bbb20a8SMartin Brandenburg ORANGEFS_I(inode)->getattr_time = jiffies - 1; 8168a24a6cSMartin Brandenburg ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS; 82274dcf55SMike Marshall 83274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 84f66debf1SAl Viro "%s: dentry instantiated for %pd\n", 855253487eSMike Marshall __func__, 86f66debf1SAl Viro dentry); 87274dcf55SMike Marshall 88c2050a45SDeepa Dinamani dir->i_mtime = dir->i_ctime = current_time(dir); 89a55f2d86SMartin Brandenburg memset(&iattr, 0, sizeof iattr); 90a55f2d86SMartin Brandenburg iattr.ia_valid |= ATTR_MTIME; 91a55f2d86SMartin Brandenburg orangefs_inode_setattr(dir, &iattr); 92274dcf55SMike Marshall mark_inode_dirty_sync(dir); 93274dcf55SMike Marshall ret = 0; 94274dcf55SMike Marshall out: 955253487eSMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 96f66debf1SAl Viro "%s: %pd: returning %d\n", 975253487eSMike Marshall __func__, 98f66debf1SAl Viro dentry, 995253487eSMike Marshall ret); 100274dcf55SMike Marshall return ret; 101274dcf55SMike Marshall } 102274dcf55SMike Marshall 103274dcf55SMike Marshall /* 104274dcf55SMike Marshall * Attempt to resolve an object name (dentry->d_name), parent handle, and 105274dcf55SMike Marshall * fsid into a handle for the object. 106274dcf55SMike Marshall */ 1078bb8aefdSYi Liu static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry, 108274dcf55SMike Marshall unsigned int flags) 109274dcf55SMike Marshall { 1108bb8aefdSYi Liu struct orangefs_inode_s *parent = ORANGEFS_I(dir); 1118bb8aefdSYi Liu struct orangefs_kernel_op_s *new_op; 112274dcf55SMike Marshall struct inode *inode; 113274dcf55SMike Marshall struct dentry *res; 114274dcf55SMike Marshall int ret = -EINVAL; 115274dcf55SMike Marshall 116274dcf55SMike Marshall /* 117274dcf55SMike Marshall * in theory we could skip a lookup here (if the intent is to 118274dcf55SMike Marshall * create) in order to avoid a potentially failed lookup, but 119274dcf55SMike Marshall * leaving it in can skip a valid lookup and try to create a file 120274dcf55SMike Marshall * that already exists (e.g. the vfs already handles checking for 121274dcf55SMike Marshall * -EEXIST on O_EXCL opens, which is broken if we skip this lookup 122274dcf55SMike Marshall * in the create path) 123274dcf55SMike Marshall */ 124f66debf1SAl Viro gossip_debug(GOSSIP_NAME_DEBUG, "%s called on %pd\n", 125f66debf1SAl Viro __func__, dentry); 126274dcf55SMike Marshall 12747b4948fSMartin Brandenburg if (dentry->d_name.len > (ORANGEFS_NAME_MAX - 1)) 128274dcf55SMike Marshall return ERR_PTR(-ENAMETOOLONG); 129274dcf55SMike Marshall 1308bb8aefdSYi Liu new_op = op_alloc(ORANGEFS_VFS_OP_LOOKUP); 131274dcf55SMike Marshall if (!new_op) 132274dcf55SMike Marshall return ERR_PTR(-ENOMEM); 133274dcf55SMike Marshall 1347cec28e9SMike Marshall new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW; 135274dcf55SMike Marshall 136274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, "%s:%s:%d using parent %pU\n", 137274dcf55SMike Marshall __FILE__, 138274dcf55SMike Marshall __func__, 139274dcf55SMike Marshall __LINE__, 140274dcf55SMike Marshall &parent->refn.khandle); 141274dcf55SMike Marshall new_op->upcall.req.lookup.parent_refn = parent->refn; 142274dcf55SMike Marshall 143274dcf55SMike Marshall strncpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name, 1446bdfb48dSXiongfeng Wang ORANGEFS_NAME_MAX - 1); 145274dcf55SMike Marshall 146274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 1476ceaf781SMartin Brandenburg "%s: doing lookup on %s under %pU,%d\n", 148274dcf55SMike Marshall __func__, 149274dcf55SMike Marshall new_op->upcall.req.lookup.d_name, 150274dcf55SMike Marshall &new_op->upcall.req.lookup.parent_refn.khandle, 1516ceaf781SMartin Brandenburg new_op->upcall.req.lookup.parent_refn.fs_id); 152274dcf55SMike Marshall 153274dcf55SMike Marshall ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 154274dcf55SMike Marshall 155274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 156274dcf55SMike Marshall "Lookup Got %pU, fsid %d (ret=%d)\n", 157274dcf55SMike Marshall &new_op->downcall.resp.lookup.refn.khandle, 158274dcf55SMike Marshall new_op->downcall.resp.lookup.refn.fs_id, 159274dcf55SMike Marshall ret); 160274dcf55SMike Marshall 161274dcf55SMike Marshall if (ret < 0) { 162274dcf55SMike Marshall if (ret == -ENOENT) { 163274dcf55SMike Marshall /* 164274dcf55SMike Marshall * if no inode was found, add a negative dentry to 165274dcf55SMike Marshall * dcache anyway; if we don't, we don't hold expected 166274dcf55SMike Marshall * lookup semantics and we most noticeably break 167274dcf55SMike Marshall * during directory renames. 168274dcf55SMike Marshall * 169274dcf55SMike Marshall * however, if the operation failed or exited, do not 170274dcf55SMike Marshall * add the dentry (e.g. in the case that a touch is 171274dcf55SMike Marshall * issued on a file that already exists that was 172274dcf55SMike Marshall * interrupted during this lookup -- no need to add 173274dcf55SMike Marshall * another negative dentry for an existing file) 174274dcf55SMike Marshall */ 175274dcf55SMike Marshall 176274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 1778bb8aefdSYi Liu "orangefs_lookup: Adding *negative* dentry " 178f66debf1SAl Viro "%p for %pd\n", 179274dcf55SMike Marshall dentry, 180f66debf1SAl Viro dentry); 181274dcf55SMike Marshall 182274dcf55SMike Marshall d_add(dentry, NULL); 183274dcf55SMike Marshall res = NULL; 184274dcf55SMike Marshall goto out; 185274dcf55SMike Marshall } 186274dcf55SMike Marshall 187274dcf55SMike Marshall /* must be a non-recoverable error */ 188274dcf55SMike Marshall res = ERR_PTR(ret); 189274dcf55SMike Marshall goto out; 190274dcf55SMike Marshall } 191274dcf55SMike Marshall 192804b1737SMiklos Szeredi orangefs_set_timeout(dentry); 19331b7c1abSMartin Brandenburg 1948bb8aefdSYi Liu inode = orangefs_iget(dir->i_sb, &new_op->downcall.resp.lookup.refn); 195274dcf55SMike Marshall if (IS_ERR(inode)) { 196274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 197274dcf55SMike Marshall "error %ld from iget\n", PTR_ERR(inode)); 198274dcf55SMike Marshall res = ERR_CAST(inode); 199274dcf55SMike Marshall goto out; 200274dcf55SMike Marshall } 201274dcf55SMike Marshall 202274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 203274dcf55SMike Marshall "%s:%s:%d " 204274dcf55SMike Marshall "Found good inode [%lu] with count [%d]\n", 205274dcf55SMike Marshall __FILE__, 206274dcf55SMike Marshall __func__, 207274dcf55SMike Marshall __LINE__, 208274dcf55SMike Marshall inode->i_ino, 209274dcf55SMike Marshall (int)atomic_read(&inode->i_count)); 210274dcf55SMike Marshall 211274dcf55SMike Marshall /* update dentry/inode pair into dcache */ 212274dcf55SMike Marshall res = d_splice_alias(inode, dentry); 213274dcf55SMike Marshall 214274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 215274dcf55SMike Marshall "Lookup success (inode ct = %d)\n", 216274dcf55SMike Marshall (int)atomic_read(&inode->i_count)); 217274dcf55SMike Marshall out: 218274dcf55SMike Marshall op_release(new_op); 219274dcf55SMike Marshall return res; 220274dcf55SMike Marshall } 221274dcf55SMike Marshall 222274dcf55SMike Marshall /* return 0 on success; non-zero otherwise */ 2238bb8aefdSYi Liu static int orangefs_unlink(struct inode *dir, struct dentry *dentry) 224274dcf55SMike Marshall { 225274dcf55SMike Marshall struct inode *inode = dentry->d_inode; 2268bb8aefdSYi Liu struct orangefs_inode_s *parent = ORANGEFS_I(dir); 2278bb8aefdSYi Liu struct orangefs_kernel_op_s *new_op; 228a55f2d86SMartin Brandenburg struct iattr iattr; 229274dcf55SMike Marshall int ret; 230274dcf55SMike Marshall 231274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 232f66debf1SAl Viro "%s: called on %pd\n" 233274dcf55SMike Marshall " (inode %pU): Parent is %pU | fs_id %d\n", 234274dcf55SMike Marshall __func__, 235f66debf1SAl Viro dentry, 236274dcf55SMike Marshall get_khandle_from_ino(inode), 237274dcf55SMike Marshall &parent->refn.khandle, 238274dcf55SMike Marshall parent->refn.fs_id); 239274dcf55SMike Marshall 2408bb8aefdSYi Liu new_op = op_alloc(ORANGEFS_VFS_OP_REMOVE); 241274dcf55SMike Marshall if (!new_op) 242274dcf55SMike Marshall return -ENOMEM; 243274dcf55SMike Marshall 244274dcf55SMike Marshall new_op->upcall.req.remove.parent_refn = parent->refn; 245274dcf55SMike Marshall strncpy(new_op->upcall.req.remove.d_name, dentry->d_name.name, 2466bdfb48dSXiongfeng Wang ORANGEFS_NAME_MAX - 1); 247274dcf55SMike Marshall 2488bb8aefdSYi Liu ret = service_operation(new_op, "orangefs_unlink", 249274dcf55SMike Marshall get_interruptible_flag(inode)); 250274dcf55SMike Marshall 2515253487eSMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 2525253487eSMike Marshall "%s: service_operation returned:%d:\n", 2535253487eSMike Marshall __func__, 2545253487eSMike Marshall ret); 2555253487eSMike Marshall 256274dcf55SMike Marshall op_release(new_op); 257274dcf55SMike Marshall 258274dcf55SMike Marshall if (!ret) { 259274dcf55SMike Marshall drop_nlink(inode); 260274dcf55SMike Marshall 261c2050a45SDeepa Dinamani dir->i_mtime = dir->i_ctime = current_time(dir); 262a55f2d86SMartin Brandenburg memset(&iattr, 0, sizeof iattr); 263a55f2d86SMartin Brandenburg iattr.ia_valid |= ATTR_MTIME; 264a55f2d86SMartin Brandenburg orangefs_inode_setattr(dir, &iattr); 265274dcf55SMike Marshall mark_inode_dirty_sync(dir); 266274dcf55SMike Marshall } 267274dcf55SMike Marshall return ret; 268274dcf55SMike Marshall } 269274dcf55SMike Marshall 2708bb8aefdSYi Liu static int orangefs_symlink(struct inode *dir, 271274dcf55SMike Marshall struct dentry *dentry, 272274dcf55SMike Marshall const char *symname) 273274dcf55SMike Marshall { 2748bb8aefdSYi Liu struct orangefs_inode_s *parent = ORANGEFS_I(dir); 2758bb8aefdSYi Liu struct orangefs_kernel_op_s *new_op; 276db0267e7SMartin Brandenburg struct orangefs_object_kref ref; 277274dcf55SMike Marshall struct inode *inode; 278a55f2d86SMartin Brandenburg struct iattr iattr; 279274dcf55SMike Marshall int mode = 755; 280274dcf55SMike Marshall int ret; 281274dcf55SMike Marshall 282274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__); 283274dcf55SMike Marshall 284274dcf55SMike Marshall if (!symname) 285274dcf55SMike Marshall return -EINVAL; 286274dcf55SMike Marshall 287c62da585SMartin Brandenburg if (strlen(symname)+1 > ORANGEFS_NAME_MAX) 288c62da585SMartin Brandenburg return -ENAMETOOLONG; 289c62da585SMartin Brandenburg 2908bb8aefdSYi Liu new_op = op_alloc(ORANGEFS_VFS_OP_SYMLINK); 291274dcf55SMike Marshall if (!new_op) 292274dcf55SMike Marshall return -ENOMEM; 293274dcf55SMike Marshall 294274dcf55SMike Marshall new_op->upcall.req.sym.parent_refn = parent->refn; 295274dcf55SMike Marshall 296274dcf55SMike Marshall fill_default_sys_attrs(new_op->upcall.req.sym.attributes, 2978bb8aefdSYi Liu ORANGEFS_TYPE_SYMLINK, 298274dcf55SMike Marshall mode); 299274dcf55SMike Marshall 300274dcf55SMike Marshall strncpy(new_op->upcall.req.sym.entry_name, 301274dcf55SMike Marshall dentry->d_name.name, 3026bdfb48dSXiongfeng Wang ORANGEFS_NAME_MAX - 1); 3036bdfb48dSXiongfeng Wang strncpy(new_op->upcall.req.sym.target, symname, ORANGEFS_NAME_MAX - 1); 304274dcf55SMike Marshall 305274dcf55SMike Marshall ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 306274dcf55SMike Marshall 307274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 3088bb8aefdSYi Liu "Symlink Got ORANGEFS handle %pU on fsid %d (ret=%d)\n", 309274dcf55SMike Marshall &new_op->downcall.resp.sym.refn.khandle, 310274dcf55SMike Marshall new_op->downcall.resp.sym.refn.fs_id, ret); 311274dcf55SMike Marshall 312274dcf55SMike Marshall if (ret < 0) { 313274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 314274dcf55SMike Marshall "%s: failed with error code %d\n", 315274dcf55SMike Marshall __func__, ret); 316274dcf55SMike Marshall goto out; 317274dcf55SMike Marshall } 318274dcf55SMike Marshall 319db0267e7SMartin Brandenburg ref = new_op->downcall.resp.sym.refn; 320db0267e7SMartin Brandenburg op_release(new_op); 321db0267e7SMartin Brandenburg 322db0267e7SMartin Brandenburg inode = orangefs_new_inode(dir->i_sb, dir, S_IFLNK | mode, 0, &ref); 323274dcf55SMike Marshall if (IS_ERR(inode)) { 324274dcf55SMike Marshall gossip_err 3258bb8aefdSYi Liu ("*** Failed to allocate orangefs symlink inode\n"); 326274dcf55SMike Marshall ret = PTR_ERR(inode); 327274dcf55SMike Marshall goto out; 328274dcf55SMike Marshall } 329*f6a4b4c9SMartin Brandenburg /* 330*f6a4b4c9SMartin Brandenburg * This is necessary because orangefs_inode_getattr will not 331*f6a4b4c9SMartin Brandenburg * re-read symlink size as it is impossible for it to change. 332*f6a4b4c9SMartin Brandenburg * Invalidating the cache does not help. orangefs_new_inode 333*f6a4b4c9SMartin Brandenburg * does not set the correct size (it does not know symname). 334*f6a4b4c9SMartin Brandenburg */ 335*f6a4b4c9SMartin Brandenburg inode->i_size = strlen(symname); 336274dcf55SMike Marshall 337274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 338274dcf55SMike Marshall "Assigned symlink inode new number of %pU\n", 339274dcf55SMike Marshall get_khandle_from_ino(inode)); 340274dcf55SMike Marshall 3411e2e547aSAl Viro d_instantiate_new(dentry, inode); 342804b1737SMiklos Szeredi orangefs_set_timeout(dentry); 3438bbb20a8SMartin Brandenburg ORANGEFS_I(inode)->getattr_time = jiffies - 1; 34468a24a6cSMartin Brandenburg ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS; 345274dcf55SMike Marshall 346274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 347f66debf1SAl Viro "Inode (Symlink) %pU -> %pd\n", 348274dcf55SMike Marshall get_khandle_from_ino(inode), 349f66debf1SAl Viro dentry); 350274dcf55SMike Marshall 351c2050a45SDeepa Dinamani dir->i_mtime = dir->i_ctime = current_time(dir); 352a55f2d86SMartin Brandenburg memset(&iattr, 0, sizeof iattr); 353a55f2d86SMartin Brandenburg iattr.ia_valid |= ATTR_MTIME; 354a55f2d86SMartin Brandenburg orangefs_inode_setattr(dir, &iattr); 355274dcf55SMike Marshall mark_inode_dirty_sync(dir); 356274dcf55SMike Marshall ret = 0; 357274dcf55SMike Marshall out: 358274dcf55SMike Marshall return ret; 359274dcf55SMike Marshall } 360274dcf55SMike Marshall 3618bb8aefdSYi Liu static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 362274dcf55SMike Marshall { 3638bb8aefdSYi Liu struct orangefs_inode_s *parent = ORANGEFS_I(dir); 3648bb8aefdSYi Liu struct orangefs_kernel_op_s *new_op; 365db0267e7SMartin Brandenburg struct orangefs_object_kref ref; 366274dcf55SMike Marshall struct inode *inode; 367a55f2d86SMartin Brandenburg struct iattr iattr; 368274dcf55SMike Marshall int ret; 369274dcf55SMike Marshall 3708bb8aefdSYi Liu new_op = op_alloc(ORANGEFS_VFS_OP_MKDIR); 371274dcf55SMike Marshall if (!new_op) 372274dcf55SMike Marshall return -ENOMEM; 373274dcf55SMike Marshall 374274dcf55SMike Marshall new_op->upcall.req.mkdir.parent_refn = parent->refn; 375274dcf55SMike Marshall 376274dcf55SMike Marshall fill_default_sys_attrs(new_op->upcall.req.mkdir.attributes, 3778bb8aefdSYi Liu ORANGEFS_TYPE_DIRECTORY, mode); 378274dcf55SMike Marshall 379274dcf55SMike Marshall strncpy(new_op->upcall.req.mkdir.d_name, 3806bdfb48dSXiongfeng Wang dentry->d_name.name, ORANGEFS_NAME_MAX - 1); 381274dcf55SMike Marshall 382274dcf55SMike Marshall ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 383274dcf55SMike Marshall 384274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 3858bb8aefdSYi Liu "Mkdir Got ORANGEFS handle %pU on fsid %d\n", 386274dcf55SMike Marshall &new_op->downcall.resp.mkdir.refn.khandle, 387274dcf55SMike Marshall new_op->downcall.resp.mkdir.refn.fs_id); 388274dcf55SMike Marshall 389274dcf55SMike Marshall if (ret < 0) { 390274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 391274dcf55SMike Marshall "%s: failed with error code %d\n", 392274dcf55SMike Marshall __func__, ret); 393274dcf55SMike Marshall goto out; 394274dcf55SMike Marshall } 395274dcf55SMike Marshall 396db0267e7SMartin Brandenburg ref = new_op->downcall.resp.mkdir.refn; 397db0267e7SMartin Brandenburg op_release(new_op); 398db0267e7SMartin Brandenburg 399db0267e7SMartin Brandenburg inode = orangefs_new_inode(dir->i_sb, dir, S_IFDIR | mode, 0, &ref); 400274dcf55SMike Marshall if (IS_ERR(inode)) { 4018bb8aefdSYi Liu gossip_err("*** Failed to allocate orangefs dir inode\n"); 402274dcf55SMike Marshall ret = PTR_ERR(inode); 403274dcf55SMike Marshall goto out; 404274dcf55SMike Marshall } 405274dcf55SMike Marshall 406274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 407274dcf55SMike Marshall "Assigned dir inode new number of %pU\n", 408274dcf55SMike Marshall get_khandle_from_ino(inode)); 409274dcf55SMike Marshall 4101e2e547aSAl Viro d_instantiate_new(dentry, inode); 411804b1737SMiklos Szeredi orangefs_set_timeout(dentry); 4128bbb20a8SMartin Brandenburg ORANGEFS_I(inode)->getattr_time = jiffies - 1; 41368a24a6cSMartin Brandenburg ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS; 414274dcf55SMike Marshall 415274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 416f66debf1SAl Viro "Inode (Directory) %pU -> %pd\n", 417274dcf55SMike Marshall get_khandle_from_ino(inode), 418f66debf1SAl Viro dentry); 419274dcf55SMike Marshall 420274dcf55SMike Marshall /* 421274dcf55SMike Marshall * NOTE: we have no good way to keep nlink consistent for directories 422274dcf55SMike Marshall * across clients; keep constant at 1. 423274dcf55SMike Marshall */ 424c2050a45SDeepa Dinamani dir->i_mtime = dir->i_ctime = current_time(dir); 425a55f2d86SMartin Brandenburg memset(&iattr, 0, sizeof iattr); 426a55f2d86SMartin Brandenburg iattr.ia_valid |= ATTR_MTIME; 427a55f2d86SMartin Brandenburg orangefs_inode_setattr(dir, &iattr); 428274dcf55SMike Marshall mark_inode_dirty_sync(dir); 429274dcf55SMike Marshall out: 430274dcf55SMike Marshall return ret; 431274dcf55SMike Marshall } 432274dcf55SMike Marshall 4338bb8aefdSYi Liu static int orangefs_rename(struct inode *old_dir, 434274dcf55SMike Marshall struct dentry *old_dentry, 435274dcf55SMike Marshall struct inode *new_dir, 4361cd66c93SMiklos Szeredi struct dentry *new_dentry, 4371cd66c93SMiklos Szeredi unsigned int flags) 438274dcf55SMike Marshall { 4398bb8aefdSYi Liu struct orangefs_kernel_op_s *new_op; 440274dcf55SMike Marshall int ret; 441274dcf55SMike Marshall 4421cd66c93SMiklos Szeredi if (flags) 4431cd66c93SMiklos Szeredi return -EINVAL; 4441cd66c93SMiklos Szeredi 445274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 44696b0cffbSAl Viro "orangefs_rename: called (%pd2 => %pd2) ct=%d\n", 44796b0cffbSAl Viro old_dentry, new_dentry, d_count(new_dentry)); 448274dcf55SMike Marshall 4498bbb20a8SMartin Brandenburg ORANGEFS_I(new_dentry->d_parent->d_inode)->getattr_time = jiffies - 1; 45071680c18SMartin Brandenburg 4518bb8aefdSYi Liu new_op = op_alloc(ORANGEFS_VFS_OP_RENAME); 452274dcf55SMike Marshall if (!new_op) 453274dcf55SMike Marshall return -EINVAL; 454274dcf55SMike Marshall 4558bb8aefdSYi Liu new_op->upcall.req.rename.old_parent_refn = ORANGEFS_I(old_dir)->refn; 4568bb8aefdSYi Liu new_op->upcall.req.rename.new_parent_refn = ORANGEFS_I(new_dir)->refn; 457274dcf55SMike Marshall 458274dcf55SMike Marshall strncpy(new_op->upcall.req.rename.d_old_name, 459274dcf55SMike Marshall old_dentry->d_name.name, 4606bdfb48dSXiongfeng Wang ORANGEFS_NAME_MAX - 1); 461274dcf55SMike Marshall strncpy(new_op->upcall.req.rename.d_new_name, 462274dcf55SMike Marshall new_dentry->d_name.name, 4636bdfb48dSXiongfeng Wang ORANGEFS_NAME_MAX - 1); 464274dcf55SMike Marshall 465274dcf55SMike Marshall ret = service_operation(new_op, 4668bb8aefdSYi Liu "orangefs_rename", 467274dcf55SMike Marshall get_interruptible_flag(old_dentry->d_inode)); 468274dcf55SMike Marshall 469274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 4708bb8aefdSYi Liu "orangefs_rename: got downcall status %d\n", 471274dcf55SMike Marshall ret); 472274dcf55SMike Marshall 473274dcf55SMike Marshall if (new_dentry->d_inode) 474c2050a45SDeepa Dinamani new_dentry->d_inode->i_ctime = current_time(new_dentry->d_inode); 475274dcf55SMike Marshall 476274dcf55SMike Marshall op_release(new_op); 477274dcf55SMike Marshall return ret; 478274dcf55SMike Marshall } 479274dcf55SMike Marshall 4808bb8aefdSYi Liu /* ORANGEFS implementation of VFS inode operations for directories */ 4816f3fc107SAl Viro const struct inode_operations orangefs_dir_inode_operations = { 4828bb8aefdSYi Liu .lookup = orangefs_lookup, 4838bb8aefdSYi Liu .get_acl = orangefs_get_acl, 4848bb8aefdSYi Liu .set_acl = orangefs_set_acl, 4858bb8aefdSYi Liu .create = orangefs_create, 4868bb8aefdSYi Liu .unlink = orangefs_unlink, 4878bb8aefdSYi Liu .symlink = orangefs_symlink, 4888bb8aefdSYi Liu .mkdir = orangefs_mkdir, 4898bb8aefdSYi Liu .rmdir = orangefs_unlink, 4908bb8aefdSYi Liu .rename = orangefs_rename, 4918bb8aefdSYi Liu .setattr = orangefs_setattr, 4928bb8aefdSYi Liu .getattr = orangefs_getattr, 4938bb8aefdSYi Liu .listxattr = orangefs_listxattr, 494933287daSMartin Brandenburg .permission = orangefs_permission, 495a55f2d86SMartin Brandenburg .update_time = orangefs_update_time, 496274dcf55SMike Marshall }; 497