dir.c (304ec482f562885b178b370cd50340447585d1c0) dir.c (6ef0bc6ddee1f62310877a1d53b1ea1d0d8e51a2)
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/ceph/ceph_debug.h>
3
4#include <linux/spinlock.h>
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/ceph/ceph_debug.h>
3
4#include <linux/spinlock.h>
5#include <linux/fs_struct.h>
5#include <linux/namei.h>
6#include <linux/slab.h>
7#include <linux/sched.h>
8#include <linux/xattr.h>
9
10#include "super.h"
11#include "mds_client.h"
12

--- 984 unchanged lines hidden (view full) ---

997 ihold(d_inode(old_dentry));
998 d_instantiate(dentry, d_inode(old_dentry));
999 }
1000 ceph_mdsc_put_request(req);
1001 return err;
1002}
1003
1004/*
6#include <linux/namei.h>
7#include <linux/slab.h>
8#include <linux/sched.h>
9#include <linux/xattr.h>
10
11#include "super.h"
12#include "mds_client.h"
13

--- 984 unchanged lines hidden (view full) ---

998 ihold(d_inode(old_dentry));
999 d_instantiate(dentry, d_inode(old_dentry));
1000 }
1001 ceph_mdsc_put_request(req);
1002 return err;
1003}
1004
1005/*
1005 * For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps. If it
1006 * looks like the link count will hit 0, drop any other caps (other
1007 * than PIN) we don't specifically want (due to the file still being
1008 * open).
1009 */
1010static int drop_caps_for_unlink(struct inode *inode)
1011{
1012 struct ceph_inode_info *ci = ceph_inode(inode);
1013 int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
1014
1015 spin_lock(&ci->i_ceph_lock);
1016 if (inode->i_nlink == 1) {
1017 drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN);
1018 ci->i_ceph_flags |= CEPH_I_NODELAY;
1019 }
1020 spin_unlock(&ci->i_ceph_lock);
1021 return drop;
1022}
1023
1024/*
1025 * rmdir and unlink are differ only by the metadata op code
1026 */
1027static int ceph_unlink(struct inode *dir, struct dentry *dentry)
1028{
1029 struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
1030 struct ceph_mds_client *mdsc = fsc->mdsc;
1031 struct inode *inode = d_inode(dentry);
1032 struct ceph_mds_request *req;

--- 17 unchanged lines hidden (view full) ---

1050 goto out;
1051 }
1052 req->r_dentry = dget(dentry);
1053 req->r_num_caps = 2;
1054 req->r_parent = dir;
1055 set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
1056 req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
1057 req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
1006 * rmdir and unlink are differ only by the metadata op code
1007 */
1008static int ceph_unlink(struct inode *dir, struct dentry *dentry)
1009{
1010 struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
1011 struct ceph_mds_client *mdsc = fsc->mdsc;
1012 struct inode *inode = d_inode(dentry);
1013 struct ceph_mds_request *req;

--- 17 unchanged lines hidden (view full) ---

1031 goto out;
1032 }
1033 req->r_dentry = dget(dentry);
1034 req->r_num_caps = 2;
1035 req->r_parent = dir;
1036 set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
1037 req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
1038 req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
1058 req->r_inode_drop = drop_caps_for_unlink(inode);
1039 req->r_inode_drop = ceph_drop_caps_for_unlink(inode);
1059 err = ceph_mdsc_do_request(mdsc, dir, req);
1060 if (!err && !req->r_reply_info.head->is_dentry)
1061 d_delete(dentry);
1062 ceph_mdsc_put_request(req);
1063out:
1064 return err;
1065}
1066

--- 31 unchanged lines hidden (view full) ---

1098 req->r_parent = new_dir;
1099 set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
1100 req->r_old_dentry_drop = CEPH_CAP_FILE_SHARED;
1101 req->r_old_dentry_unless = CEPH_CAP_FILE_EXCL;
1102 req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
1103 req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
1104 /* release LINK_RDCACHE on source inode (mds will lock it) */
1105 req->r_old_inode_drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
1040 err = ceph_mdsc_do_request(mdsc, dir, req);
1041 if (!err && !req->r_reply_info.head->is_dentry)
1042 d_delete(dentry);
1043 ceph_mdsc_put_request(req);
1044out:
1045 return err;
1046}
1047

--- 31 unchanged lines hidden (view full) ---

1079 req->r_parent = new_dir;
1080 set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
1081 req->r_old_dentry_drop = CEPH_CAP_FILE_SHARED;
1082 req->r_old_dentry_unless = CEPH_CAP_FILE_EXCL;
1083 req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
1084 req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
1085 /* release LINK_RDCACHE on source inode (mds will lock it) */
1086 req->r_old_inode_drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
1106 if (d_really_is_positive(new_dentry))
1107 req->r_inode_drop = drop_caps_for_unlink(d_inode(new_dentry));
1087 if (d_really_is_positive(new_dentry)) {
1088 req->r_inode_drop =
1089 ceph_drop_caps_for_unlink(d_inode(new_dentry));
1090 }
1108 err = ceph_mdsc_do_request(mdsc, old_dir, req);
1109 if (!err && !req->r_reply_info.head->is_dentry) {
1110 /*
1111 * Normally d_move() is done by fill_trace (called by
1112 * do_request, above). If there is no trace, we need
1113 * to do it here.
1114 */
1115 d_move(old_dentry, new_dentry);

--- 414 unchanged lines hidden ---
1091 err = ceph_mdsc_do_request(mdsc, old_dir, req);
1092 if (!err && !req->r_reply_info.head->is_dentry) {
1093 /*
1094 * Normally d_move() is done by fill_trace (called by
1095 * do_request, above). If there is no trace, we need
1096 * to do it here.
1097 */
1098 d_move(old_dentry, new_dentry);

--- 414 unchanged lines hidden ---