1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2002, 2003 Cluster File Systems, Inc.
5 * Author: Peter Braam <braam@clusterfs.com>
6 * Author: Phil Schwan <phil@clusterfs.com>
7 * Author: Andreas Dilger <adilger@clusterfs.com>
9 * This file is part of Lustre, http://www.lustre.org.
11 * Lustre is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Lustre is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Lustre; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #define DEBUG_SUBSYSTEM S_LLITE
26 #include <linux/lustre_lite.h>
27 #include <linux/file.h>
29 #include "llite_internal.h"
34 static inline struct file_operations**
35 get_save_fops(struct file* filp, int mode)
37 struct inode *inode = filp->f_dentry->d_inode;
38 struct ll_inode_info *lli = ll_i2info(inode);
39 if (mode == FILE_OPS){
40 if (S_ISFIFO(inode->i_mode)){
41 switch (filp->f_mode) {
43 return &(lli->ll_save_ffop);
45 return &(lli->ll_save_wfop);
47 return &(lli->ll_save_wrfop);
52 return &(lli->ll_save_ffop);
54 return &(lli->ll_save_ifop);
59 static inline void save_fops(struct file *filp, struct inode *inode,
60 struct file_operations *sfops)
62 struct ll_inode_info *lli = ll_i2info(inode);
64 if (sfops != filp->f_op) {
65 struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
68 if (S_ISCHR(inode->i_mode)) {
69 filp->f_op = &ll_special_chr_file_fops;
70 }else if (S_ISFIFO(inode->i_mode)){
71 filp->f_op = &ll_special_fifo_file_fops;
73 filp->f_op->owner = lli->ll_save_ffop->owner;
77 static ssize_t ll_special_file_read(struct file *filp, char *buf,
78 size_t count, loff_t *ppos)
80 struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
83 if (pfop && *pfop && (*pfop)->read)
84 rc = (*pfop)->read(filp, buf, count, ppos);
89 static ssize_t ll_special_file_write(struct file *filp, const char *buf,
90 size_t count, loff_t *ppos)
92 struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
95 if (pfop && *pfop && (*pfop)->write)
96 rc = (*pfop)->write(filp, buf, count, ppos);
100 static int ll_special_file_ioctl(struct inode *inode, struct file *filp,
101 unsigned int cmd, unsigned long arg)
103 struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
106 if (pfop && *pfop && (*pfop)->ioctl) {
107 struct file_operations *sfops = filp->f_op;
109 rc = (*pfop)->ioctl(inode, filp, cmd, arg);
110 save_fops(filp, inode, sfops);
115 static loff_t ll_special_file_seek(struct file *filp, loff_t offset, int origin)
117 struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
120 if (pfop && *pfop && (*pfop)->llseek)
121 rc = (*pfop)->llseek(filp, offset, origin);
123 rc = default_llseek(filp, offset, origin);
129 #define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
132 ll_special_file_poll(struct file *filp, struct poll_table_struct *poll_table)
134 struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
135 int rc = DEFAULT_POLLMASK;
137 if (pfop && *pfop && (*pfop)->poll)
138 rc = (*pfop)->poll(filp, poll_table);
143 static int ll_special_file_open(struct inode *inode, struct file *filp)
145 struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
148 if (pfop && *pfop && (*pfop)->open)
149 rc = (*pfop)->open(inode, filp);
154 static ssize_t ll_special_read(struct file *filp, char *buf,
155 size_t count, loff_t *ppos)
157 struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
160 if (pfop && *pfop && (*pfop)->read)
161 rc = (*pfop)->read(filp, buf, count, ppos);
166 static ssize_t ll_special_write(struct file *filp, const char *buf,
167 size_t count, loff_t *ppos)
169 struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
172 if (pfop && *pfop && (*pfop)->write)
173 rc = (*pfop)->write(filp, buf, count, ppos);
178 static int ll_special_ioctl(struct inode *inode, struct file *filp,
179 unsigned int cmd, unsigned long arg)
181 struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
184 if (pfop && *pfop && (*pfop)->ioctl) {
185 struct file_operations *sfops = filp->f_op;
187 rc = (*pfop)->ioctl(inode, filp, cmd, arg);
188 /* sometimes, file_operations will be changed in ioctl */
189 save_fops(filp, inode, sfops);
195 static int ll_special_mmap(struct file * filp, struct vm_area_struct * vma)
197 struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
200 if (pfop && *pfop && (*pfop)->mmap)
201 rc = (*pfop)->mmap(filp, vma);
206 static loff_t ll_special_seek(struct file *filp, loff_t offset, int origin)
208 struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
211 if (pfop && *pfop && (*pfop)->llseek)
212 rc = (*pfop)->llseek(filp, offset, origin);
214 rc = default_llseek(filp, offset, origin);
219 static int ll_special_fsync(struct file *filp, struct dentry *dentry, int data)
221 struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
224 if (pfop && *pfop && (*pfop)->fsync)
225 rc = (*pfop)->fsync(filp, dentry, data);
230 static int ll_special_file_fasync(int fd, struct file *filp, int on)
232 struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
235 if (pfop && *pfop && (*pfop)->fasync)
236 rc = (*pfop)->fasync(fd, filp, on);
241 static int ll_special_open(struct inode *inode, struct file *filp)
243 struct ptlrpc_request *req;
244 struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
245 struct lookup_intent *it;
249 if (pfop && *pfop && (*pfop)->open) {
250 struct file_operations *sfops = filp->f_op;
252 rc = (*pfop)->open(inode, filp);
253 /* sometimes the file_operations will be changed in open */
254 save_fops(filp, inode, sfops);
257 lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_OPEN);
261 rc = ll_local_open(filp, it);
264 req = it->d.lustre.it_data;
266 ptlrpc_req_finished(req);
271 static int ll_special_release(struct inode *inode, struct file *filp)
273 struct ll_sb_info *sbi = ll_i2sbi(inode);
274 struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
278 if (pfop && *pfop && (*pfop)->release) {
279 rc = (*pfop)->release(inode, filp);
281 lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_RELEASE);
283 rc2 = ll_mdc_close(sbi->ll_mdc_exp, inode, filp);
291 static int ll_special_file_release(struct inode *inode, struct file *filp)
293 struct ll_sb_info *sbi = ll_i2sbi(inode);
294 struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
298 if (pfop && *pfop && (*pfop)->release) {
299 rc = (*pfop)->release(inode, filp);
301 lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_RELEASE);
303 rc2 = ll_mdc_close(sbi->ll_mdc_exp, inode, filp);
312 struct inode_operations ll_special_inode_operations = {
313 setattr_raw: ll_setattr_raw,
315 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
316 getattr_it: ll_getattr,
318 revalidate_it: ll_inode_revalidate_it,
322 struct file_operations ll_special_chr_inode_fops = {
323 open: ll_special_open,
326 struct file_operations ll_special_blk_inode_fops = {
327 read: ll_special_read,
328 write: ll_special_write,
329 ioctl: ll_special_ioctl,
330 open: ll_special_open,
331 release: ll_special_release,
332 mmap: ll_special_mmap,
333 llseek: ll_special_seek,
334 fsync: ll_special_fsync,
337 struct file_operations ll_special_fifo_inode_fops = {
338 open: ll_special_open,
341 struct file_operations ll_special_sock_inode_fops = {
342 open: ll_special_open
345 struct file_operations ll_special_chr_file_fops = {
346 llseek: ll_special_file_seek,
347 read: ll_special_file_read,
348 write: ll_special_file_write,
349 poll: ll_special_file_poll,
350 ioctl: ll_special_file_ioctl,
351 open: ll_special_file_open,
352 release: ll_special_file_release,
353 fasync: ll_special_file_fasync,
356 struct file_operations ll_special_fifo_file_fops = {
357 llseek: ll_special_file_seek,
358 read: ll_special_file_read,
359 write: ll_special_file_write,
360 poll: ll_special_file_poll,
361 ioctl: ll_special_file_ioctl,
362 open: ll_special_file_open,
363 release: ll_special_file_release,