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/pagemap.h>
32 #include <linux/file.h>
34 #include <linux/obd_class.h>
35 #include <linux/obd_support.h>
36 #include <linux/lustre_lib.h>
37 #include <linux/lustre_idl.h>
38 #include <linux/lustre_fsfilt.h>
39 #include <linux/lustre_smfs.h>
41 #include "smfs_internal.h"
43 static ssize_t smfs_write(struct file *filp, const char *buf, size_t count,
46 struct inode *cache_inode;
47 struct smfs_file_info *sfi;
53 cache_inode = I2CI(filp->f_dentry->d_inode);
60 if (sfi->magic != SMFS_FILE_MAGIC)
63 if (ppos != &(filp->f_pos))
64 cache_ppos = &tmp_ppos;
66 cache_ppos = &sfi->c_file->f_pos;
69 pre_smfs_inode(filp->f_dentry->d_inode, cache_inode);
71 if (cache_inode->i_fop->write)
72 rc = cache_inode->i_fop->write(sfi->c_file, buf, count,
75 post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
76 SMFS_KML_POST(filp->f_dentry->d_inode, filp->f_dentry,
77 &count ,ppos, REINT_WRITE, "write", rc, exit);
80 duplicate_file(filp, sfi->c_file);
84 int smfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
87 struct inode *cache_inode;
88 struct smfs_file_info *sfi;
92 cache_inode = I2CI(filp->f_dentry->d_inode);
97 if (sfi->magic != SMFS_FILE_MAGIC)
100 pre_smfs_inode(inode, cache_inode);
102 if (cache_inode->i_fop->ioctl)
103 rc = cache_inode->i_fop->ioctl(cache_inode, sfi->c_file, cmd,
106 post_smfs_inode(inode, cache_inode);
107 duplicate_file(filp, sfi->c_file);
112 static ssize_t smfs_read(struct file *filp, char *buf, size_t count,
115 struct inode *cache_inode;
116 struct smfs_file_info *sfi;
122 cache_inode = I2CI(filp->f_dentry->d_inode);
127 if (sfi->magic != SMFS_FILE_MAGIC)
130 if (ppos != &(filp->f_pos))
131 cache_ppos = &tmp_ppos;
133 cache_ppos = &sfi->c_file->f_pos;
136 pre_smfs_inode(filp->f_dentry->d_inode, cache_inode);
138 if (cache_inode->i_fop->read)
139 rc = cache_inode->i_fop->read(sfi->c_file, buf, count,
143 post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
144 duplicate_file(filp, sfi->c_file);
149 static loff_t smfs_llseek(struct file *file, loff_t offset, int origin)
151 struct inode *cache_inode;
152 struct smfs_file_info *sfi;
156 cache_inode = I2CI(file->f_dentry->d_inode);
161 if (sfi->magic != SMFS_FILE_MAGIC)
164 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
166 if (cache_inode->i_fop->llseek)
167 rc = cache_inode->i_fop->llseek(sfi->c_file, offset, origin);
169 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
170 duplicate_file(file, sfi->c_file);
175 static int smfs_mmap(struct file *file, struct vm_area_struct *vma)
177 struct inode *inode = file->f_dentry->d_inode;
178 struct smfs_file_info *sfi;
179 struct inode *cache_inode = NULL;
183 cache_inode = I2CI(inode);
188 if (sfi->magic != SMFS_FILE_MAGIC)
191 if (cache_inode->i_mapping == &cache_inode->i_data)
192 inode->i_mapping = cache_inode->i_mapping;
194 pre_smfs_inode(inode, cache_inode);
195 if (cache_inode->i_fop->mmap)
196 rc = cache_inode->i_fop->mmap(sfi->c_file, vma);
198 post_smfs_inode(inode, cache_inode);
199 duplicate_file(file, sfi->c_file);
204 static int smfs_init_cache_file(struct inode *inode, struct file *filp)
206 struct smfs_file_info *sfi = NULL;
207 struct file *cache_filp = NULL;
208 struct dentry *cache_dentry = NULL;
212 OBD_ALLOC(sfi, sizeof(struct smfs_file_info));
216 cache_filp = get_empty_filp();
218 GOTO(err_exit, rc = -ENOMEM);
220 sfi->magic = SMFS_FILE_MAGIC;
222 cache_dentry = pre_smfs_dentry(NULL, I2CI(inode), filp->f_dentry);
224 GOTO(err_exit, rc = -ENOMEM);
226 cache_filp->f_vfsmnt = filp->f_vfsmnt;
228 cache_filp->f_dentry = cache_dentry;
229 duplicate_file(cache_filp, filp);
231 sfi->c_file = cache_filp;
233 if (filp->private_data != NULL)
236 filp->private_data = sfi;
241 OBD_FREE(sfi, sizeof(struct smfs_file_info));
243 put_filp(cache_filp);
247 static int smfs_cleanup_cache_file(struct file *filp)
249 struct smfs_file_info *sfi = NULL;
255 post_smfs_dentry(sfi->c_file->f_dentry);
257 put_filp(sfi->c_file);
259 OBD_FREE(sfi, sizeof(struct smfs_file_info));
261 filp->private_data = NULL;
266 int smfs_open(struct inode *inode, struct file *filp)
268 struct inode *cache_inode = NULL;
269 int rc = 0, flag = 1;
272 cache_inode = I2CI(inode);
276 if ((rc = smfs_init_cache_file(inode, filp)))
279 pre_smfs_inode(inode, cache_inode);
280 if (cache_inode->i_fop->open)
281 rc = cache_inode->i_fop->open(cache_inode, F2CF(filp));
283 post_smfs_inode(inode, cache_inode);
284 duplicate_file(filp, F2CF(filp));
286 SMFS_KML_POST(filp->f_dentry->d_inode, filp->f_dentry, &flag, NULL,
287 REINT_OPEN, "open", rc, exit);
292 int smfs_release(struct inode *inode, struct file *filp)
294 struct inode *cache_inode = NULL;
295 struct smfs_file_info *sfi = NULL;
296 int rc = 0, flag = 0;
299 cache_inode = I2CI(inode);
304 if (sfi->magic != SMFS_FILE_MAGIC)
307 pre_smfs_inode(inode, cache_inode);
308 if (cache_inode->i_fop->release)
309 rc = cache_inode->i_fop->release(cache_inode, sfi->c_file);
311 post_smfs_inode(inode, cache_inode);
312 duplicate_file(filp, sfi->c_file);
314 smfs_cleanup_cache_file(filp);
316 SMFS_KML_POST(filp->f_dentry->d_inode, filp->f_dentry, &flag, NULL,
317 REINT_CLOSE, "close", rc, exit);
322 int smfs_fsync(struct file *file, struct dentry *dentry, int datasync)
324 struct smfs_file_info *sfi = NULL;
325 struct inode *cache_inode;
328 cache_inode = I2CI(file->f_dentry->d_inode);
333 if (sfi->magic != SMFS_FILE_MAGIC)
336 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
338 if (cache_inode->i_fop->fsync)
339 rc = cache_inode->i_fop->fsync(sfi->c_file,
340 sfi->c_file->f_dentry, datasync);
342 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
343 duplicate_file(file, sfi->c_file);
348 struct file_operations smfs_file_fops = {
355 release: smfs_release,
359 static void smfs_truncate(struct inode *inode)
361 struct inode *cache_inode;
363 cache_inode = I2CI(inode);
368 pre_smfs_inode(inode, cache_inode);
369 if (cache_inode->i_op->truncate)
370 cache_inode->i_op->truncate(cache_inode);
372 post_smfs_inode(inode, cache_inode);
375 int smfs_setattr(struct dentry *dentry, struct iattr *attr)
377 struct inode *cache_inode;
378 struct dentry *cache_dentry;
382 cache_inode = I2CI(dentry->d_inode);
386 cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
390 handle = smfs_trans_start(dentry->d_inode, FSFILT_OP_SETATTR, NULL);
391 if (IS_ERR(handle) ) {
392 CERROR("smfs_do_mkdir: no space for transaction\n");
396 pre_smfs_inode(dentry->d_inode, cache_inode);
398 if (cache_inode->i_op->setattr)
399 rc = cache_inode->i_op->setattr(cache_dentry, attr);
401 SMFS_KML_POST(dentry->d_inode, dentry, attr, NULL,
402 REINT_SETATTR, "setattr", rc, exit);
404 post_smfs_inode(dentry->d_inode, cache_inode);
405 post_smfs_dentry(cache_dentry);
406 smfs_trans_commit(dentry->d_inode, handle, 0);
410 int smfs_setxattr(struct dentry *dentry, const char *name, const void *value,
411 size_t size, int flags)
413 struct inode *cache_inode;
414 struct dentry *cache_dentry;
417 cache_inode = I2CI(dentry->d_inode);
421 cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
425 pre_smfs_inode(dentry->d_inode, cache_inode);
427 if (cache_inode->i_op->setxattr)
428 rc = cache_inode->i_op->setxattr(cache_dentry, name, value,
431 post_smfs_inode(dentry->d_inode, cache_inode);
432 post_smfs_dentry(cache_dentry);
437 int smfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
440 struct inode *cache_inode;
441 struct dentry *cache_dentry;
444 cache_inode = I2CI(dentry->d_inode);
448 cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
452 pre_smfs_inode(dentry->d_inode, cache_inode);
454 if (cache_inode->i_op->getattr)
455 rc = cache_inode->i_op->getxattr(cache_dentry, name, buffer,
458 post_smfs_inode(dentry->d_inode, cache_inode);
459 post_smfs_dentry(cache_dentry);
464 ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
466 struct inode *cache_inode;
467 struct dentry *cache_dentry;
470 cache_inode = I2CI(dentry->d_inode);
474 cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
478 pre_smfs_inode(dentry->d_inode, cache_inode);
480 if (cache_inode->i_op->listxattr)
481 rc = cache_inode->i_op->listxattr(cache_dentry, buffer, size);
483 post_smfs_inode(dentry->d_inode, cache_inode);
484 post_smfs_dentry(cache_dentry);
489 int smfs_removexattr(struct dentry *dentry, const char *name)
491 struct inode *cache_inode;
492 struct dentry *cache_dentry;
495 cache_inode = I2CI(dentry->d_inode);
499 cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
503 pre_smfs_inode(dentry->d_inode, cache_inode);
505 if (cache_inode->i_op->removexattr)
506 rc = cache_inode->i_op->removexattr(cache_dentry, name);
508 post_smfs_inode(dentry->d_inode, cache_inode);
509 post_smfs_dentry(cache_dentry);
514 struct inode_operations smfs_file_iops = {
515 truncate: smfs_truncate, /* BKL held */
516 setattr: smfs_setattr, /* BKL held */
517 setxattr: smfs_setxattr, /* BKL held */
518 getxattr: smfs_getxattr, /* BKL held */
519 listxattr: smfs_listxattr, /* BKL held */
520 removexattr: smfs_removexattr, /* BKL held */