Blame view
fs/afs/mntpt.c
5.19 KB
ec26815ad [AFS]: Clean up t... |
1 |
/* mountpoint management |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 7 8 9 10 11 12 13 14 |
* * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program 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 of the License, or (at your option) any later version. */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> |
1da177e4c Linux-2.6.12-rc2 |
15 16 17 18 |
#include <linux/fs.h> #include <linux/pagemap.h> #include <linux/mount.h> #include <linux/namei.h> |
5a0e3ad6a include cleanup: ... |
19 |
#include <linux/gfp.h> |
1da177e4c Linux-2.6.12-rc2 |
20 21 22 23 24 |
#include "internal.h" static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry, |
00cd8dd3b stop passing name... |
25 |
unsigned int flags); |
1da177e4c Linux-2.6.12-rc2 |
26 |
static int afs_mntpt_open(struct inode *inode, struct file *file); |
08e0e7c82 [AF_RXRPC]: Make ... |
27 |
static void afs_mntpt_expiry_timed_out(struct work_struct *work); |
1da177e4c Linux-2.6.12-rc2 |
28 |
|
4b6f5d20b [PATCH] Make most... |
29 |
const struct file_operations afs_mntpt_file_operations = { |
1da177e4c Linux-2.6.12-rc2 |
30 |
.open = afs_mntpt_open, |
6038f373a llseek: automatic... |
31 |
.llseek = noop_llseek, |
1da177e4c Linux-2.6.12-rc2 |
32 |
}; |
754661f14 [PATCH] mark stru... |
33 |
const struct inode_operations afs_mntpt_inode_operations = { |
1da177e4c Linux-2.6.12-rc2 |
34 |
.lookup = afs_mntpt_lookup, |
1da177e4c Linux-2.6.12-rc2 |
35 |
.readlink = page_readlink, |
416351f28 AFS: AFS fixups |
36 |
.getattr = afs_getattr, |
d3e3b7eac afs: Add metadata... |
37 |
.listxattr = afs_listxattr, |
1da177e4c Linux-2.6.12-rc2 |
38 |
}; |
bec5eb614 AFS: Implement an... |
39 |
const struct inode_operations afs_autocell_inode_operations = { |
bec5eb614 AFS: Implement an... |
40 41 |
.getattr = afs_getattr, }; |
1da177e4c Linux-2.6.12-rc2 |
42 |
static LIST_HEAD(afs_vfsmounts); |
08e0e7c82 [AF_RXRPC]: Make ... |
43 |
static DECLARE_DELAYED_WORK(afs_mntpt_expiry_timer, afs_mntpt_expiry_timed_out); |
1da177e4c Linux-2.6.12-rc2 |
44 |
|
c1206a2c6 fs/afs/: possible... |
45 |
static unsigned long afs_mntpt_expiry_timeout = 10 * 60; |
1da177e4c Linux-2.6.12-rc2 |
46 |
|
1da177e4c Linux-2.6.12-rc2 |
47 |
/* |
1da177e4c Linux-2.6.12-rc2 |
48 49 50 51 |
* no valid lookup procedure on this sort of dir */ static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry, |
00cd8dd3b stop passing name... |
52 |
unsigned int flags) |
1da177e4c Linux-2.6.12-rc2 |
53 |
{ |
a455589f1 assorted conversi... |
54 |
_enter("%p,%p{%pd2}", dir, dentry, dentry); |
1da177e4c Linux-2.6.12-rc2 |
55 |
return ERR_PTR(-EREMOTE); |
ec26815ad [AFS]: Clean up t... |
56 |
} |
1da177e4c Linux-2.6.12-rc2 |
57 |
|
1da177e4c Linux-2.6.12-rc2 |
58 59 60 61 62 |
/* * no valid open procedure on this sort of dir */ static int afs_mntpt_open(struct inode *inode, struct file *file) { |
a455589f1 assorted conversi... |
63 |
_enter("%p,%p{%pD2}", inode, file, file); |
1da177e4c Linux-2.6.12-rc2 |
64 |
return -EREMOTE; |
ec26815ad [AFS]: Clean up t... |
65 |
} |
1da177e4c Linux-2.6.12-rc2 |
66 |
|
1da177e4c Linux-2.6.12-rc2 |
67 68 69 70 71 72 73 |
/* * create a vfsmount to be automounted */ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt) { struct afs_super_info *super; struct vfsmount *mnt; |
bec5eb614 AFS: Implement an... |
74 |
struct afs_vnode *vnode; |
083fd8b21 AFS: Don't pass e... |
75 |
struct page *page; |
bec5eb614 AFS: Implement an... |
76 77 |
char *devname, *options; bool rwpath = false; |
1da177e4c Linux-2.6.12-rc2 |
78 |
int ret; |
a455589f1 assorted conversi... |
79 |
_enter("{%pd}", mntpt); |
1da177e4c Linux-2.6.12-rc2 |
80 |
|
2b0143b5c VFS: normal files... |
81 |
BUG_ON(!d_inode(mntpt)); |
1da177e4c Linux-2.6.12-rc2 |
82 |
|
1da177e4c Linux-2.6.12-rc2 |
83 84 85 |
ret = -ENOMEM; devname = (char *) get_zeroed_page(GFP_KERNEL); if (!devname) |
083fd8b21 AFS: Don't pass e... |
86 |
goto error_no_devname; |
1da177e4c Linux-2.6.12-rc2 |
87 88 89 |
options = (char *) get_zeroed_page(GFP_KERNEL); if (!options) |
083fd8b21 AFS: Don't pass e... |
90 |
goto error_no_options; |
1da177e4c Linux-2.6.12-rc2 |
91 |
|
2b0143b5c VFS: normal files... |
92 |
vnode = AFS_FS_I(d_inode(mntpt)); |
bec5eb614 AFS: Implement an... |
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
if (test_bit(AFS_VNODE_PSEUDODIR, &vnode->flags)) { /* if the directory is a pseudo directory, use the d_name */ static const char afs_root_cell[] = ":root.cell."; unsigned size = mntpt->d_name.len; ret = -ENOENT; if (size < 2 || size > AFS_MAXCELLNAME) goto error_no_page; if (mntpt->d_name.name[0] == '.') { devname[0] = '#'; memcpy(devname + 1, mntpt->d_name.name, size - 1); memcpy(devname + size, afs_root_cell, sizeof(afs_root_cell)); rwpath = true; } else { devname[0] = '%'; memcpy(devname + 1, mntpt->d_name.name, size); memcpy(devname + size + 1, afs_root_cell, sizeof(afs_root_cell)); } } else { /* read the contents of the AFS special symlink */ |
2b0143b5c VFS: normal files... |
116 |
loff_t size = i_size_read(d_inode(mntpt)); |
bec5eb614 AFS: Implement an... |
117 118 119 120 121 |
char *buf; ret = -EINVAL; if (size > PAGE_SIZE - 1) goto error_no_page; |
2b0143b5c VFS: normal files... |
122 |
page = read_mapping_page(d_inode(mntpt)->i_mapping, 0, NULL); |
bec5eb614 AFS: Implement an... |
123 124 125 126 127 128 129 130 |
if (IS_ERR(page)) { ret = PTR_ERR(page); goto error_no_page; } ret = -EIO; if (PageError(page)) goto error; |
da4aa36d0 afs: remove the s... |
131 |
buf = kmap_atomic(page); |
bec5eb614 AFS: Implement an... |
132 |
memcpy(devname, buf, size); |
da4aa36d0 afs: remove the s... |
133 |
kunmap_atomic(buf); |
09cbfeaf1 mm, fs: get rid o... |
134 |
put_page(page); |
bec5eb614 AFS: Implement an... |
135 |
page = NULL; |
1da177e4c Linux-2.6.12-rc2 |
136 |
} |
1da177e4c Linux-2.6.12-rc2 |
137 138 139 140 |
/* work out what options we want */ super = AFS_FS_S(mntpt->d_sb); memcpy(options, "cell=", 5); strcpy(options + 5, super->volume->cell->name); |
bec5eb614 AFS: Implement an... |
141 |
if (super->volume->type == AFSVL_RWVOL || rwpath) |
1da177e4c Linux-2.6.12-rc2 |
142 143 144 |
strcat(options, ",rwpath"); /* try and do the mount */ |
08e0e7c82 [AF_RXRPC]: Make ... |
145 |
_debug("--- attempting mount %s -o %s ---", devname, options); |
93faccbbf fs: Better permis... |
146 |
mnt = vfs_submount(mntpt, &afs_fs_type, devname, options); |
08e0e7c82 [AF_RXRPC]: Make ... |
147 |
_debug("--- mount result %p ---", mnt); |
1da177e4c Linux-2.6.12-rc2 |
148 149 150 |
free_page((unsigned long) devname); free_page((unsigned long) options); |
08e0e7c82 [AF_RXRPC]: Make ... |
151 |
_leave(" = %p", mnt); |
1da177e4c Linux-2.6.12-rc2 |
152 |
return mnt; |
ec26815ad [AFS]: Clean up t... |
153 |
error: |
09cbfeaf1 mm, fs: get rid o... |
154 |
put_page(page); |
083fd8b21 AFS: Don't pass e... |
155 156 157 158 159 |
error_no_page: free_page((unsigned long) options); error_no_options: free_page((unsigned long) devname); error_no_devname: |
08e0e7c82 [AF_RXRPC]: Make ... |
160 |
_leave(" = %d", ret); |
1da177e4c Linux-2.6.12-rc2 |
161 |
return ERR_PTR(ret); |
ec26815ad [AFS]: Clean up t... |
162 |
} |
1da177e4c Linux-2.6.12-rc2 |
163 |
|
1da177e4c Linux-2.6.12-rc2 |
164 |
/* |
d18610b0c AFS: Use d_automo... |
165 |
* handle an automount point |
1da177e4c Linux-2.6.12-rc2 |
166 |
*/ |
d18610b0c AFS: Use d_automo... |
167 |
struct vfsmount *afs_d_automount(struct path *path) |
1da177e4c Linux-2.6.12-rc2 |
168 169 |
{ struct vfsmount *newmnt; |
1da177e4c Linux-2.6.12-rc2 |
170 |
|
a455589f1 assorted conversi... |
171 |
_enter("{%pd}", path->dentry); |
08e0e7c82 [AF_RXRPC]: Make ... |
172 |
|
d18610b0c AFS: Use d_automo... |
173 174 175 |
newmnt = afs_mntpt_do_automount(path->dentry); if (IS_ERR(newmnt)) return newmnt; |
1da177e4c Linux-2.6.12-rc2 |
176 |
|
ea5b778a8 Unexport do_add_m... |
177 178 179 180 |
mntget(newmnt); /* prevent immediate expiration */ mnt_set_expiry(newmnt, &afs_vfsmounts); queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer, afs_mntpt_expiry_timeout * HZ); |
5ffc2836a vfs: kill ->mnt_d... |
181 |
_leave(" = %p", newmnt); |
ea5b778a8 Unexport do_add_m... |
182 |
return newmnt; |
ec26815ad [AFS]: Clean up t... |
183 |
} |
1da177e4c Linux-2.6.12-rc2 |
184 |
|
1da177e4c Linux-2.6.12-rc2 |
185 186 187 |
/* * handle mountpoint expiry timer going off */ |
08e0e7c82 [AF_RXRPC]: Make ... |
188 |
static void afs_mntpt_expiry_timed_out(struct work_struct *work) |
1da177e4c Linux-2.6.12-rc2 |
189 |
{ |
08e0e7c82 [AF_RXRPC]: Make ... |
190 191 192 193 |
_enter(""); if (!list_empty(&afs_vfsmounts)) { mark_mounts_for_expiry(&afs_vfsmounts); |
0ad53eeef afs: add afs_wq a... |
194 195 |
queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer, afs_mntpt_expiry_timeout * HZ); |
08e0e7c82 [AF_RXRPC]: Make ... |
196 197 198 199 |
} _leave(""); } |
1da177e4c Linux-2.6.12-rc2 |
200 |
|
08e0e7c82 [AF_RXRPC]: Make ... |
201 202 203 204 205 206 |
/* * kill the AFS mountpoint timer if it's still running */ void afs_mntpt_kill_timer(void) { _enter(""); |
1da177e4c Linux-2.6.12-rc2 |
207 |
|
08e0e7c82 [AF_RXRPC]: Make ... |
208 |
ASSERT(list_empty(&afs_vfsmounts)); |
0ad53eeef afs: add afs_wq a... |
209 |
cancel_delayed_work_sync(&afs_mntpt_expiry_timer); |
08e0e7c82 [AF_RXRPC]: Make ... |
210 |
} |