OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [reiserfs/] [file.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
3
 */
4
 
5
 
6
#include <linux/sched.h>
7
#include <linux/reiserfs_fs.h>
8
#include <linux/smp_lock.h>
9
 
10
/*
11
** We pack the tails of files on file close, not at the time they are written.
12
** This implies an unnecessary copy of the tail and an unnecessary indirect item
13
** insertion/balancing, for files that are written in one write.
14
** It avoids unnecessary tail packings (balances) for files that are written in
15
** multiple writes and are small enough to have tails.
16
**
17
** file_release is called by the VFS layer when the file is closed.  If
18
** this is the last open file descriptor, and the file
19
** small enough to have a tail, and the tail is currently in an
20
** unformatted node, the tail is converted back into a direct item.
21
**
22
** We use reiserfs_truncate_file to pack the tail, since it already has
23
** all the conditions coded.
24
*/
25
static int reiserfs_file_release (struct inode * inode, struct file * filp)
26
{
27
 
28
    struct reiserfs_transaction_handle th ;
29
    int windex ;
30
 
31
    if (!S_ISREG (inode->i_mode))
32
        BUG ();
33
 
34
    /* fast out for when nothing needs to be done */
35
    if ((atomic_read(&inode->i_count) > 1 ||
36
         !(inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) ||
37
         !tail_has_to_be_packed(inode))       &&
38
        inode->u.reiserfs_i.i_prealloc_count <= 0) {
39
        return 0;
40
    }
41
 
42
    lock_kernel() ;
43
    down (&inode->i_sem);
44
    journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
45
    reiserfs_update_inode_transaction(inode) ;
46
 
47
#ifdef REISERFS_PREALLOCATE
48
    reiserfs_discard_prealloc (&th, inode);
49
#endif
50
    journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
51
 
52
    if (atomic_read(&inode->i_count) <= 1 &&
53
        (inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) &&
54
        tail_has_to_be_packed (inode)) {
55
        /* if regular file is released by last holder and it has been
56
           appended (we append by unformatted node only) or its direct
57
           item(s) had to be converted, then it may have to be
58
           indirect2direct converted */
59
        windex = push_journal_writer("file_release") ;
60
        reiserfs_truncate_file(inode, 0) ;
61
        pop_journal_writer(windex) ;
62
    }
63
    up (&inode->i_sem);
64
    unlock_kernel() ;
65
    return 0;
66
}
67
 
68
static void reiserfs_vfs_truncate_file(struct inode *inode) {
69
    reiserfs_truncate_file(inode, 1) ;
70
}
71
 
72
/* Sync a reiserfs file. */
73
static int reiserfs_sync_file(
74
                              struct file   * p_s_filp,
75
                              struct dentry * p_s_dentry,
76
                              int datasync
77
                              ) {
78
  struct inode * p_s_inode = p_s_dentry->d_inode;
79
  int n_err;
80
 
81
  lock_kernel() ;
82
 
83
  if (!S_ISREG(p_s_inode->i_mode))
84
      BUG ();
85
 
86
  n_err = fsync_inode_buffers(p_s_inode) ;
87
  n_err |= fsync_inode_data_buffers(p_s_inode);
88
  reiserfs_commit_for_inode(p_s_inode) ;
89
  unlock_kernel() ;
90
  return ( n_err < 0 ) ? -EIO : 0;
91
}
92
 
93
static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
94
    struct inode *inode = dentry->d_inode ;
95
    int error ;
96
    if (attr->ia_valid & ATTR_SIZE) {
97
        /* version 2 items will be caught by the s_maxbytes check
98
        ** done for us in vmtruncate
99
        */
100
        if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
101
            attr->ia_size > MAX_NON_LFS)
102
            return -EFBIG ;
103
 
104
        /* fill in hole pointers in the expanding truncate case. */
105
        if (attr->ia_size > inode->i_size) {
106
            error = generic_cont_expand(inode, attr->ia_size) ;
107
            if (inode->u.reiserfs_i.i_prealloc_count > 0) {
108
                struct reiserfs_transaction_handle th ;
109
                /* we're changing at most 2 bitmaps, inode + super */
110
                journal_begin(&th, inode->i_sb, 4) ;
111
                reiserfs_discard_prealloc (&th, inode);
112
                journal_end(&th, inode->i_sb, 4) ;
113
            }
114
            if (error)
115
                return error ;
116
        }
117
    }
118
 
119
    if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
120
         ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
121
        (get_inode_sd_version (inode) == STAT_DATA_V1))
122
                /* stat data of format v3.5 has 16 bit uid and gid */
123
            return -EINVAL;
124
 
125
    error = inode_change_ok(inode, attr) ;
126
    if (!error)
127
        inode_setattr(inode, attr) ;
128
 
129
    return error ;
130
}
131
 
132
struct file_operations reiserfs_file_operations = {
133
    read:       generic_file_read,
134
    write:      generic_file_write,
135
    ioctl:      reiserfs_ioctl,
136
    mmap:       generic_file_mmap,
137
    release:    reiserfs_file_release,
138
    fsync:      reiserfs_sync_file,
139
};
140
 
141
 
142
struct  inode_operations reiserfs_file_inode_operations = {
143
    truncate:   reiserfs_vfs_truncate_file,
144
    setattr:    reiserfs_setattr,
145
};
146
 
147
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.