6 #include <linux/slab.h>
7 #include <linux/sched.h>
47 spin_lock(&dentry->
d_lock);
69 spin_unlock(&dentry->
d_lock);
80 spin_lock(&dentry->
d_lock);
85 spin_unlock(&dentry->
d_lock);
94 static unsigned fpos_frag(loff_t
p)
98 static unsigned fpos_off(loff_t
p)
100 return p & 0xffffffff;
114 static int __dcache_readdir(
struct file *filp,
129 dout(
"__dcache_readdir %p at %llu (last %p)\n", dir, filp->
f_pos,
132 spin_lock(&parent->
d_lock);
147 di = ceph_dentry(dentry);
150 d_unhashed(dentry) ?
"!hashed" :
"hashed",
157 if (!d_unhashed(dentry) && dentry->
d_inode &&
162 dout(
" skipping %p %.*s at %llu (%llu)%s%s\n", dentry,
164 filp->
f_pos, d_unhashed(dentry) ?
" unhashed" :
"",
165 !dentry->
d_inode ?
" null" :
"");
166 spin_unlock(&dentry->
d_lock);
169 di = ceph_dentry(dentry);
173 spin_unlock(&dentry->
d_lock);
174 spin_unlock(&parent->
d_lock);
179 err = filldir(dirent, dentry->
d_name.name,
181 ceph_translate_ino(dentry->
d_sb, dentry->
d_inode->i_ino),
182 dentry->
d_inode->i_mode >> 12);
202 dout(
" lost D_COMPLETE on %p; falling back to mds\n", dir);
207 spin_lock(&parent->
d_lock);
212 spin_unlock(&parent->
d_lock);
238 static int ceph_readdir(
struct file *filp,
void *dirent,
filldir_t filldir)
241 struct inode *
inode = filp->f_dentry->d_inode;
246 int off = fpos_off(filp->
f_pos);
253 dout(
"readdir %p filp %p frag %u off %u\n", inode, filp, frag, off);
258 if (filp->
f_pos == 0) {
263 dout(
"readdir off 0 -> '.'\n");
264 if (filldir(dirent,
".", 1, ceph_make_fpos(0, 0),
265 ceph_translate_ino(inode->
i_sb, inode->
i_ino),
271 if (filp->
f_pos == 1) {
273 dout(
"readdir off 1 -> '..'\n");
274 if (filldir(dirent,
"..", 2, ceph_make_fpos(0, 1),
275 ceph_translate_ino(inode->
i_sb, ino),
290 err = __dcache_readdir(filp, dirent, filldir);
297 err = note_last_dentry(fi, fi->
dentry->d_name.name,
323 dout(
"readdir fetching %llx.%llx frag %x offset '%s'\n",
330 req->
r_dentry = dget(filp->f_dentry);
343 ceph_mdsc_put_request(req);
346 dout(
"readdir got and parsed readdir result=%d"
347 " on frag %x, end=%d, complete=%d\n", err, frag,
352 dout(
"readdir !did_prepopulate");
363 if (ceph_frag_is_rightmost(frag))
369 err = note_last_dentry(fi,
379 dout(
"readdir frag %x num %d off %d chunkoff %d\n", frag,
382 u64 pos = ceph_make_fpos(frag, off);
388 dout(
"readdir off %d (%d/%d) -> %lld '%.*s' %p\n",
396 ino = ceph_vino_to_ino(vino);
401 ceph_translate_ino(inode->
i_sb, ino), ftype) < 0) {
402 dout(
"filldir stopping us...\n");
406 filp->
f_pos = pos + 1;
416 if (!ceph_frag_is_rightmost(frag)) {
417 frag = ceph_frag_next(frag);
419 filp->
f_pos = ceph_make_fpos(frag, off);
420 dout(
"readdir next frag is %x\n", frag);
437 dout(
"readdir %p filp %p done.\n", inode, filp);
460 struct inode *inode = file->
f_mapping->host;
461 loff_t old_offset =
offset;
468 offset += inode->
i_size + 2;
471 offset += file->
f_pos;
479 if (offset != file->
f_pos) {
491 fpos_frag(offset) != fpos_frag(old_offset) ||
492 fpos_off(offset) < fi->
offset) {
493 dout(
"dir_llseek dropping %p content\n", file);
498 if (offset > old_offset)
510 struct dentry *dentry,
int err)
513 struct inode *parent = dentry->
d_parent->d_inode;
521 dout(
"ENOENT on snapdir %p '%.*s', linking to snapdir %p\n",
522 dentry, dentry->
d_name.len, dentry->
d_name.name, inode);
523 BUG_ON(!d_unhashed(dentry));
524 d_add(dentry, inode);
542 struct dentry *dentry,
int err)
548 dout(
"ENOENT and no trace, dentry %p inode %p\n",
559 dentry = ERR_PTR(err);
567 static int is_root_ceph_dentry(
struct inode *inode,
struct dentry *dentry)
577 static struct dentry *ceph_lookup(
struct inode *dir,
struct dentry *dentry,
586 dout(
"lookup %p dentry %p '%.*s'\n",
606 !is_root_ceph_dentry(dir, dentry) &&
610 dout(
" dir %p complete, -ENOENT\n", dir);
622 return ERR_CAST(req);
631 ceph_mdsc_put_request(req);
632 dout(
"lookup result=%p\n", dentry);
642 struct dentry *
result = ceph_lookup(dir, dentry, 0);
644 if (result && !IS_ERR(result)) {
656 return PTR_ERR(result);
659 static int ceph_mknod(
struct inode *dir,
struct dentry *dentry,
670 dout(
"mknod in dir %p dentry %p mode 0%ho rdev %d\n",
671 dir, dentry, mode, rdev);
687 ceph_mdsc_put_request(req);
693 static int ceph_create(
struct inode *dir,
struct dentry *dentry,
umode_t mode,
696 return ceph_mknod(dir, dentry, mode, 0);
699 static int ceph_symlink(
struct inode *dir,
struct dentry *dentry,
710 dout(
"symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest);
725 ceph_mdsc_put_request(req);
731 static int ceph_mkdir(
struct inode *dir,
struct dentry *dentry,
umode_t mode)
742 dout(
"mksnap dir %p snap '%.*s' dn %p\n", dir,
745 dout(
"mkdir dir %p dn %p mode 0%ho\n", dir, dentry, mode);
765 ceph_mdsc_put_request(req);
772 static int ceph_link(
struct dentry *old_dentry,
struct inode *dir,
773 struct dentry *dentry)
783 dout(
"link in dir %p old_dentry %p dentry %p\n", dir,
804 ceph_mdsc_put_request(req);
814 static int drop_caps_for_unlink(
struct inode *inode)
831 static int ceph_unlink(
struct inode *dir,
struct dentry *dentry)
835 struct inode *inode = dentry->
d_inode;
842 dout(
"rmsnap dir %p '%.*s' dn %p\n", dir, dentry->
d_name.len,
843 dentry->
d_name.name, dentry);
846 dout(
"unlink/rmdir dir %p dn %p inode %p\n",
866 ceph_mdsc_put_request(req);
871 static int ceph_rename(
struct inode *old_dir,
struct dentry *old_dentry,
872 struct inode *new_dir,
struct dentry *new_dentry)
879 if (ceph_snap(old_dir) != ceph_snap(new_dir))
884 dout(
"rename dir %p dentry %p to dir %p dentry %p\n",
885 old_dir, old_dentry, new_dir, new_dentry);
913 d_move(old_dentry, new_dentry);
919 ceph_mdsc_put_request(req);
928 spin_lock(&dentry->
d_lock);
930 ceph_dentry(dentry)->lease_shared_gen = 0;
931 spin_unlock(&dentry->
d_lock);
938 static int dentry_lease_is_valid(
struct dentry *dentry)
946 struct inode *dir =
NULL;
949 spin_lock(&dentry->
d_lock);
950 di = ceph_dentry(dentry);
966 session = ceph_get_mds_session(s);
973 spin_unlock(&dentry->
d_lock);
980 dout(
"dentry_lease_is_valid - dentry %p = %d\n", dentry, valid);
987 static int dir_lease_is_valid(
struct inode *dir,
struct dentry *dentry)
997 dout(
"dir_lease_is_valid dir %p v%u dentry %p v%u = %d\n",
1006 static int ceph_d_revalidate(
struct dentry *dentry,
unsigned int flags)
1014 dout(
"d_revalidate %p '%.*s' inode %p offset %lld\n", dentry,
1016 ceph_dentry(dentry)->offset);
1022 dout(
"d_revalidate %p '%.*s' inode %p is SNAPPED\n", dentry,
1028 }
else if (dentry_lease_is_valid(dentry) ||
1029 dir_lease_is_valid(dir, dentry)) {
1033 dout(
"d_revalidate %p %s\n", dentry, valid ?
"valid" :
"invalid");
1045 static void ceph_d_release(
struct dentry *dentry)
1049 dout(
"d_release %p\n", dentry);
1057 static int ceph_snapdir_d_revalidate(
struct dentry *dentry,
1074 if (dentry && ceph_dentry(dentry) &&
1076 dout(
" marking %p (%p) complete\n", inode, dentry);
1086 if (dentry && ceph_dentry(dentry)) {
1087 dout(
" marking %p (%p) complete\n", inode, dentry);
1097 if (dentry && ceph_dentry(dentry)) {
1098 dout(
" marking %p (%p) NOT complete\n", inode, dentry);
1111 static void ceph_d_prune(
struct dentry *dentry)
1115 dout(
"ceph_d_prune %p\n", dentry);
1122 if (d_unhashed(dentry))
1129 di = ceph_dentry(dentry->
d_parent);
1137 static ssize_t ceph_read_dir(
struct file *file,
char __user *
buf,
size_t size,
1141 struct inode *inode = file->f_dentry->d_inode;
1157 " subdirs: %20lld\n"
1158 "rentries: %20lld\n"
1160 " rsubdirs: %20lld\n"
1162 "rctime: %10ld.%09ld\n",
1180 *ppos += (size -
left);
1188 static int ceph_dir_fsync(
struct file *file, loff_t
start, loff_t
end,
1191 struct inode *inode = file->
f_path.dentry->d_inode;
1198 dout(
"dir_fsync %p\n", inode);
1205 if (list_empty(head))
1210 last_tid = req->
r_tid;
1213 ceph_mdsc_get_request(req);
1216 dout(
"dir_fsync %p wait on tid %llu (until %llu)\n",
1217 inode, req->
r_tid, last_tid);
1228 ceph_mdsc_put_request(req);
1231 if (ret || list_empty(head))
1235 }
while (req->
r_tid < last_tid);
1253 dout(
"dentry_lru_add %p %p '%.*s'\n", di, dn,
1255 mdsc = ceph_sb_to_client(dn->
d_sb)->mdsc;
1267 dout(
"dentry_lru_touch %p %p '%.*s' (offset %lld)\n", di, dn,
1269 mdsc = ceph_sb_to_client(dn->
d_sb)->mdsc;
1280 dout(
"dentry_lru_del %p %p '%.*s'\n", di, dn,
1282 mdsc = ceph_sb_to_client(dn->
d_sb)->mdsc;
1284 list_del_init(&di->
lru);
1309 .read = ceph_read_dir,
1310 .readdir = ceph_readdir,
1311 .llseek = ceph_dir_llseek,
1315 .fsync = ceph_dir_fsync,
1319 .lookup = ceph_lookup,
1327 .mknod = ceph_mknod,
1328 .symlink = ceph_symlink,
1329 .mkdir = ceph_mkdir,
1331 .unlink = ceph_unlink,
1332 .rmdir = ceph_unlink,
1333 .rename = ceph_rename,
1334 .create = ceph_create,
1339 .d_revalidate = ceph_d_revalidate,
1340 .d_release = ceph_d_release,
1341 .d_prune = ceph_d_prune,
1345 .d_revalidate = ceph_snapdir_d_revalidate,
1346 .d_release = ceph_d_release,
1350 .d_release = ceph_d_release,
1351 .d_prune = ceph_d_prune,