File: /usr/src/linux/fs/ufs/util.c

1     /*
2      *  linux/fs/ufs/util.c
3      *
4      * Copyright (C) 1998
5      * Daniel Pirkl <daniel.pirkl@email.cz>
6      * Charles University, Faculty of Mathematics and Physics
7      */
8      
9     #include <linux/string.h>
10     #include <linux/slab.h>
11     #include <linux/locks.h>
12     
13     #include "swab.h"
14     #include "util.h"
15     
16     #undef UFS_UTILS_DEBUG
17     
18     #ifdef UFS_UTILS_DEBUG
19     #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x;
20     #else
21     #define UFSD(x)
22     #endif
23     
24     
25     struct ufs_buffer_head * _ubh_bread_ (struct ufs_sb_private_info * uspi,
26     	kdev_t dev, unsigned fragment, unsigned size)
27     {
28     	struct ufs_buffer_head * ubh;
29     	unsigned i, j, count;
30     	if (size & ~uspi->s_fmask)
31     		return NULL;
32     	count = size >> uspi->s_fshift;
33     	if (count > UFS_MAXFRAG)
34     		return NULL;
35     	ubh = (struct ufs_buffer_head *)
36     		kmalloc (sizeof (struct ufs_buffer_head), GFP_KERNEL);
37     	if (!ubh)
38     		return NULL;
39     	ubh->fragment = fragment;
40     	ubh->count = count;
41     	for (i = 0; i < count; i++)
42     		if (!(ubh->bh[i] = bread (dev, fragment + i, uspi->s_fsize)))
43     			goto failed;
44     	for (; i < UFS_MAXFRAG; i++)
45     		ubh->bh[i] = NULL;
46     	return ubh;
47     failed:
48     	for (j = 0; j < i; j++)
49     		brelse (ubh->bh[j]);
50     	return NULL;
51     }
52     
53     struct ufs_buffer_head * ubh_bread_uspi (struct ufs_sb_private_info * uspi,
54     	kdev_t dev, unsigned fragment, unsigned size)
55     {
56     	unsigned i, j, count;
57     	if (size & ~uspi->s_fmask)
58     		return NULL;
59     	count = size >> uspi->s_fshift;
60     	if (count <= 0 || count > UFS_MAXFRAG)
61     		return NULL;
62     	USPI_UBH->fragment = fragment;
63     	USPI_UBH->count = count;
64     	for (i = 0; i < count; i++)
65     		if (!(USPI_UBH->bh[i] = bread (dev, fragment + i, uspi->s_fsize)))
66     			goto failed;
67     	for (; i < UFS_MAXFRAG; i++)
68     		USPI_UBH->bh[i] = NULL;
69     	return USPI_UBH;
70     failed:
71     	for (j = 0; j < i; j++)
72     		brelse (USPI_UBH->bh[j]);
73     	return NULL;
74     }
75     
76     void ubh_brelse (struct ufs_buffer_head * ubh)
77     {
78     	unsigned i;
79     	if (!ubh)
80     		return;
81     	for (i = 0; i < ubh->count; i++)
82     		brelse (ubh->bh[i]);
83     	kfree (ubh);
84     }
85     
86     void ubh_brelse_uspi (struct ufs_sb_private_info * uspi)
87     {
88     	unsigned i;
89     	if (!USPI_UBH)
90     		return;
91     	for ( i = 0; i < USPI_UBH->count; i++ ) {
92     		brelse (USPI_UBH->bh[i]);
93     		USPI_UBH->bh[i] = NULL;
94     	}
95     }
96     
97     void ubh_mark_buffer_dirty (struct ufs_buffer_head * ubh)
98     {
99     	unsigned i;
100     	if (!ubh)
101     		return;
102     	for ( i = 0; i < ubh->count; i++ )
103     		mark_buffer_dirty (ubh->bh[i]);
104     }
105     
106     void ubh_mark_buffer_uptodate (struct ufs_buffer_head * ubh, int flag)
107     {
108     	unsigned i;
109     	if (!ubh)
110     		return;
111     	for ( i = 0; i < ubh->count; i++ )
112     		mark_buffer_uptodate (ubh->bh[i], flag);
113     }
114     
115     void ubh_ll_rw_block (int rw, unsigned nr, struct ufs_buffer_head * ubh[])
116     {
117     	unsigned i;
118     	if (!ubh)
119     		return;
120     	for ( i = 0; i < nr; i++ )
121     		ll_rw_block (rw, ubh[i]->count, ubh[i]->bh);
122     }
123     
124     void ubh_wait_on_buffer (struct ufs_buffer_head * ubh)
125     {
126     	unsigned i;
127     	if (!ubh)
128     		return;
129     	for ( i = 0; i < ubh->count; i++ )
130     		wait_on_buffer (ubh->bh[i]);
131     }
132     
133     unsigned ubh_max_bcount (struct ufs_buffer_head * ubh)
134     {
135     	unsigned i;
136     	unsigned max = 0;
137     	if (!ubh)
138     		return 0;
139     	for ( i = 0; i < ubh->count; i++ ) 
140     		if ( atomic_read(&ubh->bh[i]->b_count) > max )
141     			max = atomic_read(&ubh->bh[i]->b_count);
142     	return max;
143     }
144     
145     void ubh_bforget (struct ufs_buffer_head * ubh)
146     {
147     	unsigned i;
148     	if (!ubh) 
149     		return;
150     	for ( i = 0; i < ubh->count; i++ ) if ( ubh->bh[i] ) 
151     		bforget (ubh->bh[i]);
152     }
153      
154     int ubh_buffer_dirty (struct ufs_buffer_head * ubh)
155     {
156     	unsigned i;
157     	unsigned result = 0;
158     	if (!ubh)
159     		return 0;
160     	for ( i = 0; i < ubh->count; i++ )
161     		result |= buffer_dirty(ubh->bh[i]);
162     	return result;
163     }
164     
165     void _ubh_ubhcpymem_(struct ufs_sb_private_info * uspi, 
166     	unsigned char * mem, struct ufs_buffer_head * ubh, unsigned size)
167     {
168     	unsigned len, bhno;
169     	if (size > (ubh->count << uspi->s_fshift))
170     		size = ubh->count << uspi->s_fshift;
171     	bhno = 0;
172     	while (size) {
173     		len = min_t(unsigned int, size, uspi->s_fsize);
174     		memcpy (mem, ubh->bh[bhno]->b_data, len);
175     		mem += uspi->s_fsize;
176     		size -= len;
177     		bhno++;
178     	}
179     }
180     
181     void _ubh_memcpyubh_(struct ufs_sb_private_info * uspi, 
182     	struct ufs_buffer_head * ubh, unsigned char * mem, unsigned size)
183     {
184     	unsigned len, bhno;
185     	if (size > (ubh->count << uspi->s_fshift))
186     		size = ubh->count << uspi->s_fshift;
187     	bhno = 0;
188     	while (size) {
189     		len = min_t(unsigned int, size, uspi->s_fsize);
190     		memcpy (ubh->bh[bhno]->b_data, mem, len);
191     		mem += uspi->s_fsize;
192     		size -= len;
193     		bhno++;
194     	}
195     }
196