source: branches/samba-3.2.x/source/modules/vfs_fileid.c@ 579

Last change on this file since 579 was 232, checked in by Herwig Bauernfeind, 17 years ago

Update 3.2 branch to 3.2.8

File size: 7.2 KB
Line 
1/*
2 * VFS module to alter the algorithm to calculate
3 * the struct file_id used as key for the share mode
4 * and byte range locking db's.
5 *
6 * Copyright (C) 2007, Stefan Metzmacher
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "includes.h"
23
24static int vfs_fileid_debug_level = DBGC_VFS;
25
26#undef DBGC_CLASS
27#define DBGC_CLASS vfs_fileid_debug_level
28
29struct fileid_mount_entry {
30 SMB_DEV_T device;
31 const char *mnt_fsname;
32 fsid_t fsid;
33 uint64_t devid;
34};
35
36struct fileid_handle_data {
37 uint64_t (*device_mapping_fn)(struct fileid_handle_data *data,
38 SMB_DEV_T dev);
39 unsigned num_mount_entries;
40 struct fileid_mount_entry *mount_entries;
41};
42
43/* load all the mount entries from the mtab */
44static void fileid_load_mount_entries(struct fileid_handle_data *data)
45{
46 FILE *f;
47 struct mntent *m;
48
49 data->num_mount_entries = 0;
50 TALLOC_FREE(data->mount_entries);
51
52 f = setmntent("/etc/mtab", "r");
53 if (!f) return;
54
55 while ((m = getmntent(f))) {
56 struct stat st;
57 struct statfs sfs;
58 struct fileid_mount_entry *cur;
59
60 if (stat(m->mnt_dir, &st) != 0) continue;
61 if (statfs(m->mnt_dir, &sfs) != 0) continue;
62
63 if (strncmp(m->mnt_fsname, "/dev/", 5) == 0) {
64 m->mnt_fsname += 5;
65 }
66
67 data->mount_entries = TALLOC_REALLOC_ARRAY(data,
68 data->mount_entries,
69 struct fileid_mount_entry,
70 data->num_mount_entries+1);
71 if (data->mount_entries == NULL) {
72 goto nomem;
73 }
74
75 cur = &data->mount_entries[data->num_mount_entries];
76 cur->device = st.st_dev;
77 cur->mnt_fsname = talloc_strdup(data->mount_entries,
78 m->mnt_fsname);
79 if (!cur->mnt_fsname) goto nomem;
80 cur->fsid = sfs.f_fsid;
81 cur->devid = (uint64_t)-1;
82
83 data->num_mount_entries++;
84 }
85 endmntent(f);
86 return;
87
88nomem:
89 if (f) endmntent(f);
90
91 data->num_mount_entries = 0;
92 TALLOC_FREE(data->mount_entries);
93
94 return;
95}
96
97/* find a mount entry given a dev_t */
98static struct fileid_mount_entry *fileid_find_mount_entry(struct fileid_handle_data *data,
99 SMB_DEV_T dev)
100{
101 int i;
102
103 if (data->num_mount_entries == 0) {
104 fileid_load_mount_entries(data);
105 }
106 for (i=0;i<data->num_mount_entries;i++) {
107 if (data->mount_entries[i].device == dev) {
108 return &data->mount_entries[i];
109 }
110 }
111 /* 2nd pass after reloading */
112 fileid_load_mount_entries(data);
113 for (i=0;i<data->num_mount_entries;i++) {
114 if (data->mount_entries[i].device == dev) {
115 return &data->mount_entries[i];
116 }
117 }
118 return NULL;
119}