if (err)
goto out_drop_write;
+ if (!work->tcon->posix_extensions && d_is_dir(old_child) &&
+ ksmbd_has_open_files(old_child)) {
+ err = -EACCES;
+ goto out3;
+ }
+
parent_fp = ksmbd_lookup_fd_inode(old_child->d_parent);
if (parent_fp) {
if ((parent_fp->daccess & FILE_DELETE_LE) ||
#include <linux/vmalloc.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/dcache.h>
#include "glob.h"
#include "vfs_cache.h"
return NULL;
}
+bool ksmbd_has_open_files(struct dentry *dentry)
+{
+ struct ksmbd_file *fp;
+ unsigned int id;
+ bool ret = false;
+
+ read_lock(&global_ft.lock);
+ idr_for_each_entry(global_ft.idr, fp, id) {
+ struct dentry *fp_dentry = fp->filp->f_path.dentry;
+
+ if (fp->f_state != FP_INITED)
+ continue;
+ if (fp_dentry == dentry)
+ continue;
+ if (is_subdir(fp_dentry, dentry)) {
+ ret = true;
+ break;
+ }
+ }
+ read_unlock(&global_ft.lock);
+
+ return ret;
+}
+
#define OPEN_ID_TYPE_VOLATILE_ID (0)
#define OPEN_ID_TYPE_PERSISTENT_ID (1)
int ksmbd_close_fd_app_instance_id(char *app_instance_id);
struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid);
struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry);
+bool ksmbd_has_open_files(struct dentry *dentry);
unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp);
struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp);
void ksmbd_launch_ksmbd_durable_scavenger(void);