1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #define DEBUG_SUBSYSTEM S_SM
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/string.h>
28 #include <linux/slab.h>
29 #include <linux/stat.h>
30 #include <linux/unistd.h>
31 #include <linux/smp_lock.h>
32 #include <linux/obd_class.h>
33 #include <linux/obd_support.h>
34 #include <linux/lustre_lib.h>
35 #include <linux/lustre_idl.h>
36 #include <linux/lustre_fsfilt.h>
37 #include <linux/lustre_smfs.h>
38 #include <linux/lustre_snap.h>
40 #include "smfs_internal.h"
42 #define NAME_ALLOC_LEN(len) ((len+16) & ~15)
44 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
45 static int smfs_create(struct inode *dir, struct dentry *dentry,
48 static int smfs_create(struct inode *dir, struct dentry *dentry,
49 int mode, struct nameidata *nd)
52 struct inode *inode = NULL;
53 struct inode *cache_dir = NULL;
54 struct dentry *cache_dentry = NULL;
55 struct dentry *cache_parent = NULL;
57 struct hook_msg msg = {
65 cache_dir = I2CI(dir);
67 LASSERT(cache_dir->i_op->create);
70 cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
71 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
72 if (!cache_dentry || !cache_parent) {
77 handle = smfs_trans_start(dir, FSFILT_OP_CREATE, NULL);
83 SMFS_PRE_HOOK(dir->i_sb, HOOK_CREATE, &msg);
85 pre_smfs_inode(dir, cache_dir);
87 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
88 rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode);
90 rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode, nd);
93 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode->i_ino, dir, 0);
95 d_instantiate(dentry, inode);
100 SMFS_POST_HOOK(dir->i_sb, HOOK_CREATE, &msg, rc);
102 post_smfs_inode(dir, cache_dir);
103 smfs_trans_commit(dir, handle, 0);
107 post_smfs_dentry(cache_dentry);
108 post_smfs_dentry(cache_parent);
112 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
113 static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry)
115 static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
116 struct nameidata *nd)
119 struct inode *cache_dir;
120 struct inode *inode = NULL;
121 struct inode * cache_inode = NULL;
122 struct dentry *cache_dentry = NULL;
123 struct dentry *cache_parent = NULL;
124 struct dentry *rdentry = NULL;
126 struct hook_msg msg = {
133 cache_dir = I2CI(dir);
135 RETURN(ERR_PTR(-ENOENT));
137 LASSERT(cache_dir->i_op->lookup);
139 /* preparing artificial backing fs dentries. */
140 cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent);
141 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
142 if (!cache_dentry || !cache_parent)
143 RETURN(ERR_PTR(-ENOMEM));
145 SMFS_PRE_HOOK(dir->i_sb, HOOK_LOOKUP, &msg);
147 /* perform lookup in backing fs. */
148 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
149 rdentry = cache_dir->i_op->lookup(cache_dir, cache_dentry);
151 rdentry = cache_dir->i_op->lookup(cache_dir, cache_dentry, nd);
155 rc = PTR_ERR(rdentry);
157 cache_inode = rdentry->d_inode;
161 cache_inode = cache_dentry->d_inode;
165 inode = smfs_get_inode(dir->i_sb, cache_inode->i_ino, dir,0);
171 d_add(dentry, inode);
173 SMFS_POST_HOOK(dir->i_sb, HOOK_LOOKUP, &msg, rc);
175 post_smfs_dentry(cache_dentry);
176 post_smfs_dentry(cache_parent);
180 static int smfs_link(struct dentry *old_dentry,
181 struct inode *dir, struct dentry *dentry)
183 struct inode *cache_old_inode = NULL;
184 struct inode *cache_dir = NULL;
185 struct inode *old_inode = NULL;
186 struct dentry *cache_dentry = NULL;
187 struct dentry *cache_old_dentry = NULL;
188 struct dentry *cache_parent = NULL;
191 struct hook_msg msg = {
193 .dentry = old_dentry,
198 cache_dir = I2CI(dir);
202 old_inode = old_dentry->d_inode;
203 cache_old_inode = I2CI(old_inode);
204 if (!cache_old_inode)
207 cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
208 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
209 cache_old_dentry = pre_smfs_dentry(NULL, cache_old_inode, old_dentry);
210 if (!cache_old_dentry || !cache_dentry || !cache_parent) {
215 handle = smfs_trans_start(dir, FSFILT_OP_LINK, NULL);
216 if (IS_ERR(handle)) {
221 pre_smfs_inode(dir, cache_dir);
222 pre_smfs_inode(old_inode, cache_old_inode);
225 SMFS_PRE_HOOK(dir->i_sb, HOOK_LINK, &msg);
227 rc = cache_dir->i_op->link(cache_old_dentry, cache_dir, cache_dentry);
229 atomic_inc(&old_inode->i_count);
230 d_instantiate(dentry, old_inode);
233 SMFS_POST_HOOK(dir->i_sb, HOOK_LINK, &msg, rc);
235 post_smfs_inode(old_inode, cache_old_inode);
236 post_smfs_inode(dir, cache_dir);
238 smfs_trans_commit(dir, handle, 0);
242 post_smfs_dentry(cache_dentry);
243 post_smfs_dentry(cache_parent);
244 post_smfs_dentry(cache_old_dentry);
249 static int smfs_unlink(struct inode * dir, struct dentry *dentry)
251 struct inode *cache_dir = I2CI(dir);
252 struct inode *cache_inode = I2CI(dentry->d_inode);
253 struct dentry *cache_dentry;
254 struct dentry *cache_parent;
258 struct hook_unlink_msg msg = {
266 if (!cache_dir || !cache_inode || !cache_dir->i_op->unlink)
269 cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
270 cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
271 if (!cache_dentry || !cache_parent) {
277 handle = smfs_trans_start(dir, FSFILT_OP_UNLINK, NULL);
278 if (IS_ERR(handle)) {
283 pre_smfs_inode(dir, cache_dir);
284 pre_smfs_inode(dentry->d_inode, cache_inode);
286 SMFS_PRE_HOOK(dir->i_sb, HOOK_UNLINK, &msg);
288 rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
290 SMFS_POST_HOOK(dir->i_sb, HOOK_UNLINK, &msg, rc);
292 post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
293 post_smfs_inode(dir, cache_dir);
296 smfs_trans_commit(dir, handle, 0);
298 post_smfs_dentry(cache_dentry);
299 post_smfs_dentry(cache_parent);
303 static int smfs_symlink(struct inode *dir, struct dentry *dentry,
306 struct inode *cache_dir = I2CI(dir);
307 struct inode *inode = NULL;
308 struct dentry *cache_dentry;
309 struct dentry *cache_parent;
312 struct hook_symlink_msg msg = {
315 .tgt_len = strlen(symname) + 1,
316 .symname = (char*)symname
321 if (!cache_dir || !cache_dir->i_op->symlink)
324 cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
325 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
326 if (!cache_parent || !cache_dentry) {
331 handle = smfs_trans_start(dir, FSFILT_OP_SYMLINK, NULL);
332 if (IS_ERR(handle)) {
338 pre_smfs_inode(dir, cache_dir);
340 SMFS_PRE_HOOK(dir->i_sb, HOOK_SYMLINK, &msg);
342 rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
344 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode->i_ino,
347 d_instantiate(dentry, inode);
352 SMFS_POST_HOOK(dir->i_sb, HOOK_SYMLINK, &msg, rc);
354 post_smfs_inode(dir, cache_dir);
355 smfs_trans_commit(dir, handle, 0);
359 post_smfs_dentry(cache_dentry);
360 post_smfs_dentry(cache_parent);
364 static int smfs_mkdir(struct inode *dir, struct dentry *dentry,
367 struct inode *cache_dir = I2CI(dir);
368 struct inode *inode = NULL;
369 struct dentry *cache_dentry;
370 struct dentry *cache_parent;
373 struct hook_msg msg = {
383 cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
384 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
386 if (!cache_parent || !cache_dentry) {
391 handle = smfs_trans_start(dir, FSFILT_OP_MKDIR, NULL);
392 if (IS_ERR(handle)) {
397 pre_smfs_inode(dir, cache_dir);
398 SMFS_PRE_HOOK(dir->i_sb, HOOK_MKDIR, &msg);
400 rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
402 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode->i_ino,
405 d_instantiate(dentry, inode);
410 SMFS_POST_HOOK(dir->i_sb, HOOK_MKDIR, &msg, rc);
411 post_smfs_inode(dir, cache_dir);
412 smfs_trans_commit(dir, handle, 0);
415 post_smfs_dentry(cache_dentry);
416 post_smfs_dentry(cache_parent);
420 static int smfs_rmdir(struct inode *dir, struct dentry *dentry)
422 struct inode *cache_dir = I2CI(dir);
423 struct inode *cache_inode = I2CI(dentry->d_inode);
424 struct dentry *cache_dentry = NULL;
425 struct dentry *cache_parent = NULL;
428 struct hook_unlink_msg msg = {
436 if (!cache_dir || !cache_dir->i_op->rmdir)
439 cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
440 cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
441 if (!cache_parent || !cache_dentry) {
446 handle = smfs_trans_start(dir, FSFILT_OP_RMDIR, NULL);
447 if (IS_ERR(handle) ) {
452 pre_smfs_inode(dir, cache_dir);
453 pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
455 SMFS_PRE_HOOK(dir->i_sb, HOOK_RMDIR, &msg);
457 rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
459 SMFS_POST_HOOK(dir->i_sb, HOOK_RMDIR, &msg, rc);
461 post_smfs_inode(dir, cache_dir);
462 post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
464 smfs_trans_commit(dir, handle, 0);
467 post_smfs_dentry(cache_dentry);
468 post_smfs_dentry(cache_parent);
472 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
473 static int smfs_mknod(struct inode *dir, struct dentry *dentry,
476 static int smfs_mknod(struct inode *dir, struct dentry *dentry,
477 int mode, dev_t rdev)
480 struct inode *cache_dir = I2CI(dir);
481 struct inode *inode = NULL;
482 struct dentry *cache_dentry = NULL;
483 struct dentry *cache_parent = NULL;
486 struct hook_msg msg = {
493 if (!cache_dir || !cache_dir->i_op->mknod)
496 cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent);
497 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
498 if (!cache_parent || !cache_dentry) {
503 handle = smfs_trans_start(dir, FSFILT_OP_MKNOD, NULL);
504 if (IS_ERR(handle)) {
509 pre_smfs_inode(dir, cache_dir);
510 pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
512 SMFS_PRE_HOOK(dir->i_sb, HOOK_MKNOD, &msg);
514 rc = cache_dir->i_op->mknod(cache_dir, cache_dentry, mode, rdev);
516 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode->i_ino,
519 d_instantiate(dentry, inode);
524 SMFS_POST_HOOK(dir->i_sb, HOOK_MKNOD, &msg, rc);
526 post_smfs_inode(dir, cache_dir);
527 post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
528 smfs_trans_commit(dir, handle, 0);
531 post_smfs_dentry(cache_dentry);
532 post_smfs_dentry(cache_parent);
536 static int smfs_rename(struct inode *old_dir, struct dentry *old_dentry,
537 struct inode *new_dir,struct dentry *new_dentry)
539 struct inode *cache_old_dir = I2CI(old_dir);
540 struct inode *cache_new_dir = I2CI(new_dir);
541 struct inode *cache_old_inode = I2CI(old_dentry->d_inode);
542 struct inode *cache_new_inode = NULL;
543 struct dentry *cache_old_dentry = NULL;
544 struct dentry *cache_new_dentry = NULL;
545 struct dentry *cache_new_parent = NULL;
546 struct dentry *cache_old_parent = NULL;
549 struct hook_rename_msg msg = {
551 .dentry = old_dentry,
553 .new_dentry = new_dentry
558 if (!cache_old_dir || !cache_new_dir || !cache_old_inode)
561 if (new_dentry->d_inode) {
562 cache_new_inode = I2CI(new_dentry->d_inode);
563 if (!cache_new_inode)
567 cache_old_parent = pre_smfs_dentry(NULL, cache_old_dir, old_dentry);
568 cache_old_dentry = pre_smfs_dentry(cache_old_parent, cache_old_inode,
570 if (!cache_old_parent || !cache_old_dentry) {
575 cache_new_parent = pre_smfs_dentry(NULL, cache_new_dir, new_dentry);
576 cache_new_dentry = pre_smfs_dentry(cache_new_parent, cache_new_inode,
578 if (!cache_new_parent || !cache_new_dentry) {
583 handle = smfs_trans_start(old_dir, FSFILT_OP_RENAME, NULL);
584 if (IS_ERR(handle)) {
589 pre_smfs_inode(old_dir, cache_old_dir);
590 pre_smfs_inode(new_dir, cache_new_dir);
591 if (new_dentry->d_inode)
592 pre_smfs_inode(new_dentry->d_inode, cache_new_dentry->d_inode);
594 SMFS_PRE_HOOK(old_dir->i_sb, HOOK_RENAME, &msg);
596 rc = cache_old_dir->i_op->rename(cache_old_dir, cache_old_dentry,
597 cache_new_dir, cache_new_dentry);
599 SMFS_POST_HOOK(old_dir->i_sb, HOOK_RENAME, &msg, rc);
601 post_smfs_inode(old_dir, cache_old_dir);
602 post_smfs_inode(new_dir, cache_new_dir);
603 if (new_dentry->d_inode)
604 post_smfs_inode(new_dentry->d_inode, cache_new_dentry->d_inode);
606 smfs_trans_commit(old_dir, handle, 0);
609 post_smfs_dentry(cache_old_dentry);
610 post_smfs_dentry(cache_old_parent);
611 post_smfs_dentry(cache_new_dentry);
612 post_smfs_dentry(cache_new_parent);
616 struct inode_operations smfs_dir_iops = {
619 link: smfs_link, /* BKL held */
620 unlink: smfs_unlink, /* BKL held */
621 symlink: smfs_symlink, /* BKL held */
622 mkdir: smfs_mkdir, /* BKL held */
623 rmdir: smfs_rmdir, /* BKL held */
624 mknod: smfs_mknod, /* BKL held */
625 rename: smfs_rename, /* BKL held */
626 setxattr: smfs_setxattr, /* BKL held */
627 getxattr: smfs_getxattr, /* BKL held */
628 listxattr: smfs_listxattr, /* BKL held */
629 removexattr: smfs_removexattr, /* BKL held */
632 static ssize_t smfs_read_dir(struct file *filp, char *buf,
633 size_t size, loff_t *ppos)
635 struct dentry *dentry = filp->f_dentry;
636 struct inode *cache_inode = NULL;
637 struct smfs_file_info *sfi = NULL;
639 loff_t *cache_ppos = NULL;
644 cache_inode = I2CI(dentry->d_inode);
646 if (!cache_inode || !cache_inode->i_fop->read)
650 if (sfi->magic != SMFS_FILE_MAGIC)
653 if (ppos != &(filp->f_pos))
654 cache_ppos = &tmp_ppos;
656 cache_ppos = &sfi->c_file->f_pos;
660 rc = cache_inode->i_fop->read(sfi->c_file, buf, size, cache_ppos);
666 duplicate_file(filp, sfi->c_file);
671 static int smfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
673 struct dentry *dentry = filp->f_dentry;
674 struct inode *cache_inode = NULL;
675 struct smfs_file_info *sfi = NULL;
677 struct hook_readdir_msg msg = {
678 .dir = dentry->d_inode,
687 cache_inode = I2CI(dentry->d_inode);
688 if (!cache_inode || !cache_inode->i_fop->readdir)
692 if (sfi->magic != SMFS_FILE_MAGIC) BUG();
694 SMFS_PRE_HOOK(dentry->d_inode->i_sb, HOOK_READDIR, &msg);
696 rc = cache_inode->i_fop->readdir(sfi->c_file, dirent, filldir);
698 SMFS_POST_HOOK(dentry->d_inode->i_sb, HOOK_READDIR, &msg, rc);
699 duplicate_file(filp, sfi->c_file);
708 struct file_operations smfs_dir_fops = {
709 .read = smfs_read_dir,
710 .readdir = smfs_readdir, /* BKL held */
711 .ioctl = smfs_ioctl, /* BKL held */
712 .fsync = smfs_fsync, /* BKL held */
714 .release = smfs_release,