1*274dcf55SMike Marshall /* 2*274dcf55SMike Marshall * (C) 2001 Clemson University and The University of Chicago 3*274dcf55SMike Marshall * 4*274dcf55SMike Marshall * See COPYING in top-level directory. 5*274dcf55SMike Marshall */ 6*274dcf55SMike Marshall 7*274dcf55SMike Marshall /* 8*274dcf55SMike Marshall * Linux VFS namei operations. 9*274dcf55SMike Marshall */ 10*274dcf55SMike Marshall 11*274dcf55SMike Marshall #include "protocol.h" 12*274dcf55SMike Marshall #include "pvfs2-kernel.h" 13*274dcf55SMike Marshall 14*274dcf55SMike Marshall /* 15*274dcf55SMike Marshall * Get a newly allocated inode to go with a negative dentry. 16*274dcf55SMike Marshall */ 17*274dcf55SMike Marshall static int pvfs2_create(struct inode *dir, 18*274dcf55SMike Marshall struct dentry *dentry, 19*274dcf55SMike Marshall umode_t mode, 20*274dcf55SMike Marshall bool exclusive) 21*274dcf55SMike Marshall { 22*274dcf55SMike Marshall struct pvfs2_inode_s *parent = PVFS2_I(dir); 23*274dcf55SMike Marshall struct pvfs2_kernel_op_s *new_op; 24*274dcf55SMike Marshall struct inode *inode; 25*274dcf55SMike Marshall int ret; 26*274dcf55SMike Marshall 27*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__); 28*274dcf55SMike Marshall 29*274dcf55SMike Marshall new_op = op_alloc(PVFS2_VFS_OP_CREATE); 30*274dcf55SMike Marshall if (!new_op) 31*274dcf55SMike Marshall return -ENOMEM; 32*274dcf55SMike Marshall 33*274dcf55SMike Marshall new_op->upcall.req.create.parent_refn = parent->refn; 34*274dcf55SMike Marshall 35*274dcf55SMike Marshall fill_default_sys_attrs(new_op->upcall.req.create.attributes, 36*274dcf55SMike Marshall PVFS_TYPE_METAFILE, mode); 37*274dcf55SMike Marshall 38*274dcf55SMike Marshall strncpy(new_op->upcall.req.create.d_name, 39*274dcf55SMike Marshall dentry->d_name.name, PVFS2_NAME_LEN); 40*274dcf55SMike Marshall 41*274dcf55SMike Marshall ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 42*274dcf55SMike Marshall 43*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 44*274dcf55SMike Marshall "Create Got PVFS2 handle %pU on fsid %d (ret=%d)\n", 45*274dcf55SMike Marshall &new_op->downcall.resp.create.refn.khandle, 46*274dcf55SMike Marshall new_op->downcall.resp.create.refn.fs_id, ret); 47*274dcf55SMike Marshall 48*274dcf55SMike Marshall if (ret < 0) { 49*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 50*274dcf55SMike Marshall "%s: failed with error code %d\n", 51*274dcf55SMike Marshall __func__, ret); 52*274dcf55SMike Marshall goto out; 53*274dcf55SMike Marshall } 54*274dcf55SMike Marshall 55*274dcf55SMike Marshall inode = pvfs2_new_inode(dir->i_sb, dir, S_IFREG | mode, 0, 56*274dcf55SMike Marshall &new_op->downcall.resp.create.refn); 57*274dcf55SMike Marshall if (IS_ERR(inode)) { 58*274dcf55SMike Marshall gossip_err("*** Failed to allocate pvfs2 file inode\n"); 59*274dcf55SMike Marshall ret = PTR_ERR(inode); 60*274dcf55SMike Marshall goto out; 61*274dcf55SMike Marshall } 62*274dcf55SMike Marshall 63*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 64*274dcf55SMike Marshall "Assigned file inode new number of %pU\n", 65*274dcf55SMike Marshall get_khandle_from_ino(inode)); 66*274dcf55SMike Marshall 67*274dcf55SMike Marshall d_instantiate(dentry, inode); 68*274dcf55SMike Marshall unlock_new_inode(inode); 69*274dcf55SMike Marshall 70*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 71*274dcf55SMike Marshall "Inode (Regular File) %pU -> %s\n", 72*274dcf55SMike Marshall get_khandle_from_ino(inode), 73*274dcf55SMike Marshall dentry->d_name.name); 74*274dcf55SMike Marshall 75*274dcf55SMike Marshall SetMtimeFlag(parent); 76*274dcf55SMike Marshall dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb); 77*274dcf55SMike Marshall mark_inode_dirty_sync(dir); 78*274dcf55SMike Marshall ret = 0; 79*274dcf55SMike Marshall out: 80*274dcf55SMike Marshall op_release(new_op); 81*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, "%s: returning %d\n", __func__, ret); 82*274dcf55SMike Marshall return ret; 83*274dcf55SMike Marshall } 84*274dcf55SMike Marshall 85*274dcf55SMike Marshall /* 86*274dcf55SMike Marshall * Attempt to resolve an object name (dentry->d_name), parent handle, and 87*274dcf55SMike Marshall * fsid into a handle for the object. 88*274dcf55SMike Marshall */ 89*274dcf55SMike Marshall static struct dentry *pvfs2_lookup(struct inode *dir, struct dentry *dentry, 90*274dcf55SMike Marshall unsigned int flags) 91*274dcf55SMike Marshall { 92*274dcf55SMike Marshall struct pvfs2_inode_s *parent = PVFS2_I(dir); 93*274dcf55SMike Marshall struct pvfs2_kernel_op_s *new_op; 94*274dcf55SMike Marshall struct inode *inode; 95*274dcf55SMike Marshall struct dentry *res; 96*274dcf55SMike Marshall int ret = -EINVAL; 97*274dcf55SMike Marshall 98*274dcf55SMike Marshall /* 99*274dcf55SMike Marshall * in theory we could skip a lookup here (if the intent is to 100*274dcf55SMike Marshall * create) in order to avoid a potentially failed lookup, but 101*274dcf55SMike Marshall * leaving it in can skip a valid lookup and try to create a file 102*274dcf55SMike Marshall * that already exists (e.g. the vfs already handles checking for 103*274dcf55SMike Marshall * -EEXIST on O_EXCL opens, which is broken if we skip this lookup 104*274dcf55SMike Marshall * in the create path) 105*274dcf55SMike Marshall */ 106*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, "%s called on %s\n", 107*274dcf55SMike Marshall __func__, dentry->d_name.name); 108*274dcf55SMike Marshall 109*274dcf55SMike Marshall if (dentry->d_name.len > (PVFS2_NAME_LEN - 1)) 110*274dcf55SMike Marshall return ERR_PTR(-ENAMETOOLONG); 111*274dcf55SMike Marshall 112*274dcf55SMike Marshall new_op = op_alloc(PVFS2_VFS_OP_LOOKUP); 113*274dcf55SMike Marshall if (!new_op) 114*274dcf55SMike Marshall return ERR_PTR(-ENOMEM); 115*274dcf55SMike Marshall 116*274dcf55SMike Marshall new_op->upcall.req.lookup.sym_follow = flags & LOOKUP_FOLLOW; 117*274dcf55SMike Marshall 118*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, "%s:%s:%d using parent %pU\n", 119*274dcf55SMike Marshall __FILE__, 120*274dcf55SMike Marshall __func__, 121*274dcf55SMike Marshall __LINE__, 122*274dcf55SMike Marshall &parent->refn.khandle); 123*274dcf55SMike Marshall new_op->upcall.req.lookup.parent_refn = parent->refn; 124*274dcf55SMike Marshall 125*274dcf55SMike Marshall strncpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name, 126*274dcf55SMike Marshall PVFS2_NAME_LEN); 127*274dcf55SMike Marshall 128*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 129*274dcf55SMike Marshall "%s: doing lookup on %s under %pU,%d (follow=%s)\n", 130*274dcf55SMike Marshall __func__, 131*274dcf55SMike Marshall new_op->upcall.req.lookup.d_name, 132*274dcf55SMike Marshall &new_op->upcall.req.lookup.parent_refn.khandle, 133*274dcf55SMike Marshall new_op->upcall.req.lookup.parent_refn.fs_id, 134*274dcf55SMike Marshall ((new_op->upcall.req.lookup.sym_follow == 135*274dcf55SMike Marshall PVFS2_LOOKUP_LINK_FOLLOW) ? "yes" : "no")); 136*274dcf55SMike Marshall 137*274dcf55SMike Marshall ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 138*274dcf55SMike Marshall 139*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 140*274dcf55SMike Marshall "Lookup Got %pU, fsid %d (ret=%d)\n", 141*274dcf55SMike Marshall &new_op->downcall.resp.lookup.refn.khandle, 142*274dcf55SMike Marshall new_op->downcall.resp.lookup.refn.fs_id, 143*274dcf55SMike Marshall ret); 144*274dcf55SMike Marshall 145*274dcf55SMike Marshall if (ret < 0) { 146*274dcf55SMike Marshall if (ret == -ENOENT) { 147*274dcf55SMike Marshall /* 148*274dcf55SMike Marshall * if no inode was found, add a negative dentry to 149*274dcf55SMike Marshall * dcache anyway; if we don't, we don't hold expected 150*274dcf55SMike Marshall * lookup semantics and we most noticeably break 151*274dcf55SMike Marshall * during directory renames. 152*274dcf55SMike Marshall * 153*274dcf55SMike Marshall * however, if the operation failed or exited, do not 154*274dcf55SMike Marshall * add the dentry (e.g. in the case that a touch is 155*274dcf55SMike Marshall * issued on a file that already exists that was 156*274dcf55SMike Marshall * interrupted during this lookup -- no need to add 157*274dcf55SMike Marshall * another negative dentry for an existing file) 158*274dcf55SMike Marshall */ 159*274dcf55SMike Marshall 160*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 161*274dcf55SMike Marshall "pvfs2_lookup: Adding *negative* dentry " 162*274dcf55SMike Marshall "%p for %s\n", 163*274dcf55SMike Marshall dentry, 164*274dcf55SMike Marshall dentry->d_name.name); 165*274dcf55SMike Marshall 166*274dcf55SMike Marshall d_add(dentry, NULL); 167*274dcf55SMike Marshall res = NULL; 168*274dcf55SMike Marshall goto out; 169*274dcf55SMike Marshall } 170*274dcf55SMike Marshall 171*274dcf55SMike Marshall /* must be a non-recoverable error */ 172*274dcf55SMike Marshall res = ERR_PTR(ret); 173*274dcf55SMike Marshall goto out; 174*274dcf55SMike Marshall } 175*274dcf55SMike Marshall 176*274dcf55SMike Marshall inode = pvfs2_iget(dir->i_sb, &new_op->downcall.resp.lookup.refn); 177*274dcf55SMike Marshall if (IS_ERR(inode)) { 178*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 179*274dcf55SMike Marshall "error %ld from iget\n", PTR_ERR(inode)); 180*274dcf55SMike Marshall res = ERR_CAST(inode); 181*274dcf55SMike Marshall goto out; 182*274dcf55SMike Marshall } 183*274dcf55SMike Marshall 184*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 185*274dcf55SMike Marshall "%s:%s:%d " 186*274dcf55SMike Marshall "Found good inode [%lu] with count [%d]\n", 187*274dcf55SMike Marshall __FILE__, 188*274dcf55SMike Marshall __func__, 189*274dcf55SMike Marshall __LINE__, 190*274dcf55SMike Marshall inode->i_ino, 191*274dcf55SMike Marshall (int)atomic_read(&inode->i_count)); 192*274dcf55SMike Marshall 193*274dcf55SMike Marshall /* update dentry/inode pair into dcache */ 194*274dcf55SMike Marshall res = d_splice_alias(inode, dentry); 195*274dcf55SMike Marshall 196*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 197*274dcf55SMike Marshall "Lookup success (inode ct = %d)\n", 198*274dcf55SMike Marshall (int)atomic_read(&inode->i_count)); 199*274dcf55SMike Marshall out: 200*274dcf55SMike Marshall op_release(new_op); 201*274dcf55SMike Marshall return res; 202*274dcf55SMike Marshall } 203*274dcf55SMike Marshall 204*274dcf55SMike Marshall /* return 0 on success; non-zero otherwise */ 205*274dcf55SMike Marshall static int pvfs2_unlink(struct inode *dir, struct dentry *dentry) 206*274dcf55SMike Marshall { 207*274dcf55SMike Marshall struct inode *inode = dentry->d_inode; 208*274dcf55SMike Marshall struct pvfs2_inode_s *parent = PVFS2_I(dir); 209*274dcf55SMike Marshall struct pvfs2_kernel_op_s *new_op; 210*274dcf55SMike Marshall int ret; 211*274dcf55SMike Marshall 212*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 213*274dcf55SMike Marshall "%s: called on %s\n" 214*274dcf55SMike Marshall " (inode %pU): Parent is %pU | fs_id %d\n", 215*274dcf55SMike Marshall __func__, 216*274dcf55SMike Marshall dentry->d_name.name, 217*274dcf55SMike Marshall get_khandle_from_ino(inode), 218*274dcf55SMike Marshall &parent->refn.khandle, 219*274dcf55SMike Marshall parent->refn.fs_id); 220*274dcf55SMike Marshall 221*274dcf55SMike Marshall new_op = op_alloc(PVFS2_VFS_OP_REMOVE); 222*274dcf55SMike Marshall if (!new_op) 223*274dcf55SMike Marshall return -ENOMEM; 224*274dcf55SMike Marshall 225*274dcf55SMike Marshall new_op->upcall.req.remove.parent_refn = parent->refn; 226*274dcf55SMike Marshall strncpy(new_op->upcall.req.remove.d_name, dentry->d_name.name, 227*274dcf55SMike Marshall PVFS2_NAME_LEN); 228*274dcf55SMike Marshall 229*274dcf55SMike Marshall ret = service_operation(new_op, "pvfs2_unlink", 230*274dcf55SMike Marshall get_interruptible_flag(inode)); 231*274dcf55SMike Marshall 232*274dcf55SMike Marshall /* when request is serviced properly, free req op struct */ 233*274dcf55SMike Marshall op_release(new_op); 234*274dcf55SMike Marshall 235*274dcf55SMike Marshall if (!ret) { 236*274dcf55SMike Marshall drop_nlink(inode); 237*274dcf55SMike Marshall 238*274dcf55SMike Marshall SetMtimeFlag(parent); 239*274dcf55SMike Marshall dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb); 240*274dcf55SMike Marshall mark_inode_dirty_sync(dir); 241*274dcf55SMike Marshall } 242*274dcf55SMike Marshall return ret; 243*274dcf55SMike Marshall } 244*274dcf55SMike Marshall 245*274dcf55SMike Marshall /* 246*274dcf55SMike Marshall * pvfs2_link() is only implemented here to make sure that we return a 247*274dcf55SMike Marshall * reasonable error code (the kernel will return a misleading EPERM 248*274dcf55SMike Marshall * otherwise). PVFS2 does not support hard links. 249*274dcf55SMike Marshall */ 250*274dcf55SMike Marshall static int pvfs2_link(struct dentry *old_dentry, 251*274dcf55SMike Marshall struct inode *dir, 252*274dcf55SMike Marshall struct dentry *dentry) 253*274dcf55SMike Marshall { 254*274dcf55SMike Marshall return -EOPNOTSUPP; 255*274dcf55SMike Marshall } 256*274dcf55SMike Marshall 257*274dcf55SMike Marshall /* 258*274dcf55SMike Marshall * pvfs2_mknod() is only implemented here to make sure that we return a 259*274dcf55SMike Marshall * reasonable error code (the kernel will return a misleading EPERM 260*274dcf55SMike Marshall * otherwise). PVFS2 does not support special files such as fifos or devices. 261*274dcf55SMike Marshall */ 262*274dcf55SMike Marshall static int pvfs2_mknod(struct inode *dir, 263*274dcf55SMike Marshall struct dentry *dentry, 264*274dcf55SMike Marshall umode_t mode, 265*274dcf55SMike Marshall dev_t rdev) 266*274dcf55SMike Marshall { 267*274dcf55SMike Marshall return -EOPNOTSUPP; 268*274dcf55SMike Marshall } 269*274dcf55SMike Marshall 270*274dcf55SMike Marshall static int pvfs2_symlink(struct inode *dir, 271*274dcf55SMike Marshall struct dentry *dentry, 272*274dcf55SMike Marshall const char *symname) 273*274dcf55SMike Marshall { 274*274dcf55SMike Marshall struct pvfs2_inode_s *parent = PVFS2_I(dir); 275*274dcf55SMike Marshall struct pvfs2_kernel_op_s *new_op; 276*274dcf55SMike Marshall struct inode *inode; 277*274dcf55SMike Marshall int mode = 755; 278*274dcf55SMike Marshall int ret; 279*274dcf55SMike Marshall 280*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__); 281*274dcf55SMike Marshall 282*274dcf55SMike Marshall if (!symname) 283*274dcf55SMike Marshall return -EINVAL; 284*274dcf55SMike Marshall 285*274dcf55SMike Marshall new_op = op_alloc(PVFS2_VFS_OP_SYMLINK); 286*274dcf55SMike Marshall if (!new_op) 287*274dcf55SMike Marshall return -ENOMEM; 288*274dcf55SMike Marshall 289*274dcf55SMike Marshall new_op->upcall.req.sym.parent_refn = parent->refn; 290*274dcf55SMike Marshall 291*274dcf55SMike Marshall fill_default_sys_attrs(new_op->upcall.req.sym.attributes, 292*274dcf55SMike Marshall PVFS_TYPE_SYMLINK, 293*274dcf55SMike Marshall mode); 294*274dcf55SMike Marshall 295*274dcf55SMike Marshall strncpy(new_op->upcall.req.sym.entry_name, 296*274dcf55SMike Marshall dentry->d_name.name, 297*274dcf55SMike Marshall PVFS2_NAME_LEN); 298*274dcf55SMike Marshall strncpy(new_op->upcall.req.sym.target, symname, PVFS2_NAME_LEN); 299*274dcf55SMike Marshall 300*274dcf55SMike Marshall ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 301*274dcf55SMike Marshall 302*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 303*274dcf55SMike Marshall "Symlink Got PVFS2 handle %pU on fsid %d (ret=%d)\n", 304*274dcf55SMike Marshall &new_op->downcall.resp.sym.refn.khandle, 305*274dcf55SMike Marshall new_op->downcall.resp.sym.refn.fs_id, ret); 306*274dcf55SMike Marshall 307*274dcf55SMike Marshall if (ret < 0) { 308*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 309*274dcf55SMike Marshall "%s: failed with error code %d\n", 310*274dcf55SMike Marshall __func__, ret); 311*274dcf55SMike Marshall goto out; 312*274dcf55SMike Marshall } 313*274dcf55SMike Marshall 314*274dcf55SMike Marshall inode = pvfs2_new_inode(dir->i_sb, dir, S_IFLNK | mode, 0, 315*274dcf55SMike Marshall &new_op->downcall.resp.sym.refn); 316*274dcf55SMike Marshall if (IS_ERR(inode)) { 317*274dcf55SMike Marshall gossip_err 318*274dcf55SMike Marshall ("*** Failed to allocate pvfs2 symlink inode\n"); 319*274dcf55SMike Marshall ret = PTR_ERR(inode); 320*274dcf55SMike Marshall goto out; 321*274dcf55SMike Marshall } 322*274dcf55SMike Marshall 323*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 324*274dcf55SMike Marshall "Assigned symlink inode new number of %pU\n", 325*274dcf55SMike Marshall get_khandle_from_ino(inode)); 326*274dcf55SMike Marshall 327*274dcf55SMike Marshall d_instantiate(dentry, inode); 328*274dcf55SMike Marshall unlock_new_inode(inode); 329*274dcf55SMike Marshall 330*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 331*274dcf55SMike Marshall "Inode (Symlink) %pU -> %s\n", 332*274dcf55SMike Marshall get_khandle_from_ino(inode), 333*274dcf55SMike Marshall dentry->d_name.name); 334*274dcf55SMike Marshall 335*274dcf55SMike Marshall SetMtimeFlag(parent); 336*274dcf55SMike Marshall dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb); 337*274dcf55SMike Marshall mark_inode_dirty_sync(dir); 338*274dcf55SMike Marshall ret = 0; 339*274dcf55SMike Marshall out: 340*274dcf55SMike Marshall op_release(new_op); 341*274dcf55SMike Marshall return ret; 342*274dcf55SMike Marshall } 343*274dcf55SMike Marshall 344*274dcf55SMike Marshall static int pvfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 345*274dcf55SMike Marshall { 346*274dcf55SMike Marshall struct pvfs2_inode_s *parent = PVFS2_I(dir); 347*274dcf55SMike Marshall struct pvfs2_kernel_op_s *new_op; 348*274dcf55SMike Marshall struct inode *inode; 349*274dcf55SMike Marshall int ret; 350*274dcf55SMike Marshall 351*274dcf55SMike Marshall new_op = op_alloc(PVFS2_VFS_OP_MKDIR); 352*274dcf55SMike Marshall if (!new_op) 353*274dcf55SMike Marshall return -ENOMEM; 354*274dcf55SMike Marshall 355*274dcf55SMike Marshall new_op->upcall.req.mkdir.parent_refn = parent->refn; 356*274dcf55SMike Marshall 357*274dcf55SMike Marshall fill_default_sys_attrs(new_op->upcall.req.mkdir.attributes, 358*274dcf55SMike Marshall PVFS_TYPE_DIRECTORY, mode); 359*274dcf55SMike Marshall 360*274dcf55SMike Marshall strncpy(new_op->upcall.req.mkdir.d_name, 361*274dcf55SMike Marshall dentry->d_name.name, PVFS2_NAME_LEN); 362*274dcf55SMike Marshall 363*274dcf55SMike Marshall ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 364*274dcf55SMike Marshall 365*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 366*274dcf55SMike Marshall "Mkdir Got PVFS2 handle %pU on fsid %d\n", 367*274dcf55SMike Marshall &new_op->downcall.resp.mkdir.refn.khandle, 368*274dcf55SMike Marshall new_op->downcall.resp.mkdir.refn.fs_id); 369*274dcf55SMike Marshall 370*274dcf55SMike Marshall if (ret < 0) { 371*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 372*274dcf55SMike Marshall "%s: failed with error code %d\n", 373*274dcf55SMike Marshall __func__, ret); 374*274dcf55SMike Marshall goto out; 375*274dcf55SMike Marshall } 376*274dcf55SMike Marshall 377*274dcf55SMike Marshall inode = pvfs2_new_inode(dir->i_sb, dir, S_IFDIR | mode, 0, 378*274dcf55SMike Marshall &new_op->downcall.resp.mkdir.refn); 379*274dcf55SMike Marshall if (IS_ERR(inode)) { 380*274dcf55SMike Marshall gossip_err("*** Failed to allocate pvfs2 dir inode\n"); 381*274dcf55SMike Marshall ret = PTR_ERR(inode); 382*274dcf55SMike Marshall goto out; 383*274dcf55SMike Marshall } 384*274dcf55SMike Marshall 385*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 386*274dcf55SMike Marshall "Assigned dir inode new number of %pU\n", 387*274dcf55SMike Marshall get_khandle_from_ino(inode)); 388*274dcf55SMike Marshall 389*274dcf55SMike Marshall d_instantiate(dentry, inode); 390*274dcf55SMike Marshall unlock_new_inode(inode); 391*274dcf55SMike Marshall 392*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 393*274dcf55SMike Marshall "Inode (Directory) %pU -> %s\n", 394*274dcf55SMike Marshall get_khandle_from_ino(inode), 395*274dcf55SMike Marshall dentry->d_name.name); 396*274dcf55SMike Marshall 397*274dcf55SMike Marshall /* 398*274dcf55SMike Marshall * NOTE: we have no good way to keep nlink consistent for directories 399*274dcf55SMike Marshall * across clients; keep constant at 1. 400*274dcf55SMike Marshall */ 401*274dcf55SMike Marshall SetMtimeFlag(parent); 402*274dcf55SMike Marshall dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb); 403*274dcf55SMike Marshall mark_inode_dirty_sync(dir); 404*274dcf55SMike Marshall out: 405*274dcf55SMike Marshall op_release(new_op); 406*274dcf55SMike Marshall return ret; 407*274dcf55SMike Marshall } 408*274dcf55SMike Marshall 409*274dcf55SMike Marshall static int pvfs2_rename(struct inode *old_dir, 410*274dcf55SMike Marshall struct dentry *old_dentry, 411*274dcf55SMike Marshall struct inode *new_dir, 412*274dcf55SMike Marshall struct dentry *new_dentry) 413*274dcf55SMike Marshall { 414*274dcf55SMike Marshall struct pvfs2_kernel_op_s *new_op; 415*274dcf55SMike Marshall int ret; 416*274dcf55SMike Marshall 417*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 418*274dcf55SMike Marshall "pvfs2_rename: called (%s/%s => %s/%s) ct=%d\n", 419*274dcf55SMike Marshall old_dentry->d_parent->d_name.name, 420*274dcf55SMike Marshall old_dentry->d_name.name, 421*274dcf55SMike Marshall new_dentry->d_parent->d_name.name, 422*274dcf55SMike Marshall new_dentry->d_name.name, 423*274dcf55SMike Marshall d_count(new_dentry)); 424*274dcf55SMike Marshall 425*274dcf55SMike Marshall new_op = op_alloc(PVFS2_VFS_OP_RENAME); 426*274dcf55SMike Marshall if (!new_op) 427*274dcf55SMike Marshall return -EINVAL; 428*274dcf55SMike Marshall 429*274dcf55SMike Marshall new_op->upcall.req.rename.old_parent_refn = PVFS2_I(old_dir)->refn; 430*274dcf55SMike Marshall new_op->upcall.req.rename.new_parent_refn = PVFS2_I(new_dir)->refn; 431*274dcf55SMike Marshall 432*274dcf55SMike Marshall strncpy(new_op->upcall.req.rename.d_old_name, 433*274dcf55SMike Marshall old_dentry->d_name.name, 434*274dcf55SMike Marshall PVFS2_NAME_LEN); 435*274dcf55SMike Marshall strncpy(new_op->upcall.req.rename.d_new_name, 436*274dcf55SMike Marshall new_dentry->d_name.name, 437*274dcf55SMike Marshall PVFS2_NAME_LEN); 438*274dcf55SMike Marshall 439*274dcf55SMike Marshall ret = service_operation(new_op, 440*274dcf55SMike Marshall "pvfs2_rename", 441*274dcf55SMike Marshall get_interruptible_flag(old_dentry->d_inode)); 442*274dcf55SMike Marshall 443*274dcf55SMike Marshall gossip_debug(GOSSIP_NAME_DEBUG, 444*274dcf55SMike Marshall "pvfs2_rename: got downcall status %d\n", 445*274dcf55SMike Marshall ret); 446*274dcf55SMike Marshall 447*274dcf55SMike Marshall if (new_dentry->d_inode) 448*274dcf55SMike Marshall new_dentry->d_inode->i_ctime = CURRENT_TIME; 449*274dcf55SMike Marshall 450*274dcf55SMike Marshall op_release(new_op); 451*274dcf55SMike Marshall return ret; 452*274dcf55SMike Marshall } 453*274dcf55SMike Marshall 454*274dcf55SMike Marshall /* PVFS2 implementation of VFS inode operations for directories */ 455*274dcf55SMike Marshall struct inode_operations pvfs2_dir_inode_operations = { 456*274dcf55SMike Marshall .lookup = pvfs2_lookup, 457*274dcf55SMike Marshall .get_acl = pvfs2_get_acl, 458*274dcf55SMike Marshall .set_acl = pvfs2_set_acl, 459*274dcf55SMike Marshall .create = pvfs2_create, 460*274dcf55SMike Marshall .link = pvfs2_link, 461*274dcf55SMike Marshall .unlink = pvfs2_unlink, 462*274dcf55SMike Marshall .symlink = pvfs2_symlink, 463*274dcf55SMike Marshall .mkdir = pvfs2_mkdir, 464*274dcf55SMike Marshall .rmdir = pvfs2_unlink, 465*274dcf55SMike Marshall .mknod = pvfs2_mknod, 466*274dcf55SMike Marshall .rename = pvfs2_rename, 467*274dcf55SMike Marshall .setattr = pvfs2_setattr, 468*274dcf55SMike Marshall .getattr = pvfs2_getattr, 469*274dcf55SMike Marshall .setxattr = generic_setxattr, 470*274dcf55SMike Marshall .getxattr = generic_getxattr, 471*274dcf55SMike Marshall .removexattr = generic_removexattr, 472*274dcf55SMike Marshall .listxattr = pvfs2_listxattr, 473*274dcf55SMike Marshall }; 474