aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2008-10-27 12:37:02 -0400
committerBoaz Harrosh <bharrosh@panasas.com>2009-03-31 12:44:24 -0400
commite806271916ed6068a0e3e4e9298dff0688b88e0d (patch)
tree53669f4a55fecd82d289c035712d416e5b8dce35
parentb14f8ab2844987f013253dd04b708bde7fc1b52d (diff)
exofs: file and file_inode operations
implementation of the file_operations and inode_operations for regular data files. Most file_operations are generic vfs implementations except: - exofs_truncate will truncate the OSD object as well - Generic file_fsync is not good for none_bd devices so open code it - The default for .flush in Linux is todo nothing so call exofs_fsync on the file. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
-rw-r--r--fs/exofs/Kbuild2
-rw-r--r--fs/exofs/exofs.h14
-rw-r--r--fs/exofs/file.c87
-rw-r--r--fs/exofs/inode.c148
4 files changed, 250 insertions, 1 deletions
diff --git a/fs/exofs/Kbuild b/fs/exofs/Kbuild
index 36d23ca79a58..c9546edaddeb 100644
--- a/fs/exofs/Kbuild
+++ b/fs/exofs/Kbuild
@@ -12,5 +12,5 @@
12# Kbuild - Gets included from the Kernels Makefile and build system 12# Kbuild - Gets included from the Kernels Makefile and build system
13# 13#
14 14
15exofs-y := osd.o 15exofs-y := osd.o inode.o file.o
16obj-$(CONFIG_EXOFS_FS) += exofs.o 16obj-$(CONFIG_EXOFS_FS) += exofs.o
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
index 365376d3f72d..a735258c7364 100644
--- a/fs/exofs/exofs.h
+++ b/fs/exofs/exofs.h
@@ -124,4 +124,18 @@ static inline struct exofs_i_info *exofs_i(struct inode *inode)
124 return container_of(inode, struct exofs_i_info, vfs_inode); 124 return container_of(inode, struct exofs_i_info, vfs_inode);
125} 125}
126 126
127/*************************
128 * function declarations *
129 *************************/
130/* inode.c */
131void exofs_truncate(struct inode *inode);
132int exofs_setattr(struct dentry *, struct iattr *);
133
134/*********************
135 * operation vectors *
136 *********************/
137/* file.c */
138extern const struct inode_operations exofs_file_inode_operations;
139extern const struct file_operations exofs_file_operations;
140
127#endif 141#endif
diff --git a/fs/exofs/file.c b/fs/exofs/file.c
new file mode 100644
index 000000000000..6ed7fe484752
--- /dev/null
+++ b/fs/exofs/file.c
@@ -0,0 +1,87 @@
1/*
2 * Copyright (C) 2005, 2006
3 * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
4 * Copyright (C) 2005, 2006
5 * International Business Machines
6 * Copyright (C) 2008, 2009
7 * Boaz Harrosh <bharrosh@panasas.com>
8 *
9 * Copyrights for code taken from ext2:
10 * Copyright (C) 1992, 1993, 1994, 1995
11 * Remy Card (card@masi.ibp.fr)
12 * Laboratoire MASI - Institut Blaise Pascal
13 * Universite Pierre et Marie Curie (Paris VI)
14 * from
15 * linux/fs/minix/inode.c
16 * Copyright (C) 1991, 1992 Linus Torvalds
17 *
18 * This file is part of exofs.
19 *
20 * exofs is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation. Since it is based on ext2, and the only
23 * valid version of GPL for the Linux kernel is version 2, the only valid
24 * version of GPL for exofs is version 2.
25 *
26 * exofs is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with exofs; if not, write to the Free Software
33 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 */
35
36#include <linux/buffer_head.h>
37
38#include "exofs.h"
39
40static int exofs_release_file(struct inode *inode, struct file *filp)
41{
42 return 0;
43}
44
45static int exofs_file_fsync(struct file *filp, struct dentry *dentry,
46 int datasync)
47{
48 int ret;
49 struct address_space *mapping = filp->f_mapping;
50
51 ret = filemap_write_and_wait(mapping);
52 if (ret)
53 return ret;
54
55 /*Note: file_fsync below also calles sync_blockdev, which is a no-op
56 * for exofs, but other then that it does sync_inode and
57 * sync_superblock which is what we need here.
58 */
59 return file_fsync(filp, dentry, datasync);
60}
61
62static int exofs_flush(struct file *file, fl_owner_t id)
63{
64 exofs_file_fsync(file, file->f_path.dentry, 1);
65 /* TODO: Flush the OSD target */
66 return 0;
67}
68
69const struct file_operations exofs_file_operations = {
70 .llseek = generic_file_llseek,
71 .read = do_sync_read,
72 .write = do_sync_write,
73 .aio_read = generic_file_aio_read,
74 .aio_write = generic_file_aio_write,
75 .mmap = generic_file_mmap,
76 .open = generic_file_open,
77 .release = exofs_release_file,
78 .fsync = exofs_file_fsync,
79 .flush = exofs_flush,
80 .splice_read = generic_file_splice_read,
81 .splice_write = generic_file_splice_write,
82};
83
84const struct inode_operations exofs_file_inode_operations = {
85 .truncate = exofs_truncate,
86 .setattr = exofs_setattr,
87};
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
new file mode 100644
index 000000000000..b0bda1e91225
--- /dev/null
+++ b/fs/exofs/inode.c
@@ -0,0 +1,148 @@
1/*
2 * Copyright (C) 2005, 2006
3 * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
4 * Copyright (C) 2005, 2006
5 * International Business Machines
6 * Copyright (C) 2008, 2009
7 * Boaz Harrosh <bharrosh@panasas.com>
8 *
9 * Copyrights for code taken from ext2:
10 * Copyright (C) 1992, 1993, 1994, 1995
11 * Remy Card (card@masi.ibp.fr)
12 * Laboratoire MASI - Institut Blaise Pascal
13 * Universite Pierre et Marie Curie (Paris VI)
14 * from
15 * linux/fs/minix/inode.c
16 * Copyright (C) 1991, 1992 Linus Torvalds
17 *
18 * This file is part of exofs.
19 *
20 * exofs is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation. Since it is based on ext2, and the only
23 * valid version of GPL for the Linux kernel is version 2, the only valid
24 * version of GPL for exofs is version 2.
25 *
26 * exofs is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with exofs; if not, write to the Free Software
33 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 */
35
36#include <linux/writeback.h>
37#include <linux/buffer_head.h>
38
39#include "exofs.h"
40
41#ifdef CONFIG_EXOFS_DEBUG
42# define EXOFS_DEBUG_OBJ_ISIZE 1
43#endif
44
45/******************************************************************************
46 * INODE OPERATIONS
47 *****************************************************************************/
48
49/*
50 * Test whether an inode is a fast symlink.
51 */
52static inline int exofs_inode_is_fast_symlink(struct inode *inode)
53{
54 struct exofs_i_info *oi = exofs_i(inode);
55
56 return S_ISLNK(inode->i_mode) && (oi->i_data[0] != 0);
57}
58
59/*
60 * get_block_t - Fill in a buffer_head
61 * An OSD takes care of block allocation so we just fake an allocation by
62 * putting in the inode's sector_t in the buffer_head.
63 * TODO: What about the case of create==0 and @iblock does not exist in the
64 * object?
65 */
66static int exofs_get_block(struct inode *inode, sector_t iblock,
67 struct buffer_head *bh_result, int create)
68{
69 map_bh(bh_result, inode->i_sb, iblock);
70 return 0;
71}
72
73const struct osd_attr g_attr_logical_length = ATTR_DEF(
74 OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8);
75
76/*
77 * Truncate a file to the specified size - all we have to do is set the size
78 * attribute. We make sure the object exists first.
79 */
80void exofs_truncate(struct inode *inode)
81{
82 struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
83 struct exofs_i_info *oi = exofs_i(inode);
84 struct osd_obj_id obj = {sbi->s_pid, inode->i_ino + EXOFS_OBJ_OFF};
85 struct osd_request *or;
86 struct osd_attr attr;
87 loff_t isize = i_size_read(inode);
88 __be64 newsize;
89 int ret;
90
91 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
92 || S_ISLNK(inode->i_mode)))
93 return;
94 if (exofs_inode_is_fast_symlink(inode))
95 return;
96 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
97 return;
98 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
99
100 nobh_truncate_page(inode->i_mapping, isize, exofs_get_block);
101
102 or = osd_start_request(sbi->s_dev, GFP_KERNEL);
103 if (unlikely(!or)) {
104 EXOFS_ERR("ERROR: exofs_truncate: osd_start_request failed\n");
105 goto fail;
106 }
107
108 osd_req_set_attributes(or, &obj);
109
110 newsize = cpu_to_be64((u64)isize);
111 attr = g_attr_logical_length;
112 attr.val_ptr = &newsize;
113 osd_req_add_set_attr_list(or, &attr, 1);
114
115 /* if we are about to truncate an object, and it hasn't been
116 * created yet, wait
117 */
118 if (unlikely(wait_obj_created(oi)))
119 goto fail;
120
121 ret = exofs_sync_op(or, sbi->s_timeout, oi->i_cred);
122 osd_end_request(or);
123 if (ret)
124 goto fail;
125
126out:
127 mark_inode_dirty(inode);
128 return;
129fail:
130 make_bad_inode(inode);
131 goto out;
132}
133
134/*
135 * Set inode attributes - just call generic functions.
136 */
137int exofs_setattr(struct dentry *dentry, struct iattr *iattr)
138{
139 struct inode *inode = dentry->d_inode;
140 int error;
141
142 error = inode_change_ok(inode, iattr);
143 if (error)
144 return error;
145
146 error = inode_setattr(inode, iattr);
147 return error;
148}