0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "protocol.h"
0013 #include "orangefs-kernel.h"
0014
0015
0016
0017
0018 static int orangefs_create(struct user_namespace *mnt_userns,
0019 struct inode *dir,
0020 struct dentry *dentry,
0021 umode_t mode,
0022 bool exclusive)
0023 {
0024 struct orangefs_inode_s *parent = ORANGEFS_I(dir);
0025 struct orangefs_kernel_op_s *new_op;
0026 struct orangefs_object_kref ref;
0027 struct inode *inode;
0028 struct iattr iattr;
0029 int ret;
0030
0031 gossip_debug(GOSSIP_NAME_DEBUG, "%s: %pd\n",
0032 __func__,
0033 dentry);
0034
0035 new_op = op_alloc(ORANGEFS_VFS_OP_CREATE);
0036 if (!new_op)
0037 return -ENOMEM;
0038
0039 new_op->upcall.req.create.parent_refn = parent->refn;
0040
0041 fill_default_sys_attrs(new_op->upcall.req.create.attributes,
0042 ORANGEFS_TYPE_METAFILE, mode);
0043
0044 strncpy(new_op->upcall.req.create.d_name,
0045 dentry->d_name.name, ORANGEFS_NAME_MAX - 1);
0046
0047 ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
0048
0049 gossip_debug(GOSSIP_NAME_DEBUG,
0050 "%s: %pd: handle:%pU: fsid:%d: new_op:%p: ret:%d:\n",
0051 __func__,
0052 dentry,
0053 &new_op->downcall.resp.create.refn.khandle,
0054 new_op->downcall.resp.create.refn.fs_id,
0055 new_op,
0056 ret);
0057
0058 if (ret < 0)
0059 goto out;
0060
0061 ref = new_op->downcall.resp.create.refn;
0062
0063 inode = orangefs_new_inode(dir->i_sb, dir, S_IFREG | mode, 0, &ref);
0064 if (IS_ERR(inode)) {
0065 gossip_err("%s: Failed to allocate inode for file :%pd:\n",
0066 __func__,
0067 dentry);
0068 ret = PTR_ERR(inode);
0069 goto out;
0070 }
0071
0072 gossip_debug(GOSSIP_NAME_DEBUG,
0073 "%s: Assigned inode :%pU: for file :%pd:\n",
0074 __func__,
0075 get_khandle_from_ino(inode),
0076 dentry);
0077
0078 d_instantiate_new(dentry, inode);
0079 orangefs_set_timeout(dentry);
0080
0081 gossip_debug(GOSSIP_NAME_DEBUG,
0082 "%s: dentry instantiated for %pd\n",
0083 __func__,
0084 dentry);
0085
0086 memset(&iattr, 0, sizeof iattr);
0087 iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
0088 iattr.ia_mtime = iattr.ia_ctime = current_time(dir);
0089 __orangefs_setattr(dir, &iattr);
0090 ret = 0;
0091 out:
0092 op_release(new_op);
0093 gossip_debug(GOSSIP_NAME_DEBUG,
0094 "%s: %pd: returning %d\n",
0095 __func__,
0096 dentry,
0097 ret);
0098 return ret;
0099 }
0100
0101
0102
0103
0104
0105 static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry,
0106 unsigned int flags)
0107 {
0108 struct orangefs_inode_s *parent = ORANGEFS_I(dir);
0109 struct orangefs_kernel_op_s *new_op;
0110 struct inode *inode;
0111 int ret = -EINVAL;
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 gossip_debug(GOSSIP_NAME_DEBUG, "%s called on %pd\n",
0122 __func__, dentry);
0123
0124 if (dentry->d_name.len > (ORANGEFS_NAME_MAX - 1))
0125 return ERR_PTR(-ENAMETOOLONG);
0126
0127 new_op = op_alloc(ORANGEFS_VFS_OP_LOOKUP);
0128 if (!new_op)
0129 return ERR_PTR(-ENOMEM);
0130
0131 new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW;
0132
0133 gossip_debug(GOSSIP_NAME_DEBUG, "%s:%s:%d using parent %pU\n",
0134 __FILE__,
0135 __func__,
0136 __LINE__,
0137 &parent->refn.khandle);
0138 new_op->upcall.req.lookup.parent_refn = parent->refn;
0139
0140 strncpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name,
0141 ORANGEFS_NAME_MAX - 1);
0142
0143 gossip_debug(GOSSIP_NAME_DEBUG,
0144 "%s: doing lookup on %s under %pU,%d\n",
0145 __func__,
0146 new_op->upcall.req.lookup.d_name,
0147 &new_op->upcall.req.lookup.parent_refn.khandle,
0148 new_op->upcall.req.lookup.parent_refn.fs_id);
0149
0150 ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
0151
0152 gossip_debug(GOSSIP_NAME_DEBUG,
0153 "Lookup Got %pU, fsid %d (ret=%d)\n",
0154 &new_op->downcall.resp.lookup.refn.khandle,
0155 new_op->downcall.resp.lookup.refn.fs_id,
0156 ret);
0157
0158 if (ret == 0) {
0159 orangefs_set_timeout(dentry);
0160 inode = orangefs_iget(dir->i_sb, &new_op->downcall.resp.lookup.refn);
0161 } else if (ret == -ENOENT) {
0162 inode = NULL;
0163 } else {
0164
0165 inode = ERR_PTR(ret);
0166 }
0167
0168 op_release(new_op);
0169 return d_splice_alias(inode, dentry);
0170 }
0171
0172
0173 static int orangefs_unlink(struct inode *dir, struct dentry *dentry)
0174 {
0175 struct inode *inode = dentry->d_inode;
0176 struct orangefs_inode_s *parent = ORANGEFS_I(dir);
0177 struct orangefs_kernel_op_s *new_op;
0178 struct iattr iattr;
0179 int ret;
0180
0181 gossip_debug(GOSSIP_NAME_DEBUG,
0182 "%s: called on %pd\n"
0183 " (inode %pU): Parent is %pU | fs_id %d\n",
0184 __func__,
0185 dentry,
0186 get_khandle_from_ino(inode),
0187 &parent->refn.khandle,
0188 parent->refn.fs_id);
0189
0190 new_op = op_alloc(ORANGEFS_VFS_OP_REMOVE);
0191 if (!new_op)
0192 return -ENOMEM;
0193
0194 new_op->upcall.req.remove.parent_refn = parent->refn;
0195 strncpy(new_op->upcall.req.remove.d_name, dentry->d_name.name,
0196 ORANGEFS_NAME_MAX - 1);
0197
0198 ret = service_operation(new_op, "orangefs_unlink",
0199 get_interruptible_flag(inode));
0200
0201 gossip_debug(GOSSIP_NAME_DEBUG,
0202 "%s: service_operation returned:%d:\n",
0203 __func__,
0204 ret);
0205
0206 op_release(new_op);
0207
0208 if (!ret) {
0209 drop_nlink(inode);
0210
0211 memset(&iattr, 0, sizeof iattr);
0212 iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
0213 iattr.ia_mtime = iattr.ia_ctime = current_time(dir);
0214 __orangefs_setattr(dir, &iattr);
0215 }
0216 return ret;
0217 }
0218
0219 static int orangefs_symlink(struct user_namespace *mnt_userns,
0220 struct inode *dir,
0221 struct dentry *dentry,
0222 const char *symname)
0223 {
0224 struct orangefs_inode_s *parent = ORANGEFS_I(dir);
0225 struct orangefs_kernel_op_s *new_op;
0226 struct orangefs_object_kref ref;
0227 struct inode *inode;
0228 struct iattr iattr;
0229 int mode = 0755;
0230 int ret;
0231
0232 gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__);
0233
0234 if (!symname)
0235 return -EINVAL;
0236
0237 if (strlen(symname)+1 > ORANGEFS_NAME_MAX)
0238 return -ENAMETOOLONG;
0239
0240 new_op = op_alloc(ORANGEFS_VFS_OP_SYMLINK);
0241 if (!new_op)
0242 return -ENOMEM;
0243
0244 new_op->upcall.req.sym.parent_refn = parent->refn;
0245
0246 fill_default_sys_attrs(new_op->upcall.req.sym.attributes,
0247 ORANGEFS_TYPE_SYMLINK,
0248 mode);
0249
0250 strncpy(new_op->upcall.req.sym.entry_name,
0251 dentry->d_name.name,
0252 ORANGEFS_NAME_MAX - 1);
0253 strncpy(new_op->upcall.req.sym.target, symname, ORANGEFS_NAME_MAX - 1);
0254
0255 ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
0256
0257 gossip_debug(GOSSIP_NAME_DEBUG,
0258 "Symlink Got ORANGEFS handle %pU on fsid %d (ret=%d)\n",
0259 &new_op->downcall.resp.sym.refn.khandle,
0260 new_op->downcall.resp.sym.refn.fs_id, ret);
0261
0262 if (ret < 0) {
0263 gossip_debug(GOSSIP_NAME_DEBUG,
0264 "%s: failed with error code %d\n",
0265 __func__, ret);
0266 goto out;
0267 }
0268
0269 ref = new_op->downcall.resp.sym.refn;
0270
0271 inode = orangefs_new_inode(dir->i_sb, dir, S_IFLNK | mode, 0, &ref);
0272 if (IS_ERR(inode)) {
0273 gossip_err
0274 ("*** Failed to allocate orangefs symlink inode\n");
0275 ret = PTR_ERR(inode);
0276 goto out;
0277 }
0278
0279
0280
0281
0282
0283
0284 inode->i_size = strlen(symname);
0285
0286 gossip_debug(GOSSIP_NAME_DEBUG,
0287 "Assigned symlink inode new number of %pU\n",
0288 get_khandle_from_ino(inode));
0289
0290 d_instantiate_new(dentry, inode);
0291 orangefs_set_timeout(dentry);
0292
0293 gossip_debug(GOSSIP_NAME_DEBUG,
0294 "Inode (Symlink) %pU -> %pd\n",
0295 get_khandle_from_ino(inode),
0296 dentry);
0297
0298 memset(&iattr, 0, sizeof iattr);
0299 iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
0300 iattr.ia_mtime = iattr.ia_ctime = current_time(dir);
0301 __orangefs_setattr(dir, &iattr);
0302 ret = 0;
0303 out:
0304 op_release(new_op);
0305 return ret;
0306 }
0307
0308 static int orangefs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
0309 struct dentry *dentry, umode_t mode)
0310 {
0311 struct orangefs_inode_s *parent = ORANGEFS_I(dir);
0312 struct orangefs_kernel_op_s *new_op;
0313 struct orangefs_object_kref ref;
0314 struct inode *inode;
0315 struct iattr iattr;
0316 int ret;
0317
0318 new_op = op_alloc(ORANGEFS_VFS_OP_MKDIR);
0319 if (!new_op)
0320 return -ENOMEM;
0321
0322 new_op->upcall.req.mkdir.parent_refn = parent->refn;
0323
0324 fill_default_sys_attrs(new_op->upcall.req.mkdir.attributes,
0325 ORANGEFS_TYPE_DIRECTORY, mode);
0326
0327 strncpy(new_op->upcall.req.mkdir.d_name,
0328 dentry->d_name.name, ORANGEFS_NAME_MAX - 1);
0329
0330 ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
0331
0332 gossip_debug(GOSSIP_NAME_DEBUG,
0333 "Mkdir Got ORANGEFS handle %pU on fsid %d\n",
0334 &new_op->downcall.resp.mkdir.refn.khandle,
0335 new_op->downcall.resp.mkdir.refn.fs_id);
0336
0337 if (ret < 0) {
0338 gossip_debug(GOSSIP_NAME_DEBUG,
0339 "%s: failed with error code %d\n",
0340 __func__, ret);
0341 goto out;
0342 }
0343
0344 ref = new_op->downcall.resp.mkdir.refn;
0345
0346 inode = orangefs_new_inode(dir->i_sb, dir, S_IFDIR | mode, 0, &ref);
0347 if (IS_ERR(inode)) {
0348 gossip_err("*** Failed to allocate orangefs dir inode\n");
0349 ret = PTR_ERR(inode);
0350 goto out;
0351 }
0352
0353 gossip_debug(GOSSIP_NAME_DEBUG,
0354 "Assigned dir inode new number of %pU\n",
0355 get_khandle_from_ino(inode));
0356
0357 d_instantiate_new(dentry, inode);
0358 orangefs_set_timeout(dentry);
0359
0360 gossip_debug(GOSSIP_NAME_DEBUG,
0361 "Inode (Directory) %pU -> %pd\n",
0362 get_khandle_from_ino(inode),
0363 dentry);
0364
0365
0366
0367
0368
0369 memset(&iattr, 0, sizeof iattr);
0370 iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
0371 iattr.ia_mtime = iattr.ia_ctime = current_time(dir);
0372 __orangefs_setattr(dir, &iattr);
0373 out:
0374 op_release(new_op);
0375 return ret;
0376 }
0377
0378 static int orangefs_rename(struct user_namespace *mnt_userns,
0379 struct inode *old_dir,
0380 struct dentry *old_dentry,
0381 struct inode *new_dir,
0382 struct dentry *new_dentry,
0383 unsigned int flags)
0384 {
0385 struct orangefs_kernel_op_s *new_op;
0386 struct iattr iattr;
0387 int ret;
0388
0389 if (flags)
0390 return -EINVAL;
0391
0392 gossip_debug(GOSSIP_NAME_DEBUG,
0393 "orangefs_rename: called (%pd2 => %pd2) ct=%d\n",
0394 old_dentry, new_dentry, d_count(new_dentry));
0395
0396 memset(&iattr, 0, sizeof iattr);
0397 iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
0398 iattr.ia_mtime = iattr.ia_ctime = current_time(new_dir);
0399 __orangefs_setattr(new_dir, &iattr);
0400
0401 new_op = op_alloc(ORANGEFS_VFS_OP_RENAME);
0402 if (!new_op)
0403 return -EINVAL;
0404
0405 new_op->upcall.req.rename.old_parent_refn = ORANGEFS_I(old_dir)->refn;
0406 new_op->upcall.req.rename.new_parent_refn = ORANGEFS_I(new_dir)->refn;
0407
0408 strncpy(new_op->upcall.req.rename.d_old_name,
0409 old_dentry->d_name.name,
0410 ORANGEFS_NAME_MAX - 1);
0411 strncpy(new_op->upcall.req.rename.d_new_name,
0412 new_dentry->d_name.name,
0413 ORANGEFS_NAME_MAX - 1);
0414
0415 ret = service_operation(new_op,
0416 "orangefs_rename",
0417 get_interruptible_flag(old_dentry->d_inode));
0418
0419 gossip_debug(GOSSIP_NAME_DEBUG,
0420 "orangefs_rename: got downcall status %d\n",
0421 ret);
0422
0423 if (new_dentry->d_inode)
0424 new_dentry->d_inode->i_ctime = current_time(new_dentry->d_inode);
0425
0426 op_release(new_op);
0427 return ret;
0428 }
0429
0430
0431 const struct inode_operations orangefs_dir_inode_operations = {
0432 .lookup = orangefs_lookup,
0433 .get_acl = orangefs_get_acl,
0434 .set_acl = orangefs_set_acl,
0435 .create = orangefs_create,
0436 .unlink = orangefs_unlink,
0437 .symlink = orangefs_symlink,
0438 .mkdir = orangefs_mkdir,
0439 .rmdir = orangefs_unlink,
0440 .rename = orangefs_rename,
0441 .setattr = orangefs_setattr,
0442 .getattr = orangefs_getattr,
0443 .listxattr = orangefs_listxattr,
0444 .permission = orangefs_permission,
0445 .update_time = orangefs_update_time,
0446 };