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
|
/* 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;
/* Links on hash list. */
struct node *hnext, **hprevp;
/* The inode as returned by virtual inode management routines. */
inode_t inode;
struct rwlock 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. */
struct rwlock 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. */
spin_lock_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 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 ();
struct node *ifind (ino_t inum);
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);
|