#ifndef LLITE_INTERNAL_H
#define LLITE_INTERNAL_H
-#include <lustre_debug.h>
+#include <obd.h>
#include <lustre_disk.h> /* for s2sbi */
-#include <lustre_eacl.h>
#include <lustre_linkea.h>
/* for struct cl_lock_descr and struct cl_io */
#include <linux/aio.h>
#include <lustre_compat.h>
#include <lustre_crypto.h>
+#include <range_lock.h>
#include "vvp_internal.h"
-#include "range_lock.h"
#include "pcc.h"
+#include "foreign_symlink.h"
#ifndef FMODE_EXEC
#define FMODE_EXEC 0
*
* We must take lli_trunc_sem in read mode on entry in to various i/o paths
* in Lustre, in order to exclude truncates. Some of these paths then need to
- * take the mmap_sem, while still holding the trunc_sem. The problem is that
- * page faults hold the mmap_sem when calling in to Lustre, and then must also
+ * take the mmap_lock, while still holding the trunc_sem. The problem is that
+ * page faults hold the mmap_lock when calling in to Lustre, and then must also
* take the trunc_sem to exclude truncate.
*
- * This means the locking order for trunc_sem and mmap_sem is sometimes AB,
+ * This means the locking order for trunc_sem and mmap_lock is sometimes AB,
* sometimes BA. This is almost OK because in both cases, we take the trunc
* sem for read, so it doesn't block.
*
*
* So we have, on our truncate sem, in order (where 'reader' and 'writer' refer
* to the mode in which they take the semaphore):
- * reader (holding mmap_sem, needs truncate_sem)
+ * reader (holding mmap_lock, needs truncate_sem)
* writer
- * reader (holding truncate sem, waiting for mmap_sem)
+ * reader (holding truncate sem, waiting for mmap_lock)
*
* And so the readers deadlock.
*
* of the order they arrived in.
*
* down_read_nowait is only used in the page fault case, where we already hold
- * the mmap_sem. This is because otherwise repeated read and write operations
+ * the mmap_lock. This is because otherwise repeated read and write operations
* (which take the truncate sem) could prevent a truncate from ever starting.
* This could still happen with page faults, but without an even more complex
* mechanism, this is unavoidable.
LLIF_PROJECT_INHERIT = 3,
/* update atime from MDS even if it's older than local inode atime. */
LLIF_UPDATE_ATIME = 4,
+ /* foreign file/dir can be unlinked unconditionnaly */
+ LLIF_FOREIGN_REMOVABLE = 5,
+ /* setting encryption context in progress */
+ LLIF_SET_ENC_CTX = 6,
};
#define LL_SBI_FILE_HEAT 0x4000000 /* file heat support */
#define LL_SBI_TEST_DUMMY_ENCRYPTION 0x8000000 /* test dummy encryption */
#define LL_SBI_ENCRYPT 0x10000000 /* client side encryption */
+#define LL_SBI_FOREIGN_SYMLINK 0x20000000 /* foreign fake-symlink support */
+/* foreign fake-symlink upcall registered */
+#define LL_SBI_FOREIGN_SYMLINK_UPCALL 0x40000000
#define LL_SBI_FLAGS { \
"nolck", \
"checksum", \
"file_heat", \
"test_dummy_encryption", \
"noencrypt", \
+ "foreign_symlink", \
+ "foreign_symlink_upcall", \
}
/* This is embedded into llite super-blocks to keep track of connect
struct dentry *ll_debugfs_entry;
struct lu_fid ll_root_fid; /* root object fid */
- int ll_flags;
+ int ll_flags;
unsigned int ll_xattr_cache_enabled:1,
ll_xattr_cache_set:1, /* already set to 0/1 */
ll_client_common_fill_super_succeeded:1,
ll_checksum_set:1;
- struct lustre_client_ocd ll_lco;
+ struct lustre_client_ocd ll_lco;
- struct lprocfs_stats *ll_stats; /* lprocfs stats counter */
+ struct lprocfs_stats *ll_stats; /* lprocfs stats counter */
/* Used to track "unstable" pages on a client, and maintain a
* LRU list of clean pages. An "unstable" page is defined as
* but is uncommitted to stable storage. */
struct cl_client_cache *ll_cache;
- struct lprocfs_stats *ll_ra_stats;
-
- struct ll_ra_info ll_ra_info;
- unsigned int ll_namelen;
- struct file_operations *ll_fop;
-
- struct lu_site *ll_site;
- struct cl_device *ll_cl;
- /* Statistics */
- struct ll_rw_extents_info ll_rw_extents_info;
- int ll_extent_process_count;
- struct ll_rw_process_info ll_rw_process_info[LL_PROCESS_HIST_MAX];
- unsigned int ll_offset_process_count;
- struct ll_rw_process_info ll_rw_offset_info[LL_OFFSET_HIST_MAX];
- unsigned int ll_rw_offset_entry_count;
- int ll_stats_track_id;
- enum stats_track_type ll_stats_track_type;
- int ll_rw_stats_on;
+ struct lprocfs_stats *ll_ra_stats;
+
+ struct ll_ra_info ll_ra_info;
+ unsigned int ll_namelen;
+ const struct file_operations *ll_fop;
+
+ struct lu_site *ll_site;
+ struct cl_device *ll_cl;
+ /* Statistics */
+ struct ll_rw_extents_info ll_rw_extents_info;
+ int ll_extent_process_count;
+ struct ll_rw_process_info ll_rw_process_info[LL_PROCESS_HIST_MAX];
+ unsigned int ll_offset_process_count;
+ struct ll_rw_process_info ll_rw_offset_info[LL_OFFSET_HIST_MAX];
+ unsigned int ll_rw_offset_entry_count;
+ int ll_stats_track_id;
+ enum stats_track_type ll_stats_track_type;
+ int ll_rw_stats_on;
/* metadata stat-ahead */
unsigned int ll_sa_running_max;/* max concurrent
/* Persistent Client Cache */
struct pcc_super ll_pcc_super;
+
+ /* to protect vs updates in all following foreign symlink fields */
+ struct rw_semaphore ll_foreign_symlink_sem;
+ /* foreign symlink path prefix */
+ char *ll_foreign_symlink_prefix;
+ /* full prefix size including leading '\0' */
+ size_t ll_foreign_symlink_prefix_size;
+ /* foreign symlink path upcall */
+ char *ll_foreign_symlink_upcall;
+ /* foreign symlink path upcall infos */
+ struct ll_foreign_symlink_upcall_item *ll_foreign_symlink_upcall_items;
+ /* foreign symlink path upcall nb infos */
+ unsigned int ll_foreign_symlink_upcall_nb_items;
};
#define SBI_DEFAULT_HEAT_DECAY_WEIGHT ((80 * 256 + 50) / 100)
return !!(sbi->ll_flags & LL_SBI_FILE_HEAT);
}
+static inline bool ll_sbi_has_foreign_symlink(struct ll_sb_info *sbi)
+{
+ return !!(sbi->ll_flags & LL_SBI_FOREIGN_SYMLINK);
+}
+
void ll_ras_enter(struct file *f, loff_t pos, size_t count);
/* llite/lcommon_misc.c */
GET_DEFAULT_LAYOUT_ROOT = 1,
};
-struct ll_dir_chain {
-};
-
-static inline void ll_dir_chain_init(struct ll_dir_chain *chain)
-{
-}
-
-static inline void ll_dir_chain_fini(struct ll_dir_chain *chain)
-{
-}
-
extern const struct file_operations ll_dir_operations;
extern const struct inode_operations ll_dir_inode_operations;
#ifdef HAVE_DIR_CONTEXT
int ll_get_mdt_idx(struct inode *inode);
int ll_get_mdt_idx_by_fid(struct ll_sb_info *sbi, const struct lu_fid *fid);
struct page *ll_get_dir_page(struct inode *dir, struct md_op_data *op_data,
- __u64 offset, struct ll_dir_chain *chain);
+ __u64 offset);
void ll_release_page(struct inode *inode, struct page *page, bool remove);
int quotactl_ioctl(struct ll_sb_info *sbi, struct if_quotactl *qctl);
extern const struct address_space_operations ll_aops;
/* llite/file.c */
-extern struct file_operations ll_file_operations;
-extern struct file_operations ll_file_operations_flock;
-extern struct file_operations ll_file_operations_noflock;
-extern struct inode_operations ll_file_inode_operations;
+extern const struct inode_operations ll_file_inode_operations;
+const struct file_operations *ll_select_file_operations(struct ll_sb_info *sbi);
extern int ll_have_md_lock(struct inode *inode, __u64 *bits,
enum ldlm_mode l_req_mode);
extern enum ldlm_mode ll_take_md_lock(struct inode *inode, __u64 bits,
int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat);
#endif
int ll_getattr_dentry(struct dentry *de, struct kstat *stat, u32 request_mask,
- unsigned int flags);
-struct posix_acl *ll_get_acl(struct inode *inode, int type);
-#ifdef HAVE_IOP_SET_ACL
+ unsigned int flags, bool foreign);
#ifdef CONFIG_LUSTRE_FS_POSIX_ACL
+struct posix_acl *ll_get_acl(struct inode *inode, int type);
int ll_set_acl(struct inode *inode, struct posix_acl *acl, int type);
#else /* !CONFIG_LUSTRE_FS_POSIX_ACL */
+#define ll_get_acl NULL
#define ll_set_acl NULL
#endif /* CONFIG_LUSTRE_FS_POSIX_ACL */
-#endif
-
static inline int ll_xflags_to_inode_flags(int xflags)
{
return ((xflags & FS_XFLAG_SYNC) ? S_SYNC : 0) |
((xflags & FS_XFLAG_IMMUTABLE) ? S_IMMUTABLE : 0);
}
-static inline int ll_inode_flags_to_xflags(int flags)
+static inline int ll_inode_flags_to_xflags(int inode_flags)
{
- return ((flags & S_SYNC) ? FS_XFLAG_SYNC : 0) |
- ((flags & S_NOATIME) ? FS_XFLAG_NOATIME : 0) |
- ((flags & S_APPEND) ? FS_XFLAG_APPEND : 0) |
- ((flags & S_IMMUTABLE) ? FS_XFLAG_IMMUTABLE : 0);
+ return ((inode_flags & S_SYNC) ? FS_XFLAG_SYNC : 0) |
+ ((inode_flags & S_NOATIME) ? FS_XFLAG_NOATIME : 0) |
+ ((inode_flags & S_APPEND) ? FS_XFLAG_APPEND : 0) |
+ ((inode_flags & S_IMMUTABLE) ? FS_XFLAG_IMMUTABLE : 0);
}
int ll_migrate(struct inode *parent, struct file *file,
struct lookup_intent *it, struct dentry *de);
/* llite/llite_lib.c */
-extern struct super_operations lustre_super_operations;
+extern const struct super_operations lustre_super_operations;
void ll_lli_init(struct ll_inode_info *lli);
int ll_fill_super(struct super_block *sb);
int ll_statfs_internal(struct ll_sb_info *sbi, struct obd_statfs *osfs,
u32 flags);
int ll_update_inode(struct inode *inode, struct lustre_md *md);
-void ll_update_inode_flags(struct inode *inode, int ext_flags);
+void ll_update_inode_flags(struct inode *inode, unsigned int ext_flags);
int ll_read_inode2(struct inode *inode, void *opaque);
void ll_delete_inode(struct inode *inode);
int ll_iocontrol(struct inode *inode, struct file *file,
}
/* llite/llite_nfs.c */
-extern struct export_operations lustre_export_operations;
+extern const struct export_operations lustre_export_operations;
__u32 get_uuid2int(const char *name, int len);
struct inode *search_inode_for_lustre(struct super_block *sb,
const struct lu_fid *fid);
int ll_dir_get_parent_fid(struct inode *dir, struct lu_fid *parent_fid);
/* llite/symlink.c */
-extern struct inode_operations ll_fast_symlink_inode_operations;
+extern const struct inode_operations ll_fast_symlink_inode_operations;
/**
* IO arguments for various VFS I/O interfaces.
/* llite/llite_mmap.c */
-int ll_teardown_mmaps(struct address_space *mapping, __u64 first, __u64 last);
int ll_file_mmap(struct file * file, struct vm_area_struct * vma);
void policy_from_vma(union ldlm_policy_data *policy, struct vm_area_struct *vma,
unsigned long addr, size_t count);
/* crypto.c */
extern const struct llcrypt_operations lustre_cryptops;
#endif
+/* llite/llite_foreign.c */
+int ll_manage_foreign(struct inode *inode, struct lustre_md *lmd);
+bool ll_foreign_is_openable(struct dentry *dentry, unsigned int flags);
+bool ll_foreign_is_removable(struct dentry *dentry, bool unset);
#endif /* LLITE_INTERNAL_H */