9 #include <linux/types.h>
10 #include <linux/string.h>
11 #include <linux/time.h>
13 #include <linux/slab.h>
17 #include <linux/nfsd/nfsfh.h>
18 #include <linux/nfsd/export.h>
21 #include <linux/module.h>
24 #define NLMDBG_FACILITY NLMDBG_SVCSUBS
30 #define FILE_HASH_BITS 7
31 #define FILE_NRHASH (1<<FILE_HASH_BITS)
36 static inline void nlm_debug_print_fh(
char *
msg,
struct nfs_fh *
f)
41 dprintk(
"lockd: %s (%08x %08x %08x %08x %08x %08x %08x %08x)\n",
42 msg, fhp[0], fhp[1], fhp[2], fhp[3],
43 fhp[4], fhp[5], fhp[6], fhp[7]);
46 static inline void nlm_debug_print_file(
char *msg,
struct nlm_file *
file)
48 struct inode *
inode = file->f_file->f_path.dentry->d_inode;
54 static inline void nlm_debug_print_fh(
char *msg,
struct nfs_fh *f)
59 static inline void nlm_debug_print_file(
char *msg,
struct nlm_file *
file)
65 static inline unsigned int file_hash(
struct nfs_fh *f)
88 struct nlm_file *
file;
92 nlm_debug_print_fh(
"nlm_lookup_file", f);
100 if (!nfs_compare_fh(&file->f_handle, f))
103 nlm_debug_print_fh(
"creating file for", f);
112 INIT_HLIST_NODE(&file->f_list);
113 INIT_LIST_HEAD(&file->f_blocks);
121 if ((nfserr =
nlmsvc_ops->fopen(rqstp, f, &file->f_file)) != 0) {
122 dprintk(
"lockd: open failed (error %d)\n", nfserr);
126 hlist_add_head(&file->f_list, &nlm_files[hash]);
129 dprintk(
"lockd: found file %p (count %d)\n", file, file->f_count);
147 nlm_delete_file(
struct nlm_file *
file)
149 nlm_debug_print_file(
"closing file", file);
150 if (!hlist_unhashed(&file->f_list)) {
151 hlist_del(&file->f_list);
164 nlm_traverse_locks(
struct nlm_host *
host,
struct nlm_file *file,
165 nlm_host_match_fn_t
match)
167 struct inode *
inode = nlmsvc_file_inode(file);
169 struct nlm_host *lockhost;
181 lockhost = (
struct nlm_host *) fl->
fl_owner;
190 printk(
"lockd: unlock failure in %s:%d\n",
203 nlmsvc_always_match(
void *dummy1,
struct nlm_host *dummy2)
212 nlm_inspect_file(
struct nlm_host *host,
struct nlm_file *file, nlm_host_match_fn_t match)
216 return nlm_traverse_locks(host, file, match);
224 nlm_file_inuse(
struct nlm_file *file)
226 struct inode *inode = nlmsvc_file_inode(file);
229 if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares)
248 nlm_traverse_files(
void *
data, nlm_host_match_fn_t match,
249 int (*is_failover_file)(
void *data,
struct nlm_file *file))
252 struct nlm_file *
file;
258 if (is_failover_file && !is_failover_file(data, file))
265 if (nlm_inspect_file(data, file, match))
271 if (list_empty(&file->f_blocks) && !file->f_locks
272 && !file->f_shares && !file->f_count) {
273 hlist_del(&file->f_list);
295 dprintk(
"lockd: nlm_release_file(%p, ct = %d)\n",
296 file, file->f_count);
302 if (--file->f_count == 0 && !nlm_file_inuse(file))
303 nlm_delete_file(file);
326 nlmsvc_mark_host(
void *data,
struct nlm_host *hint)
328 struct nlm_host *host =
data;
330 if ((hint->net ==
NULL) ||
331 (host->net == hint->net))
337 nlmsvc_same_host(
void *data,
struct nlm_host *
other)
339 struct nlm_host *host =
data;
341 return host ==
other;
345 nlmsvc_is_client(
void *data,
struct nlm_host *
dummy)
347 struct nlm_host *host =
data;
349 if (host->h_server) {
354 if (host->h_nsmhandle)
355 host->h_nsmhandle->sm_sticky = 1;
367 struct nlm_host hint;
369 dprintk(
"lockd: nlmsvc_mark_resources for net %p\n", net);
371 nlm_traverse_files(&hint, nlmsvc_mark_host,
NULL);
380 dprintk(
"lockd: nlmsvc_free_host_resources\n");
382 if (nlm_traverse_files(host, nlmsvc_same_host,
NULL)) {
384 "lockd: couldn't remove all locks held by %s\n",
405 nlm_traverse_files(
NULL, nlmsvc_is_client,
NULL);
409 nlmsvc_match_sb(
void *datap,
struct nlm_file *file)
413 return sb == file->f_file->f_path.dentry->d_sb;
427 ret = nlm_traverse_files(sb, nlmsvc_always_match, nlmsvc_match_sb);
428 return ret ? -
EIO : 0;
433 nlmsvc_match_ip(
void *datap,
struct nlm_host *host)
435 return rpc_cmp_addr(nlm_srcaddr(host), datap);
450 ret = nlm_traverse_files(server_addr, nlmsvc_match_ip,
NULL);
451 return ret ? -
EIO : 0;