1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/* fatfs.h - Interface for fatfs.
Copyright (C) 1997, 1999, 2002, 2003 Free Software Foundation, Inc.
Written by Thomas Bushnell, n/BSG and Marcus Brinkmann.
This file is part of the GNU Hurd.
The GNU Hurd is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
The GNU Hurd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#include <sys/types.h>
#include <sys/mman.h>
#include <hurd/diskfs.h>
#include <hurd/diskfs-pager.h>
#include <hurd/store.h>
#include "fat.h"
#include "virt-inode.h"
/* There is no such thing as an inode in this format, all such information
being recorded in the directory entry. So we report inode numbers as
the start cluster number of the file. When messing around with the
directory entry, hold the DIRENT_LOCK. */
struct disknode
{
cluster_t start_cluster;
/* The inode as returned by virtual inode management routines. */
inode_t inode;
/* The directory that hold this file, always hold a reference. */
struct node *dirnode;
pthread_rwlock_t dirent_lock;
char *link_target; /* For S_ISLNK. */
size_t translen;
char *translator;
/* Lock to hold while fiddling with this inode's block allocation
info. */
pthread_rwlock_t alloc_lock;
/* Lock to hold while extending this inode's block allocation info.
Hold only if you hold readers alloc_lock, then you don't need to
hold it if you hold writers alloc_lock already. */
pthread_spinlock_t chain_extension_lock;
struct cluster_chain *first;
struct cluster_chain *last;
cluster_t length_of_chain;
int chain_complete;
/* This file's pager. */
struct pager *pager;
/* Index to start a directory lookup at. */
int dir_idx;
};
struct lookup_context
{
/* The inode as returned by virtual inode management routines. */
inode_t inode;
/* Use BUF as the directory file map. */
vm_address_t buf;
/* Directory this node was allocated in (used by diskfs_alloc_node). */
struct node *dir;
};
struct user_pager_info
{
struct node *node;
enum pager_type
{
FAT,
FILE_DATA,
} type;
vm_prot_t max_prot;
};
/* The physical media. */
extern struct store *store;
/* The UID and GID for all files in the filesystem. */
extern uid_t fs_uid;
extern gid_t fs_gid;
/* Mapped image of the FAT. */
extern void *fat_image;
/* Handy source of zeroes. */
extern vm_address_t zerocluster;
extern struct dirrect dr_root_node;
#define LOG2_BLOCKS_PER_CLUSTER \
(log2_bytes_per_cluster - store->log2_block_size)
#define round_cluster(offs) \
((((offs) + bytes_per_cluster - 1) \
>> log2_bytes_per_cluster) << log2_bytes_per_cluster)
#define FAT_FIRST_CLUSTER_BLOCK(cluster) \
(((cluster - 2) << LOG2_BLOCKS_PER_CLUSTER) + \
(first_data_byte >> store->log2_block_size))
void drop_pager_softrefs (struct node *);
void allow_pager_softrefs (struct node *);
void create_fat_pager (void);
void flush_node_pager (struct node *node);
void write_all_disknodes ();
error_t fat_get_next_cluster (cluster_t cluster, cluster_t *next_cluster);
void fat_to_unix_filename (const char *, char *);
error_t diskfs_cached_lookup_in_dirbuf (int cache_id, struct node **npp,
vm_address_t buf);
void refresh_node_stats (void);
|