2 * Copyright (c) 1995 - 2004 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "arla_local.h"
38 #include <nnpfs/nnpfs_dirent.h>
40 #define NNPFS_DIRENT_BLOCKSIZE 512
41 #define nnpfs_dirent dirent
44 static long blocksize
= NNPFS_DIRENT_BLOCKSIZE
; /* XXX */
47 * Write out all remaining data in `args'
51 flushbuf (void *vargs
)
53 struct write_dirent_args
*args
= (struct write_dirent_args
*)vargs
;
54 unsigned inc
= blocksize
- (args
->ptr
- args
->buf
);
55 struct nnpfs_dirent
*last
= (struct nnpfs_dirent
*)args
->last
;
57 last
->d_reclen
+= inc
;
58 if (write (args
->fd
, args
->buf
, blocksize
) != blocksize
)
59 arla_warn (ADEBWARN
, errno
, "write");
60 args
->ptr
= args
->buf
;
62 memset(args
->buf
, 0, blocksize
);
66 * Write a dirent to the args buf in `arg' containg `fid' and `name'.
70 write_dirent(VenusFid
*fid
, const char *name
, void *arg
)
72 struct nnpfs_dirent dirent
, *real
;
73 struct write_dirent_args
*args
= (struct write_dirent_args
*)arg
;
75 dirent
.d_namlen
= strlen (name
);
76 #ifdef _GENERIC_DIRSIZ
77 dirent
.d_reclen
= _GENERIC_DIRSIZ(&dirent
);
78 #elif defined(DIRENT_SIZE)
79 dirent
.d_reclen
= DIRENT_SIZE(&dirent
);
80 #elif defined(_DIRENT_SIZE)
81 dirent
.d_reclen
= _DIRENT_SIZE(&dirent
);
83 dirent
.d_reclen
= DIRSIZ(&dirent
);
86 if (args
->ptr
+ dirent
.d_reclen
> args
->buf
+ blocksize
)
88 real
= (struct nnpfs_dirent
*)args
->ptr
;
90 real
->d_namlen
= dirent
.d_namlen
;
91 real
->d_reclen
= dirent
.d_reclen
;
92 #if defined(HAVE_STRUCT_DIRENT_D_TYPE) && !defined(__linux__)
93 real
->d_type
= DT_UNKNOWN
;
96 real
->d_fileno
= dentry2ino (name
, fid
, args
->e
);
97 strlcpy (real
->d_name
, name
, sizeof(real
->d_name
));
98 args
->ptr
+= real
->d_reclen
;
99 args
->off
+= real
->d_reclen
;
105 conv_dir (FCacheEntry
*e
, CredCacheEntry
*ce
, u_int tokens
)
107 return conv_dir_sub(e
, ce
, tokens
, write_dirent
, flushbuf
, blocksize
);
111 * remove `filename` from the converted directory for `e'
115 #define DIRBLKSIZ 1024
119 dir_remove_name (FCacheEntry
*e
, const char *filename
)
121 char cache_name
[MAXPATHLEN
];
129 struct nnpfs_dirent
*dp
;
130 struct nnpfs_dirent
*last_dp
;
132 fcache_extra_file_name (e
, cache_name
, MAXPATHLEN
);
133 fd
= open (cache_name
, O_RDWR
, 0);
137 /* fcache_fhget (cache_name, cache_handle); */
139 if (fstat (fd
, &sb
) < 0) {
146 ret
= fbuf_create (&fb
, fd
, len
, FBUF_READ
|FBUF_WRITE
);
153 for (p
= buf
= fbuf_buf (&fb
); p
< buf
+ len
; p
+= dp
->d_reclen
) {
155 dp
= (struct nnpfs_dirent
*)p
;
157 assert (dp
->d_reclen
> 0);
159 if (strcmp (filename
, dp
->d_name
) == 0) {
160 if (last_dp
!= NULL
) {
165 * d_reclen can be as largest (in worst case)
166 * DIRBLKSIZ, and may not cause the entry to cross a
167 * DIRBLKSIZ boundery.
169 len
= last_dp
->d_reclen
+ dp
->d_reclen
;
171 off1
= (char *)last_dp
- buf
;
176 if (len
< DIRBLKSIZ
&& off1
== off2
)
177 last_dp
->d_reclen
= len
;