* better
[mascara-docs.git] / i386 / linux-2.3.21 / fs / ufs / file.c
blob33d68ba5d00055298bffb230d5f279e91eb8c096
1 /*
2 * linux/fs/ufs/file.c
4 * Copyright (C) 1998
5 * Daniel Pirkl <daniel.pirkl@email.cz>
6 * Charles University, Faculty of Mathematics and Physics
8 * from
10 * linux/fs/ext2/file.c
12 * Copyright (C) 1992, 1993, 1994, 1995
13 * Remy Card (card@masi.ibp.fr)
14 * Laboratoire MASI - Institut Blaise Pascal
15 * Universite Pierre et Marie Curie (Paris VI)
17 * from
19 * linux/fs/minix/file.c
21 * Copyright (C) 1991, 1992 Linus Torvalds
23 * ext2 fs regular file handling primitives
26 #include <asm/uaccess.h>
27 #include <asm/system.h>
29 #include <linux/errno.h>
30 #include <linux/fs.h>
31 #include <linux/ufs_fs.h>
32 #include <linux/fcntl.h>
33 #include <linux/sched.h>
34 #include <linux/stat.h>
35 #include <linux/locks.h>
36 #include <linux/mm.h>
37 #include <linux/pagemap.h>
39 #define NBUF 32
41 #define MIN(a,b) (((a)<(b))?(a):(b))
42 #define MAX(a,b) (((a)>(b))?(a):(b))
45 * Make sure the offset never goes beyond the 32-bit mark..
47 static long long ufs_file_lseek(
48 struct file *file,
49 long long offset,
50 int origin )
52 long long retval;
53 struct inode *inode = file->f_dentry->d_inode;
55 switch (origin) {
56 case 2:
57 offset += inode->i_size;
58 break;
59 case 1:
60 offset += file->f_pos;
62 retval = -EINVAL;
63 /* make sure the offset fits in 32 bits */
64 if (((unsigned long long) offset >> 32) == 0) {
65 if (offset != file->f_pos) {
66 file->f_pos = offset;
67 file->f_reada = 0;
68 file->f_version = ++event;
70 retval = offset;
72 return retval;
75 static inline void remove_suid(struct inode *inode)
77 unsigned int mode;
79 /* set S_IGID if S_IXGRP is set, and always set S_ISUID */
80 mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID;
82 /* was any of the uid bits set? */
83 mode &= inode->i_mode;
84 if (mode && !suser()) {
85 inode->i_mode &= ~mode;
86 mark_inode_dirty(inode);
91 * Write to a file (through the page cache).
93 static ssize_t
94 ufs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
96 ssize_t retval;
98 retval = generic_file_write(file, buf, count,
99 ppos, block_write_partial_page);
100 if (retval > 0) {
101 struct inode *inode = file->f_dentry->d_inode;
102 remove_suid(inode);
103 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
104 mark_inode_dirty(inode);
106 return retval;
110 * Called when an inode is released. Note that this is different
111 * from ufs_open: open gets called at every open, but release
112 * gets called only when /all/ the files are closed.
114 static int ufs_release_file (struct inode * inode, struct file * filp)
116 return 0;
120 * We have mostly NULL's here: the current defaults are ok for
121 * the ufs filesystem.
123 static struct file_operations ufs_file_operations = {
124 ufs_file_lseek, /* lseek */
125 generic_file_read, /* read */
126 ufs_file_write, /* write */
127 NULL, /* readdir - bad */
128 NULL, /* poll - default */
129 NULL, /* ioctl */
130 generic_file_mmap, /* mmap */
131 NULL, /* no special open is needed */
132 NULL, /* flush */
133 ufs_release_file, /* release */
134 NULL, /* fsync */
135 NULL, /* fasync */
136 NULL, /* check_media_change */
137 NULL /* revalidate */
140 struct inode_operations ufs_file_inode_operations = {
141 &ufs_file_operations,/* default file operations */
142 NULL, /* create */
143 NULL, /* lookup */
144 NULL, /* link */
145 NULL, /* unlink */
146 NULL, /* symlink */
147 NULL, /* mkdir */
148 NULL, /* rmdir */
149 NULL, /* mknod */
150 NULL, /* rename */
151 NULL, /* readlink */
152 NULL, /* follow_link */
153 ufs_getfrag_block, /* get_block */
154 block_read_full_page, /* readpage */
155 block_write_full_page, /* writepage */
156 block_flushpage, /* flushpage */
157 ufs_truncate, /* truncate */
158 NULL, /* permission */
159 NULL, /* smap */
160 NULL /* revalidate */